Reset s->tlsext_ticket_expected in ssl_scan_serverhello_tlsext.
[openssl.git] / ssl / s3_clnt.c
index 534dc1f8f7c19db1f495aa98dd14401c87084862..98d775b91a2f50c32cf5a373545c34cd895c7173 100644 (file)
 #include <openssl/engine.h>
 #endif
 
-static const SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
 
+#ifndef OPENSSL_NO_SSL3_METHOD
 static const SSL_METHOD *ssl3_get_client_method(int ver)
        {
        if (ver == SSL3_VERSION)
@@ -182,6 +182,7 @@ IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
                        ssl_undefined_function,
                        ssl3_connect,
                        ssl3_get_client_method)
+#endif
 
 int ssl3_connect(SSL *s)
        {
@@ -2002,6 +2003,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;
@@ -2014,9 +2016,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);
@@ -2190,12 +2192,18 @@ int ssl3_get_certificate_request(SSL *s)
                        s->cert->pkeys[i].digest = NULL;
                        s->cert->pkeys[i].valid_flags = 0;
                        }
-               if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
+               if ((llen & 1) || !tls1_save_sigalgs(s, p, llen))
                        {
                        ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
                        SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR);
                        goto err;
                        }
+               if (!tls1_process_sigalgs(s))
+                       {
+                       ssl3_send_alert(s,SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                       SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+                       goto err;
+                       }
                p += llen;
                }
 
@@ -2344,7 +2352,7 @@ int ssl3_get_new_session_ticket(SSL *s)
                }
        memcpy(s->session->tlsext_tick, p, ticklen);
        s->session->tlsext_ticklen = ticklen;
-       /* There are two ways to detect a resumed ticket sesion.
+       /* There are two ways to detect a resumed ticket session.
         * One is to set an appropriate session ID and then the server
         * must return a match in ServerHello. This allows the normal
         * client session ID matching to work and we know much 
@@ -3119,7 +3127,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;
@@ -3133,8 +3145,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)
                                {
@@ -3148,7 +3161,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;
@@ -3182,14 +3202,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)
                                {