diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/content.h | 7 | ||||
-rw-r--r-- | content/fetch.h | 5 | ||||
-rw-r--r-- | content/fetchers/curl.c | 177 | ||||
-rw-r--r-- | content/hlcache.c | 9 | ||||
-rw-r--r-- | content/llcache.c | 285 | ||||
-rw-r--r-- | content/llcache.h | 35 |
6 files changed, 171 insertions, 347 deletions
diff --git a/content/content.h b/content/content.h index 144a698c1..f8f8d32f1 100644 --- a/content/content.h +++ b/content/content.h @@ -44,7 +44,7 @@ struct object_params; struct rect; struct redraw_context; struct llcache_query_msg; -struct ssl_cert_info; +struct cert_chain; /** Status of a content */ typedef enum { @@ -118,10 +118,7 @@ union content_msg_data { * CONTENT_MSG_SSL_CERTS - The certificate chain from the * underlying fetch */ - struct { - const struct ssl_cert_info *certs; /**< The chain */ - size_t num; /**< The number of certs in the chain */ - } certs; + const struct cert_chain *chain; /** * CONTENT_MSG_ERROR - Error from content or underlying fetch diff --git a/content/fetch.h b/content/fetch.h index 9a81ece95..9e80b2685 100644 --- a/content/fetch.h +++ b/content/fetch.h @@ -75,10 +75,7 @@ typedef struct fetch_msg { const char *realm; } auth; - struct { - const struct ssl_cert_info *certs; - size_t num_certs; - } certs; + const struct cert_chain *chain; } data; } fetch_msg; diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c index 0be33ae16..83e92d808 100644 --- a/content/fetchers/curl.c +++ b/content/fetchers/curl.c @@ -149,7 +149,7 @@ struct curl_fetch_info { struct curl_httppost *post_multipart; /**< Multipart post data, or 0. */ uint64_t last_progress_update; /**< Time of last progress update */ int cert_depth; /**< deepest certificate in use */ - struct cert_info cert_data[MAX_SSL_CERTS]; /**< HTTPS certificate data */ + struct cert_info cert_data[MAX_CERT_DEPTH]; /**< HTTPS certificate data */ }; /** curl handle cache entry */ @@ -471,128 +471,37 @@ failed: static void fetch_curl_report_certs_upstream(struct curl_fetch_info *f) { - int depth; + size_t depth; BIO *mem; - BUF_MEM *buf; - const ASN1_INTEGER *asn1_num; - BIGNUM *bignum; - struct ssl_cert_info ssl_certs[MAX_SSL_CERTS]; + BUF_MEM *buf[MAX_CERT_DEPTH]; + struct cert_chain chain; fetch_msg msg; - struct cert_info *certs = f->cert_data; - memset(ssl_certs, 0, sizeof(ssl_certs)); + struct cert_info *certs; + + memset(&chain, 0, sizeof(chain)); + + certs = f->cert_data; + chain.depth = f->cert_depth + 1; /* 0 indexed certificate depth */ - for (depth = 0; depth <= f->cert_depth; depth++) { + for (depth = 0; depth < chain.depth; depth++) { if (certs[depth].cert == NULL) { /* This certificate is missing, skip it */ - ssl_certs[depth].err = SSL_CERT_ERR_CERT_MISSING; + chain.certs[depth].err = SSL_CERT_ERR_CERT_MISSING; continue; } - /* get certificate version */ - ssl_certs[depth].version = X509_get_version(certs[depth].cert); - - /* not before date */ - mem = BIO_new(BIO_s_mem()); - ASN1_TIME_print(mem, X509_get_notBefore(certs[depth].cert)); - BIO_get_mem_ptr(mem, &buf); - (void) BIO_set_close(mem, BIO_NOCLOSE); - BIO_free(mem); - memcpy(ssl_certs[depth].not_before, - buf->data, - min(sizeof(ssl_certs[depth].not_before) - 1, - (unsigned)buf->length)); - ssl_certs[depth].not_before[min(sizeof(ssl_certs[depth].not_before) - 1, - (unsigned)buf->length)] = 0; - BUF_MEM_free(buf); - - /* not after date */ - mem = BIO_new(BIO_s_mem()); - ASN1_TIME_print(mem, - X509_get_notAfter(certs[depth].cert)); - BIO_get_mem_ptr(mem, &buf); - (void) BIO_set_close(mem, BIO_NOCLOSE); - BIO_free(mem); - memcpy(ssl_certs[depth].not_after, - buf->data, - min(sizeof(ssl_certs[depth].not_after) - 1, - (unsigned)buf->length)); - ssl_certs[depth].not_after[min(sizeof(ssl_certs[depth].not_after) - 1, - (unsigned)buf->length)] = 0; - BUF_MEM_free(buf); - - /* signature type */ - ssl_certs[depth].sig_type = - X509_get_signature_type(certs[depth].cert); - - /* serial number */ - asn1_num = X509_get_serialNumber(certs[depth].cert); - if (asn1_num != NULL) { - bignum = ASN1_INTEGER_to_BN(asn1_num, NULL); - if (bignum != NULL) { - char *tmp = BN_bn2hex(bignum); - if (tmp != NULL) { - strncpy(ssl_certs[depth].serialnum, - tmp, - sizeof(ssl_certs[depth].serialnum)); - ssl_certs[depth].serialnum[sizeof(ssl_certs[depth].serialnum)-1] = '\0'; - OPENSSL_free(tmp); - } - BN_free(bignum); - bignum = NULL; - } - } - - /* issuer name */ - mem = BIO_new(BIO_s_mem()); - X509_NAME_print_ex(mem, - X509_get_issuer_name(certs[depth].cert), - 0, XN_FLAG_SEP_CPLUS_SPC | - XN_FLAG_DN_REV | XN_FLAG_FN_NONE); - BIO_get_mem_ptr(mem, &buf); - (void) BIO_set_close(mem, BIO_NOCLOSE); - BIO_free(mem); - memcpy(ssl_certs[depth].issuer, - buf->data, - min(sizeof(ssl_certs[depth].issuer) - 1, - (unsigned) buf->length)); - ssl_certs[depth].issuer[min(sizeof(ssl_certs[depth].issuer) - 1, - (unsigned) buf->length)] = 0; - BUF_MEM_free(buf); - - /* subject */ - mem = BIO_new(BIO_s_mem()); - X509_NAME_print_ex(mem, - X509_get_subject_name(certs[depth].cert), - 0, - XN_FLAG_SEP_CPLUS_SPC | - XN_FLAG_DN_REV | - XN_FLAG_FN_NONE); - BIO_get_mem_ptr(mem, &buf); - (void) BIO_set_close(mem, BIO_NOCLOSE); - BIO_free(mem); - memcpy(ssl_certs[depth].subject, - buf->data, - min(sizeof(ssl_certs[depth].subject) - 1, - (unsigned)buf->length)); - ssl_certs[depth].subject[min(sizeof(ssl_certs[depth].subject) - 1, - (unsigned) buf->length)] = 0; - BUF_MEM_free(buf); - - /* type of certificate */ - ssl_certs[depth].cert_type = - X509_certificate_type(certs[depth].cert, - X509_get_pubkey(certs[depth].cert)); - /* error code (if any) */ switch (certs[depth].err) { case X509_V_OK: - ssl_certs[depth].err = SSL_CERT_ERR_OK; + chain.certs[depth].err = SSL_CERT_ERR_OK; break; + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: /* fallthrough */ case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - ssl_certs[depth].err = SSL_CERT_ERR_BAD_ISSUER; + chain.certs[depth].err = SSL_CERT_ERR_BAD_ISSUER; break; + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: /* fallthrough */ case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: @@ -600,41 +509,66 @@ fetch_curl_report_certs_upstream(struct curl_fetch_info *f) case X509_V_ERR_CERT_SIGNATURE_FAILURE: /* fallthrough */ case X509_V_ERR_CRL_SIGNATURE_FAILURE: - ssl_certs[depth].err = SSL_CERT_ERR_BAD_SIG; + chain.certs[depth].err = SSL_CERT_ERR_BAD_SIG; break; + case X509_V_ERR_CERT_NOT_YET_VALID: /* fallthrough */ case X509_V_ERR_CRL_NOT_YET_VALID: - ssl_certs[depth].err = SSL_CERT_ERR_TOO_YOUNG; + chain.certs[depth].err = SSL_CERT_ERR_TOO_YOUNG; break; + case X509_V_ERR_CERT_HAS_EXPIRED: /* fallthrough */ case X509_V_ERR_CRL_HAS_EXPIRED: - ssl_certs[depth].err = SSL_CERT_ERR_TOO_OLD; + chain.certs[depth].err = SSL_CERT_ERR_TOO_OLD; break; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - ssl_certs[depth].err = SSL_CERT_ERR_SELF_SIGNED; + chain.certs[depth].err = SSL_CERT_ERR_SELF_SIGNED; break; + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - ssl_certs[depth].err = SSL_CERT_ERR_CHAIN_SELF_SIGNED; + chain.certs[depth].err = SSL_CERT_ERR_CHAIN_SELF_SIGNED; break; + case X509_V_ERR_CERT_REVOKED: - ssl_certs[depth].err = SSL_CERT_ERR_REVOKED; + chain.certs[depth].err = SSL_CERT_ERR_REVOKED; break; + case X509_V_ERR_HOSTNAME_MISMATCH: - ssl_certs[depth].err = SSL_CERT_ERR_HOSTNAME_MISMATCH; + chain.certs[depth].err = SSL_CERT_ERR_HOSTNAME_MISMATCH; break; + default: - ssl_certs[depth].err = SSL_CERT_ERR_UNKNOWN; + chain.certs[depth].err = SSL_CERT_ERR_UNKNOWN; break; } + + /* + * get certificate in Distinguished Encoding Rules (DER) format. + */ + mem = BIO_new(BIO_s_mem()); + i2d_X509_bio(mem, certs[depth].cert); + BIO_get_mem_ptr(mem, &buf[depth]); + (void) BIO_set_close(mem, BIO_NOCLOSE); + BIO_free(mem); + + chain.certs[depth].der = (uint8_t *)buf[depth]->data; + chain.certs[depth].der_length = buf[depth]->length; } msg.type = FETCH_CERTS; - msg.data.certs.certs = ssl_certs; - msg.data.certs.num_certs = depth; + msg.data.chain = &chain; fetch_send_callback(&msg, f->fetch_handle); + + /* release the openssl memory buffer */ + for (depth = 0; depth < chain.depth; depth++) { + if (buf[depth] != NULL) { + BUF_MEM_free(buf[depth]); + } + } } @@ -667,7 +601,7 @@ fetch_curl_verify_callback(int verify_ok, X509_STORE_CTX *x509_ctx) fetch = X509_STORE_CTX_get_app_data(x509_ctx); /* certificate chain is excessively deep so fail verification */ - if (depth >= MAX_SSL_CERTS) { + if (depth >= MAX_CERT_DEPTH) { X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG); return 0; @@ -1098,8 +1032,11 @@ static void fetch_curl_free(void *vf) curl_formfree(f->post_multipart); } - for (i = 0; i < MAX_SSL_CERTS && f->cert_data[i].cert; i++) { - ns_X509_free(f->cert_data[i].cert); + /* free certificate data */ + for (i = 0; i < MAX_CERT_DEPTH; i++) { + if (f->cert_data[i].cert != NULL) { + ns_X509_free(f->cert_data[i].cert); + } } free(f); diff --git a/content/hlcache.c b/content/hlcache.c index ec011ecdc..23dbc5706 100644 --- a/content/hlcache.c +++ b/content/hlcache.c @@ -423,8 +423,10 @@ static nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx, * \param pw Pointer to client-specific data * \return NSERROR_OK on success, appropriate error otherwise */ -static nserror hlcache_llcache_callback(llcache_handle *handle, - const llcache_event *event, void *pw) +static nserror +hlcache_llcache_callback(llcache_handle *handle, + const llcache_event *event, + void *pw) { hlcache_retrieval_ctx *ctx = pw; lwc_string *effective_type = NULL; @@ -439,8 +441,7 @@ static nserror hlcache_llcache_callback(llcache_handle *handle, hlcache_event hlevent; hlevent.type = CONTENT_MSG_SSL_CERTS; - hlevent.data.certs.certs = event->data.certs.certs; - hlevent.data.certs.num = event->data.certs.num; + hlevent.data.chain = event->data.chain; ctx->handle->cb(ctx->handle, &hlevent, ctx->handle->pw); } diff --git a/content/llcache.c b/content/llcache.c index 8a71f1874..3a75bf971 100644 --- a/content/llcache.c +++ b/content/llcache.c @@ -36,6 +36,7 @@ #include <string.h> #include <strings.h> #include <nsutils/time.h> +#include <nsutils/base64.h> #include "netsurf/inttypes.h" #include "utils/config.h" @@ -175,8 +176,7 @@ struct llcache_object { size_t source_len; /**< Byte length of source data */ size_t source_alloc; /**< Allocated size of source buffer */ - size_t ssl_cert_count; /**< The number of SSL certificates stored */ - struct ssl_cert_info *ssl_certs; /**< SSL certificate information if count is non-zero */ + struct cert_chain *chain; /**< Certificate chain from the fetch */ llcache_store_state store_state; /**< where the data for the object is stored */ @@ -969,11 +969,7 @@ static nserror llcache_object_destroy(llcache_object *object) NSLOG(llcache, DEBUG, "Destroying object %p, %s", object, nsurl_access(object->url)); - if (object->ssl_cert_count != 0) { - free(object->ssl_certs); - object->ssl_certs = NULL; - object->ssl_cert_count = 0; - } + cert_chain_free(object->chain); if (object->source_data != NULL) { if (object->store_state == LLCACHE_STATE_DISC) { @@ -1240,6 +1236,13 @@ llcache_serialise_metadata(llcache_object *object, char *op; unsigned int hloop; int use; + size_t cert_chain_depth; + + if (object->chain != NULL) { + cert_chain_depth = object->chain->depth; + } else { + cert_chain_depth = 0; + } allocsize = 10 + 1; /* object length */ @@ -1251,22 +1254,19 @@ llcache_serialise_metadata(llcache_object *object, allocsize += 10 + 1; /* space for number of header entries */ - allocsize += 10 + 1; /* space for number of SSL certificates */ - - allocsize += nsurl_length(object->url) + 1; - for (hloop = 0 ; hloop < object->num_headers ; hloop++) { allocsize += strlen(object->headers[hloop].name) + 1; allocsize += strlen(object->headers[hloop].value) + 1; } - for (hloop = 0; hloop < object->ssl_cert_count; hloop++) { - allocsize += (10 + 1) * 4; /* version, sig_type, cert_type, err */ - allocsize += strlen(object->ssl_certs[hloop].not_before) + 1; - allocsize += strlen(object->ssl_certs[hloop].not_after) + 1; - allocsize += strlen(object->ssl_certs[hloop].serialnum) + 1; - allocsize += strlen(object->ssl_certs[hloop].issuer) + 1; - allocsize += strlen(object->ssl_certs[hloop].subject) + 1; + allocsize += nsurl_length(object->url) + 1; + + /* space for number of DER formatted certificates */ + allocsize += 10 + 1; + + for (hloop = 0; hloop < cert_chain_depth; hloop++) { + allocsize += 10 + 1; /* error status */ + allocsize += 4 * ((object->chain->certs[hloop].der_length + 2) / 3); } data = malloc(allocsize); @@ -1351,8 +1351,8 @@ llcache_serialise_metadata(llcache_object *object, datasize -= use; } - /* number of ssl certificates */ - use = snprintf(op, datasize, "%" PRIsizet, object->ssl_cert_count); + /* number of DER formatted ssl certificates */ + use = snprintf(op, datasize, "%" PRIsizet, cert_chain_depth); if (use < 0) { goto operror; } @@ -1363,80 +1363,13 @@ llcache_serialise_metadata(llcache_object *object, datasize -= use; /* SSL certificates */ - for (hloop = 0; hloop < object->ssl_cert_count; hloop++) { - struct ssl_cert_info *cert = &(object->ssl_certs[hloop]); - /* Certificate version */ - use = snprintf(op, datasize, "%ld", cert->version); - if (use < 0) { - goto operror; - } - use++; /* does not count the null */ - if (use > datasize) - goto overflow; - op += use; - datasize -= use; - /* not_before */ - use = snprintf(op, datasize, "%s", cert->not_before); - if (use < 0) { - goto operror; - } - use++; /* does not count the null */ - if (use > datasize) - goto overflow; - op += use; - datasize -= use; - /* not_after */ - use = snprintf(op, datasize, "%s", cert->not_after); - if (use < 0) { - goto operror; - } - use++; /* does not count the null */ - if (use > datasize) - goto overflow; - op += use; - datasize -= use; - /* Signature type */ - use = snprintf(op, datasize, "%d", cert->sig_type); - if (use < 0) { - goto operror; - } - use++; /* does not count the null */ - if (use > datasize) - goto overflow; - op += use; - datasize -= use; - /* serialnum */ - use = snprintf(op, datasize, "%s", cert->serialnum); - if (use < 0) { - goto operror; - } - use++; /* does not count the null */ - if (use > datasize) - goto overflow; - op += use; - datasize -= use; - /* issuer */ - use = snprintf(op, datasize, "%s", cert->issuer); - if (use < 0) { - goto operror; - } - use++; /* does not count the null */ - if (use > datasize) - goto overflow; - op += use; - datasize -= use; - /* subject */ - use = snprintf(op, datasize, "%s", cert->subject); - if (use < 0) { - goto operror; - } - use++; /* does not count the null */ - if (use > datasize) - goto overflow; - op += use; - datasize -= use; - /* Certificate type */ - use = snprintf(op, datasize, "%d", cert->cert_type); + for (hloop = 0; hloop < cert_chain_depth; hloop++) { + size_t output_length; + nsuerror res; + + /* Certificate error code */ + use = snprintf(op, datasize, "%d", + (int)(object->chain->certs[hloop].err)); if (use < 0) { goto operror; } @@ -1445,14 +1378,26 @@ llcache_serialise_metadata(llcache_object *object, goto overflow; op += use; datasize -= use; - /* Certificate error code */ - use = snprintf(op, datasize, "%d", (int)(cert->err)); - if (use < 0) { - goto operror; + + /* DER certificate data in base64 encoding */ + if (object->chain->certs[hloop].der != NULL) { + output_length = datasize; + res = nsu_base64_encode( + object->chain->certs[hloop].der, + object->chain->certs[hloop].der_length, + (uint8_t *)op, + &output_length); + if (res != NSUERROR_OK) { + goto operror; + } + use = output_length; + } else { + use = 0; } - use++; /* does not count the null */ + use++; /* allow for null */ if (use > datasize) goto overflow; + *(op + output_length) = 0; op += use; datasize -= use; } @@ -1510,7 +1455,7 @@ llcache_process_metadata(llcache_object *object) size_t num_headers; size_t hloop; size_t ssl_cert_count = 0; - struct ssl_cert_info *ssl_certs = NULL; + struct cert_chain *chain = NULL; NSLOG(llcache, INFO, "Retrieving metadata"); @@ -1642,7 +1587,7 @@ llcache_process_metadata(llcache_object *object) goto skip_ssl_certificates; } - /* Next line is the number of SSL certificates*/ + /* Next line is the number of DER base64 encoded certificates */ line++; ln += lnsize + 1; lnsize = strlen(ln); @@ -1657,72 +1602,20 @@ llcache_process_metadata(llcache_object *object) goto skip_ssl_certificates; } - ssl_certs = calloc(sizeof(struct ssl_cert_info), ssl_cert_count); - if (ssl_certs == NULL) { - res = NSERROR_NOMEM; + if (ssl_cert_count > MAX_CERT_DEPTH) { + res = NSERROR_INVALID; + goto format_error; + } + + res = cert_chain_alloc(ssl_cert_count, &chain); + if (res != NSERROR_OK) { goto format_error; } for (hloop = 0; hloop < ssl_cert_count; hloop++) { - struct ssl_cert_info *cert = &ssl_certs[hloop]; int errcode; - /* Certificate version */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - if ((lnsize < 1) || (sscanf(ln, "%ld", &cert->version) != 1)) { - res = NSERROR_INVALID; - goto format_error; - } - /* Not before */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - memcpy(&cert->not_before, ln, lnsize); - /* Not after */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - memcpy(&cert->not_after, ln, lnsize); - /* Signature type */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - if ((lnsize < 1) || (sscanf(ln, "%d", &cert->sig_type) != 1)) { - res = NSERROR_INVALID; - goto format_error; - } - /* Serial Number */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - memcpy(&cert->serialnum, ln, lnsize); - /* issuer */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - memcpy(&cert->issuer, ln, lnsize); - /* subject */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - memcpy(&cert->subject, ln, lnsize); - /* Certificate type */ - line++; - ln += lnsize + 1; - lnsize = strlen(ln); - remaining -= lnsize + 1; - if ((lnsize < 1) || (sscanf(ln, "%d", &cert->cert_type) != 1)) { - res = NSERROR_INVALID; - goto format_error; - } + nsuerror nsures; + /* Certificate error code */ line++; ln += lnsize + 1; @@ -1735,9 +1628,25 @@ llcache_process_metadata(llcache_object *object) if (errcode < SSL_CERT_ERR_OK || errcode > SSL_CERT_ERR_MAX_KNOWN) { /* Error with the cert code, assume UNKNOWN */ - cert->err = SSL_CERT_ERR_UNKNOWN; + chain->certs[hloop].err = SSL_CERT_ERR_UNKNOWN; } else { - cert->err = (ssl_cert_err)errcode; + chain->certs[hloop].err = (ssl_cert_err)errcode; + } + + /* base64 encoded DER certificate data */ + line++; + ln += lnsize + 1; + lnsize = strlen(ln); + remaining -= lnsize + 1; + if (lnsize > 0) { + nsures = nsu_base64_decode_alloc((const uint8_t *)ln, + lnsize, + &chain->certs[hloop].der, + &chain->certs[hloop].der_length); + if (nsures != NSUERROR_OK) { + res = NSERROR_NOMEM; + goto format_error; + } } } @@ -1754,8 +1663,7 @@ skip_ssl_certificates: object->cache.res_time = response_time; object->cache.fin_time = completion_time; - object->ssl_cert_count = ssl_cert_count; - object->ssl_certs = ssl_certs; + object->chain = chain; /* object stored in backing store */ object->store_state = LLCACHE_STATE_DISC; @@ -1768,9 +1676,7 @@ format_error: line, res); guit->llcache->release(object->url, BACKING_STORE_META); - if (ssl_certs != NULL) { - free(ssl_certs); - } + cert_chain_free(chain); return res; } @@ -3173,21 +3079,15 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p) case FETCH_CERTS: /* Certificate information from the fetch */ - /* Persist the data onto our object */ - object->ssl_certs = calloc(sizeof(struct ssl_cert_info), - msg->data.certs.num_certs); - if (object->ssl_certs != NULL) { - object->ssl_cert_count = msg->data.certs.num_certs; - memcpy(object->ssl_certs, msg->data.certs.certs, - sizeof(struct ssl_cert_info) * object->ssl_cert_count); - } - - /* Now pass on the event */ - event.type = LLCACHE_EVENT_GOT_CERTS; - event.data.certs.certs = msg->data.certs.certs; - event.data.certs.num = msg->data.certs.num_certs; + /* Persist the chain onto our object */ + error = cert_chain_dup(msg->data.chain, &object->chain); + if (error != NSERROR_OK) { + /* Now pass on the event */ + event.type = LLCACHE_EVENT_GOT_CERTS; + event.data.chain = msg->data.chain; - error = llcache_send_event_to_users(object, &event); + error = llcache_send_event_to_users(object, &event); + } break; /* Events requiring action */ @@ -3388,10 +3288,9 @@ static nserror llcache_object_notify_users(llcache_object *object) handle->state = LLCACHE_FETCH_HEADERS; /* Emit any certificate data we hold */ - if (object->ssl_cert_count > 0) { + if (object->chain != NULL) { event.type = LLCACHE_EVENT_GOT_CERTS; - event.data.certs.certs = object->ssl_certs; - event.data.certs.num = object->ssl_cert_count; + event.data.chain = object->chain; error = handle->cb(handle, &event, handle->pw); } else { error = NSERROR_OK; @@ -3613,16 +3512,12 @@ llcache_object_snapshot(llcache_object *object, llcache_object **snapshot) } } - if (object->ssl_cert_count != 0) { - newobj->ssl_certs = calloc(sizeof(struct ssl_cert_info), - object->ssl_cert_count); - if (newobj->ssl_certs == NULL) { + if (object->chain != NULL) { + error = cert_chain_dup(object->chain, &newobj->chain); + if (error != NSERROR_OK) { llcache_object_destroy(newobj); - return NSERROR_NOMEM; + return error; } - memcpy(newobj->ssl_certs, object->ssl_certs, - sizeof(struct ssl_cert_info) * object->ssl_cert_count); - newobj->ssl_cert_count = object->ssl_cert_count; } newobj->fetch.state = LLCACHE_FETCH_COMPLETE; @@ -3662,7 +3557,7 @@ total_object_size(llcache_object *object) } } - tot += object->ssl_cert_count * sizeof(struct ssl_cert_info); + tot += cert_chain_size(object->chain); return tot; } diff --git a/content/llcache.h b/content/llcache.h index 8d2411e0a..514272f29 100644 --- a/content/llcache.h +++ b/content/llcache.h @@ -30,7 +30,7 @@ #include "utils/errors.h" #include "utils/nsurl.h" -struct ssl_cert_info; +struct cert_chain; struct fetch_multipart_data; /** Handle for low-level cache object */ @@ -83,26 +83,23 @@ typedef enum { * and must be copied if it is desirable to retain. */ typedef struct { - llcache_event_type type; /**< Type of event */ + llcache_event_type type; /**< Type of event */ union { struct { - const uint8_t *buf; /**< Buffer of data */ - size_t len; /**< Length of buffer, in bytes */ - } data; /**< Received data */ + const uint8_t *buf; /**< Buffer of data */ + size_t len; /**< Byte length of buffer */ + } data; /**< Received data */ struct { - nserror code; /**< The error code */ - const char *msg; /**< Error message */ + nserror code; /**< The error code */ + const char *msg; /**< Error message */ } error; - const char *progress_msg; /**< Progress message */ + const char *progress_msg; /**< Progress message */ struct { - nsurl *from; /**< Redirect origin */ - nsurl *to; /**< Redirect target */ - } redirect; /**< Fetch URL redirect occured */ - struct { - const struct ssl_cert_info *certs; /**< The chain */ - size_t num; /**< Number of certs in chain */ - } certs; - } data; /**< Event data */ + nsurl *from; /**< Redirect origin */ + nsurl *to; /**< Redirect target */ + } redirect; /**< Fetch URL redirect occured */ + const struct cert_chain *chain; /**< Certificate chain */ + } data; /**< Event data */ } llcache_event; /** @@ -171,17 +168,17 @@ struct llcache_parameters { size_t hysteresis; /**< The hysteresis around the target size */ /** The minimum lifetime to consider sending objects to backing store.*/ - int minimum_lifetime; + int minimum_lifetime; /** The minimum bandwidth to allow the backing store to * use in bytes/second */ - size_t minimum_bandwidth; + size_t minimum_bandwidth; /** The maximum bandwidth to allow the backing store to use in * bytes/second */ - size_t maximum_bandwidth; + size_t maximum_bandwidth; /** The time quantum over which to calculate the bandwidth values */ |