diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-07-24 22:53:27 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-07-24 22:53:27 +1000 |
commit | 6725682d77510bf6d499957897d7be124d603f40 (patch) | |
tree | 447e5bce5607b4873f7f018df1b2e4c21a394e92 /ssl | |
parent | ae89578be2930c726d6ef56451233757a89f224f (diff) | |
download | openssl-new-6725682d77510bf6d499957897d7be124d603f40.tar.gz |
Add X509 related libctx changes.
- In order to not add many X509_XXXX_with_libctx() functions the libctx and propq may be stored in the X509 object via a call to X509_new_with_libctx().
- Loading via PEM_read_bio_X509() or d2i_X509() should pass in a created cert using X509_new_with_libctx().
- Renamed some XXXX_ex() to XXX_with_libctx() for X509 API's.
- Removed the extra parameters in check_purpose..
- X509_digest() has been modified so that it expects a const EVP_MD object() and then internally it does the fetch when it needs to (via ASN1_item_digest_with_libctx()).
- Added API's that set the libctx when they load such as X509_STORE_new_with_libctx() so that the cert chains can be verified.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12153)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/s3_lib.c | 4 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 35 | ||||
-rw-r--r-- | ssl/ssl_conf.c | 22 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 14 | ||||
-rw-r--r-- | ssl/ssl_mcnf.c | 6 | ||||
-rw-r--r-- | ssl/ssl_rsa.c | 125 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 10 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 8 |
8 files changed, 147 insertions, 77 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index a7f1e4d83a..8f5aaaf942 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4001,10 +4001,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) return 0; } } - if (!X509v3_cache_extensions((X509 *)parg, ctx->libctx, ctx->propq)) { - SSLerr(0, ERR_LIB_X509); - return 0; - } if (!sk_X509_push(ctx->extra_certs, (X509 *)parg)) { SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE); return 0; diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index e81542a89e..e6262bfaeb 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -257,18 +257,12 @@ int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain) { int i, r; CERT_PKEY *cpk = s != NULL ? s->cert->key : ctx->cert->key; - SSL_CTX *realctx = s != NULL ? s->ctx : ctx; if (!cpk) return 0; for (i = 0; i < sk_X509_num(chain); i++) { X509 *x = sk_X509_value(chain, i); - if (!X509v3_cache_extensions(x, realctx->libctx, realctx->propq)) { - SSLerr(0, ERR_LIB_X509); - return 0; - } - r = ssl_security_cert(s, ctx, x, 0, 0); if (r != 1) { SSLerr(SSL_F_SSL_CERT_SET0_CHAIN, r); @@ -614,29 +608,39 @@ static unsigned long xname_hash(const X509_NAME *a) return X509_NAME_hash((X509_NAME *)a); } -STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) +STACK_OF(X509_NAME) *SSL_load_client_CA_file_with_libctx(const char *file, + OPENSSL_CTX *libctx, + const char *propq) { BIO *in = BIO_new(BIO_s_file()); X509 *x = NULL; X509_NAME *xn = NULL; STACK_OF(X509_NAME) *ret = NULL; LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp); + OPENSSL_CTX *prev_libctx = NULL; if ((name_hash == NULL) || (in == NULL)) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + SSLerr(0, ERR_R_MALLOC_FAILURE); goto err; } + x = X509_new_with_libctx(libctx, propq); + if (x == NULL) { + SSLerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } if (!BIO_read_filename(in, file)) goto err; + /* Internally lh_X509_NAME_retrieve() needs the libctx to retrieve SHA1 */ + prev_libctx = OPENSSL_CTX_set0_default(libctx); for (;;) { if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) break; if (ret == NULL) { ret = sk_X509_NAME_new_null(); if (ret == NULL) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + SSLerr(0, ERR_R_MALLOC_FAILURE); goto err; } } @@ -663,6 +667,8 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) sk_X509_NAME_pop_free(ret, X509_NAME_free); ret = NULL; done: + /* restore the old libctx */ + OPENSSL_CTX_set0_default(prev_libctx); BIO_free(in); X509_free(x); lh_X509_NAME_free(name_hash); @@ -671,6 +677,11 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) return ret; } +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) +{ + return SSL_load_client_CA_file_with_libctx(file, NULL, NULL); +} + int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *file) { @@ -841,6 +852,7 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) X509_STORE_CTX *xs_ctx = NULL; STACK_OF(X509) *chain = NULL, *untrusted = NULL; X509 *x; + SSL_CTX *real_ctx = (s == NULL) ? ctx : s->ctx; int i, rv = 0; if (!cpk->x509) { @@ -872,10 +884,7 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) untrusted = cpk->chain; } - if (s == NULL) - xs_ctx = X509_STORE_CTX_new_with_libctx(ctx->libctx, ctx->propq); - else - xs_ctx = X509_STORE_CTX_new_with_libctx(s->ctx->libctx, s->ctx->propq); + xs_ctx = X509_STORE_CTX_new_with_libctx(real_ctx->libctx, ctx->propq); if (xs_ctx == NULL) { SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_MALLOC_FAILURE); goto err; diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index fe9b8ec3ea..56590da207 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -470,13 +470,23 @@ static int do_store(SSL_CONF_CTX *cctx, { CERT *cert; X509_STORE **st; + SSL_CTX *ctx; + OPENSSL_CTX *libctx = NULL; + const char *propq = NULL; - if (cctx->ctx) + if (cctx->ctx != NULL) { cert = cctx->ctx->cert; - else if (cctx->ssl) + ctx = cctx->ctx; + } else if (cctx->ssl != NULL) { cert = cctx->ssl->cert; - else + ctx = cctx->ssl->ctx; + } else { return 1; + } + if (ctx != NULL) { + libctx = ctx->libctx; + propq = ctx->propq; + } st = verify_store ? &cert->verify_store : &cert->chain_store; if (*st == NULL) { *st = X509_STORE_new(); @@ -484,11 +494,13 @@ static int do_store(SSL_CONF_CTX *cctx, return 0; } - if (CAfile != NULL && !X509_STORE_load_file(*st, CAfile)) + if (CAfile != NULL && !X509_STORE_load_file_with_libctx(*st, CAfile, + libctx, propq)) return 0; if (CApath != NULL && !X509_STORE_load_path(*st, CApath)) return 0; - if (CAstore != NULL && !X509_STORE_load_store(*st, CAstore)) + if (CAstore != NULL && !X509_STORE_load_store_with_libctx(*st, CAstore, + libctx, propq)) return 0; return 1; } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index c92e361cde..871606cfc1 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -4254,7 +4254,8 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { - return X509_STORE_set_default_paths(ctx->cert_store); + return X509_STORE_set_default_paths_with_libctx(ctx->cert_store, + ctx->libctx, ctx->propq); } int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx) @@ -4286,7 +4287,8 @@ int SSL_CTX_set_default_verify_file(SSL_CTX *ctx) /* We ignore errors, in case the directory doesn't exist */ ERR_set_mark(); - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + X509_LOOKUP_load_file_with_libctx(lookup, NULL, X509_FILETYPE_DEFAULT, + ctx->libctx, ctx->propq); ERR_pop_to_mark(); @@ -4304,7 +4306,7 @@ int SSL_CTX_set_default_verify_store(SSL_CTX *ctx) /* We ignore errors, in case the directory doesn't exist */ ERR_set_mark(); - X509_LOOKUP_add_store(lookup, NULL); + X509_LOOKUP_add_store_with_libctx(lookup, NULL, ctx->libctx, ctx->propq); ERR_pop_to_mark(); @@ -4313,7 +4315,8 @@ int SSL_CTX_set_default_verify_store(SSL_CTX *ctx) int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile) { - return X509_STORE_load_file(ctx->cert_store, CAfile); + return X509_STORE_load_file_with_libctx(ctx->cert_store, CAfile, + ctx->libctx, ctx->propq); } int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath) @@ -4323,7 +4326,8 @@ int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath) int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore) { - return X509_STORE_load_store(ctx->cert_store, CAstore); + return X509_STORE_load_store_with_libctx(ctx->cert_store, CAstore, + ctx->libctx, ctx->propq); } int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, diff --git a/ssl/ssl_mcnf.c b/ssl/ssl_mcnf.c index 27ba7728d7..66f0bc5abe 100644 --- a/ssl/ssl_mcnf.c +++ b/ssl/ssl_mcnf.c @@ -28,6 +28,8 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) unsigned int flags; const SSL_METHOD *meth; const SSL_CONF_CMD *cmds; + OPENSSL_CTX *prev_libctx = NULL; + OPENSSL_CTX *libctx = NULL; if (s == NULL && ctx == NULL) { SSLerr(SSL_F_SSL_DO_CONFIG, ERR_R_PASSED_NULL_PARAMETER); @@ -53,15 +55,18 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) if (s != NULL) { meth = s->method; SSL_CONF_CTX_set_ssl(cctx, s); + libctx = s->ctx->libctx; } else { meth = ctx->method; SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); + libctx = ctx->libctx; } if (meth->ssl_accept != ssl_undefined_function) flags |= SSL_CONF_FLAG_SERVER; if (meth->ssl_connect != ssl_undefined_function) flags |= SSL_CONF_FLAG_CLIENT; SSL_CONF_CTX_set_flags(cctx, flags); + prev_libctx = OPENSSL_CTX_set0_default(libctx); for (i = 0; i < cmd_count; i++) { char *cmdstr, *arg; @@ -79,6 +84,7 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) } rv = SSL_CONF_CTX_finish(cctx); err: + OPENSSL_CTX_set0_default(prev_libctx); SSL_CONF_CTX_free(cctx); return rv <= 0 ? 0 : 1; } diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 3df32b725b..144dd2c374 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -34,10 +34,7 @@ int SSL_use_certificate(SSL *ssl, X509 *x) SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (!X509v3_cache_extensions(x, ssl->ctx->libctx, ssl->ctx->propq)) { - SSLerr(0, ERR_LIB_X509); - return 0; - } + rv = ssl_security_cert(ssl, NULL, x, 0, 1); if (rv != 1) { SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv); @@ -52,7 +49,7 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) int j; BIO *in; int ret = 0; - X509 *x = NULL; + X509 *cert = NULL, *x = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { @@ -64,19 +61,29 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); goto end; } + + if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + x = X509_new_with_libctx(ssl->ctx->libctx, ssl->ctx->propq); + if (x == NULL) { + SSLerr(0, ERR_R_MALLOC_FAILURE); + goto end; + } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); + cert = d2i_X509_bio(in, &x); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ssl->default_passwd_callback, - ssl->default_passwd_callback_userdata); + cert = PEM_read_bio_X509(in, &x, ssl->default_passwd_callback, + ssl->default_passwd_callback_userdata); } else { SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } - if (x == NULL) { + if (cert == NULL) { SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); goto end; } @@ -93,8 +100,14 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) X509 *x; int ret; - x = d2i_X509(NULL, &d, (long)len); + x = X509_new_with_libctx(ssl->ctx->libctx, ssl->ctx->propq); if (x == NULL) { + SSLerr(0, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (d2i_X509(&x, &d, (long)len)== NULL) { + X509_free(x); SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); return 0; } @@ -316,10 +329,7 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (!X509v3_cache_extensions(x, ctx->libctx, ctx->propq)) { - SSLerr(0, ERR_LIB_X509); - return 0; - } + rv = ssl_security_cert(NULL, ctx, x, 0, 1); if (rv != 1) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv); @@ -390,10 +400,10 @@ static int ssl_set_cert(CERT *c, X509 *x) int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { - int j; + int j = SSL_R_BAD_VALUE; BIO *in; int ret = 0; - X509 *x = NULL; + X509 *x = NULL, *cert = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { @@ -405,19 +415,24 @@ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); goto end; } + if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + x = X509_new_with_libctx(ctx->libctx, ctx->propq); + if (x == NULL) { + SSLerr(0, ERR_R_MALLOC_FAILURE); + goto end; + } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); + cert = d2i_X509_bio(in, &x); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; + cert = PEM_read_bio_X509(in, &x, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); } - - if (x == NULL) { + if (cert == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); goto end; } @@ -434,8 +449,14 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) X509 *x; int ret; - x = d2i_X509(NULL, &d, (long)len); + x = X509_new_with_libctx(ctx->libctx, ctx->propq); if (x == NULL) { + SSLerr(0, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (d2i_X509(&x, &d, (long)len) == NULL) { + X509_free(x); SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); return 0; } @@ -610,6 +631,7 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) X509 *x = NULL; pem_password_cb *passwd_callback; void *passwd_callback_userdata; + SSL_CTX *real_ctx = (ssl == NULL) ? ctx : ssl->ctx; ERR_clear_error(); /* clear error stack for * SSL_CTX_use_certificate() */ @@ -633,9 +655,13 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) goto end; } - x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, - passwd_callback_userdata); + x = X509_new_with_libctx(real_ctx->libctx, real_ctx->propq); if (x == NULL) { + SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE); + goto end; + } + if (PEM_read_bio_X509_AUX(in, &x, passwd_callback, + passwd_callback_userdata) == NULL) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); goto end; } @@ -667,23 +693,32 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) goto end; } - while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback, - passwd_callback_userdata)) - != NULL) { - if (ctx) - r = SSL_CTX_add0_chain_cert(ctx, ca); - else - r = SSL_add0_chain_cert(ssl, ca); - /* - * Note that we must not free ca if it was successfully added to - * the chain (while we must free the main certificate, since its - * reference count is increased by SSL_CTX_use_certificate). - */ - if (!r) { - X509_free(ca); - ret = 0; + while (1) { + ca = X509_new_with_libctx(real_ctx->libctx, real_ctx->propq); + if (ca == NULL) { + SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE); goto end; } + if (PEM_read_bio_X509(in, &ca, passwd_callback, + passwd_callback_userdata) != NULL) { + if (ctx) + r = SSL_CTX_add0_chain_cert(ctx, ca); + else + r = SSL_add0_chain_cert(ssl, ca); + /* + * Note that we must not free ca if it was successfully added to + * the chain (while we must free the main certificate, since its + * reference count is increased by SSL_CTX_use_certificate). + */ + if (!r) { + X509_free(ca); + ret = 0; + goto end; + } + } else { + X509_free(ca); + break; + } } /* When the while loop ends, it's usually just EOF. */ err = ERR_peek_last_error(); @@ -1063,15 +1098,9 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr int j; int rv; CERT *c = ssl != NULL ? ssl->cert : ctx->cert; - SSL_CTX *actualctx = ssl == NULL ? ctx : ssl->ctx; STACK_OF(X509) *dup_chain = NULL; EVP_PKEY *pubkey = NULL; - if (!X509v3_cache_extensions(x509, actualctx->libctx, actualctx->propq)) { - SSLerr(0, ERR_R_X509_LIB); - goto out; - } - /* Do all security checks before anything else */ rv = ssl_security_cert(ssl, ctx, x509, 0, 1); if (rv != 1) { diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index d7722d76e0..4cd85ef609 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -1858,12 +1858,20 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) } certstart = certbytes; - x = d2i_X509(NULL, (const unsigned char **)&certbytes, cert_len); + x = X509_new_with_libctx(s->ctx->libctx, s->ctx->propq); if (x == NULL) { + SSLfatal(s, SSL_AD_DECODE_ERROR, + SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); + SSLerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } + if (d2i_X509(&x, (const unsigned char **)&certbytes, + cert_len) == NULL) { SSLfatal(s, SSL_AD_BAD_CERTIFICATE, SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_ASN1_LIB); goto err; } + if (certbytes != (certstart + cert_len)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index abffbd6326..b329e89379 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -3676,12 +3676,18 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) } certstart = certbytes; - x = d2i_X509(NULL, (const unsigned char **)&certbytes, l); + x = X509_new_with_libctx(s->ctx->libctx, s->ctx->propq); if (x == NULL) { SSLfatal(s, SSL_AD_DECODE_ERROR, + SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + if (d2i_X509(&x, (const unsigned char **)&certbytes, l) == NULL) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); goto err; } + if (certbytes != (certstart + l)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, |