diff options
author | Vincent Sanders <vince@kyllikki.org> | 2020-02-23 21:41:39 +0000 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2020-02-24 16:59:18 +0000 |
commit | f172a21df9e5e5e73379a4a700957e965d872d3c (patch) | |
tree | 4d28630ef0092b5b70ac2dac847cc7c218d13c63 /utils | |
parent | 5c205fbff0a307bf04439ed884b5c294873ef1f2 (diff) | |
download | netsurf-f172a21df9e5e5e73379a4a700957e965d872d3c.tar.gz netsurf-f172a21df9e5e5e73379a4a700957e965d872d3c.tar.bz2 |
about scheme certificate viewer initial implementation
Diffstat (limited to 'utils')
-rw-r--r-- | utils/ssl_certs.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/utils/ssl_certs.c b/utils/ssl_certs.c index 09500a4fe..94e83eba0 100644 --- a/utils/ssl_certs.c +++ b/utils/ssl_certs.c @@ -24,9 +24,11 @@ #include <stdlib.h> #include <stdint.h> #include <string.h> +#include <nsutils/base64.h> #include "utils/errors.h" #include "utils/log.h" +#include "utils/nsurl.h" #include "netsurf/ssl_certs.h" @@ -128,6 +130,91 @@ cert_chain_dup(const struct cert_chain *src, struct cert_chain **dst_out) } +#define MIN_CERT_LEN 64 + +static nserror +process_query_section(const char *str, size_t len, struct cert_chain* chain) +{ + nsuerror nsures; + + if ((len > (5 + MIN_CERT_LEN)) && + (strncmp(str, "cert=", 5) == 0)) { + /* possible certificate entry */ + nsures = nsu_base64_decode_alloc_url( + (const uint8_t *)str + 5, + len - 5, + &chain->certs[chain->depth].der, + &chain->certs[chain->depth].der_length); + if (nsures == NSUERROR_OK) { + chain->depth++; + } + } else if ((len > 8) && + (strncmp(str, "certerr=", 8) == 0)) { + /* certificate entry error code */ + if (chain->depth > 0) { + chain->certs[chain->depth - 1].err = strtoul(str + 8, NULL, 10); + } + } + return NSERROR_OK; +} + +/* + * create a certificate chain from a fetch query string + * + * exported interface documented in netsurf/ssl_certs.h + */ +nserror cert_chain_from_query(struct nsurl *url, struct cert_chain **chain_out) +{ + struct cert_chain* chain; + nserror res; + char *querystr; + size_t querylen; + size_t kvstart; + size_t kvlen; + + res = nsurl_get(url, NSURL_QUERY, &querystr, &querylen); + if (res != NSERROR_OK) { + return res; + } + + if (querylen < MIN_CERT_LEN) { + free(querystr); + return NSERROR_NEED_DATA; + } + + res = cert_chain_alloc(0, &chain); + if (res != NSERROR_OK) { + free(querystr); + return res; + } + + for (kvlen = 0, kvstart = 0; kvstart < querylen; kvstart += kvlen) { + /* get query section length */ + kvlen = 0; + while (((kvstart + kvlen) < querylen) && + (querystr[kvstart + kvlen] != '&')) { + kvlen++; + } + + res = process_query_section(querystr + kvstart, kvlen, chain); + if (res != NSERROR_OK) { + break; + } + kvlen++; /* account for & separator */ + } + free(querystr); + + if (chain->depth > 0) { + *chain_out = chain; + } else { + free(chain); + return NSERROR_INVALID; + } + + return NSERROR_OK; +} + + /* * free certificate chain * |