Fixed error introduced in commit f2be92b94dad3c6cbdf79d99a324804094cf1617
[openssl.git] / ssl / s3_clnt.c
index 9457dfb3c0e304309424beb3a31b2d0f930c14fd..3e89e5204d7bab86c74724a4e1b0167b468d1007 100644 (file)
@@ -1979,6 +1979,7 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
                if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s))
                        {
                        int num;
+                       unsigned int size;
 
                        j=0;
                        q=md_buf;
@@ -1991,9 +1992,9 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
                                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,(unsigned int *)&i);
-                               q+=i;
-                               j+=i;
+                               EVP_DigestFinal_ex(&md_ctx,q,&size);
+                               q+=size;
+                               j+=size;
                                }
                        i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
                                                                pkey->pkey.rsa);
@@ -3096,7 +3097,11 @@ int ssl3_send_client_key_exchange(SSL *s)
 #ifndef OPENSSL_NO_PSK
                else if (alg_k & SSL_kPSK)
                        {
-                       char identity[PSK_MAX_IDENTITY_LEN];
+                       /* The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes
+                        * to return a \0-terminated identity. The last byte
+                        * is for us for simulating strnlen. */
+                       char identity[PSK_MAX_IDENTITY_LEN + 2];
+                       size_t identity_len;
                        unsigned char *t = NULL;
                        unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
                        unsigned int pre_ms_len = 0, psk_len = 0;
@@ -3110,8 +3115,9 @@ int ssl3_send_client_key_exchange(SSL *s)
                                goto err;
                                }
 
+                       memset(identity, 0, sizeof(identity));
                        psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
-                               identity, PSK_MAX_IDENTITY_LEN,
+                               identity, sizeof(identity) - 1,
                                psk_or_pre_ms, sizeof(psk_or_pre_ms));
                        if (psk_len > PSK_MAX_PSK_LEN)
                                {
@@ -3125,7 +3131,14 @@ int ssl3_send_client_key_exchange(SSL *s)
                                        SSL_R_PSK_IDENTITY_NOT_FOUND);
                                goto psk_err;
                                }
-
+                       identity[PSK_MAX_IDENTITY_LEN + 1] = '\0';
+                       identity_len = strlen(identity);
+                       if (identity_len > PSK_MAX_IDENTITY_LEN)
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+                                       ERR_R_INTERNAL_ERROR);
+                               goto psk_err;
+                               }
                        /* create PSK pre_master_secret */
                        pre_ms_len = 2+psk_len+2+psk_len;
                        t = psk_or_pre_ms;
@@ -3159,14 +3172,13 @@ int ssl3_send_client_key_exchange(SSL *s)
                        s->session->master_key_length =
                                s->method->ssl3_enc->generate_master_secret(s,
                                        s->session->master_key,
-                                       psk_or_pre_ms, pre_ms_len); 
-                       n = strlen(identity);
-                       s2n(n, p);
-                       memcpy(p, identity, n);
-                       n+=2;
+                                       psk_or_pre_ms, pre_ms_len);
+                       s2n(identity_len, p);
+                       memcpy(p, identity, identity_len);
+                       n = 2 + identity_len;
                        psk_err = 0;
                psk_err:
-                       OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
+                       OPENSSL_cleanse(identity, sizeof(identity));
                        OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
                        if (psk_err != 0)
                                {