From ed031ec403c68f06dc48c222873c32c8e2248c01 Mon Sep 17 00:00:00 2001 From: tb Date: Thu, 20 Oct 2022 15:22:51 +0000 Subject: [PATCH] Provide ssl_session_dup() SSL_SESSION_dup() is a currently essentially unused public OpenSSL 1.1.1 API. Add a version that does not duplicate the secrets for internal use. If the public API should be needed, we can easily make it a wrapper. ok jsing --- lib/libssl/ssl_locl.h | 3 +- lib/libssl/ssl_sess.c | 107 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h index 1ddc5e0d5c1..42ae4290748 100644 --- a/lib/libssl/ssl_locl.h +++ b/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.428 2022/10/20 15:20:27 tb Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.429 2022/10/20 15:22:51 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1313,6 +1313,7 @@ int ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, int ssl_security_shared_group(const SSL *ssl, uint16_t group_id); int ssl_security_supported_group(const SSL *ssl, uint16_t group_id); +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int include_ticket); int ssl_get_new_session(SSL *s, int session); int ssl_get_prev_session(SSL *s, CBS *session_id, CBS *ext_block, int *alert); diff --git a/lib/libssl/ssl_sess.c b/lib/libssl/ssl_sess.c index 39e8b3353aa..dcf9b103da2 100644 --- a/lib/libssl/ssl_sess.c +++ b/lib/libssl/ssl_sess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_sess.c,v 1.119 2022/10/20 15:21:22 tb Exp $ */ +/* $OpenBSD: ssl_sess.c,v 1.120 2022/10/20 15:22:51 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -242,6 +242,111 @@ SSL_SESSION_new(void) return (ss); } +SSL_SESSION * +ssl_session_dup(SSL_SESSION *sess, int include_ticket) +{ + SSL_SESSION *copy; + CBS cbs; + + if ((copy = calloc(1, sizeof(*copy))) == NULL) { + SSLerrorx(ERR_R_MALLOC_FAILURE); + goto err; + } + + copy->ssl_version = sess->ssl_version; + + CBS_init(&cbs, sess->master_key, sess->master_key_length); + if (!CBS_write_bytes(&cbs, copy->master_key, sizeof(copy->master_key), + ©->master_key_length)) + goto err; + + CBS_init(&cbs, sess->session_id, sess->session_id_length); + if (!CBS_write_bytes(&cbs, copy->session_id, sizeof(copy->session_id), + ©->session_id_length)) + goto err; + + CBS_init(&cbs, sess->sid_ctx, sess->sid_ctx_length); + if (!CBS_write_bytes(&cbs, copy->sid_ctx, sizeof(copy->sid_ctx), + ©->sid_ctx_length)) + goto err; + + if (sess->peer_cert != NULL) { + if (!X509_up_ref(sess->peer_cert)) + goto err; + copy->peer_cert = sess->peer_cert; + } + copy->peer_cert_type = sess->peer_cert_type; + + copy->verify_result = sess->verify_result; + + copy->timeout = sess->timeout; + copy->time = sess->time; + copy->references = 1; + + copy->cipher = sess->cipher; + copy->cipher_id = sess->cipher_id; + + if (sess->ciphers != NULL) { + if ((copy->ciphers = sk_SSL_CIPHER_dup(sess->ciphers)) == NULL) + goto err; + } + + if (sess->tlsext_hostname != NULL) { + copy->tlsext_hostname = strdup(sess->tlsext_hostname); + if (copy->tlsext_hostname == NULL) + goto err; + } + + if (include_ticket) { + CBS_init(&cbs, sess->tlsext_tick, sess->tlsext_ticklen); + if (!CBS_stow(&cbs, ©->tlsext_tick, ©->tlsext_ticklen)) + goto err; + copy->tlsext_tick_lifetime_hint = + sess->tlsext_tick_lifetime_hint; + + /* + * XXX - copy sess->resumption_master_secret and all other + * TLSv1.3 info here. + */ + } + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, copy, + ©->ex_data)) + goto err; + + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ©->ex_data, + &sess->ex_data)) + goto err; + + /* Omit prev/next: the new session gets its own slot in the cache. */ + + copy->not_resumable = sess->not_resumable; + + CBS_init(&cbs, sess->tlsext_ecpointformatlist, + sess->tlsext_ecpointformatlist_length); + if (!CBS_stow(&cbs, ©->tlsext_ecpointformatlist, + ©->tlsext_ecpointformatlist_length)) + goto err; + + if (sess->tlsext_supportedgroups != NULL) { + if ((copy->tlsext_supportedgroups = calloc(sizeof(uint16_t), + sess->tlsext_supportedgroups_length)) == NULL) + goto err; + memcpy(copy->tlsext_supportedgroups, + sess->tlsext_supportedgroups, + sizeof(uint16_t) * sess->tlsext_supportedgroups_length); + copy->tlsext_supportedgroups_length = + sess->tlsext_supportedgroups_length; + } + + return copy; + + err: + SSL_SESSION_free(copy); + + return NULL; +} + const unsigned char * SSL_SESSION_get_id(const SSL_SESSION *ss, unsigned int *len) { -- 2.20.1