X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_clnt.c;h=98d775b91a2f50c32cf5a373545c34cd895c7173;hp=0054e7f25d57d00cba53f2ca50f679891fc8fe4e;hb=a06cd5d056c6a5b1d161786873e21a5e53d554d8;hpb=4082fea81c150e9f2643819148d275e500f309a3 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 0054e7f25d..98d775b91a 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -167,9 +167,9 @@ #include #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) { @@ -240,6 +241,13 @@ int ssl3_connect(SSL *s) ret = -1; goto end; } + + if (!ssl_security(s, SSL_SECOP_VERSION, 0, + s->version, NULL)) + { + SSLerr(SSL_F_SSL3_CONNECT, SSL_R_VERSION_TOO_LOW); + return -1; + } /* s->version=SSL3_VERSION; */ s->type=SSL_ST_CONNECT; @@ -311,26 +319,11 @@ int ssl3_connect(SSL *s) } s->init_num=0; break; -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_CR_SUPPLEMENTAL_DATA_A: - case SSL3_ST_CR_SUPPLEMENTAL_DATA_B: - ret = tls1_get_server_supplemental_data(s); - if (ret <= 0) goto end; - s->state=SSL3_ST_CR_CERT_A; - s->init_num = 0; - break; -#endif case SSL3_ST_CR_CERT_A: case SSL3_ST_CR_CERT_B: #ifndef OPENSSL_NO_TLSEXT ret=ssl3_check_finished(s); if (ret <= 0) goto end; - if (ret == 3) - { - s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A; - s->init_num=0; - break; - } if (ret == 2) { s->hit = 1; @@ -342,9 +335,9 @@ int ssl3_connect(SSL *s) break; } #endif - /* Check if it is anon DH/ECDH */ + /* Check if it is anon DH/ECDH, SRP auth */ /* or PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { ret=ssl3_get_server_certificate(s); @@ -409,14 +402,10 @@ int ssl3_connect(SSL *s) } } #endif -#ifndef OPENSSL_NO_TLSEXT - s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A; -#else if (s->s3->tmp.cert_req) s->state=SSL3_ST_CW_CERT_A; else s->state=SSL3_ST_CW_KEY_EXCH_A; -#endif s->init_num=0; break; @@ -523,19 +512,6 @@ int ssl3_connect(SSL *s) break; #endif -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_CW_SUPPLEMENTAL_DATA_A: - case SSL3_ST_CW_SUPPLEMENTAL_DATA_B: - ret = tls1_send_client_supplemental_data(s, &skip); - if (ret <= 0) goto end; - if (s->s3->tmp.cert_req) - s->state=SSL3_ST_CW_CERT_A; - else - s->state=SSL3_ST_CW_KEY_EXCH_A; - s->init_num=0; - break; -#endif - case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: ret=ssl3_send_finished(s, @@ -543,6 +519,7 @@ int ssl3_connect(SSL *s) s->method->ssl3_enc->client_finished_label, s->method->ssl3_enc->client_finished_label_len); if (ret <= 0) goto end; + s->s3->flags |= SSL3_FLAGS_CCS_OK; s->state=SSL3_ST_CW_FLUSH; /* clear flags */ @@ -592,6 +569,7 @@ int ssl3_connect(SSL *s) case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: + s->s3->flags |= SSL3_FLAGS_CCS_OK; ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); if (ret <= 0) goto end; @@ -689,6 +667,7 @@ int ssl3_client_hello(SSL *s) unsigned char *p,*d; int i; unsigned long l; + int al = 0; #ifndef OPENSSL_NO_COMP int j; SSL_COMP *comp; @@ -870,8 +849,7 @@ int ssl3_client_hello(SSL *s) *(p++)=1; #else - if ((s->options & SSL_OP_NO_COMPRESSION) - || !s->ctx->comp_methods) + if (!ssl_allow_compression(s) || !s->ctx->comp_methods) j=0; else j=sk_SSL_COMP_num(s->ctx->comp_methods); @@ -891,8 +869,9 @@ int ssl3_client_hello(SSL *s) SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); goto err; } - if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL) { + ssl3_send_alert(s,SSL3_AL_FATAL,al); SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); goto err; } @@ -1028,6 +1007,7 @@ int ssl3_get_server_hello(SSL *s) { s->session->cipher = pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s, p+j); + s->s3->flags |= SSL3_FLAGS_CCS_OK; } } #endif /* OPENSSL_NO_TLSEXT */ @@ -1043,6 +1023,7 @@ int ssl3_get_server_hello(SSL *s) SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); goto f_err; } + s->s3->flags |= SSL3_FLAGS_CCS_OK; s->hit=1; } else /* a miss or crap from the other end */ @@ -1077,9 +1058,7 @@ int ssl3_get_server_hello(SSL *s) /* If it is a disabled cipher we didn't send it in client hello, * so return an error. */ - if (c->algorithm_ssl & ct->mask_ssl || - c->algorithm_mkey & ct->mask_k || - c->algorithm_auth & ct->mask_a) + if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK)) { al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED); @@ -1148,7 +1127,7 @@ int ssl3_get_server_hello(SSL *s) } if (j == 0) comp=NULL; - else if (s->options & SSL_OP_NO_COMPRESSION) + else if (!ssl_allow_compression(s)) { al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED); @@ -1290,6 +1269,12 @@ int ssl3_get_server_certificate(SSL *s) goto f_err; } ERR_clear_error(); /* but we keep s->verify_result */ + if (i > 1) + { + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, i); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } sc=ssl_sess_cert_new(); if (sc == NULL) goto err; @@ -1394,8 +1379,8 @@ int ssl3_get_key_exchange(SSL *s) #endif EVP_MD_CTX md_ctx; unsigned char *param,*p; - int al,i,j,param_len,ok; - long n,alg_k,alg_a; + int al,j,ok; + long i,param_len,n,alg_k,alg_a; EVP_PKEY *pkey=NULL; const EVP_MD *md = NULL; #ifndef OPENSSL_NO_RSA @@ -1471,36 +1456,48 @@ int ssl3_get_key_exchange(SSL *s) s->session->sess_cert=ssl_sess_cert_new(); } + /* Total length of the parameters including the length prefix */ param_len=0; + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; alg_a=s->s3->tmp.new_cipher->algorithm_auth; EVP_MD_CTX_init(&md_ctx); + al=SSL_AD_DECODE_ERROR; + #ifndef OPENSSL_NO_PSK if (alg_k & SSL_kPSK) { char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1]; - al=SSL_AD_HANDSHAKE_FAILURE; + param_len = 2; + if (param_len > n) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } n2s(p,i); - param_len=i+2; + /* Store PSK identity hint for later use, hint is used * in ssl3_send_client_key_exchange. Assume that the * maximum length of a PSK identity hint can be as * long as the maximum length of a PSK identity. */ if (i > PSK_MAX_IDENTITY_LEN) { + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); goto f_err; } - if (param_len > n) + if (i > n - param_len) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); goto f_err; } + param_len += i; + /* If received PSK identity hint contains NULL * characters, the hint is truncated from the first * NULL. p may not be ending with NULL, so create a @@ -1512,6 +1509,7 @@ int ssl3_get_key_exchange(SSL *s) s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint); if (s->ctx->psk_identity_hint == NULL) { + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; } @@ -1524,14 +1522,22 @@ int ssl3_get_key_exchange(SSL *s) #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { - n2s(p,i); - param_len=i+2; + param_len = 2; if (param_len > n) { - al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p,i); + + if (i > n - param_len) + { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH); goto f_err; } + param_len += i; + if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1539,14 +1545,24 @@ int ssl3_get_key_exchange(SSL *s) } p+=i; + + if (2 > n - param_len) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + n2s(p,i); - param_len+=i+2; - if (param_len > n) + + if (i > n - param_len) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH); goto f_err; } + param_len += i; + if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1554,15 +1570,25 @@ int ssl3_get_key_exchange(SSL *s) } p+=i; + + if (1 > n - param_len) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 1; + i = (unsigned int)(p[0]); p++; - param_len+=i+1; - if (param_len > n) + + if (i > n - param_len) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH); goto f_err; } + param_len += i; + if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1570,14 +1596,23 @@ int ssl3_get_key_exchange(SSL *s) } p+=i; + if (2 > n - param_len) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + n2s(p,i); - param_len+=i+2; - if (param_len > n) + + if (i > n - param_len) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH); goto f_err; } + param_len += i; + if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1586,6 +1621,12 @@ int ssl3_get_key_exchange(SSL *s) p+=i; n-=param_len; + if (!srp_verify_server_param(s, &al)) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_PARAMETERS); + goto f_err; + } + /* We must check if there is a certificate */ #ifndef OPENSSL_NO_RSA if (alg_a & SSL_aRSA) @@ -1609,14 +1650,23 @@ int ssl3_get_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); goto err; } - n2s(p,i); - param_len=i+2; + + param_len = 2; if (param_len > n) { - al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p,i); + + if (i > n - param_len) + { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH); goto f_err; } + param_len += i; + if (!(rsa->n=BN_bin2bn(p,i,rsa->n))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1624,14 +1674,23 @@ int ssl3_get_key_exchange(SSL *s) } p+=i; + if (2 > n - param_len) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + n2s(p,i); - param_len+=i+2; - if (param_len > n) + + if (i > n - param_len) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH); goto f_err; } + param_len += i; + if (!(rsa->e=BN_bin2bn(p,i,rsa->e))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1656,21 +1715,30 @@ int ssl3_get_key_exchange(SSL *s) ; #endif #ifndef OPENSSL_NO_DH - else if (alg_k & SSL_kEDH) + else if (alg_k & SSL_kDHE) { if ((dh=DH_new()) == NULL) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB); goto err; } - n2s(p,i); - param_len=i+2; + + param_len = 2; if (param_len > n) { - al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p,i); + + if (i > n - param_len) + { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH); goto f_err; } + param_len += i; + if (!(dh->p=BN_bin2bn(p,i,NULL))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1678,14 +1746,23 @@ int ssl3_get_key_exchange(SSL *s) } p+=i; + if (2 > n - param_len) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + n2s(p,i); - param_len+=i+2; - if (param_len > n) + + if (i > n - param_len) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH); goto f_err; } + param_len += i; + if (!(dh->g=BN_bin2bn(p,i,NULL))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1693,14 +1770,23 @@ int ssl3_get_key_exchange(SSL *s) } p+=i; + if (2 > n - param_len) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + n2s(p,i); - param_len+=i+2; - if (param_len > n) + + if (i > n - param_len) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH); goto f_err; } + param_len += i; + if (!(dh->pub_key=BN_bin2bn(p,i,NULL))) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB); @@ -1709,6 +1795,14 @@ int ssl3_get_key_exchange(SSL *s) p+=i; n-=param_len; + if (!ssl_security(s, SSL_SECOP_TMP_DH, + DH_security_bits(dh), 0, dh)) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_DH_KEY_TOO_SMALL); + goto f_err; + } + #ifndef OPENSSL_NO_RSA if (alg_a & SSL_aRSA) pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); @@ -1752,15 +1846,21 @@ int ssl3_get_key_exchange(SSL *s) */ /* XXX: For now we only support named (not generic) curves - * and the ECParameters in this case is just three bytes. + * and the ECParameters in this case is just three bytes. We + * also need one byte for the length of the encoded point */ - param_len=3; + param_len=4; + if (param_len > n) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } /* Check curve is one of our preferences, if not server has - * sent an invalid curve. + * sent an invalid curve. ECParameters is 3 bytes. */ - if (!tls1_check_curve(s, p, param_len)) + if (!tls1_check_curve(s, p, 3)) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_CURVE); goto f_err; } @@ -1807,15 +1907,15 @@ int ssl3_get_key_exchange(SSL *s) encoded_pt_len = *p; /* length of encoded point */ p+=1; - param_len += (1 + encoded_pt_len); - if ((param_len > n) || + + if ((encoded_pt_len > n - param_len) || (EC_POINT_oct2point(group, srvr_ecpoint, p, encoded_pt_len, bn_ctx) == 0)) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT); goto f_err; } + param_len += encoded_pt_len; n-=param_len; p+=encoded_pt_len; @@ -1858,12 +1958,18 @@ int ssl3_get_key_exchange(SSL *s) { if (SSL_USE_SIGALGS(s)) { - int rv = tls12_check_peer_sigalg(&md, s, p, pkey); + int rv; + if (2 > n) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + rv = tls12_check_peer_sigalg(&md, s, p, pkey); if (rv == -1) goto err; else if (rv == 0) { - al = SSL_AD_DECODE_ERROR; goto f_err; } #ifdef SSL_DEBUG @@ -1874,15 +1980,21 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); } else md = EVP_sha1(); - + + if (2 > n) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } n2s(p,i); n-=2; j=EVP_PKEY_size(pkey); + /* Check signature length. If n is 0 then signature is empty */ if ((i != n) || (n > j) || (n <= 0)) { /* wrong packet length */ - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH); goto f_err; } @@ -1891,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; @@ -1903,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); @@ -1941,8 +2054,8 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); } else { - /* aNULL or kPSK do not need public keys */ - if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK)) + /* aNULL, aSRP or kPSK do not need public keys */ + if (!(alg_a & (SSL_aNULL|SSL_aSRP)) && !(alg_k & SSL_kPSK)) { /* Might be wrong key type, check it */ if (ssl3_check_cert_and_algorithm(s)) @@ -1953,7 +2066,6 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); /* still data left over */ if (n != 0) { - al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE); goto f_err; } @@ -2080,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; } @@ -2234,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 @@ -2393,6 +2511,13 @@ int ssl3_send_client_key_exchange(SSL *s) RSA *rsa; unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + if (s->session->sess_cert == NULL) + { + /* We should always have a server certificate with SSL_kRSA. */ + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto err; + } + if (s->session->sess_cert->peer_rsa_tmp != NULL) rsa=s->session->sess_cert->peer_rsa_tmp; else @@ -2581,7 +2706,7 @@ int ssl3_send_client_key_exchange(SSL *s) } #endif #ifndef OPENSSL_NO_DH - else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + else if (alg_k & (SSL_kDHE|SSL_kDHr|SSL_kDHd)) { DH *dh_srvr,*dh_clnt; SESS_CERT *scert = s->session->sess_cert; @@ -2692,6 +2817,13 @@ int ssl3_send_client_key_exchange(SSL *s) int ecdh_clnt_cert = 0; int field_size = 0; + if (s->session->sess_cert == NULL) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + /* Did we send out the client's * ECDH share for use in premaster * computation as part of client certificate? @@ -2995,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; @@ -3009,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) { @@ -3024,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; @@ -3058,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) { @@ -3307,11 +3450,20 @@ int ssl3_send_client_certificate(SSL *s) if (s->state == SSL3_ST_CW_CERT_A) { /* Let cert callback update client certificates if required */ - if (s->cert->cert_cb - && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0) + if (s->cert->cert_cb) { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR); - return 0; + i = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (i < 0) + { + s->rwstate=SSL_X509_LOOKUP; + return -1; + } + if (i == 0) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR); + return 0; + } + s->rwstate=SSL_NOTHING; } if (ssl3_check_client_certificate(s)) s->state=SSL3_ST_CW_CERT_C; @@ -3371,8 +3523,13 @@ int ssl3_send_client_certificate(SSL *s) if (s->state == SSL3_ST_CW_CERT_C) { s->state=SSL3_ST_CW_CERT_D; - ssl3_output_cert_chain(s, - (s->s3->tmp.cert_req == 2)?NULL:s->cert->key); + if (!ssl3_output_cert_chain(s, + (s->s3->tmp.cert_req == 2)?NULL:s->cert->key)) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR); + return 0; + } } /* SSL3_ST_CW_CERT_D */ return ssl_do_write(s); @@ -3469,7 +3626,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif #ifndef OPENSSL_NO_DH - if ((alg_k & SSL_kEDH) && + if ((alg_k & SSL_kDHE) && !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL))) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY); @@ -3506,7 +3663,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) else #endif #ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + if (alg_k & (SSL_kDHE|SSL_kDHr|SSL_kDHd)) { if (dh == NULL || DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) @@ -3566,10 +3723,11 @@ int ssl3_check_finished(SSL *s) int ok; long n; - /* Read the message to see if it is supplemental data, - * regardless if there is a session ticket this function is - * called when we really expect a Certificate message, so - * permit appropriate message length */ + /* If we have no ticket it cannot be a resumed session. */ + if (!s->session->tlsext_tick) + return 1; + /* this function is called when we really expect a Certificate + * message, so permit appropriate message length */ n=s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B, @@ -3579,11 +3737,6 @@ int ssl3_check_finished(SSL *s) if (!ok) return((int)n); s->s3->tmp.reuse_message = 1; - if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA) - return 3; - /* If we have no ticket it cannot be a resumed session. */ - if (!s->session->tlsext_tick) - return 1; if ((s->s3->tmp.message_type == SSL3_MT_FINISHED) || (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET)) return 2; @@ -3609,147 +3762,3 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) i = s->ctx->client_cert_cb(s,px509,ppkey); return i; } - -#ifndef OPENSSL_NO_TLSEXT -int tls1_send_client_supplemental_data(SSL *s, int *skip) - { - if (s->ctx->cli_supp_data_records_count) - { - unsigned char *p = NULL; - unsigned char *size_loc = NULL; - cli_supp_data_record *record = NULL; - size_t length = 0; - size_t i = 0; - - for (i = 0; i < s->ctx->cli_supp_data_records_count; i++) - { - const unsigned char *out = NULL; - unsigned short outlen = 0; - int cb_retval = 0; - record = &s->ctx->cli_supp_data_records[i]; - - /* NULL callback or -1 omits supp data entry*/ - if (!record->fn2) - continue; - cb_retval = record->fn2(s, record->supp_data_type, - &out, &outlen, - record->arg); - if (cb_retval == -1) - continue; /* skip this supp data entry */ - if (cb_retval == 0) - { - SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length) - { - SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - /* if first entry, write handshake message type */ - if (length == 0) - { - if (!BUF_MEM_grow_clean(s->init_buf, 4)) - { - SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL3_MT_SUPPLEMENTAL_DATA; - /* update message length when all - * callbacks complete */ - size_loc = p; - /* skip over handshake length field (3 - * bytes) and supp_data length field - * (3 bytes) */ - p += 3 + 3; - length += 1 +3 +3; - } - if (!BUF_MEM_grow(s->init_buf, outlen + 4)) - { - SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; - } - s2n(record->supp_data_type, p); - s2n(outlen, p); - memcpy(p, out, outlen); - length += (outlen + 4); - p += outlen; - } - if (length > 0) - { - /* write handshake length */ - l2n3(length - 4, size_loc); - /* supp_data length */ - l2n3(length - 7, size_loc); - s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B; - s->init_num = length; - s->init_off = 0; - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); - } - } - - /* no supp data message sent */ - *skip = 1; - s->init_num = 0; - s->init_off = 0; - return 1; - } - -int tls1_get_server_supplemental_data(SSL *s) - { - int al = 0; - int ok; - long n; - const unsigned char *p, *d; - unsigned short supp_data_entry_type = 0; - unsigned long supp_data_entry_len = 0; - unsigned long supp_data_len = 0; - size_t i; - int cb_retval = 0; - - n=s->method->ssl_get_message(s, - SSL3_ST_CR_SUPPLEMENTAL_DATA_A, - SSL3_ST_CR_SUPPLEMENTAL_DATA_B, - SSL3_MT_SUPPLEMENTAL_DATA, - /* use default limit */ - TLSEXT_MAXLEN_supplemental_data, - &ok); - - if (!ok) return((int)n); - - p = (unsigned char *)s->init_msg; - d = p; - /* The message cannot be empty */ - if (n < 3) - { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH); - goto f_err; - } - n2l3(p, supp_data_len); - while (p < d+supp_data_len) - { - n2s(p, supp_data_entry_type); - n2s(p, supp_data_entry_len); - /* if there is a callback for this supp data type, send it */ - for (i=0; i < s->ctx->cli_supp_data_records_count; i++) - { - if (s->ctx->cli_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->cli_supp_data_records[i].fn1) - { - cb_retval = s->ctx->cli_supp_data_records[i].fn1(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->cli_supp_data_records[i].arg); - if (cb_retval == 0) - { - SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB); - goto f_err; - } - } - } - p += supp_data_entry_len; - } - return 1; -f_err: - ssl3_send_alert(s,SSL3_AL_FATAL,al); - return -1; - } -#endif