summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/content.h7
-rw-r--r--content/fetch.h5
-rw-r--r--content/fetchers/curl.c177
-rw-r--r--content/hlcache.c9
-rw-r--r--content/llcache.c285
-rw-r--r--content/llcache.h35
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
*/