[openssl-commits] [openssl] OpenSSL_1_0_1-stable update

Matt Caswell matt at openssl.org
Fri Nov 20 16:02:28 UTC 2015


The branch OpenSSL_1_0_1-stable has been updated
       via  a5184a6c89ff954261e73d1e8691ab73b9b4b2d4 (commit)
      from  e71aab1c02e6a47ec56b1e341e80d09797d3d4de (commit)


- Log -----------------------------------------------------------------
commit a5184a6c89ff954261e73d1e8691ab73b9b4b2d4
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Nov 6 16:31:21 2015 +0000

    Ensure all EVP calls have their returns checked where appropriate
    
    There are lots of calls to EVP functions from within libssl There were
    various places where we should probably check the return value but don't.
    This adds these checks.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (cherry picked from commit 56d913467541506572f908a34c32ca7071f77a94)
    
    Conflicts:
    	ssl/s3_enc.c
    	ssl/s3_srvr.c

-----------------------------------------------------------------------

Summary of changes:
 ssl/s3_cbc.c   |  45 ++++++++++++++++--------
 ssl/s3_clnt.c  |  73 ++++++++++++++++++++++++--------------
 ssl/s3_enc.c   | 108 +++++++++++++++++++++++++++++++++------------------------
 ssl/s3_srvr.c  |  55 +++++++++++++++++++----------
 ssl/ssl.h      |   1 +
 ssl/ssl_ciph.c |  11 +++---
 ssl/ssl_err.c  |   2 ++
 ssl/ssl_lib.c  |   7 ++--
 ssl/ssl_locl.h |  18 +++++-----
 ssl/ssl_rsa.c  |  23 ++++++++++--
 ssl/t1_enc.c   |  48 +++++++++++++++++--------
 ssl/t1_lib.c   |  27 +++++++++------
 12 files changed, 271 insertions(+), 147 deletions(-)

diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index 2fb71f2..b3bff74 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -411,8 +411,9 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
  * functions, above, we know that data_plus_mac_size is large enough to contain
  * a padding byte and MAC. (If the padding was invalid, it might contain the
  * padding too. )
+ * Returns 1 on success or 0 on error
  */
-void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
                             unsigned char *md_out,
                             size_t *md_out_size,
                             const unsigned char header[13],
@@ -455,7 +456,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
 
     switch (EVP_MD_CTX_type(ctx)) {
     case NID_md5:
-        MD5_Init((MD5_CTX *)md_state.c);
+        if (MD5_Init((MD5_CTX *)md_state.c) <= 0)
+            return 0;
         md_final_raw = tls1_md5_final_raw;
         md_transform =
             (void (*)(void *ctx, const unsigned char *block))MD5_Transform;
@@ -464,7 +466,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
         length_is_big_endian = 0;
         break;
     case NID_sha1:
-        SHA1_Init((SHA_CTX *)md_state.c);
+        if (SHA1_Init((SHA_CTX *)md_state.c) <= 0)
+            return 0;
         md_final_raw = tls1_sha1_final_raw;
         md_transform =
             (void (*)(void *ctx, const unsigned char *block))SHA1_Transform;
@@ -472,14 +475,16 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
         break;
 #ifndef OPENSSL_NO_SHA256
     case NID_sha224:
-        SHA224_Init((SHA256_CTX *)md_state.c);
+        if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0)
+            return 0;
         md_final_raw = tls1_sha256_final_raw;
         md_transform =
             (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
         md_size = 224 / 8;
         break;
     case NID_sha256:
-        SHA256_Init((SHA256_CTX *)md_state.c);
+        if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0)
+            return 0;
         md_final_raw = tls1_sha256_final_raw;
         md_transform =
             (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
@@ -488,7 +493,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
 #endif
 #ifndef OPENSSL_NO_SHA512
     case NID_sha384:
-        SHA384_Init((SHA512_CTX *)md_state.c);
+        if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0)
+            return 0;
         md_final_raw = tls1_sha512_final_raw;
         md_transform =
             (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
@@ -497,7 +503,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
         md_length_size = 16;
         break;
     case NID_sha512:
-        SHA512_Init((SHA512_CTX *)md_state.c);
+        if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0)
+            return 0;
         md_final_raw = tls1_sha512_final_raw;
         md_transform =
             (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
@@ -514,7 +521,7 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
         OPENSSL_assert(0);
         if (md_out_size)
             *md_out_size = -1;
-        return;
+        return 0;
     }
 
     OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
