PR: 2326
[openssl.git] / ssl / s3_clnt.c
index 0541de95b9308f30e46b756395c23b7943e8477b..f46aaef6ce026a56dbc48b093ae05ebf49285fa0 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
@@ -278,24 +281,19 @@ int ssl3_connect(SSL *s)
                case SSL3_ST_CR_SRVR_HELLO_A:
                case SSL3_ST_CR_SRVR_HELLO_B:
                        ret=ssl3_get_server_hello(s);
                case SSL3_ST_CR_SRVR_HELLO_A:
                case SSL3_ST_CR_SRVR_HELLO_B:
                        ret=ssl3_get_server_hello(s);
-#ifndef OPENSSL_NO_SRP
-                       if ((ret == 0) && (s->s3->warn_alert == SSL_AD_MISSING_SRP_USERNAME))
-                               {
-                               if (!SRP_have_to_put_srp_username(s))
-                                       {
-                                       SSLerr(SSL_F_SSL3_CONNECT,SSL_R_MISSING_SRP_USERNAME);
-                                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_USER_CANCELLED);
-                                       goto end;
-                                       }
-                               s->state=SSL3_ST_CW_CLNT_HELLO_A;
-                               if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
-                               break;
-                               }
-#endif
                        if (ret <= 0) goto end;
 
                        if (s->hit)
                        if (ret <= 0) goto end;
 
                        if (s->hit)
+                               {
                                s->state=SSL3_ST_CR_FINISHED_A;
                                s->state=SSL3_ST_CR_FINISHED_A;
+#ifndef OPENSSL_NO_TLSEXT
+                               if (s->tlsext_ticket_expected)
+                                       {
+                                       /* receive renewed session ticket */
+                                       s->state=SSL3_ST_CR_SESSION_TICKET_A;
+                                       }
+#endif
+                               }
                        else
                                s->state=SSL3_ST_CR_CERT_A;
                        s->init_num=0;
                        else
                                s->state=SSL3_ST_CR_CERT_A;
                        s->init_num=0;
@@ -453,7 +451,7 @@ int ssl3_connect(SSL *s)
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
                        s->state=SSL3_ST_CW_FINISHED_A;
 #else
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
                        s->state=SSL3_ST_CW_FINISHED_A;
 #else
-                       if (s->next_proto_negotiated)
+                       if (s->s3->next_proto_neg_seen)
                                s->state=SSL3_ST_CW_NEXT_PROTO_A;
                        else
                                s->state=SSL3_ST_CW_FINISHED_A;
                                s->state=SSL3_ST_CW_NEXT_PROTO_A;
                        else
                                s->state=SSL3_ST_CW_FINISHED_A;
@@ -891,6 +889,14 @@ int ssl3_get_server_hello(SSL *s)
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);
                goto f_err;
                }
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);
                goto f_err;
                }
+       /* TLS v1.2 only ciphersuites require v1.2 or later */
+       if ((c->algorithm_ssl & SSL_TLSV1_2) && 
+               (TLS1_get_version(s) < TLS1_2_VERSION))
+               {
+               al=SSL_AD_ILLEGAL_PARAMETER;
+               SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
+               goto f_err;
+               }
        p+=ssl_put_cipher_by_char(s,NULL,NULL);
 
        sk=ssl_get_ciphers_by_id(s);
        p+=ssl_put_cipher_by_char(s,NULL,NULL);
 
        sk=ssl_get_ciphers_by_id(s);
@@ -922,9 +928,11 @@ int ssl3_get_server_hello(SSL *s)
                        }
                }
        s->s3->tmp.new_cipher=c;
                        }
                }
        s->s3->tmp.new_cipher=c;
-       if (!ssl3_digest_cached_records(s))
+       /* Don't digest cached records if TLS v1.2: we may need them for
+        * client authentication.
+        */
+       if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s))
                goto f_err;
                goto f_err;
-
        /* lets get the compression algorithm */
        /* COMPRESSION */
 #ifdef OPENSSL_NO_COMP
        /* lets get the compression algorithm */
        /* COMPRESSION */
 #ifdef OPENSSL_NO_COMP
@@ -997,7 +1005,7 @@ int ssl3_get_server_hello(SSL *s)
                /* wrong packet length */
                al=SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);
                /* wrong packet length */
                al=SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);
-               goto err;
+               goto f_err;
                }
 
        return(1);
                }
 
        return(1);
