diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2015-06-11 18:03:37 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2015-06-11 18:03:37 +0000 |
commit | d7a2d00e5375699d95f3720a7b779ded3c805b5f (patch) | |
tree | ce015b962f950e2fd404fdd6180b3cbdff9eb335 /ssl/ssl_sess.c | |
parent | a46f5e3e504e070c9b4803e9bd1572a33e0987a8 (diff) |
Diffstat (limited to 'ssl/ssl_sess.c')
-rw-r--r-- | ssl/ssl_sess.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 9c797e3ed6065..e1695ab40601a 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -135,6 +135,79 @@ SSL_SESSION *SSL_SESSION_new(void) return (ss); } +/* + * 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. + */ +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) +{ + SSL_SESSION *dest; + + dest = OPENSSL_malloc(sizeof(*src)); + if (dest == NULL) { + goto err; + } + memcpy(dest, src, sizeof(*dest)); + + /* + * Set the various pointers to NULL so that we can call SSL_SESSION_free in + * the case of an error whilst halfway through constructing dest + */ + dest->ciphers = NULL; +#ifndef OPENSSL_NO_TLSEXT + dest->tlsext_hostname = NULL; +#endif + dest->tlsext_tick = NULL; + memset(&dest->ex_data, 0, sizeof(dest->ex_data)); + + /* We deliberately don't copy the prev and next pointers */ + dest->prev = NULL; + dest->next = NULL; + + dest->references = 1; + + if (src->sess_cert != NULL) + CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); + + if (src->peer != NULL) + CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); + + if(src->ciphers != NULL) { + dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); + if (dest->ciphers == NULL) + goto err; + } + + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, + &dest->ex_data, &src->ex_data)) { + goto err; + } + +#ifndef OPENSSL_NO_TLSEXT + if (src->tlsext_hostname) { + dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); + if (dest->tlsext_hostname == NULL) { + goto err; + } + } +#endif + + if (ticket != 0) { + dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); + if(dest->tlsext_tick == NULL) + goto err; + } else { + dest->tlsext_tick_lifetime_hint = 0; + dest->tlsext_ticklen = 0; + } + + return dest; +err: + SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(dest); + return NULL; +} + const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) { @@ -310,6 +383,12 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) goto err; + + if (session_id + len > limit) { + fatal = 1; + goto err; + } + #ifndef OPENSSL_NO_TLSEXT r = tls1_process_ticket(s, session_id, len, limit, &ret); if (r == -1) { |