@@ -652,7 +659,7 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
              */
             if (header_length <= md_block_size) {
                 /* Should never happen */
-                return;
+                return 0;
             }
             overhang = header_length - md_block_size;
             md_transform(md_state.c, header);
@@ -733,26 +740,34 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
     }
 
     EVP_MD_CTX_init(&md_ctx);
-    EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ );
+    if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0)
+        goto err;
     if (is_sslv3) {
         /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
         memset(hmac_pad, 0x5c, sslv3_pad_length);
 
-        EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
-        EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
-        EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+        if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0
+                || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0
+                || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+            goto err;
     } else {
         /* Complete the HMAC in the standard manner. */
         for (i = 0; i < md_block_size; i++)
             hmac_pad[i] ^= 0x6a;
 
-        EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
-        EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+        if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0
+                || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+            goto err;
     }
     EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
     if (md_out_size)
         *md_out_size = md_out_size_u;
     EVP_MD_CTX_cleanup(&md_ctx);
+
+    return 1;
+err:
+    EVP_MD_CTX_cleanup(&md_ctx);
+    return 0;
 }
 
 #ifdef OPENSSL_FIPS
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 28df7ca..0578a9c 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1883,14 +1883,20 @@ int ssl3_get_key_exchange(SSL *s)
             q = md_buf;
             for (num = 2; num > 0; num--) {
                 EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-                EVP_DigestInit_ex(&md_ctx, (num == 2)
-                                  ? s->ctx->md5 : s->ctx->sha1, NULL);
-                EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
-                                 SSL3_RANDOM_SIZE);
-                EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
-                                 SSL3_RANDOM_SIZE);
-                EVP_DigestUpdate(&md_ctx, param, param_len);
-                EVP_DigestFinal_ex(&md_ctx, q, &size);
+                if (EVP_DigestInit_ex(&md_ctx,
+                                      (num == 2) ? s->ctx->md5 : s->ctx->sha1,
+                                      NULL) <= 0
+                        || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
+                                            SSL3_RANDOM_SIZE) <= 0
+                        || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
+                                            SSL3_RANDOM_SIZE) <= 0
+                        || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0
+                        || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) {
+                    SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+                           ERR_R_INTERNAL_ERROR);
+                    al = SSL_AD_INTERNAL_ERROR;
+                    goto f_err;
+                }
                 q += size;
                 j += size;
             }
