mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-02-24 02:14:11 +03:00
Migrate SSL certificate storage to the browser window
* Fetchers now provide the certificates before headers * This is propagated all the way to the browser window * When a query occurs, we retrieve it from there and fire the query with those stored certificates. * The serial number is a bignum, store it as hex. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
This commit is contained in:
parent
bccf101714
commit
bfb1bb1192
@ -142,6 +142,9 @@ nserror content_llcache_callback(llcache_handle *llcache,
|
||||
nserror error = NSERROR_OK;
|
||||
|
||||
switch (event->type) {
|
||||
case LLCACHE_EVENT_GOT_CERTS:
|
||||
/* Will never happen: handled in hlcache */
|
||||
break;
|
||||
case LLCACHE_EVENT_HAD_HEADERS:
|
||||
/* Will never happen: handled in hlcache */
|
||||
break;
|
||||
|
@ -44,6 +44,7 @@ struct object_params;
|
||||
struct rect;
|
||||
struct redraw_context;
|
||||
struct llcache_query_msg;
|
||||
struct ssl_cert_info;
|
||||
|
||||
/** Status of a content */
|
||||
typedef enum {
|
||||
@ -59,6 +60,7 @@ typedef enum {
|
||||
/** Used in callbacks to indicate what has occurred. */
|
||||
typedef enum {
|
||||
CONTENT_MSG_LOG, /**< Content wishes to log something */
|
||||
CONTENT_MSG_SSL_CERTS, /**< Content is from SSL and this is its chain */
|
||||
CONTENT_MSG_QUERY, /**< Something under the content has a query */
|
||||
CONTENT_MSG_QUERY_FINISHED, /**< Something under the content finished its query */
|
||||
CONTENT_MSG_LOADING, /**< fetching or converting */
|
||||
@ -107,6 +109,11 @@ union content_msg_data {
|
||||
size_t msglen; /**< The length of that message */
|
||||
browser_window_console_flags flags; /**< The flags of the logging */
|
||||
} log;
|
||||
/** 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;
|
||||
/** CONTENT_MSG_QUERY - Query from underlying object somewhere */
|
||||
const struct llcache_query_msg *query_msg;
|
||||
/** CONTENT_MSG_QUERY_FINISHED - Query from underlying object finished */
|
||||
|
@ -42,6 +42,7 @@ typedef enum {
|
||||
FETCH_ERROR,
|
||||
FETCH_REDIRECT,
|
||||
FETCH_NOTMODIFIED,
|
||||
FETCH_CERTS,
|
||||
FETCH_AUTH,
|
||||
FETCH_CERT_ERR,
|
||||
FETCH_SSL_ERR
|
||||
@ -70,7 +71,7 @@ typedef struct fetch_msg {
|
||||
struct {
|
||||
const struct ssl_cert_info *certs;
|
||||
size_t num_certs;
|
||||
} cert_err;
|
||||
} certs;
|
||||
} data;
|
||||
} fetch_msg;
|
||||
|
||||
@ -95,12 +96,15 @@ struct ssl_cert_info {
|
||||
char not_before[32]; /**< Valid from date */
|
||||
char not_after[32]; /**< Valid to date */
|
||||
int sig_type; /**< Signature type */
|
||||
long serial; /**< Serial number */
|
||||
char serialnum[64]; /**< Serial number */
|
||||
char issuer[256]; /**< Issuer details */
|
||||
char subject[256]; /**< Subject details */
|
||||
int cert_type; /**< Certificate type */
|
||||
};
|
||||
|
||||
/** maximum number of X509 certificates in chain for TLS connection */
|
||||
#define MAX_SSL_CERTS 10
|
||||
|
||||
typedef void (*fetch_callback)(const fetch_msg *msg, void *p);
|
||||
|
||||
/**
|
||||
|
@ -64,9 +64,6 @@
|
||||
/** maximum number of progress notifications per second */
|
||||
#define UPDATES_PER_SECOND 2
|
||||
|
||||
/** maximum number of X509 certificates in chain for TLS connection */
|
||||
#define MAX_CERTS 10
|
||||
|
||||
/* the ciphersuites we are willing to use */
|
||||
#define CIPHER_LIST \
|
||||
/* disable everything */ \
|
||||
@ -109,7 +106,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_CERTS]; /**< HTTPS certificate data */
|
||||
struct cert_info cert_data[MAX_SSL_CERTS]; /**< HTTPS certificate data */
|
||||
};
|
||||
|
||||
/** curl handle cache entry */
|
||||
@ -445,6 +442,129 @@ failed:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Report the certificate information in the fetch to the users
|
||||
*/
|
||||
static void
|
||||
fetch_curl_report_certs_upstream(struct curl_fetch_info *f)
|
||||
{
|
||||
int depth;
|
||||
BIO *mem;
|
||||
BUF_MEM *buf;
|
||||
const ASN1_INTEGER *asn1_num;
|
||||
BIGNUM *bignum;
|
||||
struct ssl_cert_info ssl_certs[MAX_SSL_CERTS];
|
||||
fetch_msg msg;
|
||||
struct cert_info *certs = f->cert_data;
|
||||
memset(ssl_certs, 0, sizeof(ssl_certs));
|
||||
|
||||
for (depth = 0; depth <= f->cert_depth; depth++) {
|
||||
assert(certs[depth].cert != NULL);
|
||||
|
||||
/* 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_get0_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));
|
||||
}
|
||||
|
||||
msg.type = FETCH_CERTS;
|
||||
msg.data.certs.certs = ssl_certs;
|
||||
msg.data.certs.num_certs = depth;
|
||||
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OpenSSL Certificate verification callback
|
||||
*
|
||||
@ -479,7 +599,7 @@ fetch_curl_verify_callback(int verify_ok, X509_STORE_CTX *x509_ctx)
|
||||
}
|
||||
|
||||
/* certificate chain is excessively deep so fail verification */
|
||||
if (depth >= MAX_CERTS) {
|
||||
if (depth >= MAX_SSL_CERTS) {
|
||||
X509_STORE_CTX_set_error(x509_ctx,
|
||||
X509_V_ERR_CERT_CHAIN_TOO_LONG);
|
||||
return 0;
|
||||
@ -524,6 +644,7 @@ fetch_curl_verify_callback(int verify_ok, X509_STORE_CTX *x509_ctx)
|
||||
*/
|
||||
static int fetch_curl_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *parm)
|
||||
{
|
||||
struct curl_fetch_info *f = (struct curl_fetch_info *) parm;
|
||||
int ok;
|
||||
|
||||
/* Store fetch struct in context for verify callback */
|
||||
@ -534,6 +655,8 @@ static int fetch_curl_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *parm)
|
||||
ok = X509_verify_cert(x509_ctx);
|
||||
}
|
||||
|
||||
fetch_curl_report_certs_upstream(f);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -886,7 +1009,7 @@ static void fetch_curl_free(void *vf)
|
||||
curl_formfree(f->post_multipart);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CERTS && f->cert_data[i].cert; i++) {
|
||||
for (i = 0; i < MAX_SSL_CERTS && f->cert_data[i].cert; i++) {
|
||||
ns_X509_free(f->cert_data[i].cert);
|
||||
}
|
||||
|
||||
@ -955,114 +1078,6 @@ static bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* setup callback to allow the user to examine certificates which have
|
||||
* failed to validate during fetch.
|
||||
*/
|
||||
static void
|
||||
curl_start_cert_validate(struct curl_fetch_info *f,
|
||||
struct cert_info *certs)
|
||||
{
|
||||
int depth;
|
||||
BIO *mem;
|
||||
BUF_MEM *buf;
|
||||
struct ssl_cert_info ssl_certs[MAX_CERTS];
|
||||
fetch_msg msg;
|
||||
|
||||
for (depth = 0; depth <= f->cert_depth; depth++) {
|
||||
assert(certs[depth].cert != NULL);
|
||||
|
||||
/* 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 */
|
||||
ssl_certs[depth].serial =
|
||||
ASN1_INTEGER_get(
|
||||
X509_get_serialNumber(certs[depth].cert));
|
||||
|
||||
/* 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));
|
||||
|
||||
/* and clean up */
|
||||
ns_X509_free(certs[depth].cert);
|
||||
}
|
||||
|
||||
msg.type = FETCH_CERT_ERR;
|
||||
msg.data.cert_err.certs = ssl_certs;
|
||||
msg.data.cert_err.num_certs = depth;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a completed fetch (CURLMSG_DONE from curl_multi_info_read()).
|
||||
@ -1079,7 +1094,6 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
struct curl_fetch_info *f;
|
||||
char **_hideous_hack = (char **) (void *) &f;
|
||||
CURLcode code;
|
||||
struct cert_info certs[MAX_CERTS];
|
||||
|
||||
/* find the structure associated with this fetch */
|
||||
/* For some reason, cURL thinks CURLINFO_PRIVATE should be a string?! */
|
||||
@ -1127,9 +1141,6 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
/* CURLE_SSL_PEER_CERTIFICATE renamed to
|
||||
* CURLE_PEER_FAILED_VERIFICATION
|
||||
*/
|
||||
memset(certs, 0, sizeof(certs));
|
||||
memcpy(certs, f->cert_data, sizeof(certs));
|
||||
memset(f->cert_data, 0, sizeof(f->cert_data));
|
||||
cert = true;
|
||||
} else {
|
||||
NSLOG(netsurf, INFO, "Unknown cURL response code %d", result);
|
||||
@ -1146,7 +1157,9 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
} else if (cert) {
|
||||
/* user needs to validate certificate with issue */
|
||||
curl_start_cert_validate(f, certs);
|
||||
fetch_msg msg;
|
||||
msg.type = FETCH_CERT_ERR;
|
||||
fetch_send_callback(&msg, f->fetch_handle);
|
||||
} else if (error) {
|
||||
fetch_msg msg;
|
||||
switch (result) {
|
||||
|
@ -433,6 +433,18 @@ static nserror hlcache_llcache_callback(llcache_handle *handle,
|
||||
assert(ctx->llcache == handle);
|
||||
|
||||
switch (event->type) {
|
||||
case LLCACHE_EVENT_GOT_CERTS:
|
||||
/* Pass them on upward */
|
||||
if (ctx->handle->cb != NULL) {
|
||||
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;
|
||||
|
||||
ctx->handle->cb(ctx->handle, &hlevent, ctx->handle->pw);
|
||||
}
|
||||
break;
|
||||
case LLCACHE_EVENT_HAD_HEADERS:
|
||||
error = mimesniff_compute_effective_type(llcache_handle_get_header(handle, "Content-Type"), NULL, 0,
|
||||
ctx->flags & HLCACHE_RETRIEVE_SNIFF_TYPE,
|
||||
|
@ -2360,12 +2360,9 @@ static nserror llcache_fetch_auth(llcache_object *object, const char *realm)
|
||||
* Handle a TLS certificate verification failure
|
||||
*
|
||||
* \param object Object being fetched
|
||||
* \param certs Certificate chain
|
||||
* \param num Number of certificates in chain
|
||||
* \return NSERROR_OK on success, appropriate error otherwise
|
||||
*/
|
||||
static nserror llcache_fetch_cert_error(llcache_object *object,
|
||||
const struct ssl_cert_info *certs, size_t num)
|
||||
static nserror llcache_fetch_cert_error(llcache_object *object)
|
||||
{
|
||||
nserror error = NSERROR_OK;
|
||||
|
||||
@ -2386,8 +2383,6 @@ static nserror llcache_fetch_cert_error(llcache_object *object,
|
||||
/* Emit query for TLS */
|
||||
query.type = LLCACHE_QUERY_SSL;
|
||||
query.url = object->url;
|
||||
query.data.ssl.certs = certs;
|
||||
query.data.ssl.num = num;
|
||||
|
||||
/* Construct the query event */
|
||||
event.type = LLCACHE_EVENT_QUERY;
|
||||
@ -2880,7 +2875,17 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
|
||||
error = llcache_send_event_to_users(object, &event);
|
||||
|
||||
break;
|
||||
case FETCH_CERTS:
|
||||
/* Certificate information from the fetch */
|
||||
/** \todo CERTS - Should we persist this on the object and
|
||||
* then catch up new users etc?
|
||||
*/
|
||||
event.type = LLCACHE_EVENT_GOT_CERTS;
|
||||
event.data.certs.certs = msg->data.certs.certs;
|
||||
event.data.certs.num = msg->data.certs.num_certs;
|
||||
|
||||
error = llcache_send_event_to_users(object, &event);
|
||||
break;
|
||||
/* Events requiring action */
|
||||
case FETCH_AUTH:
|
||||
/* Need Authentication */
|
||||
@ -2902,9 +2907,7 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
|
||||
object->candidate = NULL;
|
||||
}
|
||||
|
||||
error = llcache_fetch_cert_error(object,
|
||||
msg->data.cert_err.certs,
|
||||
msg->data.cert_err.num_certs);
|
||||
error = llcache_fetch_cert_error(object);
|
||||
break;
|
||||
case FETCH_SSL_ERR:
|
||||
/* TLS connection setup failed */
|
||||
|
@ -103,6 +103,7 @@ typedef nserror (*llcache_query_response)(bool proceed, void *cbpw);
|
||||
|
||||
/** Low-level cache event types */
|
||||
typedef enum {
|
||||
LLCACHE_EVENT_GOT_CERTS, /**< SSL certificates arrived */
|
||||
LLCACHE_EVENT_HAD_HEADERS, /**< Received all headers */
|
||||
LLCACHE_EVENT_HAD_DATA, /**< Received some data */
|
||||
LLCACHE_EVENT_DONE, /**< Finished fetching data */
|
||||
@ -143,6 +144,10 @@ typedef 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;
|
||||
llcache_query_msg query;/**< Query event */
|
||||
} data; /**< Event data */
|
||||
} llcache_event;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef NETSURF_DESKTOP_BROWSER_PRIVATE_H_
|
||||
#define NETSURF_DESKTOP_BROWSER_PRIVATE_H_
|
||||
|
||||
#include "content/fetch.h"
|
||||
#include "desktop/frame_types.h"
|
||||
|
||||
struct box;
|
||||
@ -88,6 +89,14 @@ struct browser_fetch_parameters {
|
||||
bool parent_quirks; /**< Optional parent quirks */
|
||||
};
|
||||
|
||||
/**
|
||||
* The SSL context for a fetch, as provided by the fetchers
|
||||
*/
|
||||
struct browser_ssl_info {
|
||||
struct ssl_cert_info certs[MAX_SSL_CERTS]; /**< The certificate chain */
|
||||
size_t num; /**< The number of certificates in the chain */
|
||||
};
|
||||
|
||||
/**
|
||||
* Browser window data.
|
||||
*/
|
||||
@ -103,6 +112,11 @@ struct browser_window {
|
||||
*/
|
||||
struct browser_fetch_parameters current_parameters;
|
||||
|
||||
/**
|
||||
* The SSL information for the current content
|
||||
*/
|
||||
struct browser_ssl_info current_ssl_info;
|
||||
|
||||
/**
|
||||
* Content handle of page in process of being loaded or NULL
|
||||
* if no page is being loaded.
|
||||
@ -114,6 +128,11 @@ struct browser_window {
|
||||
*/
|
||||
struct browser_fetch_parameters loading_parameters;
|
||||
|
||||
/**
|
||||
* The SSL information for the loading content
|
||||
*/
|
||||
struct browser_ssl_info loading_ssl_info;
|
||||
|
||||
/**
|
||||
* Favicon
|
||||
*/
|
||||
|
@ -688,10 +688,16 @@ static nserror browser_window_content_ready(struct browser_window *bw)
|
||||
|
||||
bw->current_content = bw->loading_content;
|
||||
bw->loading_content = NULL;
|
||||
|
||||
/* Transfer the fetch parameters */
|
||||
browser_window__free_fetch_parameters(&bw->current_parameters);
|
||||
bw->current_parameters = bw->loading_parameters;
|
||||
memset(&bw->loading_parameters, 0, sizeof(bw->loading_parameters));
|
||||
|
||||
/* Transfer the SSL info */
|
||||
bw->current_ssl_info = bw->loading_ssl_info;
|
||||
bw->loading_ssl_info.num = 0;
|
||||
|
||||
/* Format the new content to the correct dimensions */
|
||||
browser_window_get_dimensions(bw, &width, &height);
|
||||
width /= bw->scale;
|
||||
@ -825,6 +831,14 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
|
||||
nserror res = NSERROR_OK;
|
||||
|
||||
switch (event->type) {
|
||||
case CONTENT_MSG_SSL_CERTS:
|
||||
/* SSL certificate information has arrived, store it */
|
||||
assert(event->data.certs.num < MAX_SSL_CERTS);
|
||||
memcpy(&bw->loading_ssl_info.certs[0],
|
||||
event->data.certs.certs,
|
||||
sizeof(struct ssl_cert_info) * event->data.certs.num);
|
||||
bw->loading_ssl_info.num = event->data.certs.num;
|
||||
break;
|
||||
case CONTENT_MSG_LOG:
|
||||
browser_window_console_log(bw,
|
||||
event->data.log.src,
|
||||
@ -1138,16 +1152,22 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
|
||||
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_QUERY:
|
||||
case CONTENT_MSG_QUERY: {
|
||||
/** \todo QUERY - Decide what is right here */
|
||||
/* For now, we directly invoke the known global handler for queries */
|
||||
llcache_query query = *(event->data.query_msg->query);
|
||||
if (query.type == LLCACHE_QUERY_SSL) {
|
||||
query.data.ssl.certs = &bw->loading_ssl_info.certs[0];
|
||||
query.data.ssl.num = bw->loading_ssl_info.num;
|
||||
}
|
||||
|
||||
return netsurf_llcache_query_handler(
|
||||
event->data.query_msg->query,
|
||||
&query,
|
||||
NULL,
|
||||
event->data.query_msg->cb,
|
||||
event->data.query_msg->cb_pw);
|
||||
break;
|
||||
|
||||
}
|
||||
case CONTENT_MSG_QUERY_FINISHED:
|
||||
/** \todo QUERY - Decide what is right here */
|
||||
break;
|
||||
@ -2844,6 +2864,9 @@ browser_window__navigate_internal(struct browser_window *bw,
|
||||
|
||||
NSLOG(netsurf, INFO, "Loading '%s'", nsurl_access(params->url));
|
||||
|
||||
/* Clear SSL info for load */
|
||||
bw->loading_ssl_info.num = 0;
|
||||
|
||||
/* Set up retrieval parameters */
|
||||
if (!(params->flags & BW_NAVIGATE_UNVERIFIABLE)) {
|
||||
fetch_flags |= LLCACHE_RETRIEVE_VERIFIABLE;
|
||||
|
@ -181,6 +181,9 @@ static nserror download_callback(llcache_handle *handle,
|
||||
nserror error = NSERROR_OK;
|
||||
|
||||
switch (event->type) {
|
||||
case LLCACHE_EVENT_GOT_CERTS:
|
||||
/* Nominally not interested in these */
|
||||
break;
|
||||
case LLCACHE_EVENT_HAD_HEADERS:
|
||||
error = download_context_process_headers(ctx);
|
||||
if (error != NSERROR_OK) {
|
||||
|
@ -71,7 +71,6 @@ struct sslcert_session_data {
|
||||
struct sslcert_entry {
|
||||
treeview_node *entry;
|
||||
char version[24];
|
||||
char serial[24];
|
||||
char type[24];
|
||||
struct treeview_field_data data[SSLCERT_V_N_FIELDS - 1];
|
||||
};
|
||||
@ -134,11 +133,9 @@ sslcert_viewer_set_treeview_field_data(struct sslcert_entry *e,
|
||||
&e->data[SSLCERT_V_SUBJECT],
|
||||
cert->subject, ssl_d);
|
||||
|
||||
written = snprintf(e->serial, sizeof(e->serial), "%li", cert->serial);
|
||||
assert(written < sizeof(e->serial));
|
||||
sslcert_viewer_field_builder(SSLCERT_V_SERIAL,
|
||||
&e->data[SSLCERT_V_SERIAL],
|
||||
e->serial, ssl_d);
|
||||
cert->serialnum, ssl_d);
|
||||
|
||||
written = snprintf(e->type, sizeof(e->type), "%i", cert->cert_type);
|
||||
assert(written < sizeof(e->type));
|
||||
|
Loading…
x
Reference in New Issue
Block a user