@@ -1654,7 +1662,7 @@ int ssl3_get_key_exchange(SSL *s)
        /* if it was signed, check the signature */
        if (pkey != NULL)
                {
        /* if it was signed, check the signature */
        if (pkey != NULL)
                {
-               if (s->version >= TLS1_2_VERSION)
+               if (TLS1_get_version(s) >= TLS1_2_VERSION)
                        {
                        int sigalg = tls12_get_sigid(pkey);
                        /* Should never happen */
                        {
                        int sigalg = tls12_get_sigid(pkey);
                        /* Should never happen */
@@ -1699,7 +1707,7 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
                        }
 
 #ifndef OPENSSL_NO_RSA
                        }
 
 #ifndef OPENSSL_NO_RSA
-               if (pkey->type == EVP_PKEY_RSA && s->version < TLS1_2_VERSION)
+               if (pkey->type == EVP_PKEY_RSA && TLS1_get_version(s) < TLS1_2_VERSION)
                        {
                        int num;
 
                        {
                        int num;
 
@@ -1707,6 +1715,8 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
                        q=md_buf;
                        for (num=2; num > 0; num--)
                                {
                        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_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);
@@ -1793,7 +1803,7 @@ int ssl3_get_certificate_request(SSL *s)
        {
        int ok,ret=0;
        unsigned long n,nc,l;
        {
        int ok,ret=0;
        unsigned long n,nc,l;
-       unsigned int llen,sigalglen, ctype_num,i;
+       unsigned int llen, ctype_num,i;
        X509_NAME *xn=NULL;
        const unsigned char *p,*q;
        unsigned char *d;
        X509_NAME *xn=NULL;
        const unsigned char *p,*q;
        unsigned char *d;
@@ -1813,6 +1823,14 @@ int ssl3_get_certificate_request(SSL *s)
        if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
                {
                s->s3->tmp.reuse_message=1;
        if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
                {
                s->s3->tmp.reuse_message=1;
+               /* If we get here we don't need any cached handshake records
+                * as we wont be doing client auth.
+                */
+               if (s->s3->handshake_buffer)
+                       {
+                       if (!ssl3_digest_cached_records(s))
+                               goto err;
+                       }
                return(1);
                }
 
                return(1);
                }
 
@@ -1849,17 +1867,26 @@ int ssl3_get_certificate_request(SSL *s)
        for (i=0; i<ctype_num; i++)
                s->s3->tmp.ctype[i]= p[i];
        p+=ctype_num;
        for (i=0; i<ctype_num; i++)
                s->s3->tmp.ctype[i]= p[i];
        p+=ctype_num;
-       /* HACK! For now just skip over signatature algorithms */
-       if (s->version >= TLS1_2_VERSION)
+       if (TLS1_get_version(s) >= TLS1_2_VERSION)
                {
                {
-               n2s(p, sigalglen);
-               p += sigalglen;
-               sigalglen += 2;
+               n2s(p, llen);
+               /* Check we have enough room for signature algorithms and
+                * following length value.
+                */
+               if ((unsigned long)(p - d + llen + 2) > n)
+                       {
+                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+                       SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG);
+                       goto err;
+                       }
+               if ((llen & 1) || !tls1_process_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;
+                       }
+               p += llen;
                }
                }
-       else
-               sigalglen = 0;
-               
-               
 
        /* get the CA RDNs */
        n2s(p,llen);
 
        /* get the CA RDNs */
        n2s(p,llen);
@@ -1872,7 +1899,7 @@ fclose(out);
 }
 #endif
 
 }
 #endif
 
-       if ((llen+ctype_num+sigalglen+2+1) != n)
+       if ((unsigned long)(p - d + llen) != n)
                {
                ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
                SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);
                {
                ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
                SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);
@@ -1978,7 +2005,7 @@ int ssl3_get_new_session_ticket(SSL *s)
        if (n < 6)
                {
                /* need at least ticket_lifetime_hint + ticket length */
        if (n < 6)
                {
                /* need at least ticket_lifetime_hint + ticket length */
-               al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
+               al = SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
@@ -1989,7 +2016,7 @@ int ssl3_get_new_session_ticket(SSL *s)
        /* ticket_lifetime_hint + ticket_length + ticket */
        if (ticklen + 6 != n)
                {
        /* ticket_lifetime_hint + ticket_length + ticket */
        if (ticklen + 6 != n)
                {
-               al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
+               al = SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
@@ -2384,6 +2411,7 @@ int ssl3_send_client_key_exchange(SSL *s)
                        if (!DH_generate_key(dh_clnt))
                                {
                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
                        if (!DH_generate_key(dh_clnt))
                                {
                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+                               DH_free(dh_clnt);
                                goto err;
                                }
 
                                goto err;
                                }
 
@@ -2395,6 +2423,7 @@ int ssl3_send_client_key_exchange(SSL *s)
                        if (n <= 0)
                                {
                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
                        if (n <= 0)
                                {
                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+                               DH_free(dh_clnt);
                                goto err;
                                }
 
                                goto err;
                                }
 
@@ -2844,12 +2873,13 @@ int ssl3_send_client_verify(SSL *s)
        unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
        EVP_PKEY *pkey;
        EVP_PKEY_CTX *pctx=NULL;
        unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
        EVP_PKEY *pkey;
        EVP_PKEY_CTX *pctx=NULL;
-#ifndef OPENSSL_NO_RSA
+       EVP_MD_CTX mctx;
        unsigned u=0;
        unsigned u=0;
-#endif
        unsigned long n;
        int j;
 
        unsigned long n;
        int j;
 
+       EVP_MD_CTX_init(&mctx);
+
        if (s->state == SSL3_ST_CW_CERT_VRFY_A)
                {
                d=(unsigned char *)s->init_buf->data;
        if (s->state == SSL3_ST_CW_CERT_VRFY_A)
                {
                d=(unsigned char *)s->init_buf->data;
@@ -2860,7 +2890,8 @@ int ssl3_send_client_verify(SSL *s)
                EVP_PKEY_sign_init(pctx);
                if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
                        {
                EVP_PKEY_sign_init(pctx);
                if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
                        {
-                       s->method->ssl3_enc->cert_verify_mac(s,
+                       if (TLS1_get_version(s) < TLS1_2_VERSION)
+                               s->method->ssl3_enc->cert_verify_mac(s,
                                                NID_sha1,
                                                &(data[MD5_DIGEST_LENGTH]));
                        }
                                                NID_sha1,
                                                &(data[MD5_DIGEST_LENGTH]));
                        }
@@ -2868,6 +2899,41 @@ int ssl3_send_client_verify(SSL *s)
                        {
                        ERR_clear_error();
                        }
                        {
                        ERR_clear_error();
                        }
+               /* For TLS v1.2 send signature algorithm and signature
+                * using agreed digest and cached handshake records.
+                */
+               if (TLS1_get_version(s) >= TLS1_2_VERSION)
+                       {
+                       long hdatalen = 0;
+                       void *hdata;
+                       const EVP_MD *md = s->cert->key->digest;
+                       hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,
+                                                               &hdata);
+                       if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+                                               ERR_R_INTERNAL_ERROR);
+                               goto err;
+                               }
+                       p += 2;
+#ifdef SSL_DEBUG
+                       fprintf(stderr, "Using TLS 1.2 with client alg %s\n",
+                                                       EVP_MD_name(md));
+#endif
+                       if (!EVP_SignInit_ex(&mctx, md, NULL)
+                               || !EVP_SignUpdate(&mctx, hdata, hdatalen)
+                               || !EVP_SignFinal(&mctx, p + 2, &u, pkey))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+                                               ERR_R_EVP_LIB);
+                               goto err;
+                               }
+                       s2n(u,p);
+                       n = u + 4;
+                       if (!ssl3_digest_cached_records(s))
+                               goto err;
+                       }
+               else
 #ifndef OPENSSL_NO_RSA
                if (pkey->type == EVP_PKEY_RSA)
                        {
 #ifndef OPENSSL_NO_RSA
                if (pkey->type == EVP_PKEY_RSA)
                        {
@@ -2950,9 +3016,11 @@ int ssl3_send_client_verify(SSL *s)
                s->init_num=(int)n+4;
                s->init_off=0;
                }
                s->init_num=(int)n+4;
                s->init_off=0;
                }
+       EVP_MD_CTX_cleanup(&mctx);
        EVP_PKEY_CTX_free(pctx);
        return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 err:
        EVP_PKEY_CTX_free(pctx);
        return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 err:
+       EVP_MD_CTX_cleanup(&mctx);
        EVP_PKEY_CTX_free(pctx);
        return(-1);
        }
        EVP_PKEY_CTX_free(pctx);
        return(-1);
        }