@@ -1909,12 +1915,16 @@ int ssl3_get_key_exchange(SSL *s)
         } else
 #endif
         {
-            EVP_VerifyInit_ex(&md_ctx, md, NULL);
-            EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
-                             SSL3_RANDOM_SIZE);
-            EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
-                             SSL3_RANDOM_SIZE);
-            EVP_VerifyUpdate(&md_ctx, param, param_len);
+            if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0
+                    || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
+                                        SSL3_RANDOM_SIZE) <= 0
+                    || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
+                                        SSL3_RANDOM_SIZE) <= 0
+                    || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) {
+                al = SSL_AD_INTERNAL_ERROR;
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB);
+                goto f_err;
+            }
             if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) {
                 /* bad signature */
                 al = SSL_AD_DECRYPT_ERROR;
@@ -2839,10 +2849,13 @@ int ssl3_send_client_key_exchange(SSL *s)
 
             /* Otherwise, generate ephemeral key pair */
 
-            EVP_PKEY_encrypt_init(pkey_ctx);
-            /* Generate session key */
-            if (RAND_bytes(premaster_secret, 32) <= 0) {
+            if (pkey_ctx == NULL
+                    || EVP_PKEY_encrypt_init(pkey_ctx) <= 0
+                    /* Generate session key */
+                    || RAND_bytes(premaster_secret, 32) <= 0) {
                 EVP_PKEY_CTX_free(pkey_ctx);
+                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+                       ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             /*
@@ -2863,13 +2876,18 @@ int ssl3_send_client_key_exchange(SSL *s)
              * data
              */
             ukm_hash = EVP_MD_CTX_create();
-            EVP_DigestInit(ukm_hash,
-                           EVP_get_digestbynid(NID_id_GostR3411_94));
-            EVP_DigestUpdate(ukm_hash, s->s3->client_random,
-                             SSL3_RANDOM_SIZE);
-            EVP_DigestUpdate(ukm_hash, s->s3->server_random,
-                             SSL3_RANDOM_SIZE);
-            EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
+            if (EVP_DigestInit(ukm_hash,
+                               EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0
+                    || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
+                                        SSL3_RANDOM_SIZE) <= 0
+                    || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
+                                        SSL3_RANDOM_SIZE) <= 0
+                    || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
+                EVP_MD_CTX_destroy(ukm_hash);
+                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+                       ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
             EVP_MD_CTX_destroy(ukm_hash);
             if (EVP_PKEY_CTX_ctrl
                 (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
@@ -2885,7 +2903,7 @@ int ssl3_send_client_key_exchange(SSL *s)
             *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
             msglen = 255;
             if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32)
-                < 0) {
+                <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_LIBRARY_BUG);
                 goto err;
@@ -3086,7 +3104,10 @@ int ssl3_send_client_verify(SSL *s)
         pkey = s->cert->key->privatekey;
 /* Create context from key and test if sha1 is allowed as digest */
         pctx = EVP_PKEY_CTX_new(pkey, NULL);
-        EVP_PKEY_sign_init(pctx);
+        if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) {
+            SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
         if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) {
             if (TLS1_get_version(s) < TLS1_2_VERSION)
                 s->method->ssl3_enc->cert_verify_mac(s,
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 152f40d..85ebac8 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -253,7 +253,10 @@ int ssl3_change_cipher_state(SSL *s, int which)
             EVP_CIPHER_CTX_init(s->enc_read_ctx);
         dd = s->enc_read_ctx;
 
-        ssl_replace_hash(&s->read_hash, m);
+        if (ssl_replace_hash(&s->read_hash, m) == NULL) {
+                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+                goto err2;
+        }
 #ifndef OPENSSL_NO_COMP
         /* COMPRESS */
         if (s->expand != NULL) {
@@ -288,7 +291,10 @@ int ssl3_change_cipher_state(SSL *s, int which)
              */
             EVP_CIPHER_CTX_init(s->enc_write_ctx);
         dd = s->enc_write_ctx;
-        ssl_replace_hash(&s->write_hash, m);
+        if (ssl_replace_hash(&s->write_hash, m) == NULL) {
+                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+                goto err2;
+        }
 #ifndef OPENSSL_NO_COMP
         /* COMPRESS */
         if (s->compress != NULL) {
@@ -674,19 +680,21 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
         return 0;
 
     npad = (48 / n) * n;
-    if (sender != NULL)
-        EVP_DigestUpdate(&ctx, sender, len);
-    EVP_DigestUpdate(&ctx, s->session->master_key,
-                     s->session->master_key_length);
-    EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
-    EVP_DigestFinal_ex(&ctx, md_buf, &i);
-
-    EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL);
-    EVP_DigestUpdate(&ctx, s->session->master_key,
-                     s->session->master_key_length);
-    EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
-    EVP_DigestUpdate(&ctx, md_buf, i);
-    EVP_DigestFinal_ex(&ctx, p, &ret);
+    if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0)
+            || EVP_DigestUpdate(&ctx, s->session->master_key,
+                                s->session->master_key_length) <= 0
+            || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0
+            || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0
+
+            || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0
+            || EVP_DigestUpdate(&ctx, s->session->master_key,
+                                s->session->master_key_length) <= 0
+            || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0
+            || EVP_DigestUpdate(&ctx, md_buf, i) <= 0
+            || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) {
+        SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR);
+        ret = 0;
+    }
 
     EVP_MD_CTX_cleanup(&ctx);
 
@@ -758,33 +766,36 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
         header[j++] = rec->length & 0xff;
 
         /* Final param == is SSLv3 */
-        ssl3_cbc_digest_record(hash,
-                               md, &md_size,
-                               header, rec->input,
-                               rec->length + md_size, orig_len,
-                               mac_sec, md_size, 1);
+        if (ssl3_cbc_digest_record(hash,
+                                   md, &md_size,
+                                   header, rec->input,
+                                   rec->length + md_size, orig_len,
+                                   mac_sec, md_size, 1) <= 0)
+            return -1;
     } else {
         unsigned int md_size_u;
         /* Chop the digest off the end :-) */
         EVP_MD_CTX_init(&md_ctx);
 
-        EVP_MD_CTX_copy_ex(&md_ctx, hash);
-        EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
-        EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad);
-        EVP_DigestUpdate(&md_ctx, seq, 8);
         rec_char = rec->type;
-        EVP_DigestUpdate(&md_ctx, &rec_char, 1);
         p = md;
         s2n(rec->length, p);
-        EVP_DigestUpdate(&md_ctx, md, 2);
-        EVP_DigestUpdate(&md_ctx, rec->input, rec->length);
-        EVP_DigestFinal_ex(&md_ctx, md, NULL);
-
-        EVP_MD_CTX_copy_ex(&md_ctx, hash);
-        EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
-        EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad);
-        EVP_DigestUpdate(&md_ctx, md, md_size);
-        EVP_DigestFinal_ex(&md_ctx, md, &md_size_u);
+        if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
+                || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
+                || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0
+                || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0
+                || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0
+                || EVP_DigestUpdate(&md_ctx, md, 2) <= 0
+                || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0
+                || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0
+                || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
+                || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
+                || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0
+                || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0
+                || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) {
+            EVP_MD_CTX_cleanup(&md_ctx);
+            return -1;
+        }
         md_size = md_size_u;
 
         EVP_MD_CTX_cleanup(&md_ctx);
