From ef18f5fcfa9cf3eeefcc89685bead61b8239028f Mon Sep 17 00:00:00 2001 From: jsing <> Date: Thu, 4 Apr 2019 15:03:21 +0000 Subject: Provide SSL chain/cert chain APIs. These allow for chains to be managed on a per-certificate basis rather than as a single "extra certificates" list. Note that "chain" in this context does not actually include the leaf certificate however, unlike SSL_CTX_use_certificate_chain_{file,mem}(). Thanks to sthen@ for running this through a bulk ports build. ok beck@ tb@ --- src/lib/libssl/Symbols.list | 12 +++++ src/lib/libssl/s3_lib.c | 114 +++++++++++++++++++++++++++++++++++++++++++- src/lib/libssl/ssl.h | 37 +++++++++++++- 3 files changed, 161 insertions(+), 2 deletions(-) diff --git a/src/lib/libssl/Symbols.list b/src/lib/libssl/Symbols.list index 425d71126b..e72616a779 100644 --- a/src/lib/libssl/Symbols.list +++ b/src/lib/libssl/Symbols.list @@ -57,14 +57,18 @@ SSL_CIPHER_is_aead SSL_COMP_add_compression_method SSL_COMP_get_compression_methods SSL_COMP_get_name +SSL_CTX_add0_chain_cert +SSL_CTX_add1_chain_cert SSL_CTX_add_client_CA SSL_CTX_add_session SSL_CTX_callback_ctrl SSL_CTX_check_private_key +SSL_CTX_clear_chain_certs SSL_CTX_ctrl SSL_CTX_flush_sessions SSL_CTX_free SSL_CTX_get0_certificate +SSL_CTX_get0_chain_certs SSL_CTX_get0_param SSL_CTX_get_cert_store SSL_CTX_get_ciphers @@ -93,6 +97,8 @@ SSL_CTX_sess_set_get_cb SSL_CTX_sess_set_new_cb SSL_CTX_sess_set_remove_cb SSL_CTX_sessions +SSL_CTX_set0_chain +SSL_CTX_set1_chain SSL_CTX_set1_groups SSL_CTX_set1_groups_list SSL_CTX_set1_param @@ -164,6 +170,8 @@ SSL_SESSION_set_time SSL_SESSION_set_timeout SSL_SESSION_up_ref SSL_accept +SSL_add0_chain_cert +SSL_add1_chain_cert SSL_add_client_CA SSL_add_dir_cert_subjects_to_stack SSL_add_file_cert_subjects_to_stack @@ -175,6 +183,7 @@ SSL_cache_hit SSL_callback_ctrl SSL_check_private_key SSL_clear +SSL_clear_chain_certs SSL_connect SSL_copy_session_id SSL_ctrl @@ -184,6 +193,7 @@ SSL_dup_CA_list SSL_export_keying_material SSL_free SSL_get0_alpn_selected +SSL_get0_chain_certs SSL_get0_next_proto_negotiated SSL_get0_param SSL_get1_session @@ -247,6 +257,8 @@ SSL_renegotiate_pending SSL_rstate_string SSL_rstate_string_long SSL_select_next_proto +SSL_set0_chain +SSL_set1_chain SSL_set1_groups SSL_set1_groups_list SSL_set1_host diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index 49f402d065..0357a70ca3 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_lib.c,v 1.185 2019/03/25 17:21:18 jsing Exp $ */ +/* $OpenBSD: s3_lib.c,v 1.186 2019/04/04 15:03:21 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1875,6 +1875,47 @@ _SSL_set_tlsext_status_ocsp_resp(SSL *s, unsigned char *resp, int resp_len) return 1; } +int +SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) +{ + return ssl_cert_set0_chain(ssl->cert, chain); +} + +int +SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) +{ + return ssl_cert_set1_chain(ssl->cert, chain); +} + +int +SSL_add0_chain_cert(SSL *ssl, X509 *x509) +{ + return ssl_cert_add0_chain_cert(ssl->cert, x509); +} + +int +SSL_add1_chain_cert(SSL *ssl, X509 *x509) +{ + return ssl_cert_add1_chain_cert(ssl->cert, x509); +} + +int +SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) +{ + *out_chain = NULL; + + if (ssl->cert->key != NULL) + *out_chain = ssl->cert->key->chain; + + return 1; +} + +int +SSL_clear_chain_certs(SSL *ssl) +{ + return ssl_cert_set0_chain(ssl->cert, NULL); +} + int SSL_set1_groups(SSL *s, const int *groups, size_t groups_len) { @@ -1956,6 +1997,21 @@ ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: return _SSL_set_tlsext_status_ocsp_resp(s, parg, larg); + case SSL_CTRL_CHAIN: + if (larg == 0) + return SSL_set0_chain(s, (STACK_OF(X509) *)parg); + else + return SSL_set1_chain(s, (STACK_OF(X509) *)parg); + + case SSL_CTRL_CHAIN_CERT: + if (larg == 0) + return SSL_add0_chain_cert(s, (X509 *)parg); + else + return SSL_add1_chain_cert(s, (X509 *)parg); + + case SSL_CTRL_GET_CHAIN_CERTS: + return SSL_get0_chain_certs(s, (STACK_OF(X509) **)parg); + case SSL_CTRL_SET_GROUPS: return SSL_set1_groups(s, parg, larg); @@ -2127,6 +2183,47 @@ _SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg) return 1; } +int +SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) +{ + return ssl_cert_set0_chain(ctx->internal->cert, chain); +} + +int +SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) +{ + return ssl_cert_set1_chain(ctx->internal->cert, chain); +} + +int +SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) +{ + return ssl_cert_add0_chain_cert(ctx->internal->cert, x509); +} + +int +SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) +{ + return ssl_cert_add1_chain_cert(ctx->internal->cert, x509); +} + +int +SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) +{ + *out_chain = NULL; + + if (ctx->internal->cert->key != NULL) + *out_chain = ctx->internal->cert->key->chain; + + return 1; +} + +int +SSL_CTX_clear_chain_certs(SSL_CTX *ctx) +{ + return ssl_cert_set0_chain(ctx->internal->cert, NULL); +} + static int _SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *cert) { @@ -2208,6 +2305,21 @@ ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: return _SSL_CTX_set_tlsext_status_arg(ctx, parg); + case SSL_CTRL_CHAIN: + if (larg == 0) + return SSL_CTX_set0_chain(ctx, (STACK_OF(X509) *)parg); + else + return SSL_CTX_set1_chain(ctx, (STACK_OF(X509) *)parg); + + case SSL_CTRL_CHAIN_CERT: + if (larg == 0) + return SSL_CTX_add0_chain_cert(ctx, (X509 *)parg); + else + return SSL_CTX_add1_chain_cert(ctx, (X509 *)parg); + + case SSL_CTRL_GET_CHAIN_CERTS: + return SSL_CTX_get0_chain_certs(ctx, (STACK_OF(X509) **)parg); + case SSL_CTRL_EXTRA_CHAIN_CERT: return _SSL_CTX_add_extra_chain_cert(ctx, parg); diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index 58b1be6d0d..fc89b0ef6e 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.h,v 1.165 2019/03/17 17:28:08 jsing Exp $ */ +/* $OpenBSD: ssl.h,v 1.166 2019/04/04 15:03:21 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1118,6 +1118,9 @@ int PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x); #define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +#define SSL_CTRL_CHAIN 88 +#define SSL_CTRL_CHAIN_CERT 89 + #define SSL_CTRL_SET_GROUPS 91 #define SSL_CTRL_SET_GROUPS_LIST 92 @@ -1125,6 +1128,8 @@ int PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x); #define SSL_CTRL_GET_SERVER_TMP_KEY 109 +#define SSL_CTRL_GET_CHAIN_CERTS 115 + #define SSL_CTRL_SET_DH_AUTO 118 #define SSL_CTRL_SET_MIN_PROTO_VERSION 123 @@ -1174,6 +1179,20 @@ int PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x); #define SSL_set_ecdh_auto(s, onoff) \ SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) +int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); +int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); +int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509); +int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509); +int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain); +int SSL_CTX_clear_chain_certs(SSL_CTX *ctx); + +int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain); +int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain); +int SSL_add0_chain_cert(SSL *ssl, X509 *x509); +int SSL_add1_chain_cert(SSL *ssl, X509 *x509); +int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain); +int SSL_clear_chain_certs(SSL *ssl); + int SSL_CTX_set1_groups(SSL_CTX *ctx, const int *groups, size_t groups_len); int SSL_CTX_set1_groups_list(SSL_CTX *ctx, const char *groups); @@ -1215,14 +1234,30 @@ int SSL_set_max_proto_version(SSL *ssl, uint16_t version); * Also provide those functions as macros for compatibility with * existing users. */ +#define SSL_CTX_set0_chain SSL_CTX_set0_chain +#define SSL_CTX_set1_chain SSL_CTX_set1_chain +#define SSL_CTX_add0_chain_cert SSL_CTX_add0_chain_cert +#define SSL_CTX_add1_chain_cert SSL_CTX_add1_chain_cert +#define SSL_CTX_get0_chain_certs SSL_CTX_get0_chain_certs +#define SSL_CTX_clear_chain_certs SSL_CTX_clear_chain_certs + +#define SSL_add0_chain_cert SSL_add0_chain_cert +#define SSL_add1_chain_cert SSL_add1_chain_cert +#define SSL_set0_chain SSL_set0_chain +#define SSL_set1_chain SSL_set1_chain +#define SSL_get0_chain_certs SSL_get0_chain_certs +#define SSL_clear_chain_certs SSL_clear_chain_certs + #define SSL_CTX_set1_groups SSL_CTX_set1_groups #define SSL_CTX_set1_groups_list SSL_CTX_set1_groups_list #define SSL_set1_groups SSL_set1_groups #define SSL_set1_groups_list SSL_set1_groups_list + #define SSL_CTX_get_min_proto_version SSL_CTX_get_min_proto_version #define SSL_CTX_get_max_proto_version SSL_CTX_get_max_proto_version #define SSL_CTX_set_min_proto_version SSL_CTX_set_min_proto_version #define SSL_CTX_set_max_proto_version SSL_CTX_set_max_proto_version + #define SSL_get_min_proto_version SSL_get_min_proto_version #define SSL_get_max_proto_version SSL_get_max_proto_version #define SSL_set_min_proto_version SSL_set_min_proto_version -- cgit v1.2.3-55-g6feb