summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2022-10-20 15:22:52 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2022-10-20 15:22:52 +0000
commit54efad9297ae275889b0f7e9140408381844ee17 (patch)
treea91aecf84b6037ba57ba67be0a1e78efa4c35a39
parent99d7a3ab170b9b6367dc5116855888fd4bf132e1 (diff)
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
-rw-r--r--lib/libssl/ssl_locl.h3
-rw-r--r--lib/libssl/ssl_sess.c107
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),
+ &copy->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),
+ &copy->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),
+ &copy->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, &copy->tlsext_tick, &copy->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,
+ &copy->ex_data))
+ goto err;
+
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, &copy->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, &copy->tlsext_ecpointformatlist,
+ &copy->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)
{