@@ -826,17 +837,24 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 
     EVP_MD_CTX_init(&ctx);
     for (i = 0; i < 3; i++) {
-        EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL);
-        EVP_DigestUpdate(&ctx, salt[i], strlen((const char *)salt[i]));
-        EVP_DigestUpdate(&ctx, p, len);
-        EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE);
-        EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE);
-        EVP_DigestFinal_ex(&ctx, buf, &n);
-
-        EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL);
-        EVP_DigestUpdate(&ctx, p, len);
-        EVP_DigestUpdate(&ctx, buf, n);
-        EVP_DigestFinal_ex(&ctx, out, &n);
+        if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0
+                || EVP_DigestUpdate(&ctx, salt[i],
+                                    strlen((const char *)salt[i])) <= 0
+                || EVP_DigestUpdate(&ctx, p, len) <= 0
+                || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]),
+                                    SSL3_RANDOM_SIZE) <= 0
+                || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]),
+                                    SSL3_RANDOM_SIZE) <= 0
+                || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0
+
+                || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0
+                || EVP_DigestUpdate(&ctx, p, len) <= 0
+                || EVP_DigestUpdate(&ctx, buf, n) <= 0
+                || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) {
+            SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
+            ret = 0;
+            break;
+        }
         out += n;
         ret += n;
     }
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index e45fc4e..5c5914e 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1986,14 +1986,22 @@ int ssl3_send_server_key_exchange(SSL *s)
                 for (num = 2; num > 0; num--) {
                     EVP_MD_CTX_set_flags(&md_ctx,
                                          EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-                    EVP_DigestInit_ex(&md_ctx, (num == 2)
-                                      ? s->ctx->md5 : s->ctx->sha1, NULL);
-                    EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
-                                     SSL3_RANDOM_SIZE);
-                    EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
-                                     SSL3_RANDOM_SIZE);
-                    EVP_DigestUpdate(&md_ctx, &(d[4]), n);
-                    EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i);
+                    if (EVP_DigestInit_ex(&md_ctx,
+                                          (num == 2) ? s->ctx->md5
+                                                     : s->ctx->sha1,
+                                          NULL) <= 0
+                        || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
+                                            SSL3_RANDOM_SIZE) <= 0
+                        || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
+                                            SSL3_RANDOM_SIZE) <= 0
+                        || EVP_DigestUpdate(&md_ctx, &(d[4]), n) <= 0
+                        || EVP_DigestFinal_ex(&md_ctx, q,
+                                              (unsigned int *)&i) <= 0) {
+                        SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
+                               ERR_LIB_EVP);
+                        al = SSL_AD_INTERNAL_ERROR;
+                        goto f_err;
+                    }
                     q += i;
                     j += i;
                 }
