PACKET: simplify ServerKeyExchange parsing
Reviewed-by: Matt Caswell <matt@openssl.org>
This commit is contained in:
parent
28dc5d1963
commit
329428708d
4 changed files with 101 additions and 200 deletions
|
@ -2115,6 +2115,7 @@ void ERR_load_SSL_strings(void);
|
||||||
# define SSL_R_BAD_DH_PUB_KEY_VALUE 393
|
# define SSL_R_BAD_DH_PUB_KEY_VALUE 393
|
||||||
# define SSL_R_BAD_DH_P_LENGTH 110
|
# define SSL_R_BAD_DH_P_LENGTH 110
|
||||||
# define SSL_R_BAD_DH_P_VALUE 395
|
# define SSL_R_BAD_DH_P_VALUE 395
|
||||||
|
# define SSL_R_BAD_DH_VALUE 102
|
||||||
# define SSL_R_BAD_DIGEST_LENGTH 111
|
# define SSL_R_BAD_DIGEST_LENGTH 111
|
||||||
# define SSL_R_BAD_DSA_SIGNATURE 112
|
# define SSL_R_BAD_DSA_SIGNATURE 112
|
||||||
# define SSL_R_BAD_ECC_CERT 304
|
# define SSL_R_BAD_ECC_CERT 304
|
||||||
|
|
|
@ -418,6 +418,8 @@ __owur static inline int PACKET_memdup(const PACKET *pkt, unsigned char **data,
|
||||||
__owur static inline int PACKET_strndup(const PACKET *pkt, char **data)
|
__owur static inline int PACKET_strndup(const PACKET *pkt, char **data)
|
||||||
{
|
{
|
||||||
OPENSSL_free(*data);
|
OPENSSL_free(*data);
|
||||||
|
|
||||||
|
/* This will succeed on an empty packet, unless pkt->curr == NULL. */
|
||||||
*data = BUF_strndup((const char*)pkt->curr, PACKET_remaining(pkt));
|
*data = BUF_strndup((const char*)pkt->curr, PACKET_remaining(pkt));
|
||||||
return (*data != NULL);
|
return (*data != NULL);
|
||||||
}
|
}
|
||||||
|
|
289
ssl/s3_clnt.c
289
ssl/s3_clnt.c
|
@ -1434,7 +1434,6 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
#endif
|
#endif
|
||||||
EVP_MD_CTX md_ctx;
|
EVP_MD_CTX md_ctx;
|
||||||
int al, j, verify_ret, ok;
|
int al, j, verify_ret, ok;
|
||||||
unsigned int i;
|
|
||||||
long n, alg_k, alg_a;
|
long n, alg_k, alg_a;
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
const EVP_MD *md = NULL;
|
const EVP_MD *md = NULL;
|
||||||
|
@ -1449,11 +1448,8 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
BN_CTX *bn_ctx = NULL;
|
BN_CTX *bn_ctx = NULL;
|
||||||
EC_POINT *srvr_ecpoint = NULL;
|
EC_POINT *srvr_ecpoint = NULL;
|
||||||
int curve_nid = 0;
|
int curve_nid = 0;
|
||||||
unsigned int encoded_pt_len = 0;
|
|
||||||
#endif
|
#endif
|
||||||
PACKET pkt, save_param_start;
|
PACKET pkt, save_param_start, signature;
|
||||||
unsigned char *data, *param;
|
|
||||||
size_t param_len;
|
|
||||||
|
|
||||||
EVP_MD_CTX_init(&md_ctx);
|
EVP_MD_CTX_init(&md_ctx);
|
||||||
|
|
||||||
|
@ -1512,9 +1508,9 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
#ifndef OPENSSL_NO_PSK
|
#ifndef OPENSSL_NO_PSK
|
||||||
/* PSK ciphersuites are preceded by an identity hint */
|
/* PSK ciphersuites are preceded by an identity hint */
|
||||||
if (alg_k & SSL_PSK) {
|
if (alg_k & SSL_PSK) {
|
||||||
|
PACKET psk_identity_hint;
|
||||||
if (!PACKET_get_net_2(&pkt, &i)) {
|
if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity_hint)) {
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1524,34 +1520,17 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
* a PSK identity hint can be as long as the maximum length of a PSK
|
* a PSK identity hint can be as long as the maximum length of a PSK
|
||||||
* identity.
|
* identity.
|
||||||
*/
|
*/
|
||||||
if (i > PSK_MAX_IDENTITY_LEN) {
|
if (PACKET_remaining(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN) {
|
||||||
al = SSL_AD_HANDSHAKE_FAILURE;
|
al = SSL_AD_HANDSHAKE_FAILURE;
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG);
|
||||||
goto f_err;
|
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 (!PACKET_strndup(&psk_identity_hint,
|
||||||
if (i != 0) {
|
&s->session->psk_identity_hint)) {
|
||||||
unsigned char *hint = NULL;
|
al = SSL_AD_INTERNAL_ERROR;
|
||||||
|
|
||||||
if (!PACKET_get_bytes(&pkt, &hint, i)) {
|
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
|
|
||||||
goto f_err;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing else to do for plain PSK or RSAPSK */
|
/* Nothing else to do for plain PSK or RSAPSK */
|
||||||
|
@ -1560,62 +1539,27 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
#endif /* !OPENSSL_NO_PSK */
|
#endif /* !OPENSSL_NO_PSK */
|
||||||
#ifndef OPENSSL_NO_SRP
|
#ifndef OPENSSL_NO_SRP
|
||||||
if (alg_k & SSL_kSRP) {
|
if (alg_k & SSL_kSRP) {
|
||||||
if (!PACKET_get_net_2(&pkt, &i)) {
|
PACKET prime, generator, salt, server_pub;
|
||||||
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_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;
|
goto f_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PACKET_get_bytes(&pkt, &data, i)) {
|
if ((s->srp_ctx.N =
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH);
|
BN_bin2bn(PACKET_data(&prime),
|
||||||
goto f_err;
|
PACKET_remaining(&prime), NULL)) == NULL
|
||||||
}
|
|| (s->srp_ctx.g =
|
||||||
|
BN_bin2bn(PACKET_data(&generator),
|
||||||
if ((s->srp_ctx.N = BN_bin2bn(data, i, NULL)) == NULL) {
|
PACKET_remaining(&generator), NULL)) == NULL
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
|
|| (s->srp_ctx.s =
|
||||||
goto err;
|
BN_bin2bn(PACKET_data(&salt),
|
||||||
}
|
PACKET_remaining(&salt), NULL)) == NULL
|
||||||
|
|| (s->srp_ctx.B =
|
||||||
if (!PACKET_get_net_2(&pkt, &i)) {
|
BN_bin2bn(PACKET_data(&server_pub),
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
PACKET_remaining(&server_pub), NULL)) == NULL) {
|
||||||
goto f_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PACKET_get_bytes(&pkt, &data, i)) {
|
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH);
|
|
||||||
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) {
|
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -1632,43 +1576,29 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
#endif /* !OPENSSL_NO_SRP */
|
#endif /* !OPENSSL_NO_SRP */
|
||||||
#ifndef OPENSSL_NO_RSA
|
#ifndef OPENSSL_NO_RSA
|
||||||
if (alg_k & SSL_kRSA) {
|
if (alg_k & SSL_kRSA) {
|
||||||
|
PACKET mod, exp;
|
||||||
/* Temporary RSA keys only allowed in export ciphersuites */
|
/* Temporary RSA keys only allowed in export ciphersuites */
|
||||||
if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
|
if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
|
||||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = RSA_new()) == NULL) {
|
if ((rsa = RSA_new()) == NULL) {
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PACKET_get_net_2(&pkt, &i)) {
|
if ((rsa->n = BN_bin2bn(PACKET_data(&mod), PACKET_remaining(&mod),
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
rsa->n)) == NULL
|
||||||
goto f_err;
|
|| (rsa->e = BN_bin2bn(PACKET_data(&exp), PACKET_remaining(&exp),
|
||||||
}
|
rsa->e)) == NULL) {
|
||||||
|
|
||||||
if (!PACKET_get_bytes(&pkt, &data, i)) {
|
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH);
|
|
||||||
goto f_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rsa->n = BN_bin2bn(data, i, rsa->n)) == 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_RSA_E_LENGTH);
|
|
||||||
goto f_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rsa->e = BN_bin2bn(data, i, rsa->e)) == NULL) {
|
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -1695,68 +1625,33 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
#endif
|
#endif
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
|
else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
|
||||||
|
PACKET prime, generator, pub_key;
|
||||||
|
|
||||||
|
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 ((dh = DH_new()) == NULL) {
|
if ((dh = DH_new()) == NULL) {
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PACKET_get_net_2(&pkt, &i)) {
|
if ((dh->p = BN_bin2bn(PACKET_data(&prime),
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
PACKET_remaining(&prime), NULL)) == NULL
|
||||||
goto f_err;
|
|| (dh->g = BN_bin2bn(PACKET_data(&generator),
|
||||||
}
|
PACKET_remaining(&generator), NULL)) == NULL
|
||||||
|
|| (dh->pub_key =
|
||||||
if (!PACKET_get_bytes(&pkt, &data, i)) {
|
BN_bin2bn(PACKET_data(&pub_key),
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH);
|
PACKET_remaining(&pub_key), NULL)) == NULL) {
|
||||||
goto f_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dh->p = BN_bin2bn(data, i, NULL)) == NULL) {
|
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BN_is_zero(dh->p)) {
|
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_P_VALUE);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_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);
|
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1778,6 +1673,8 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
|
else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
|
||||||
EC_GROUP *ngroup;
|
EC_GROUP *ngroup;
|
||||||
const EC_GROUP *group;
|
const EC_GROUP *group;
|
||||||
|
PACKET encoded_pt;
|
||||||
|
unsigned char *ecparams;
|
||||||
|
|
||||||
if ((ecdh = EC_KEY_new()) == NULL) {
|
if ((ecdh = EC_KEY_new()) == NULL) {
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
|
||||||
|
@ -1786,15 +1683,10 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extract elliptic curve parameters and the server's ephemeral ECDH
|
* Extract elliptic curve parameters and the server's ephemeral ECDH
|
||||||
* public key. Keep accumulating lengths of various components in
|
* public key. For now we only support named (not generic) curves and
|
||||||
* param_len and make sure it never exceeds n.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX: For now we only support named (not generic) curves and the
|
|
||||||
* ECParameters in this case is just three bytes.
|
* 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);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
|
@ -1802,12 +1694,12 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
* Check curve is one of our preferences, if not server has sent an
|
* Check curve is one of our preferences, if not server has sent an
|
||||||
* invalid curve. ECParameters is 3 bytes.
|
* 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);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE);
|
||||||
goto f_err;
|
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;
|
al = SSL_AD_INTERNAL_ERROR;
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||||
SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
|
SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
|
||||||
|
@ -1842,14 +1734,13 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PACKET_get_1(&pkt, &encoded_pt_len)) {
|
if (!PACKET_get_length_prefixed_1(&pkt, &encoded_pt)) {
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PACKET_get_bytes(&pkt, &data, encoded_pt_len) ||
|
if (EC_POINT_oct2point(group, srvr_ecpoint, PACKET_data(&encoded_pt),
|
||||||
(EC_POINT_oct2point(group, srvr_ecpoint,
|
PACKET_remaining(&encoded_pt), bn_ctx) == 0) {
|
||||||
data, encoded_pt_len, bn_ctx) == 0)) {
|
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT);
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
|
@ -1883,21 +1774,29 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
}
|
}
|
||||||
#endif /* !OPENSSL_NO_EC */
|
#endif /* !OPENSSL_NO_EC */
|
||||||
|
|
||||||
|
/* if it was signed, check the signature */
|
||||||
|
if (pkey != NULL) {
|
||||||
|
PACKET params;
|
||||||
/*
|
/*
|
||||||
* |pkt| now points to the beginning of the signature, so the difference
|
* |pkt| now points to the beginning of the signature, so the difference
|
||||||
* equals the length of the parameters.
|
* equals the length of the parameters.
|
||||||
*/
|
*/
|
||||||
param_len = PACKET_remaining(&save_param_start) - PACKET_remaining(&pkt);
|
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 it was signed, check the signature */
|
|
||||||
if (pkey != NULL) {
|
|
||||||
if (SSL_USE_SIGALGS(s)) {
|
if (SSL_USE_SIGALGS(s)) {
|
||||||
|
unsigned char *sigalgs;
|
||||||
int rv;
|
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);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
rv = tls12_check_peer_sigalg(&md, s, data, pkey);
|
rv = tls12_check_peer_sigalg(&md, s, sigalgs, pkey);
|
||||||
if (rv == -1)
|
if (rv == -1)
|
||||||
goto err;
|
goto err;
|
||||||
else if (rv == 0) {
|
else if (rv == 0) {
|
||||||
|
@ -1906,11 +1805,13 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
#ifdef SSL_DEBUG
|
#ifdef SSL_DEBUG
|
||||||
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||||
#endif
|
#endif
|
||||||
} else
|
} else {
|
||||||
md = EVP_sha1();
|
md = EVP_sha1();
|
||||||
|
}
|
||||||
|
|
||||||
if (!PACKET_get_net_2(&pkt, &i)) {
|
if (!PACKET_get_length_prefixed_2(&pkt, &signature)
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
|
|| PACKET_remaining(&pkt) != 0) {
|
||||||
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
|
||||||
goto f_err;
|
goto f_err;
|
||||||
}
|
}
|
||||||
j = EVP_PKEY_size(pkey);
|
j = EVP_PKEY_size(pkey);
|
||||||
|
@ -1922,19 +1823,11 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
/*
|
/*
|
||||||
* Check signature length
|
* Check signature length
|
||||||
*/
|
*/
|
||||||
if (i > (unsigned int)j
|
if (PACKET_remaining(&signature) > (size_t)j) {
|
||||||
|| !PACKET_get_bytes(&pkt, &data, i)
|
|
||||||
|| PACKET_remaining(&pkt) != 0) {
|
|
||||||
/* wrong packet length */
|
/* wrong packet length */
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH);
|
||||||
goto f_err;
|
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
|
#ifndef OPENSSL_NO_RSA
|
||||||
if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) {
|
if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) {
|
||||||
int num;
|
int num;
|
||||||
|
@ -1950,13 +1843,15 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
SSL3_RANDOM_SIZE);
|
SSL3_RANDOM_SIZE);
|
||||||
EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
|
EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
|
||||||
SSL3_RANDOM_SIZE);
|
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);
|
EVP_DigestFinal_ex(&md_ctx, q, &size);
|
||||||
q += size;
|
q += size;
|
||||||
j += size;
|
j += size;
|
||||||
}
|
}
|
||||||
verify_ret =
|
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) {
|
if (verify_ret < 0) {
|
||||||
al = SSL_AD_DECRYPT_ERROR;
|
al = SSL_AD_DECRYPT_ERROR;
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT);
|
||||||
|
@ -1976,8 +1871,10 @@ int ssl3_get_key_exchange(SSL *s)
|
||||||
SSL3_RANDOM_SIZE);
|
SSL3_RANDOM_SIZE);
|
||||||
EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
|
EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
|
||||||
SSL3_RANDOM_SIZE);
|
SSL3_RANDOM_SIZE);
|
||||||
EVP_VerifyUpdate(&md_ctx, param, param_len);
|
EVP_VerifyUpdate(&md_ctx, PACKET_data(¶ms),
|
||||||
if (EVP_VerifyFinal(&md_ctx, data, (int)i, pkey) <= 0) {
|
PACKET_remaining(¶ms));
|
||||||
|
if (EVP_VerifyFinal(&md_ctx, PACKET_data(&signature),
|
||||||
|
PACKET_remaining(&signature), pkey) <= 0) {
|
||||||
/* bad signature */
|
/* bad signature */
|
||||||
al = SSL_AD_DECRYPT_ERROR;
|
al = SSL_AD_DECRYPT_ERROR;
|
||||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
|
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
|
||||||
|
|
|
@ -351,6 +351,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
|
||||||
{ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"},
|
{ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"},
|
||||||
{ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"},
|
{ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"},
|
||||||
{ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"},
|
{ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"},
|
||||||
|
{ERR_REASON(SSL_R_BAD_DH_VALUE), "bad dh value"},
|
||||||
{ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"},
|
{ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"},
|
||||||
{ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"},
|
{ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"},
|
||||||
{ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"},
|
{ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"},
|
||||||
|
|
Loading…
Reference in a new issue