Loading ssl/statem/statem_clnt.c +99 −86 Original line number Diff line number Diff line Loading @@ -1393,45 +1393,9 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al) #endif } MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al) { EVP_MD_CTX *md_ctx; int al = -1; long alg_k, alg_a; EVP_PKEY *pkey = NULL; PACKET save_param_start, signature; md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; } alg_k = s->s3->tmp.new_cipher->algorithm_mkey; save_param_start = *pkt; #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) EVP_PKEY_free(s->s3->peer_tmp); s->s3->peer_tmp = NULL; #endif alg_a = s->s3->tmp.new_cipher->algorithm_auth; if (alg_k & SSL_PSK) { if (!tls_process_ske_psk_preamble(s, pkt, &al)) goto err; } /* Nothing else to do for plain PSK or RSAPSK */ if (alg_k & (SSL_kPSK | SSL_kRSAPSK)) { } else if (alg_k & SSL_kSRP) { if (!tls_process_ske_srp(s, pkt, &pkey, &al)) goto err; } #ifndef OPENSSL_NO_DH else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { PACKET prime, generator, pub_key; EVP_PKEY *peer_tmp = NULL; Loading @@ -1441,17 +1405,18 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (!PACKET_get_length_prefixed_2(pkt, &prime) || !PACKET_get_length_prefixed_2(pkt, &generator) || !PACKET_get_length_prefixed_2(pkt, &pub_key)) { *al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; return 0; } peer_tmp = EVP_PKEY_new(); dh = DH_new(); if (peer_tmp == NULL || dh == NULL) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto dherr; goto err; } p = BN_bin2bn(PACKET_data(&prime), PACKET_remaining(&prime), NULL); Loading @@ -1460,62 +1425,110 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) bnpub_key = BN_bin2bn(PACKET_data(&pub_key), PACKET_remaining(&pub_key), NULL); if (p == NULL || g == NULL || bnpub_key == NULL) { *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); goto dherr; goto err; } if (BN_is_zero(p) || BN_is_zero(g) || BN_is_zero(bnpub_key)) { *al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_DH_VALUE); goto dherr; goto err; } if (!DH_set0_pqg(dh, p, NULL, g)) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); goto dherr; goto err; } p = g = NULL; if (!DH_set0_key(dh, bnpub_key, NULL)) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); goto dherr; goto err; } bnpub_key = NULL; if (!ssl_security(s, SSL_SECOP_TMP_DH, DH_security_bits(dh), 0, dh)) { al = SSL_AD_HANDSHAKE_FAILURE; *al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_DH_KEY_TOO_SMALL); goto dherr; goto err; } if (EVP_PKEY_assign_DH(peer_tmp, dh) == 0) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); goto dherr; goto err; } s->s3->peer_tmp = peer_tmp; goto dhend; dherr: /* * FIXME: This makes assumptions about which ciphersuites come with * public keys. We should have a less ad-hoc way of doing this */ if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aRSA|SSL_aDSS)) *pkey = X509_get0_pubkey(s->session->peer); /* else anonymous DH, so no certificate or pkey. */ return 1; err: BN_free(p); BN_free(g); BN_free(bnpub_key); DH_free(dh); EVP_PKEY_free(peer_tmp); return 0; #else SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); *al = SSL_AD_INTERNAL_ERROR; return 0; #endif } MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) { EVP_MD_CTX *md_ctx; int al = -1; long alg_k, alg_a; EVP_PKEY *pkey = NULL; PACKET save_param_start, signature; md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; dhend: /* * FIXME: This makes assumptions about which ciphersuites come with * public keys. We should have a less ad-hoc way of doing this */ if (alg_a & (SSL_aRSA|SSL_aDSS)) pkey = X509_get0_pubkey(s->session->peer); /* else anonymous DH, so no certificate or pkey. */ } #endif /* !OPENSSL_NO_DH */ alg_k = s->s3->tmp.new_cipher->algorithm_mkey; save_param_start = *pkt; #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) EVP_PKEY_free(s->s3->peer_tmp); s->s3->peer_tmp = NULL; #endif alg_a = s->s3->tmp.new_cipher->algorithm_auth; if (alg_k & SSL_PSK) { if (!tls_process_ske_psk_preamble(s, pkt, &al)) goto err; } /* Nothing else to do for plain PSK or RSAPSK */ if (alg_k & (SSL_kPSK | SSL_kRSAPSK)) { } else if (alg_k & SSL_kSRP) { if (!tls_process_ske_srp(s, pkt, &pkey, &al)) goto err; } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { if (!tls_process_ske_dhe(s, pkt, &pkey, &al)) goto err; } #ifndef OPENSSL_NO_EC else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) { PACKET encoded_pt; Loading Loading
ssl/statem/statem_clnt.c +99 −86 Original line number Diff line number Diff line Loading @@ -1393,45 +1393,9 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al) #endif } MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al) { EVP_MD_CTX *md_ctx; int al = -1; long alg_k, alg_a; EVP_PKEY *pkey = NULL; PACKET save_param_start, signature; md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; } alg_k = s->s3->tmp.new_cipher->algorithm_mkey; save_param_start = *pkt; #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) EVP_PKEY_free(s->s3->peer_tmp); s->s3->peer_tmp = NULL; #endif alg_a = s->s3->tmp.new_cipher->algorithm_auth; if (alg_k & SSL_PSK) { if (!tls_process_ske_psk_preamble(s, pkt, &al)) goto err; } /* Nothing else to do for plain PSK or RSAPSK */ if (alg_k & (SSL_kPSK | SSL_kRSAPSK)) { } else if (alg_k & SSL_kSRP) { if (!tls_process_ske_srp(s, pkt, &pkey, &al)) goto err; } #ifndef OPENSSL_NO_DH else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { PACKET prime, generator, pub_key; EVP_PKEY *peer_tmp = NULL; Loading @@ -1441,17 +1405,18 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (!PACKET_get_length_prefixed_2(pkt, &prime) || !PACKET_get_length_prefixed_2(pkt, &generator) || !PACKET_get_length_prefixed_2(pkt, &pub_key)) { *al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; return 0; } peer_tmp = EVP_PKEY_new(); dh = DH_new(); if (peer_tmp == NULL || dh == NULL) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto dherr; goto err; } p = BN_bin2bn(PACKET_data(&prime), PACKET_remaining(&prime), NULL); Loading @@ -1460,62 +1425,110 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) bnpub_key = BN_bin2bn(PACKET_data(&pub_key), PACKET_remaining(&pub_key), NULL); if (p == NULL || g == NULL || bnpub_key == NULL) { *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); goto dherr; goto err; } if (BN_is_zero(p) || BN_is_zero(g) || BN_is_zero(bnpub_key)) { *al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_DH_VALUE); goto dherr; goto err; } if (!DH_set0_pqg(dh, p, NULL, g)) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); goto dherr; goto err; } p = g = NULL; if (!DH_set0_key(dh, bnpub_key, NULL)) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); goto dherr; goto err; } bnpub_key = NULL; if (!ssl_security(s, SSL_SECOP_TMP_DH, DH_security_bits(dh), 0, dh)) { al = SSL_AD_HANDSHAKE_FAILURE; *al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_DH_KEY_TOO_SMALL); goto dherr; goto err; } if (EVP_PKEY_assign_DH(peer_tmp, dh) == 0) { al = SSL_AD_INTERNAL_ERROR; *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); goto dherr; goto err; } s->s3->peer_tmp = peer_tmp; goto dhend; dherr: /* * FIXME: This makes assumptions about which ciphersuites come with * public keys. We should have a less ad-hoc way of doing this */ if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aRSA|SSL_aDSS)) *pkey = X509_get0_pubkey(s->session->peer); /* else anonymous DH, so no certificate or pkey. */ return 1; err: BN_free(p); BN_free(g); BN_free(bnpub_key); DH_free(dh); EVP_PKEY_free(peer_tmp); return 0; #else SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); *al = SSL_AD_INTERNAL_ERROR; return 0; #endif } MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) { EVP_MD_CTX *md_ctx; int al = -1; long alg_k, alg_a; EVP_PKEY *pkey = NULL; PACKET save_param_start, signature; md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; dhend: /* * FIXME: This makes assumptions about which ciphersuites come with * public keys. We should have a less ad-hoc way of doing this */ if (alg_a & (SSL_aRSA|SSL_aDSS)) pkey = X509_get0_pubkey(s->session->peer); /* else anonymous DH, so no certificate or pkey. */ } #endif /* !OPENSSL_NO_DH */ alg_k = s->s3->tmp.new_cipher->algorithm_mkey; save_param_start = *pkt; #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) EVP_PKEY_free(s->s3->peer_tmp); s->s3->peer_tmp = NULL; #endif alg_a = s->s3->tmp.new_cipher->algorithm_auth; if (alg_k & SSL_PSK) { if (!tls_process_ske_psk_preamble(s, pkt, &al)) goto err; } /* Nothing else to do for plain PSK or RSAPSK */ if (alg_k & (SSL_kPSK | SSL_kRSAPSK)) { } else if (alg_k & SSL_kSRP) { if (!tls_process_ske_srp(s, pkt, &pkey, &al)) goto err; } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { if (!tls_process_ske_dhe(s, pkt, &pkey, &al)) goto err; } #ifndef OPENSSL_NO_EC else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) { PACKET encoded_pt; Loading