@@ -2023,16 +2031,17 @@ int ssl3_send_server_key_exchange(SSL *s)
 #ifdef SSL_DEBUG
                 fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
 #endif
-                EVP_SignInit_ex(&md_ctx, md, NULL);
-                EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
-                               SSL3_RANDOM_SIZE);
-                EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
-                               SSL3_RANDOM_SIZE);
-                EVP_SignUpdate(&md_ctx, &(d[4]), n);
-                if (!EVP_SignFinal(&md_ctx, &(p[2]),
-                                   (unsigned int *)&i, pkey)) {
+                if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0
+                        || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
+                                          SSL3_RANDOM_SIZE) <= 0
+                        || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
+                                          SSL3_RANDOM_SIZE) <= 0
+                        || EVP_SignUpdate(&md_ctx, &(d[4]), n) <= 0
+                        || EVP_SignFinal(&md_ctx, &(p[2]),
+                                         (unsigned int *)&i, pkey) <= 0) {
                     SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
-                    goto err;
+                    al = SSL_AD_INTERNAL_ERROR;
+                    goto f_err;
                 }
                 s2n(i, p);
                 n += i + 2;
@@ -2883,7 +2892,10 @@ int ssl3_get_client_key_exchange(SSL *s)
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
-        EVP_PKEY_decrypt_init(pkey_ctx);
+        if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
+            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto gerr;
+        }
         /*
          * If client certificate is present and is of the same type, maybe
          * use it for key exchange.  Don't mind errors from
@@ -3132,7 +3144,12 @@ int ssl3_get_cert_verify(SSL *s)
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
-        EVP_PKEY_verify_init(pctx);
+        if (EVP_PKEY_verify_init(pctx) <= 0) {
+            EVP_PKEY_CTX_free(pctx);
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
         if (i != 64) {
             fprintf(stderr, "GOST signature length is %d", i);
         }
diff --git a/ssl/ssl.h b/ssl/ssl.h
index d9657eb..b8456c6 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2313,6 +2313,7 @@ void ERR_load_SSL_strings(void);
 # define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC                 292
 # define SSL_F_SSL3_ENC                                   134
 # define SSL_F_SSL3_GENERATE_KEY_BLOCK                    238
+# define SSL_F_SSL3_GENERATE_MASTER_SECRET                388
 # define SSL_F_SSL3_GET_CERTIFICATE_REQUEST               135
 # define SSL_F_SSL3_GET_CERT_STATUS                       289
 # define SSL_F_SSL3_GET_CERT_VERIFY                       136
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index cac525e..cb559d9 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -356,10 +356,11 @@ static int get_optional_pkey_id(const char *pkey_name)
     const EVP_PKEY_ASN1_METHOD *ameth;
     int pkey_id = 0;
     ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1);
-    if (ameth) {
-        EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+    if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+                                         ameth) > 0) {
+        return pkey_id;
     }
-    return pkey_id;
+    return 0;
 }
 
 #else
@@ -371,7 +372,9 @@ static int get_optional_pkey_id(const char *pkey_name)
     int pkey_id = 0;
     ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1);
     if (ameth) {
-        EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+        if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+                                    ameth) <= 0)
+            pkey_id = 0;
     }
     if (tmpeng)
         ENGINE_finish(tmpeng);
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 26f149e..caa671a 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -162,6 +162,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"},
     {ERR_FUNC(SSL_F_SSL3_CHECK_FINISHED), "SSL3_CHECK_FINISHED"},
     {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"},
+    {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET),
+     "ssl3_generate_master_secret"},
     {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),
      "SSL3_GET_CERTIFICATE_REQUEST"},
     {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index e11746a..9cfeaf3 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3283,8 +3283,11 @@ EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
 {
     ssl_clear_hash_ctx(hash);
     *hash = EVP_MD_CTX_create();
-    if (md)
-        EVP_DigestInit_ex(*hash, md, NULL);
+    if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
+        EVP_MD_CTX_destroy(*hash);
+        *hash = NULL;
+        return NULL;
+    }
     return *hash;
 }
 
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 5edf7a8..f5d9df6 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1218,15 +1218,15 @@ int tls1_cbc_remove_padding(const SSL *s,
                             SSL3_RECORD *rec,
                             unsigned block_size, unsigned mac_size);
 char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
-void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
-                            unsigned char *md_out,
-                            size_t *md_out_size,
-                            const unsigned char header[13],
-                            const unsigned char *data,
-                            size_t data_plus_mac_size,
-                            size_t data_plus_mac_plus_padding_size,
-                            const unsigned char *mac_secret,
-                            unsigned mac_secret_length, char is_sslv3);
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+                           unsigned char *md_out,
+                           size_t *md_out_size,
+                           const unsigned char header[13],
+                           const unsigned char *data,
+                           size_t data_plus_mac_size,
+                           size_t data_plus_mac_plus_padding_size,
+                           const unsigned char *mac_secret,
+                           unsigned mac_secret_length, char is_sslv3);
 
 void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx,
                            EVP_MD_CTX *mac_ctx, const unsigned char *data,
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index daf15dd..c91a998 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -160,7 +160,10 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
     }
 
     RSA_up_ref(rsa);
-    EVP_PKEY_assign_RSA(pkey, rsa);
+    if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+        RSA_free(rsa);
+        return 0;
+    }
 
     ret = ssl_set_pkey(ssl->cert, pkey);
     EVP_PKEY_free(pkey);
@@ -181,6 +184,15 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
     if (c->pkeys[i].x509 != NULL) {
         EVP_PKEY *pktmp;
         pktmp = X509_get_pubkey(c->pkeys[i].x509);
+        if (pktmp == NULL) {
+            SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE);
+            EVP_PKEY_free(pktmp);
+            return 0;
+        }
+        /*
+         * The return code from EVP_PKEY_copy_parameters is deliberately
+         * ignored. Some EVP_PKEY types cannot do this.
+         */
         EVP_PKEY_copy_parameters(pktmp, pkey);
         EVP_PKEY_free(pktmp);
         ERR_clear_error();
