From 4e5f1e0420a23688bec26a60ba7f49ffdd33ba62 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Mon, 25 Mar 2019 16:35:48 +0000 Subject: Rework ssl3_output_cert_chain() to take a CERT_PKEY and consider chains. We will now include the certificates in the chain in the certificate list, or use the existing extra_certs if present. Failing that we fall back to the automatic chain building if not disabled. This also simplifies the code significantly. ok beck@ tb@ --- src/lib/libssl/ssl_both.c | 60 ++++++++++++++++++++++------------------------- src/lib/libssl/ssl_clnt.c | 4 ++-- src/lib/libssl/ssl_locl.h | 4 ++-- src/lib/libssl/ssl_srvr.c | 8 +++---- 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/lib/libssl/ssl_both.c b/src/lib/libssl/ssl_both.c index 77ab26e8b5..6bd5f08111 100644 --- a/src/lib/libssl/ssl_both.c +++ b/src/lib/libssl/ssl_both.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_both.c,v 1.14 2018/11/08 22:28:52 jsing Exp $ */ +/* $OpenBSD: ssl_both.c,v 1.15 2019/03/25 16:35:48 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -378,60 +378,56 @@ ssl3_add_cert(CBB *cbb, X509 *x) } int -ssl3_output_cert_chain(SSL *s, CBB *cbb, X509 *x) +ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk) { - int no_chain = 0; + X509_STORE_CTX *xs_ctx = NULL; + STACK_OF(X509) *chain; CBB cert_list; + X509 *x; int ret = 0; int i; if (!CBB_add_u24_length_prefixed(cbb, &cert_list)) goto err; - if ((s->internal->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs) - no_chain = 1; + /* Send an empty certificate list when no certificate is available. */ + if (cpk == NULL) + goto done; - /* TLSv1 sends a chain with nothing in it, instead of an alert. */ - if (x != NULL) { - if (no_chain) { - if (!ssl3_add_cert(&cert_list, x)) - goto err; - } else { - X509_STORE_CTX xs_ctx; + if ((chain = cpk->chain) == NULL) + chain = s->ctx->extra_certs; - if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, - x, NULL)) { - SSLerror(s, ERR_R_X509_LIB); - goto err; - } - X509_verify_cert(&xs_ctx); - - /* Don't leave errors in the queue. */ - ERR_clear_error(); - for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { - x = sk_X509_value(xs_ctx.chain, i); - if (!ssl3_add_cert(&cert_list, x)) { - X509_STORE_CTX_cleanup(&xs_ctx); - goto err; - } - } - X509_STORE_CTX_cleanup(&xs_ctx); + if (chain != NULL || (s->internal->mode & SSL_MODE_NO_AUTO_CHAIN)) { + if (!ssl3_add_cert(&cert_list, cpk->x509)) + goto err; + } else { + if ((xs_ctx = X509_STORE_CTX_new()) == NULL) + goto err; + if (!X509_STORE_CTX_init(xs_ctx, s->ctx->cert_store, + cpk->x509, NULL)) { + SSLerror(s, ERR_R_X509_LIB); + goto err; } + X509_verify_cert(xs_ctx); + ERR_clear_error(); + chain = xs_ctx->chain; } - /* Thawte special :-) */ - for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) { - x = sk_X509_value(s->ctx->extra_certs, i); + for (i = 0; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); if (!ssl3_add_cert(&cert_list, x)) goto err; } + done: if (!CBB_flush(cbb)) goto err; ret = 1; err: + X509_STORE_CTX_free(xs_ctx); + return (ret); } diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index f3c439e6c0..262e09fe5e 100644 --- a/src/lib/libssl/ssl_clnt.c +++ b/src/lib/libssl/ssl_clnt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_clnt.c,v 1.58 2019/03/19 16:53:03 jsing Exp $ */ +/* $OpenBSD: ssl_clnt.c,v 1.59 2019/03/25 16:35:48 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -2693,7 +2693,7 @@ ssl3_send_client_certificate(SSL *s) SSL3_MT_CERTIFICATE)) goto err; if (!ssl3_output_cert_chain(s, &client_cert, - (S3I(s)->tmp.cert_req == 2) ? NULL : s->cert->key->x509)) + (S3I(s)->tmp.cert_req == 2) ? NULL : s->cert->key)) goto err; if (!ssl3_handshake_msg_finish(s, &cbb)) goto err; diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 509183a7fa..5d39d1a391 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.239 2019/03/25 16:24:57 jsing Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.240 2019/03/25 16:35:48 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1154,7 +1154,7 @@ int ssl3_renegotiate_check(SSL *ssl); int ssl3_dispatch_alert(SSL *s); int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); -int ssl3_output_cert_chain(SSL *s, CBB *cbb, X509 *x); +int ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk); SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, STACK_OF(SSL_CIPHER) *srvr); int ssl3_setup_buffers(SSL *s); diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 6872fa3523..f2aafc3032 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_srvr.c,v 1.64 2019/02/09 15:26:15 jsing Exp $ */ +/* $OpenBSD: ssl_srvr.c,v 1.65 2019/03/25 16:35:48 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -2467,7 +2467,7 @@ int ssl3_send_server_certificate(SSL *s) { CBB cbb, server_cert; - X509 *x; + CERT_PKEY *cpk; /* * Server Certificate - RFC 5246, section 7.4.2. @@ -2476,7 +2476,7 @@ ssl3_send_server_certificate(SSL *s) memset(&cbb, 0, sizeof(cbb)); if (S3I(s)->hs.state == SSL3_ST_SW_CERT_A) { - if ((x = ssl_get_server_send_cert(s)) == NULL) { + if ((cpk = ssl_get_server_send_pkey(s)) == NULL) { SSLerror(s, ERR_R_INTERNAL_ERROR); return (0); } @@ -2484,7 +2484,7 @@ ssl3_send_server_certificate(SSL *s) if (!ssl3_handshake_msg_start(s, &cbb, &server_cert, SSL3_MT_CERTIFICATE)) goto err; - if (!ssl3_output_cert_chain(s, &server_cert, x)) + if (!ssl3_output_cert_chain(s, &server_cert, cpk)) goto err; if (!ssl3_handshake_msg_finish(s, &cbb)) goto err; -- cgit v1.2.3-55-g6feb