X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_sess.c;h=1482a3e7c75bdba03d9920263731f7c42222c3ad;hp=c7bbc96e4cf9a399ddb8ce99bff9c1c93720c870;hb=3edabd3ccb7aac89af5a63cfb2378e33a8be05d7;hpb=c80149d9f09b3a5a5b1621fa705e900d455334d4 diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index c7bbc96e4c..1482a3e7c7 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the OpenSSL license (the "License"). You may not use @@ -12,6 +12,7 @@ #include #include #include +#include "internal/refcount.h" #include "ssl_locl.h" #include "statem/statem_locl.h" @@ -93,6 +94,11 @@ SSL_SESSION *SSL_SESSION_new(void) return ss; } +SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src) +{ + return ssl_session_dup(src, 1); +} + /* * Create a new SSL_SESSION and duplicate the contents of |src| into it. If * ticket == 0 then no ticket information is duplicated, otherwise it is. @@ -122,11 +128,13 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) dest->ext.supportedgroups = NULL; #endif dest->ext.tick = NULL; + dest->ext.alpn_selected = NULL; #ifndef OPENSSL_NO_SRP dest->srp_username = NULL; #endif dest->peer_chain = NULL; dest->peer = NULL; + dest->ext.tick_nonce = NULL; memset(&dest->ex_data, 0, sizeof(dest->ex_data)); /* We deliberately don't copy the prev and next pointers */ @@ -212,6 +220,22 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) dest->ext.ticklen = 0; } + if (src->ext.alpn_selected) { + dest->ext.alpn_selected = + (unsigned char*)OPENSSL_strndup((char*)src->ext.alpn_selected, + src->ext.alpn_selected_len); + if (dest->ext.alpn_selected == NULL) { + goto err; + } + } + + if (src->ext.tick_nonce != NULL) { + dest->ext.tick_nonce = OPENSSL_memdup(src->ext.tick_nonce, + src->ext.tick_nonce_len); + if (dest->ext.tick_nonce == NULL) + goto err; + } + #ifndef OPENSSL_NO_SRP if (src->srp_username) { dest->srp_username = OPENSSL_strdup(src->srp_username); @@ -259,12 +283,12 @@ unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) */ #define MAX_SESS_ID_ATTEMPTS 10 -static int def_generate_session_id(const SSL *ssl, unsigned char *id, +static int def_generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len) { unsigned int retry = 0; do - if (RAND_bytes(id, *id_len) <= 0) + if (ssl_randbytes(ssl, id, *id_len) <= 0) return 0; while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; @@ -468,7 +492,8 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al) goto err; case TICKET_NONE: case TICKET_EMPTY: - try_session_cache = 1; + if (hello->session_id_len > 0) + try_session_cache = 1; break; case TICKET_NO_DECRYPT: case TICKET_SUCCESS: @@ -527,11 +552,11 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al) (s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE)) { /* - * The following should not return 1, otherwise, things are - * very strange + * Either return value of SSL_CTX_add_session should not + * interrupt the session resumption process. The return + * value is intentionally ignored. */ - if (SSL_CTX_add_session(s->session_ctx, ret)) - goto err; + SSL_CTX_add_session(s->session_ctx, ret); } } } @@ -775,6 +800,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) OPENSSL_free(ss->srp_username); #endif OPENSSL_free(ss->ext.alpn_selected); + OPENSSL_free(ss->ext.tick_nonce); CRYPTO_THREAD_lock_free(ss->lock); OPENSSL_clear_free(ss, sizeof(*ss)); } @@ -858,16 +884,40 @@ int SSL_SESSION_get_protocol_version(const SSL_SESSION *s) return s->ssl_version; } +int SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version) +{ + s->ssl_version = version; + return 1; +} + const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s) { return s->cipher; } +int SSL_SESSION_set_cipher(SSL_SESSION *s, const SSL_CIPHER *cipher) +{ + s->cipher = cipher; + return 1; +} + const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s) { return s->ext.hostname; } +int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname) +{ + OPENSSL_free(s->ext.hostname); + if (hostname == NULL) { + s->ext.hostname = NULL; + return 1; + } + s->ext.hostname = OPENSSL_strdup(hostname); + + return s->ext.hostname != NULL; +} + int SSL_SESSION_has_ticket(const SSL_SESSION *s) { return (s->ext.ticklen > 0) ? 1 : 0; @@ -891,6 +941,40 @@ uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s) return s->ext.max_early_data; } +int SSL_SESSION_set_max_early_data(SSL_SESSION *s, uint32_t max_early_data) +{ + s->ext.max_early_data = max_early_data; + + return 1; +} + +void SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s, + const unsigned char **alpn, + size_t *len) +{ + *alpn = s->ext.alpn_selected; + *len = s->ext.alpn_selected_len; +} + +int SSL_SESSION_set1_alpn_selected(SSL_SESSION *s, const unsigned char *alpn, + size_t len) +{ + OPENSSL_free(s->ext.alpn_selected); + if (alpn == NULL || len == 0) { + s->ext.alpn_selected = NULL; + s->ext.alpn_selected_len = 0; + return 1; + } + s->ext.alpn_selected = OPENSSL_memdup(alpn, len); + if (s->ext.alpn_selected == NULL) { + s->ext.alpn_selected_len = 0; + return 0; + } + s->ext.alpn_selected_len = len; + + return 1; +} + X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) { return s->peer;