X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_clnt.c;h=f46aaef6ce026a56dbc48b093ae05ebf49285fa0;hp=0541de95b9308f30e46b756395c23b7943e8477b;hb=f3d781bb43050abf89bdc0ace3a880d3af6cfcb7;hpb=a2f9200fba20ae7c25531c2f2ce6f80610f257e2 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 0541de95b9..f46aaef6ce 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -157,6 +157,9 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif #ifndef OPENSSL_NO_DH #include #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); -#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) + { 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; @@ -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 (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; @@ -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; } + /* 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); @@ -922,9 +928,11 @@ int ssl3_get_server_hello(SSL *s) } } 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; - /* 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); - goto err; + goto f_err; } return(1); @@ -1654,7 +1662,7 @@ int ssl3_get_key_exchange(SSL *s) /* 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 */ @@ -1699,7 +1707,7 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); } #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; @@ -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--) { + 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); @@ -1793,7 +1803,7 @@ int ssl3_get_certificate_request(SSL *s) { 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; @@ -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 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); } @@ -1849,17 +1867,26 @@ int ssl3_get_certificate_request(SSL *s) for (i=0; is3->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); @@ -1872,7 +1899,7 @@ fclose(out); } #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); @@ -1978,7 +2005,7 @@ int ssl3_get_new_session_ticket(SSL *s) 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; } @@ -1989,7 +2016,7 @@ int ssl3_get_new_session_ticket(SSL *s) /* 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; } @@ -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); + DH_free(dh_clnt); 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); + DH_free(dh_clnt); 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; -#ifndef OPENSSL_NO_RSA + EVP_MD_CTX mctx; unsigned u=0; -#endif 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; @@ -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) { - 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])); } @@ -2868,6 +2899,41 @@ int ssl3_send_client_verify(SSL *s) { 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) { @@ -2950,9 +3016,11 @@ int ssl3_send_client_verify(SSL *s) 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_MD_CTX_cleanup(&mctx); EVP_PKEY_CTX_free(pctx); return(-1); }