Always ensure that session->cipher is set
authorMatt Caswell <matt@openssl.org>
Thu, 19 Jan 2017 15:01:55 +0000 (15:01 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 30 Jan 2017 10:18:22 +0000 (10:18 +0000)
If we have deserialized the SSL_SESSION then in some circumstances the
session->cipher value is NULL. We were patching up in some places but not
in others. We should just do it as part of loading the SSL_SESSION.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2259)

ssl/ssl_asn1.c
ssl/ssl_ciph.c
ssl/ssl_locl.h
ssl/ssl_sess.c
ssl/statem/extensions_clnt.c
ssl/statem/extensions_srvr.c

index ced6a51f4b6cde78c7e3b37e297ed70a55fa4c98..568f41ff5b016f36f298b59a6cabe718b22d5f40 100644 (file)
@@ -284,8 +284,10 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
     p = as->cipher->data;
     id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1];
 
-    ret->cipher = NULL;
     ret->cipher_id = id;
+    ret->cipher = ssl3_get_cipher_by_id(id);
+    if (ret->cipher == NULL)
+        goto err;
 
     if (!ssl_session_memcpy(ret->session_id, &ret->session_id_length,
                             as->session_id, SSL3_MAX_SSL_SESSION_ID_LENGTH))
index d4145ba5da05b592b5c5fbaad18f03143ffbafc3..88b99cca142fea7ef7cfe6a3bcc8d931eb27b57f 100644 (file)
@@ -2018,14 +2018,3 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
 
     return 1;
 }
-
-const EVP_MD *ssl_cipher_get_handshake_md(int cipher_id)
-{
-    const SSL_CIPHER *cipher = ssl3_get_cipher_by_id(cipher_id);
-    if (cipher == NULL) {
-        /* Don't recognise this cipher */
-        return NULL;
-    }
-
-    return ssl_md(cipher->algorithm2);
-}
index 64019fe0aadc116ec5fd6137e22bd2eed5bb3c9d..a59683bdff9272ca267b7624f9b9a1e7e9874f99 100644 (file)
@@ -1956,7 +1956,6 @@ __owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
 __owur int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
 __owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl,
                                                 const unsigned char *ptr);
-__owur const EVP_MD *ssl_cipher_get_handshake_md(int cipher_id);
 __owur int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain);
 __owur int ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain);
 __owur int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x);
index c28a5e1b3f34b7076e17ae40056715ab64530ba6..77c917f38a0d6d9f5dc69c52ddb60a0d97fb84ec 100644 (file)
@@ -91,6 +91,9 @@ SSL_SESSION *SSL_SESSION_new(void)
 {
     SSL_SESSION *ss;
 
+    if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL))
+        return NULL;
+
     ss = OPENSSL_zalloc(sizeof(*ss));
     if (ss == NULL) {
         SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE);
@@ -586,21 +589,6 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
         goto err;
     }
 
-    if (ret->cipher == NULL) {
-        unsigned char buf[5], *p;
-        unsigned long l;
-
-        p = buf;
-        l = ret->cipher_id;
-        l2n(l, p);
-        if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR)
-            ret->cipher = ssl_get_cipher_by_char(s, &(buf[2]));
-        else
-            ret->cipher = ssl_get_cipher_by_char(s, &(buf[1]));
-        if (ret->cipher == NULL)
-            goto err;
-    }
-
     if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */
         s->session_ctx->stats.sess_timeout++;
         if (try_session_cache) {
index c17901a954760a91ba06799ec5f6aaa24a9cbaec..368f1968d8b1bf0813de543369fe05eab1eeb0be 100644 (file)
@@ -717,7 +717,11 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
      */
     agems += s->session->ext.tick_age_add;
 
-    md = ssl_cipher_get_handshake_md(s->session->cipher_id);
+    if (s->session->cipher == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_PSK, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    md = ssl_md(s->session->cipher->algorithm2);
     if (md == NULL) {
         /* Don't recognise this cipher so we can't use the session. Ignore it */
         return 1;
index 5a5d846e04811b65319237b3c326bc2c3f6b7c4b..088dcbc3b65a6c54d406682693de9048c0b7cc2e 100644 (file)
@@ -712,7 +712,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al)
         if (ret == TICKET_NO_DECRYPT)
             continue;
 
-        md = ssl_cipher_get_handshake_md(sess->cipher_id);
+        md = ssl_md(sess->cipher->algorithm2);
         if (md == NULL) {
             /*
              * Don't recognise this cipher so we can't use the session.