move ssl certificate serialisation into a url to the ssl_cert utility code

This commit is contained in:
Vincent Sanders 2020-05-09 22:42:12 +01:00
parent a98003674b
commit fbc0847db0
3 changed files with 92 additions and 53 deletions

View File

@ -4769,65 +4769,23 @@ nserror browser_window_show_certificates(struct browser_window *bw)
{
nserror res;
nsurl *url;
size_t allocsize;
size_t urlstrlen;
uint8_t *urlstr;
size_t depth;
if (bw->current_cert_chain == NULL) {
return NSERROR_NOT_FOUND;
}
allocsize = 20;
for (depth = 0; depth < bw->current_cert_chain->depth; depth++) {
allocsize += 7; /* allow for &cert= */
allocsize += 4 * ((bw->current_cert_chain->certs[depth].der_length + 2) / 3);
res = cert_chain_to_query(bw->current_cert_chain, &url);
if (res == NSERROR_OK) {
res = browser_window_create(BW_CREATE_HISTORY |
BW_CREATE_FOREGROUND |
BW_CREATE_TAB,
url,
NULL,
bw,
NULL);
nsurl_unref(url);
}
urlstr = malloc(allocsize);
if (urlstr == NULL) {
return NSERROR_NOMEM;
}
urlstrlen = snprintf((char *)urlstr, allocsize, "about:certificate");
for (depth = 0; depth < bw->current_cert_chain->depth; depth++) {
nsuerror nsures;
size_t output_length;
urlstrlen += snprintf((char *)urlstr + urlstrlen,
allocsize - urlstrlen,
"&cert=");
output_length = allocsize - urlstrlen;
nsures = nsu_base64_encode_url(
bw->current_cert_chain->certs[depth].der,
bw->current_cert_chain->certs[depth].der_length,
(uint8_t *)urlstr + urlstrlen,
&output_length);
if (nsures != NSUERROR_OK) {
free(urlstr);
return (nserror)nsures;
}
urlstrlen += output_length;
}
urlstr[17] = '?';
urlstr[urlstrlen] = 0;
res = nsurl_create((const char *)urlstr, &url);
free(urlstr);
if (res != NSERROR_OK) {
return res;
}
res = browser_window_create(BW_CREATE_HISTORY |
BW_CREATE_FOREGROUND |
BW_CREATE_TAB,
url,
NULL,
bw,
NULL);
nsurl_unref(url);
return res;
}

View File

@ -118,6 +118,14 @@ nserror cert_chain_dup(const struct cert_chain *src, struct cert_chain **dst_out
*/
nserror cert_chain_from_query(struct nsurl *url, struct cert_chain **chain_out);
/**
* create a fetch query string from a certificate chain
*
*
* \return NSERROR_OK on success or NSERROR_NOMEM on memory exhaustion
*/
nserror cert_chain_to_query(struct cert_chain *chain, struct nsurl **url_out);
/**
* free a certificate chain
*

View File

@ -132,6 +132,9 @@ cert_chain_dup(const struct cert_chain *src, struct cert_chain **dst_out)
#define MIN_CERT_LEN 64
/**
* process a part of a query extracting the certificate of an error code
*/
static nserror
process_query_section(const char *str, size_t len, struct cert_chain* chain)
{
@ -215,6 +218,76 @@ nserror cert_chain_from_query(struct nsurl *url, struct cert_chain **chain_out)
}
/*
* create a fetch query string from a certificate chain
*
* exported interface documented in netsurf/ssl_certs.h
*/
nserror cert_chain_to_query(struct cert_chain *chain, struct nsurl **url_out )
{
nserror res;
nsurl *url;
size_t allocsize;
size_t urlstrlen;
uint8_t *urlstr;
size_t depth;
allocsize = 20;
for (depth = 0; depth < chain->depth; depth++) {
allocsize += 7; /* allow for &cert= */
allocsize += 4 * ((chain->certs[depth].der_length + 2) / 3);
if (chain->certs[depth].err != SSL_CERT_ERR_OK) {
allocsize += 20; /* allow for &certerr=4000000000 */
}
}
urlstr = malloc(allocsize);
if (urlstr == NULL) {
return NSERROR_NOMEM;
}
urlstrlen = snprintf((char *)urlstr, allocsize, "about:certificate");
for (depth = 0; depth < chain->depth; depth++) {
nsuerror nsures;
size_t output_length;
urlstrlen += snprintf((char *)urlstr + urlstrlen,
allocsize - urlstrlen,
"&cert=");
output_length = allocsize - urlstrlen;
nsures = nsu_base64_encode_url(
chain->certs[depth].der,
chain->certs[depth].der_length,
(uint8_t *)urlstr + urlstrlen,
&output_length);
if (nsures != NSUERROR_OK) {
free(urlstr);
return (nserror)nsures;
}
urlstrlen += output_length;
if (chain->certs[depth].err != SSL_CERT_ERR_OK) {
urlstrlen += snprintf((char *)urlstr + urlstrlen,
allocsize - urlstrlen,
"&certerr=%d",
chain->certs[depth].err);
}
}
urlstr[17] = '?';
urlstr[urlstrlen] = 0;
res = nsurl_create((const char *)urlstr, &url);
free(urlstr);
if (res == NSERROR_OK) {
*url_out = url;
}
return res;
}
/*
* free certificate chain
*