@@ -382,6 +394,10 @@ static int ssl_set_cert(CERT *c, X509 *x)
     }
 
     if (c->pkeys[i].privatekey != NULL) {
+        /*
+         * The return code from EVP_PKEY_copy_parameters is deliberately
+         * ignored. Some EVP_PKEY types cannot do this.
+         */
         EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
         ERR_clear_error();
 
@@ -502,7 +518,10 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
     }
 
     RSA_up_ref(rsa);
-    EVP_PKEY_assign_RSA(pkey, rsa);
+    if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+        RSA_free(rsa);
+        return 0;
+    }
 
     ret = ssl_set_pkey(ctx->cert, pkey);
     EVP_PKEY_free(pkey);
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 8f45294..985356d 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -385,6 +385,8 @@ int tls1_change_cipher_state(SSL *s, int which)
             EVP_CIPHER_CTX_init(s->enc_read_ctx);
         dd = s->enc_read_ctx;
         mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
+        if (mac_ctx == NULL)
+            goto err;
 #ifndef OPENSSL_NO_COMP
         if (s->expand != NULL) {
             COMP_CTX_free(s->expand);
@@ -423,11 +425,14 @@ int tls1_change_cipher_state(SSL *s, int which)
         dd = s->enc_write_ctx;
         if (SSL_IS_DTLS(s)) {
             mac_ctx = EVP_MD_CTX_create();
-            if (!mac_ctx)
+            if (mac_ctx == NULL)
                 goto err;
             s->write_hash = mac_ctx;
-        } else
+        } else {
             mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
+            if (mac_ctx == NULL)
+                goto err;
+        }
 #ifndef OPENSSL_NO_COMP
         if (s->compress != NULL) {
             COMP_CTX_free(s->compress);
@@ -500,7 +505,12 @@ int tls1_change_cipher_state(SSL *s, int which)
     if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
         mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
                                        mac_secret, *mac_secret_size);
