X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_clnt.c;h=2df5afe14e726ebb2e128798645ec294fca8dbf8;hp=036a531d7c996f9d43ae92b7fd8b19b8f54be7d4;hb=329428708d6836676f6a7078aa2e2a1db9a1addb;hpb=e9fa092efca0afbf99bb575193f69e3f8a938f02 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 036a531d7c..2df5afe14e 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -928,10 +928,11 @@ int ssl3_get_server_hello(SSL *s) { STACK_OF(SSL_CIPHER) *sk; const SSL_CIPHER *c; - PACKET pkt; - unsigned char *session_id, *cipherchars; + PACKET pkt, session_id; + size_t session_id_len; + unsigned char *cipherchars; int i, al = SSL_AD_INTERNAL_ERROR, ok; - unsigned int j; + unsigned int compression; long n; #ifndef OPENSSL_NO_COMP SSL_COMP *comp; @@ -1075,15 +1076,26 @@ int ssl3_get_server_hello(SSL *s) s->hit = 0; - /* get the session-id length */ - if (!PACKET_get_1(&pkt, &j) - || (j > sizeof s->session->session_id) - || (j > SSL3_SESSION_ID_SIZE)) { + /* Get the session-id. */ + if (!PACKET_get_length_prefixed_1(&pkt, &session_id)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + session_id_len = PACKET_remaining(&session_id); + if (session_id_len > sizeof s->session->session_id + || session_id_len > SSL3_SESSION_ID_SIZE) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG); goto f_err; } + if (!PACKET_get_bytes(&pkt, &cipherchars, TLS_CIPHER_LEN)) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + /* * Check if we can resume the session based on external pre-shared secret. * EAP-FAST (RFC 4851) supports two types of session resumption. @@ -1099,13 +1111,6 @@ int ssl3_get_server_hello(SSL *s) if (s->version >= TLS1_VERSION && s->tls_session_secret_cb && s->session->tlsext_tick) { SSL_CIPHER *pref_cipher = NULL; - PACKET bookmark = pkt; - if (!PACKET_forward(&pkt, j) - || !PACKET_get_bytes(&pkt, &cipherchars, TLS_CIPHER_LEN)) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } s->session->master_key_length = sizeof(s->session->master_key); if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, @@ -1118,18 +1123,11 @@ int ssl3_get_server_hello(SSL *s) al = SSL_AD_INTERNAL_ERROR; goto f_err; } - pkt = bookmark; } - /* Get the session id */ - if (!PACKET_get_bytes(&pkt, &session_id, j)) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - - if (j != 0 && j == s->session->session_id_length - && memcmp(session_id, s->session->session_id, j) == 0) { + if (session_id_len != 0 && session_id_len == s->session->session_id_length + && memcmp(PACKET_data(&session_id), s->session->session_id, + session_id_len) == 0) { if (s->sid_ctx_length != s->session->sid_ctx_length || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) { /* actually a client application bug */ @@ -1152,15 +1150,13 @@ int ssl3_get_server_hello(SSL *s) goto f_err; } } - s->session->session_id_length = j; - memcpy(s->session->session_id, session_id, j); /* j could be 0 */ - } - if (!PACKET_get_bytes(&pkt, &cipherchars, TLS_CIPHER_LEN)) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); - al = SSL_AD_DECODE_ERROR; - goto f_err; + s->session->session_id_length = session_id_len; + /* session_id_len could be 0 */ + memcpy(s->session->session_id, PACKET_data(&session_id), + session_id_len); } + c = ssl_get_cipher_by_char(s, cipherchars); if (c == NULL) { /* unknown cipher */ @@ -1214,13 +1210,13 @@ int ssl3_get_server_hello(SSL *s) goto f_err; /* lets get the compression algorithm */ /* COMPRESSION */ - if (!PACKET_get_1(&pkt, &j)) { + if (!PACKET_get_1(&pkt, &compression)) { SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; } #ifdef OPENSSL_NO_COMP - if (j != 0) { + if (compression != 0) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); @@ -1235,22 +1231,23 @@ int ssl3_get_server_hello(SSL *s) goto f_err; } #else - if (s->hit && j != s->session->compress_meth) { + if (s->hit && compression != s->session->compress_meth) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED); goto f_err; } - if (j == 0) + if (compression == 0) comp = NULL; else if (!ssl_allow_compression(s)) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED); goto f_err; - } else - comp = ssl3_comp_find(s->ctx->comp_methods, j); + } else { + comp = ssl3_comp_find(s->ctx->comp_methods, compression); + } - if ((j != 0) && (comp == NULL)) { + if (compression != 0 && comp == NULL) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); @@ -1437,7 +1434,6 @@ int ssl3_get_key_exchange(SSL *s) #endif EVP_MD_CTX md_ctx; int al, j, verify_ret, ok; - unsigned int i; long n, alg_k, alg_a; EVP_PKEY *pkey = NULL; const EVP_MD *md = NULL; @@ -1452,11 +1448,8 @@ int ssl3_get_key_exchange(SSL *s) BN_CTX *bn_ctx = NULL; EC_POINT *srvr_ecpoint = NULL; int curve_nid = 0; - unsigned int encoded_pt_len = 0; #endif - PACKET pkt, save_param_start; - unsigned char *data, *param; - size_t param_len; + PACKET pkt, save_param_start, signature; EVP_MD_CTX_init(&md_ctx); @@ -1515,9 +1508,9 @@ int ssl3_get_key_exchange(SSL *s) #ifndef OPENSSL_NO_PSK /* PSK ciphersuites are preceded by an identity hint */ if (alg_k & SSL_PSK) { - - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + PACKET psk_identity_hint; + if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity_hint)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1527,33 +1520,16 @@ int ssl3_get_key_exchange(SSL *s) * a PSK identity hint can be as long as the maximum length of a PSK * identity. */ - if (i > PSK_MAX_IDENTITY_LEN) { + if (PACKET_remaining(&psk_identity_hint) > 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 (PACKET_remaining(&pkt) < i) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); - goto f_err; - } - - OPENSSL_free(s->session->psk_identity_hint); - if (i != 0) { - unsigned char *hint = NULL; - if (!PACKET_get_bytes(&pkt, &hint, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - s->session->psk_identity_hint = BUF_strndup((char *)hint, i); - if (s->session->psk_identity_hint == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto f_err; - } - } else { - s->session->psk_identity_hint = NULL; + if (!PACKET_strndup(&psk_identity_hint, + &s->session->psk_identity_hint)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; } } @@ -1563,62 +1539,27 @@ int ssl3_get_key_exchange(SSL *s) #endif /* !OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH); - goto f_err; - } - - if ((s->srp_ctx.N = BN_bin2bn(data, i, NULL)) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH); + PACKET prime, generator, salt, server_pub; + if (!PACKET_get_length_prefixed_2(&pkt, &prime) + || !PACKET_get_length_prefixed_2(&pkt, &generator) + || !PACKET_get_length_prefixed_1(&pkt, &salt) + || !PACKET_get_length_prefixed_2(&pkt, &server_pub)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } - if ((s->srp_ctx.g = BN_bin2bn(data, i, NULL)) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - - if (!PACKET_get_1(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH); - goto f_err; - } - - if ((s->srp_ctx.s = BN_bin2bn(data, i, NULL)) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH); - goto f_err; - } - - if ((s->srp_ctx.B = BN_bin2bn(data, i, NULL)) == NULL) { + if ((s->srp_ctx.N = + BN_bin2bn(PACKET_data(&prime), + PACKET_remaining(&prime), NULL)) == NULL + || (s->srp_ctx.g = + BN_bin2bn(PACKET_data(&generator), + PACKET_remaining(&generator), NULL)) == NULL + || (s->srp_ctx.s = + BN_bin2bn(PACKET_data(&salt), + PACKET_remaining(&salt), NULL)) == NULL + || (s->srp_ctx.B = + BN_bin2bn(PACKET_data(&server_pub), + PACKET_remaining(&server_pub), NULL)) == NULL) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); goto err; } @@ -1635,43 +1576,29 @@ int ssl3_get_key_exchange(SSL *s) #endif /* !OPENSSL_NO_SRP */ #ifndef OPENSSL_NO_RSA if (alg_k & SSL_kRSA) { + PACKET mod, exp; /* Temporary RSA keys only allowed in export ciphersuites */ if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } - if ((rsa = RSA_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH); + if (!PACKET_get_length_prefixed_2(&pkt, &mod) + || !PACKET_get_length_prefixed_2(&pkt, &exp)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } - if ((rsa->n = BN_bin2bn(data, i, rsa->n)) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + if ((rsa = RSA_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto err; } - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH); - goto f_err; - } - - if ((rsa->e = BN_bin2bn(data, i, rsa->e)) == NULL) { + if ((rsa->n = BN_bin2bn(PACKET_data(&mod), PACKET_remaining(&mod), + rsa->n)) == NULL + || (rsa->e = BN_bin2bn(PACKET_data(&exp), PACKET_remaining(&exp), + rsa->e)) == NULL) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); goto err; } @@ -1698,68 +1625,33 @@ int ssl3_get_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_DH else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { - if ((dh = DH_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } + PACKET prime, generator, pub_key; - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + if (!PACKET_get_length_prefixed_2(&pkt, &prime) + || !PACKET_get_length_prefixed_2(&pkt, &generator) + || !PACKET_get_length_prefixed_2(&pkt, &pub_key)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH); - goto f_err; - } - - if ((dh->p = BN_bin2bn(data, i, NULL)) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - - if (BN_is_zero(dh->p)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE); - goto f_err; - } - - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH); - goto f_err; - } - - if ((dh->g = BN_bin2bn(data, i, NULL)) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + if ((dh = DH_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB); goto err; } - if (BN_is_zero(dh->g)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); - goto f_err; - } - - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (!PACKET_get_bytes(&pkt, &data, i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH); - goto f_err; - } - - if ((dh->pub_key = BN_bin2bn(data, i, NULL)) == NULL) { + if ((dh->p = BN_bin2bn(PACKET_data(&prime), + PACKET_remaining(&prime), NULL)) == NULL + || (dh->g = BN_bin2bn(PACKET_data(&generator), + PACKET_remaining(&generator), NULL)) == NULL + || (dh->pub_key = + BN_bin2bn(PACKET_data(&pub_key), + PACKET_remaining(&pub_key), NULL)) == NULL) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); goto err; } - if (BN_is_zero(dh->pub_key)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE); + if (BN_is_zero(dh->p) || BN_is_zero(dh->g) || BN_is_zero(dh->pub_key)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_VALUE); goto f_err; } @@ -1781,6 +1673,8 @@ int ssl3_get_key_exchange(SSL *s) else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) { EC_GROUP *ngroup; const EC_GROUP *group; + PACKET encoded_pt; + unsigned char *ecparams; if ((ecdh = EC_KEY_new()) == NULL) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); @@ -1789,15 +1683,10 @@ int ssl3_get_key_exchange(SSL *s) /* * Extract elliptic curve parameters and the server's ephemeral ECDH - * public key. Keep accumulating lengths of various components in - * param_len and make sure it never exceeds n. - */ - - /* - * XXX: For now we only support named (not generic) curves and the + * public key. For now we only support named (not generic) curves and * ECParameters in this case is just three bytes. */ - if (!PACKET_get_bytes(&pkt, &data, 3)) { + if (!PACKET_get_bytes(&pkt, &ecparams, 3)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); goto f_err; } @@ -1805,12 +1694,12 @@ int ssl3_get_key_exchange(SSL *s) * Check curve is one of our preferences, if not server has sent an * invalid curve. ECParameters is 3 bytes. */ - if (!tls1_check_curve(s, data, 3)) { + if (!tls1_check_curve(s, ecparams, 3)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE); goto f_err; } - if ((curve_nid = tls1_ec_curve_id2nid(*(data + 2))) == 0) { + if ((curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2))) == 0) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); @@ -1845,14 +1734,13 @@ int ssl3_get_key_exchange(SSL *s) goto err; } - if (!PACKET_get_1(&pkt, &encoded_pt_len)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + if (!PACKET_get_length_prefixed_1(&pkt, &encoded_pt)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } - if (!PACKET_get_bytes(&pkt, &data, encoded_pt_len) || - (EC_POINT_oct2point(group, srvr_ecpoint, - data, encoded_pt_len, bn_ctx) == 0)) { + if (EC_POINT_oct2point(group, srvr_ecpoint, PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt), bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); goto f_err; } @@ -1886,21 +1774,29 @@ int ssl3_get_key_exchange(SSL *s) } #endif /* !OPENSSL_NO_EC */ - /* - * |pkt| now points to the beginning of the signature, so the difference - * equals the length of the parameters. - */ - param_len = PACKET_remaining(&save_param_start) - PACKET_remaining(&pkt); - /* if it was signed, check the signature */ if (pkey != NULL) { + PACKET params; + /* + * |pkt| now points to the beginning of the signature, so the difference + * equals the length of the parameters. + */ + if (!PACKET_get_sub_packet(&save_param_start, ¶ms, + PACKET_remaining(&save_param_start) - + PACKET_remaining(&pkt))) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } + if (SSL_USE_SIGALGS(s)) { + unsigned char *sigalgs; int rv; - if (!PACKET_get_bytes(&pkt, &data, 2)) { + if (!PACKET_get_bytes(&pkt, &sigalgs, 2)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); goto f_err; } - rv = tls12_check_peer_sigalg(&md, s, data, pkey); + rv = tls12_check_peer_sigalg(&md, s, sigalgs, pkey); if (rv == -1) goto err; else if (rv == 0) { @@ -1909,11 +1805,13 @@ int ssl3_get_key_exchange(SSL *s) #ifdef SSL_DEBUG fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); #endif - } else + } else { md = EVP_sha1(); + } - if (!PACKET_get_net_2(&pkt, &i)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + if (!PACKET_get_length_prefixed_2(&pkt, &signature) + || PACKET_remaining(&pkt) != 0) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } j = EVP_PKEY_size(pkey); @@ -1925,19 +1823,11 @@ int ssl3_get_key_exchange(SSL *s) /* * Check signature length */ - if (i > (unsigned int)j - || !PACKET_get_bytes(&pkt, &data, i) - || PACKET_remaining(&pkt) != 0) { + if (PACKET_remaining(&signature) > (size_t)j) { /* wrong packet length */ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH); goto f_err; } - pkt = save_param_start; - if (!PACKET_get_bytes(&pkt, ¶m, param_len)) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto f_err; - } #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { int num; @@ -1953,13 +1843,15 @@ int ssl3_get_key_exchange(SSL *s) SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md_ctx, param, param_len); + EVP_DigestUpdate(&md_ctx, PACKET_data(¶ms), + PACKET_remaining(¶ms)); EVP_DigestFinal_ex(&md_ctx, q, &size); q += size; j += size; } verify_ret = - RSA_verify(NID_md5_sha1, md_buf, j, data, i, pkey->pkey.rsa); + RSA_verify(NID_md5_sha1, md_buf, j, PACKET_data(&signature), + PACKET_remaining(&signature), pkey->pkey.rsa); if (verify_ret < 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT); @@ -1979,8 +1871,10 @@ int ssl3_get_key_exchange(SSL *s) SSL3_RANDOM_SIZE); EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE); - EVP_VerifyUpdate(&md_ctx, param, param_len); - if (EVP_VerifyFinal(&md_ctx, data, (int)i, pkey) <= 0) { + EVP_VerifyUpdate(&md_ctx, PACKET_data(¶ms), + PACKET_remaining(¶ms)); + if (EVP_VerifyFinal(&md_ctx, PACKET_data(&signature), + PACKET_remaining(&signature), pkey) <= 0) { /* bad signature */ al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); @@ -2195,6 +2089,7 @@ int ssl3_get_new_session_ticket(SSL *s) { int ok, al, ret = 0; unsigned int ticklen; + unsigned long ticket_lifetime_hint; long n; PACKET pkt; @@ -2212,6 +2107,18 @@ int ssl3_get_new_session_ticket(SSL *s) goto f_err; } + if (!PACKET_get_net_4(&pkt, &ticket_lifetime_hint) + || !PACKET_get_net_2(&pkt, &ticklen) + || PACKET_remaining(&pkt) != ticklen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + /* Server is allowed to change its mind and send an empty ticket. */ + if (ticklen == 0) + return 1; + if (s->session->session_id_length > 0) { int i = s->session_ctx->session_cache_mode; SSL_SESSION *new_sess; @@ -2243,15 +2150,9 @@ int ssl3_get_new_session_ticket(SSL *s) s->session = new_sess; } - if (!PACKET_get_net_4(&pkt, &s->session->tlsext_tick_lifetime_hint) - || !PACKET_get_net_2(&pkt, &ticklen) - || PACKET_remaining(&pkt) != ticklen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); - goto f_err; - } OPENSSL_free(s->session->tlsext_tick); s->session->tlsext_ticklen = 0; + s->session->tlsext_tick = OPENSSL_malloc(ticklen); if (!s->session->tlsext_tick) { SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); @@ -2262,6 +2163,8 @@ int ssl3_get_new_session_ticket(SSL *s) SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); goto f_err; } + + s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; s->session->tlsext_ticklen = ticklen; /* * There are two ways to detect a resumed ticket session. One is to set