Fix missing return value checks
[openssl.git] / ssl / t1_enc.c
index 3f4973e9ac51ed11585f2e724b54fd7a944f2bfe..df97f193864bab1d9323aaa59977549ac1dcb676 100644 (file)
@@ -260,6 +260,11 @@ static int tls1_PRF(long digest_mask,
         if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask)
             count++;
     }
+    if(!count) {
+        /* Should never happen */
+        SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     len = slen / count;
     if (count == 1)
         slen = 0;
@@ -548,16 +553,24 @@ int tls1_change_cipher_state(SSL *s, int which)
 #endif                          /* KSSL_DEBUG */
 
     if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
-        EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE));
-        EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv);
-    } else
-        EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
-
+        if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE))
+            || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv)) {
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+    } else {
+        if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) {
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+    }
     /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
-    if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size)
-        EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY,
-                            *mac_secret_size, mac_secret);
-
+    if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size
+        && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY,
+                                *mac_secret_size, mac_secret)) {
+        SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+        goto err2;
+    }
 #ifdef OPENSSL_SSL_TRACE_CRYPTO
     if (s->msg_callback) {
         int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0;
@@ -649,6 +662,7 @@ int tls1_setup_key_block(SSL *s)
 
     if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) {
         SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(p1);
         goto err;
     }
 #ifdef TLS_DEBUG
@@ -919,57 +933,30 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
     return ((int)ret);
 }
 
-int tls1_final_finish_mac(SSL *s,
-                          const char *str, int slen, unsigned char *out)
+int tls1_final_finish_mac(SSL *s, const char *str, int slen,
+                          unsigned char *out)
 {
-    unsigned int i;
-    EVP_MD_CTX ctx;
-    unsigned char buf[2 * EVP_MAX_MD_SIZE];
-    unsigned char *q, buf2[12];
-    int idx;
-    long mask;
-    int err = 0;
-    const EVP_MD *md;
-
-    q = buf;
+    int hashlen;
+    unsigned char hash[2 * EVP_MAX_MD_SIZE];
+    unsigned char buf2[12];
 
     if (s->s3->handshake_buffer)
         if (!ssl3_digest_cached_records(s))
             return 0;
 
-    EVP_MD_CTX_init(&ctx);
+    hashlen = ssl_handshake_hash(s, hash, sizeof(hash));
 
-    for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) {
-        if (mask & ssl_get_algorithm2(s)) {
-            int hashsize = EVP_MD_size(md);
-            EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
-            if (!hdgst || hashsize < 0
-                || hashsize > (int)(sizeof buf - (size_t)(q - buf))) {
-                /*
-                 * internal error: 'buf' is too small for this cipersuite!
-                 */
-                err = 1;
-            } else {
-                if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
-                    !EVP_DigestFinal_ex(&ctx, q, &i) ||
-                    (i != (unsigned int)hashsize))
-                    err = 1;
-                q += hashsize;
-            }
-        }
-    }
+    if (hashlen == 0)
+        return 0;
 
     if (!tls1_PRF(ssl_get_algorithm2(s),
-                  str, slen, buf, (int)(q - buf), NULL, 0, NULL, 0, NULL, 0,
+                  str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0,
                   s->session->master_key, s->session->master_key_length,
                   out, buf2, sizeof buf2))
-        err = 1;
-    EVP_MD_CTX_cleanup(&ctx);
-
-    if (err)
         return 0;
-    else
-        return sizeof buf2;
+    OPENSSL_cleanse(hash, hashlen);
+    OPENSSL_cleanse(buf2, sizeof(buf2));
+    return sizeof buf2;
 }
 
 int tls1_mac(SSL *ssl, unsigned char *md, int send)
@@ -1091,21 +1078,49 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
                                 int len)
 {
     unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
-    const void *co = NULL, *so = NULL;
-    int col = 0, sol = 0;
 
 #ifdef KSSL_DEBUG
     fprintf(stderr, "tls1_generate_master_secret(%p,%p, %p, %d)\n", s, out, p,
             len);
 #endif                          /* KSSL_DEBUG */
 
-
-    tls1_PRF(ssl_get_algorithm2(s),
-             TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
-             s->s3->client_random, SSL3_RANDOM_SIZE,
-             co, col,
-             s->s3->server_random, SSL3_RANDOM_SIZE,
-             so, sol, p, len, s->session->master_key, buff, sizeof buff);
+    if (s->session->flags & SSL_SESS_FLAG_EXTMS) {
+        unsigned char hash[EVP_MAX_MD_SIZE * 2];
+        int hashlen;
+        /* If we don't have any digests cache records */
+        if (s->s3->handshake_buffer) {
+            /*
+             * keep record buffer: this wont affect client auth because we're
+             * freezing the buffer at the same point (after client key
+             * exchange and before certificate verify)
+             */
+            s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
+            if(!ssl3_digest_cached_records(s))
+                return -1;
+        }
+        hashlen = ssl_handshake_hash(s, hash, sizeof(hash));
+#ifdef SSL_DEBUG
+        fprintf(stderr, "Handshake hashes:\n");
+        BIO_dump_fp(stderr, (char *)hash, hashlen);
+#endif
+        tls1_PRF(ssl_get_algorithm2(s),
+                 TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+                 TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE,
+                 hash, hashlen,
+                 NULL, 0,
+                 NULL, 0,
+                 NULL, 0, p, len, s->session->master_key, buff, sizeof buff);
+        OPENSSL_cleanse(hash, hashlen);
+    } else {
+        tls1_PRF(ssl_get_algorithm2(s),
+                 TLS_MD_MASTER_SECRET_CONST,
+                 TLS_MD_MASTER_SECRET_CONST_SIZE,
+                 s->s3->client_random, SSL3_RANDOM_SIZE,
+                 NULL, 0,
+                 s->s3->server_random, SSL3_RANDOM_SIZE,
+                 NULL, 0, p, len, s->session->master_key, buff, sizeof buff);
+    }
+    OPENSSL_cleanse(buff, sizeof buff);
 #ifdef SSL_DEBUG
     fprintf(stderr, "Premaster Secret:\n");
     BIO_dump_fp(stderr, (char *)p, len);
@@ -1204,6 +1219,9 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
     if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
                TLS_MD_MASTER_SECRET_CONST_SIZE) == 0)
         goto err1;
+    if (memcmp(val, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+               TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE) == 0)
+        goto err1;
     if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
                TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0)
         goto err1;
@@ -1216,6 +1234,8 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                   NULL, 0,
                   s->session->master_key, s->session->master_key_length,
                   out, buff, olen);
+    OPENSSL_cleanse(val, vallen);
+    OPENSSL_cleanse(buff, olen);
 
 #ifdef KSSL_DEBUG
     fprintf(stderr, "tls1_export_keying_material() complete\n");
@@ -1302,11 +1322,6 @@ int tls1_alert_code(int code)
         return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
     case SSL_AD_INAPPROPRIATE_FALLBACK:
         return (TLS1_AD_INAPPROPRIATE_FALLBACK);
-#if 0
-        /* not appropriate for TLS, not used for DTLS */
-    case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE:
-        return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
-#endif
     default:
         return (-1);
     }