-        EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key);
+        if (mac_key == NULL
+                || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) {
+            EVP_PKEY_free(mac_key);
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
         EVP_PKEY_free(mac_key);
     }
 #ifdef TLS_DEBUG
@@ -913,8 +923,9 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
     }
 
     EVP_MD_CTX_init(&ctx);
-    EVP_MD_CTX_copy_ex(&ctx, d);
-    EVP_DigestFinal_ex(&ctx, out, &ret);
+    if (EVP_MD_CTX_copy_ex(&ctx, d) <=0
+            || EVP_DigestFinal_ex(&ctx, out, &ret) <= 0)
+        ret = 0;
     EVP_MD_CTX_cleanup(&ctx);
     return ((int)ret);
 }
@@ -1041,17 +1052,24 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
          * are hashing because that gives an attacker a timing-oracle.
          */
         /* Final param == not SSLv3 */
-        ssl3_cbc_digest_record(mac_ctx,
-                               md, &md_size,
-                               header, rec->input,
-                               rec->length + md_size, orig_len,
-                               ssl->s3->read_mac_secret,
-                               ssl->s3->read_mac_secret_size, 0);
+        if (ssl3_cbc_digest_record(mac_ctx,
+                                   md, &md_size,
+                                   header, rec->input,
+                                   rec->length + md_size, orig_len,
+                                   ssl->s3->read_mac_secret,
+                                   ssl->s3->read_mac_secret_size, 0) <= 0) {
+            if (!stream_mac)
+                EVP_MD_CTX_cleanup(&hmac);
+            return -1;
+        }
     } else {
-        EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
-        EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
-        t = EVP_DigestSignFinal(mac_ctx, md, &md_size);
-        OPENSSL_assert(t > 0);
+        if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
+                || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
+                || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
+            if (!stream_mac)
+                EVP_MD_CTX_cleanup(&hmac);
+            return -1;
+        }
 #ifdef OPENSSL_FIPS
         if (!send && FIPS_mode())
             tls_fips_digest_extra(ssl->enc_read_ctx,
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index b1b8bb0..27f1216 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -2291,10 +2291,13 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
         /* Check key name matches */
         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
             return 2;
-        HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
-                     tlsext_tick_md(), NULL);
-        EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
-                           tctx->tlsext_tick_aes_key, etick + 16);
+        if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+                         tlsext_tick_md(), NULL) <= 0
+                || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+                                      tctx->tlsext_tick_aes_key,
+                                      etick + 16) <= 0) {
+            goto err;
+       }
     }
     /*
      * Attempt to process session ticket, first conduct sanity and integrity
@@ -2302,13 +2305,14 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
      */
     mlen = HMAC_size(&hctx);
     if (mlen < 0) {
-        EVP_CIPHER_CTX_cleanup(&ctx);
-        return -1;
+        goto err;
     }
     eticklen -= mlen;
     /* Check HMAC of encrypted ticket */
-    HMAC_Update(&hctx, etick, eticklen);
-    HMAC_Final(&hctx, tick_hmac, NULL);
+    if (HMAC_Update(&hctx, etick, eticklen) <= 0
+            || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) {
+        goto err;
+    }
     HMAC_CTX_cleanup(&hctx);
     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
         EVP_CIPHER_CTX_cleanup(&ctx);
@@ -2319,11 +2323,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
     eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
     sdec = OPENSSL_malloc(eticklen);
-    if (!sdec) {
+    if (!sdec || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
         EVP_CIPHER_CTX_cleanup(&ctx);
         return -1;
     }
-    EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
     if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
         EVP_CIPHER_CTX_cleanup(&ctx);
         OPENSSL_free(sdec);
@@ -2356,6 +2359,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
      * For session parse failure, indicate that we need to send a new ticket.
      */
     return 2;
+err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    HMAC_CTX_cleanup(&hctx);
+    return -1;
 }
 
 /* Tables to translate from NIDs to TLS v1.2 ids */


More information about the openssl-commits mailing list