|
@@ -1624,6 +1624,12 @@ int ssl3_get_key_exchange(SSL *s)
|
|
|
}
|
|
}
|
|
|
p += i;
|
|
p += i;
|
|
|
|
|
|
|
|
|
|
+ if (BN_is_zero(dh->p)) {
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
if (2 > n - param_len) {
|
|
if (2 > n - param_len) {
|
|
|
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;
|
|
@@ -1644,6 +1650,11 @@ int ssl3_get_key_exchange(SSL *s)
|
|
|
}
|
|
}
|
|
|
p += i;
|
|
p += i;
|
|
|
|
|
|
|
|
|
|
+ if (BN_is_zero(dh->g)) {
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (2 > n - param_len) {
|
|
if (2 > n - param_len) {
|
|
|
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;
|
|
@@ -1665,6 +1676,11 @@ int ssl3_get_key_exchange(SSL *s)
|
|
|
p += i;
|
|
p += i;
|
|
|
n -= param_len;
|
|
n -= param_len;
|
|
|
|
|
|
|
|
|
|
+ if (BN_is_zero(dh->pub_key)) {
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
# ifndef OPENSSL_NO_RSA
|
|
# ifndef OPENSSL_NO_RSA
|
|
|
if (alg_a & SSL_aRSA)
|
|
if (alg_a & SSL_aRSA)
|
|
|
pkey =
|
|
pkey =
|
|
@@ -1867,14 +1883,20 @@ int ssl3_get_key_exchange(SSL *s)
|
|
|
q = md_buf;
|
|
q = md_buf;
|
|
|
for (num = 2; num > 0; num--) {
|
|
for (num = 2; num > 0; num--) {
|
|
|
EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
|
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);
|
|
|
|
|
- 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, &size);
|
|
|
|
|
|
|
+ if (EVP_DigestInit_ex(&md_ctx,
|
|
|
|
|
+ (num == 2) ? s->ctx->md5 : s->ctx->sha1,
|
|
|
|
|
+ NULL) <= 0
|
|
|
|
|
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
|
|
|
|
|
+ SSL3_RANDOM_SIZE) <= 0
|
|
|
|
|
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
|
|
|
|
|
+ SSL3_RANDOM_SIZE) <= 0
|
|
|
|
|
+ || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0
|
|
|
|
|
+ || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) {
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
|
|
|
|
+ ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ al = SSL_AD_INTERNAL_ERROR;
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
q += size;
|
|
q += size;
|
|
|
j += size;
|
|
j += size;
|
|
|
}
|
|
}
|
|
@@ -1893,12 +1915,16 @@ int ssl3_get_key_exchange(SSL *s)
|
|
|
} else
|
|
} else
|
|
|
#endif
|
|
#endif
|
|
|
{
|
|
{
|
|
|
- EVP_VerifyInit_ex(&md_ctx, md, NULL);
|
|
|
|
|
- EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
|
|
|
|
|
- SSL3_RANDOM_SIZE);
|
|
|
|
|
- EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
|
|
|
|
|
- SSL3_RANDOM_SIZE);
|
|
|
|
|
- EVP_VerifyUpdate(&md_ctx, param, param_len);
|
|
|
|
|
|
|
+ if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0
|
|
|
|
|
+ || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
|
|
|
|
|
+ SSL3_RANDOM_SIZE) <= 0
|
|
|
|
|
+ || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
|
|
|
|
|
+ SSL3_RANDOM_SIZE) <= 0
|
|
|
|
|
+ || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) {
|
|
|
|
|
+ al = SSL_AD_INTERNAL_ERROR;
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) {
|
|
if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) {
|
|
|
/* bad signature */
|
|
/* bad signature */
|
|
|
al = SSL_AD_DECRYPT_ERROR;
|
|
al = SSL_AD_DECRYPT_ERROR;
|
|
@@ -2118,6 +2144,7 @@ int ssl3_get_new_session_ticket(SSL *s)
|
|
|
long n;
|
|
long n;
|
|
|
const unsigned char *p;
|
|
const unsigned char *p;
|
|
|
unsigned char *d;
|
|
unsigned char *d;
|
|
|
|
|
+ unsigned long ticket_lifetime_hint;
|
|
|
|
|
|
|
|
n = s->method->ssl_get_message(s,
|
|
n = s->method->ssl_get_message(s,
|
|
|
SSL3_ST_CR_SESSION_TICKET_A,
|
|
SSL3_ST_CR_SESSION_TICKET_A,
|
|
@@ -2136,6 +2163,19 @@ int ssl3_get_new_session_ticket(SSL *s)
|
|
|
|
|
|
|
|
p = d = (unsigned char *)s->init_msg;
|
|
p = d = (unsigned char *)s->init_msg;
|
|
|
|
|
|
|
|
|
|
+ n2l(p, ticket_lifetime_hint);
|
|
|
|
|
+ n2s(p, ticklen);
|
|
|
|
|
+ /* ticket_lifetime_hint + ticket_length + ticket */
|
|
|
|
|
+ if (ticklen + 6 != n) {
|
|
|
|
|
+ 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) {
|
|
if (s->session->session_id_length > 0) {
|
|
|
int i = s->session_ctx->session_cache_mode;
|
|
int i = s->session_ctx->session_cache_mode;
|
|
|
SSL_SESSION *new_sess;
|
|
SSL_SESSION *new_sess;
|
|
@@ -2167,14 +2207,6 @@ int ssl3_get_new_session_ticket(SSL *s)
|
|
|
s->session = new_sess;
|
|
s->session = new_sess;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- n2l(p, s->session->tlsext_tick_lifetime_hint);
|
|
|
|
|
- n2s(p, ticklen);
|
|
|
|
|
- /* ticket_lifetime_hint + ticket_length + ticket */
|
|
|
|
|
- if (ticklen + 6 != n) {
|
|
|
|
|
- al = SSL_AD_DECODE_ERROR;
|
|
|
|
|
- SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
|
|
|
|
|
- goto f_err;
|
|
|
|
|
- }
|
|
|
|
|
if (s->session->tlsext_tick) {
|
|
if (s->session->tlsext_tick) {
|
|
|
OPENSSL_free(s->session->tlsext_tick);
|
|
OPENSSL_free(s->session->tlsext_tick);
|
|
|
s->session->tlsext_ticklen = 0;
|
|
s->session->tlsext_ticklen = 0;
|
|
@@ -2185,6 +2217,7 @@ int ssl3_get_new_session_ticket(SSL *s)
|
|
|
goto err;
|
|
goto err;
|
|
|
}
|
|
}
|
|
|
memcpy(s->session->tlsext_tick, p, ticklen);
|
|
memcpy(s->session->tlsext_tick, p, ticklen);
|
|
|
|
|
+ s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
|
|
|
s->session->tlsext_ticklen = ticklen;
|
|
s->session->tlsext_ticklen = ticklen;
|
|
|
/*
|
|
/*
|
|
|
* There are two ways to detect a resumed ticket session. One is to set
|
|
* There are two ways to detect a resumed ticket session. One is to set
|
|
@@ -2354,6 +2387,7 @@ int ssl3_send_client_key_exchange(SSL *s)
|
|
|
|| (pkey->pkey.rsa == NULL)) {
|
|
|| (pkey->pkey.rsa == NULL)) {
|
|
|
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
|
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
|
|
ERR_R_INTERNAL_ERROR);
|
|
ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ EVP_PKEY_free(pkey);
|
|
|
goto err;
|
|
goto err;
|
|
|
}
|
|
}
|
|
|
rsa = pkey->pkey.rsa;
|
|
rsa = pkey->pkey.rsa;
|
|
@@ -2801,6 +2835,11 @@ int ssl3_send_client_key_exchange(SSL *s)
|
|
|
|
|
|
|
|
pkey_ctx = EVP_PKEY_CTX_new(pub_key =
|
|
pkey_ctx = EVP_PKEY_CTX_new(pub_key =
|
|
|
X509_get_pubkey(peer_cert), NULL);
|
|
X509_get_pubkey(peer_cert), NULL);
|
|
|
|
|
+ if (pkey_ctx == NULL) {
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
|
|
|
|
+ ERR_R_MALLOC_FAILURE);
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ }
|
|
|
/*
|
|
/*
|
|
|
* If we have send a certificate, and certificate key
|
|
* If we have send a certificate, and certificate key
|
|
|
*
|
|
*
|
|
@@ -2810,10 +2849,13 @@ int ssl3_send_client_key_exchange(SSL *s)
|
|
|
|
|
|
|
|
/* Otherwise, generate ephemeral key pair */
|
|
/* Otherwise, generate ephemeral key pair */
|
|
|
|
|
|
|
|
- EVP_PKEY_encrypt_init(pkey_ctx);
|
|
|
|
|
- /* Generate session key */
|
|
|
|
|
- if (RAND_bytes(premaster_secret, 32) <= 0) {
|
|
|
|
|
|
|
+ if (pkey_ctx == NULL
|
|
|
|
|
+ || EVP_PKEY_encrypt_init(pkey_ctx) <= 0
|
|
|
|
|
+ /* Generate session key */
|
|
|
|
|
+ || RAND_bytes(premaster_secret, 32) <= 0) {
|
|
|
EVP_PKEY_CTX_free(pkey_ctx);
|
|
EVP_PKEY_CTX_free(pkey_ctx);
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
|
|
|
|
+ ERR_R_INTERNAL_ERROR);
|
|
|
goto err;
|
|
goto err;
|
|
|
}
|
|
}
|
|
|
/*
|
|
/*
|
|
@@ -2834,13 +2876,18 @@ int ssl3_send_client_key_exchange(SSL *s)
|
|
|
* data
|
|
* data
|
|
|
*/
|
|
*/
|
|
|
ukm_hash = EVP_MD_CTX_create();
|
|
ukm_hash = EVP_MD_CTX_create();
|
|
|
- EVP_DigestInit(ukm_hash,
|
|
|
|
|
- EVP_get_digestbynid(NID_id_GostR3411_94));
|
|
|
|
|
- EVP_DigestUpdate(ukm_hash, s->s3->client_random,
|
|
|
|
|
- SSL3_RANDOM_SIZE);
|
|
|
|
|
- EVP_DigestUpdate(ukm_hash, s->s3->server_random,
|
|
|
|
|
- SSL3_RANDOM_SIZE);
|
|
|
|
|
- EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
|
|
|
|
|
|
|
+ if (EVP_DigestInit(ukm_hash,
|
|
|
|
|
+ EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0
|
|
|
|
|
+ || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
|
|
|
|
|
+ SSL3_RANDOM_SIZE) <= 0
|
|
|
|
|
+ || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
|
|
|
|
|
+ SSL3_RANDOM_SIZE) <= 0
|
|
|
|
|
+ || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
|
|
|
|
|
+ EVP_MD_CTX_destroy(ukm_hash);
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
|
|
|
|
+ ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ }
|
|
|
EVP_MD_CTX_destroy(ukm_hash);
|
|
EVP_MD_CTX_destroy(ukm_hash);
|
|
|
if (EVP_PKEY_CTX_ctrl
|
|
if (EVP_PKEY_CTX_ctrl
|
|
|
(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
|
|
(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
|
|
@@ -2856,7 +2903,7 @@ int ssl3_send_client_key_exchange(SSL *s)
|
|
|
*(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
|
|
*(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
|
|
|
msglen = 255;
|
|
msglen = 255;
|
|
|
if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32)
|
|
if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32)
|
|
|
- < 0) {
|
|
|
|
|
|
|
+ <= 0) {
|
|
|
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
|
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
|
|
SSL_R_LIBRARY_BUG);
|
|
SSL_R_LIBRARY_BUG);
|
|
|
goto err;
|
|
goto err;
|
|
@@ -3057,7 +3104,10 @@ int ssl3_send_client_verify(SSL *s)
|
|
|
pkey = s->cert->key->privatekey;
|
|
pkey = s->cert->key->privatekey;
|
|
|
/* Create context from key and test if sha1 is allowed as digest */
|
|
/* Create context from key and test if sha1 is allowed as digest */
|
|
|
pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
|
pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
|
|
- EVP_PKEY_sign_init(pctx);
|
|
|
|
|
|
|
+ if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) {
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ }
|
|
|
if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) {
|
|
if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) {
|
|
|
if (TLS1_get_version(s) < TLS1_2_VERSION)
|
|
if (TLS1_get_version(s) < TLS1_2_VERSION)
|
|
|
s->method->ssl3_enc->cert_verify_mac(s,
|
|
s->method->ssl3_enc->cert_verify_mac(s,
|
|
@@ -3194,7 +3244,6 @@ int ssl3_send_client_certificate(SSL *s)
|
|
|
* If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP;
|
|
* If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP;
|
|
|
* return(-1); We then get retied later
|
|
* return(-1); We then get retied later
|
|
|
*/
|
|
*/
|
|
|
- i = 0;
|
|
|
|
|
i = ssl_do_client_cert_cb(s, &x509, &pkey);
|
|
i = ssl_do_client_cert_cb(s, &x509, &pkey);
|
|
|
if (i < 0) {
|
|
if (i < 0) {
|
|
|
s->rwstate = SSL_X509_LOOKUP;
|
|
s->rwstate = SSL_X509_LOOKUP;
|