Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/ea142abdd090a46ba4589a4db784c49820bbbd69
...commit
http://git.netsurf-browser.org/netsurf.git/commit/ea142abdd090a46ba4589a4db784c49820bbbd69
...tree
http://git.netsurf-browser.org/netsurf.git/tree/ea142abdd090a46ba4589a4db784c49820bbbd69
The branch, master has been updated
via ea142abdd090a46ba4589a4db784c49820bbbd69 (commit)
via 0c0b9faddda8345a37e0d720acb9acbc887f24c2 (commit)
via f49654cfc5113788eac430bcf09f7f215ba0fa5e (commit)
from 2277d69ba132e1f5529acc14141b37c349a2f44e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=ea142abdd090a46ba4589a4db784c49820bbbd69
commit ea142abdd090a46ba4589a4db784c49820bbbd69
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
llcache: Reload SSL certificate data from serialised store
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/llcache.c b/content/llcache.c
index 5c53999..8a71f18 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1497,6 +1497,7 @@ llcache_process_metadata(llcache_object *object)
nserror res;
uint8_t *metadata = NULL;
size_t metadatalen = 0;
+ size_t remaining = 0;
nsurl *metadataurl;
unsigned int line;
char *ln;
@@ -1508,6 +1509,8 @@ llcache_process_metadata(llcache_object *object)
time_t completion_time;
size_t num_headers;
size_t hloop;
+ size_t ssl_cert_count = 0;
+ struct ssl_cert_info *ssl_certs = NULL;
NSLOG(llcache, INFO, "Retrieving metadata");
@@ -1522,10 +1525,20 @@ llcache_process_metadata(llcache_object *object)
NSLOG(llcache, INFO, "Processing retrieved data");
+ /* metadata is stored as a sequence of NULL terminated strings
+ * which we call 'line's here.
+ */
+
+ /* We track remaining data because as we extend this data structure
+ * we need to know if we should continue to parse
+ */
+ remaining = metadatalen;
+
/* metadata line 1 is the url the metadata referrs to */
line = 1;
ln = (char *)metadata;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
if (lnsize < 7) {
res = NSERROR_INVALID;
@@ -1559,6 +1572,7 @@ llcache_process_metadata(llcache_object *object)
line = 2;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
if ((lnsize < 1) || (sscanf(ln, "%" PRIsizet, &source_length) != 1)) {
res = NSERROR_INVALID;
@@ -1570,6 +1584,7 @@ llcache_process_metadata(llcache_object *object)
line = 3;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = nsc_snptimet(ln, lnsize, &request_time);
if (res != NSERROR_OK)
@@ -1580,6 +1595,7 @@ llcache_process_metadata(llcache_object *object)
line = 4;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = nsc_snptimet(ln, lnsize, &response_time);
if (res != NSERROR_OK)
@@ -1590,6 +1606,7 @@ llcache_process_metadata(llcache_object *object)
line = 5;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = nsc_snptimet(ln, lnsize, &completion_time);
if (res != NSERROR_OK)
@@ -1600,6 +1617,7 @@ llcache_process_metadata(llcache_object *object)
line = 6;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
if ((lnsize < 1) || (sscanf(ln, "%" PRIsizet, &num_headers) != 1)) {
res = NSERROR_INVALID;
@@ -1611,6 +1629,7 @@ llcache_process_metadata(llcache_object *object)
line++;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = llcache_fetch_process_header(object,
(uint8_t *)ln,
@@ -1619,6 +1638,110 @@ llcache_process_metadata(llcache_object *object)
goto format_error;
}
+ if (remaining == 0) {
+ goto skip_ssl_certificates;
+ }
+
+ /* Next line is the number of SSL certificates*/
+ line++;
+ ln += lnsize + 1;
+ lnsize = strlen(ln);
+ remaining -= lnsize + 1;
+
+ if ((lnsize < 1) || (sscanf(ln, "%" PRIsizet, &ssl_cert_count) != 1)) {
+ res = NSERROR_INVALID;
+ goto format_error;
+ }
+
+ if (ssl_cert_count == 0) {
+ goto skip_ssl_certificates;
+ }
+
+ ssl_certs = calloc(sizeof(struct ssl_cert_info), ssl_cert_count);
+ if (ssl_certs == NULL) {
+ res = NSERROR_NOMEM;
+ 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;
+ }
+ /* Certificate error code */
+ line++;
+ ln += lnsize + 1;
+ lnsize = strlen(ln);
+ remaining -= lnsize + 1;
+ if ((lnsize < 1) || (sscanf(ln, "%d", &errcode) != 1)) {
+ res = NSERROR_INVALID;
+ goto format_error;
+ }
+ 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;
+ } else {
+ cert->err = (ssl_cert_err)errcode;
+ }
+ }
+
+skip_ssl_certificates:
guit->llcache->release(object->url, BACKING_STORE_META);
/* update object on successful parse of metadata */
@@ -1631,6 +1754,9 @@ llcache_process_metadata(llcache_object *object)
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 stored in backing store */
object->store_state = LLCACHE_STATE_DISC;
@@ -1642,6 +1768,10 @@ format_error:
line, res);
guit->llcache->release(object->url, BACKING_STORE_META);
+ if (ssl_certs != NULL) {
+ free(ssl_certs);
+ }
+
return res;
}
diff --git a/include/netsurf/ssl_certs.h b/include/netsurf/ssl_certs.h
index 7e933b1..dcd644e 100644
--- a/include/netsurf/ssl_certs.h
+++ b/include/netsurf/ssl_certs.h
@@ -27,6 +27,9 @@
/**
* ssl certificate error status
+ *
+ * Do not reorder / remove entries because these may be persisted to the disk
+ * cache as simple ints.
*/
typedef enum {
SSL_CERT_ERR_OK, /**< Nothing wrong with this certificate */
@@ -41,6 +44,9 @@ typedef enum {
SSL_CERT_ERR_HOSTNAME_MISMATCH, /**< This certificate host did not
match the server */
} ssl_cert_err;
+/** Always the max known ssl certificate error type */
+#define SSL_CERT_ERR_MAX_KNOWN SSL_CERT_ERR_HOSTNAME_MISMATCH
+
/**
* ssl certificate information for certificate error message
*/
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=0c0b9faddda8345a37e0d720acb9acbc887f24c2
commit 0c0b9faddda8345a37e0d720acb9acbc887f24c2
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
llcache: Persist SSL certificate data
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/llcache.c b/content/llcache.c
index e870ee2..5c53999 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1251,6 +1251,8 @@ 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++) {
@@ -1258,6 +1260,15 @@ llcache_serialise_metadata(llcache_object *object,
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;
+ }
+
data = malloc(allocsize);
if (data == NULL) {
return NSERROR_NOMEM;
@@ -1340,6 +1351,112 @@ llcache_serialise_metadata(llcache_object *object,
datasize -= use;
}
+ /* number of ssl certificates */
+ use = snprintf(op, datasize, "%" PRIsizet, object->ssl_cert_count);
+ if (use < 0) {
+ goto operror;
+ }
+ use++; /* does not count the null */
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ 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);
+ if (use < 0) {
+ goto operror;
+ }
+ use++; /* does not count the null */
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+ /* Certificate error code */
+ use = snprintf(op, datasize, "%d", (int)(cert->err));
+ if (use < 0) {
+ goto operror;
+ }
+ use++; /* does not count the null */
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+ }
+
NSLOG(llcache, DEBUG, "Filled buffer with %d spare", datasize);
*data_out = data;
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=f49654cfc5113788eac430bcf09f7f215ba0fa5e
commit f49654cfc5113788eac430bcf09f7f215ba0fa5e
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
llcache: Support storing SSL certificate data
In order to support persisting SSL data we first have to store it
and support catching up new users.
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/llcache.c b/content/llcache.c
index ccfa61d..e870ee2 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -175,6 +175,9 @@ 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 */
+
llcache_store_state store_state; /**< where the data for the object is
stored */
llcache_object_user *users; /**< List of users */
@@ -966,6 +969,12 @@ 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;
+ }
+
if (object->source_data != NULL) {
if (object->store_state == LLCACHE_STATE_DISC) {
guit->llcache->release(object->url, BACKING_STORE_NONE);
@@ -2916,9 +2925,17 @@ static void llcache_fetch_callback(const fetch_msg *msg,
void *p)
case FETCH_CERTS:
/* Certificate information from the fetch */
- /** \todo CERTS - Should we persist this on the object and
- * then catch up new users etc?
- */
+
+ /* 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;
@@ -3122,6 +3139,40 @@ static nserror
llcache_object_notify_users(llcache_object *object)
if (handle->state == LLCACHE_FETCH_INIT &&
objstate > LLCACHE_FETCH_INIT) {
handle->state = LLCACHE_FETCH_HEADERS;
+
+ /* Emit any certificate data we hold */
+ if (object->ssl_cert_count > 0) {
+ event.type = LLCACHE_EVENT_GOT_CERTS;
+ event.data.certs.certs = object->ssl_certs;
+ event.data.certs.num = object->ssl_cert_count;
+ error = handle->cb(handle, &event, handle->pw);
+ } else {
+ error = NSERROR_OK;
+ }
+
+ if (user->queued_for_delete) {
+ next_user = user->next;
+ llcache_object_remove_user(object, user);
+ llcache_object_user_destroy(user);
+
+ if (error != NSERROR_OK)
+ return error;
+
+ continue;
+ } else if (error == NSERROR_NEED_DATA) {
+ /* User requested replay */
+ handle->state = LLCACHE_FETCH_HEADERS;
+
+ /* Continue with the next user -- we'll
+ * reemit the event next time round */
+ user->iterator_target = false;
+ next_user = user->next;
+ llcache_users_not_caught_up();
+ continue;
+ } else if (error != NSERROR_OK) {
+ user->iterator_target = false;
+ return error;
+ }
}
/* User: HEADERS, Obj: DATA, COMPLETE => User->DATA */
@@ -3315,6 +3366,18 @@ 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) {
+ llcache_object_destroy(newobj);
+ return NSERROR_NOMEM;
+ }
+ 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;
*snapshot = newobj;
@@ -3352,6 +3415,8 @@ total_object_size(llcache_object *object)
}
}
+ tot += object->ssl_cert_count * sizeof(struct ssl_cert_info);
+
return tot;
}
-----------------------------------------------------------------------
Summary of changes:
content/llcache.c | 318 ++++++++++++++++++++++++++++++++++++++++++-
include/netsurf/ssl_certs.h | 6 +
2 files changed, 321 insertions(+), 3 deletions(-)
diff --git a/content/llcache.c b/content/llcache.c
index ccfa61d..8a71f18 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -175,6 +175,9 @@ 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 */
+
llcache_store_state store_state; /**< where the data for the object is
stored */
llcache_object_user *users; /**< List of users */
@@ -966,6 +969,12 @@ 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;
+ }
+
if (object->source_data != NULL) {
if (object->store_state == LLCACHE_STATE_DISC) {
guit->llcache->release(object->url, BACKING_STORE_NONE);
@@ -1242,6 +1251,8 @@ 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++) {
@@ -1249,6 +1260,15 @@ llcache_serialise_metadata(llcache_object *object,
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;
+ }
+
data = malloc(allocsize);
if (data == NULL) {
return NSERROR_NOMEM;
@@ -1331,6 +1351,112 @@ llcache_serialise_metadata(llcache_object *object,
datasize -= use;
}
+ /* number of ssl certificates */
+ use = snprintf(op, datasize, "%" PRIsizet, object->ssl_cert_count);
+ if (use < 0) {
+ goto operror;
+ }
+ use++; /* does not count the null */
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ 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);
+ if (use < 0) {
+ goto operror;
+ }
+ use++; /* does not count the null */
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+ /* Certificate error code */
+ use = snprintf(op, datasize, "%d", (int)(cert->err));
+ if (use < 0) {
+ goto operror;
+ }
+ use++; /* does not count the null */
+ if (use > datasize)
+ goto overflow;
+ op += use;
+ datasize -= use;
+ }
+
NSLOG(llcache, DEBUG, "Filled buffer with %d spare", datasize);
*data_out = data;
@@ -1371,6 +1497,7 @@ llcache_process_metadata(llcache_object *object)
nserror res;
uint8_t *metadata = NULL;
size_t metadatalen = 0;
+ size_t remaining = 0;
nsurl *metadataurl;
unsigned int line;
char *ln;
@@ -1382,6 +1509,8 @@ llcache_process_metadata(llcache_object *object)
time_t completion_time;
size_t num_headers;
size_t hloop;
+ size_t ssl_cert_count = 0;
+ struct ssl_cert_info *ssl_certs = NULL;
NSLOG(llcache, INFO, "Retrieving metadata");
@@ -1396,10 +1525,20 @@ llcache_process_metadata(llcache_object *object)
NSLOG(llcache, INFO, "Processing retrieved data");
+ /* metadata is stored as a sequence of NULL terminated strings
+ * which we call 'line's here.
+ */
+
+ /* We track remaining data because as we extend this data structure
+ * we need to know if we should continue to parse
+ */
+ remaining = metadatalen;
+
/* metadata line 1 is the url the metadata referrs to */
line = 1;
ln = (char *)metadata;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
if (lnsize < 7) {
res = NSERROR_INVALID;
@@ -1433,6 +1572,7 @@ llcache_process_metadata(llcache_object *object)
line = 2;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
if ((lnsize < 1) || (sscanf(ln, "%" PRIsizet, &source_length) != 1)) {
res = NSERROR_INVALID;
@@ -1444,6 +1584,7 @@ llcache_process_metadata(llcache_object *object)
line = 3;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = nsc_snptimet(ln, lnsize, &request_time);
if (res != NSERROR_OK)
@@ -1454,6 +1595,7 @@ llcache_process_metadata(llcache_object *object)
line = 4;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = nsc_snptimet(ln, lnsize, &response_time);
if (res != NSERROR_OK)
@@ -1464,6 +1606,7 @@ llcache_process_metadata(llcache_object *object)
line = 5;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = nsc_snptimet(ln, lnsize, &completion_time);
if (res != NSERROR_OK)
@@ -1474,6 +1617,7 @@ llcache_process_metadata(llcache_object *object)
line = 6;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
if ((lnsize < 1) || (sscanf(ln, "%" PRIsizet, &num_headers) != 1)) {
res = NSERROR_INVALID;
@@ -1485,6 +1629,7 @@ llcache_process_metadata(llcache_object *object)
line++;
ln += lnsize + 1;
lnsize = strlen(ln);
+ remaining -= lnsize + 1;
res = llcache_fetch_process_header(object,
(uint8_t *)ln,
@@ -1493,6 +1638,110 @@ llcache_process_metadata(llcache_object *object)
goto format_error;
}
+ if (remaining == 0) {
+ goto skip_ssl_certificates;
+ }
+
+ /* Next line is the number of SSL certificates*/
+ line++;
+ ln += lnsize + 1;
+ lnsize = strlen(ln);
+ remaining -= lnsize + 1;
+
+ if ((lnsize < 1) || (sscanf(ln, "%" PRIsizet, &ssl_cert_count) != 1)) {
+ res = NSERROR_INVALID;
+ goto format_error;
+ }
+
+ if (ssl_cert_count == 0) {
+ goto skip_ssl_certificates;
+ }
+
+ ssl_certs = calloc(sizeof(struct ssl_cert_info), ssl_cert_count);
+ if (ssl_certs == NULL) {
+ res = NSERROR_NOMEM;
+ 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;
+ }
+ /* Certificate error code */
+ line++;
+ ln += lnsize + 1;
+ lnsize = strlen(ln);
+ remaining -= lnsize + 1;
+ if ((lnsize < 1) || (sscanf(ln, "%d", &errcode) != 1)) {
+ res = NSERROR_INVALID;
+ goto format_error;
+ }
+ 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;
+ } else {
+ cert->err = (ssl_cert_err)errcode;
+ }
+ }
+
+skip_ssl_certificates:
guit->llcache->release(object->url, BACKING_STORE_META);
/* update object on successful parse of metadata */
@@ -1505,6 +1754,9 @@ llcache_process_metadata(llcache_object *object)
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 stored in backing store */
object->store_state = LLCACHE_STATE_DISC;
@@ -1516,6 +1768,10 @@ format_error:
line, res);
guit->llcache->release(object->url, BACKING_STORE_META);
+ if (ssl_certs != NULL) {
+ free(ssl_certs);
+ }
+
return res;
}
@@ -2916,9 +3172,17 @@ static void llcache_fetch_callback(const fetch_msg *msg,
void *p)
case FETCH_CERTS:
/* Certificate information from the fetch */
- /** \todo CERTS - Should we persist this on the object and
- * then catch up new users etc?
- */
+
+ /* 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;
@@ -3122,6 +3386,40 @@ static nserror
llcache_object_notify_users(llcache_object *object)
if (handle->state == LLCACHE_FETCH_INIT &&
objstate > LLCACHE_FETCH_INIT) {
handle->state = LLCACHE_FETCH_HEADERS;
+
+ /* Emit any certificate data we hold */
+ if (object->ssl_cert_count > 0) {
+ event.type = LLCACHE_EVENT_GOT_CERTS;
+ event.data.certs.certs = object->ssl_certs;
+ event.data.certs.num = object->ssl_cert_count;
+ error = handle->cb(handle, &event, handle->pw);
+ } else {
+ error = NSERROR_OK;
+ }
+
+ if (user->queued_for_delete) {
+ next_user = user->next;
+ llcache_object_remove_user(object, user);
+ llcache_object_user_destroy(user);
+
+ if (error != NSERROR_OK)
+ return error;
+
+ continue;
+ } else if (error == NSERROR_NEED_DATA) {
+ /* User requested replay */
+ handle->state = LLCACHE_FETCH_HEADERS;
+
+ /* Continue with the next user -- we'll
+ * reemit the event next time round */
+ user->iterator_target = false;
+ next_user = user->next;
+ llcache_users_not_caught_up();
+ continue;
+ } else if (error != NSERROR_OK) {
+ user->iterator_target = false;
+ return error;
+ }
}
/* User: HEADERS, Obj: DATA, COMPLETE => User->DATA */
@@ -3315,6 +3613,18 @@ 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) {
+ llcache_object_destroy(newobj);
+ return NSERROR_NOMEM;
+ }
+ 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;
*snapshot = newobj;
@@ -3352,6 +3662,8 @@ total_object_size(llcache_object *object)
}
}
+ tot += object->ssl_cert_count * sizeof(struct ssl_cert_info);
+
return tot;
}
diff --git a/include/netsurf/ssl_certs.h b/include/netsurf/ssl_certs.h
index 7e933b1..dcd644e 100644
--- a/include/netsurf/ssl_certs.h
+++ b/include/netsurf/ssl_certs.h
@@ -27,6 +27,9 @@
/**
* ssl certificate error status
+ *
+ * Do not reorder / remove entries because these may be persisted to the disk
+ * cache as simple ints.
*/
typedef enum {
SSL_CERT_ERR_OK, /**< Nothing wrong with this certificate */
@@ -41,6 +44,9 @@ typedef enum {
SSL_CERT_ERR_HOSTNAME_MISMATCH, /**< This certificate host did not
match the server */
} ssl_cert_err;
+/** Always the max known ssl certificate error type */
+#define SSL_CERT_ERR_MAX_KNOWN SSL_CERT_ERR_HOSTNAME_MISMATCH
+
/**
* ssl certificate information for certificate error message
*/
--
NetSurf Browser
_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org