Latest update (add quic)
This commit is contained in:
+149
-30
@@ -914,6 +914,14 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt,
|
||||
break;
|
||||
|
||||
case TLS_ST_CW_END_OF_EARLY_DATA:
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
/* QUIC does not send EndOfEarlyData, draft-ietf-quic-tls-24 S8.3 */
|
||||
if (s->quic_method != NULL) {
|
||||
*confunc = NULL;
|
||||
*mt = SSL3_MT_DUMMY;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
*confunc = tls_construct_end_of_early_data;
|
||||
*mt = SSL3_MT_END_OF_EARLY_DATA;
|
||||
break;
|
||||
@@ -2231,21 +2239,6 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
|
||||
* knows how to get a key from an encoded point with the help of
|
||||
* a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0()
|
||||
* downgrades an EVP_PKEY to contain a legacy key.
|
||||
*
|
||||
* THIS IS TEMPORARY
|
||||
*/
|
||||
EVP_PKEY_get0(s->s3.peer_tmp);
|
||||
if (EVP_PKEY_id(s->s3.peer_tmp) == EVP_PKEY_NONE) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_ECDHE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_set1_tls_encodedpoint(s->s3.peer_tmp,
|
||||
PACKET_data(&encoded_pt),
|
||||
PACKET_remaining(&encoded_pt))) {
|
||||
@@ -3148,21 +3141,6 @@ static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
|
||||
* knows how to get a key from an encoded point with the help of
|
||||
* a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0()
|
||||
* downgrades an EVP_PKEY to contain a legacy key.
|
||||
*
|
||||
* THIS IS TEMPORARY
|
||||
*/
|
||||
EVP_PKEY_get0(ckey);
|
||||
if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ssl_derive(s, ckey, skey, 0) == 0) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
@@ -3314,6 +3292,144 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
int gost18_cke_cipher_nid(const SSL *s)
|
||||
{
|
||||
if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_MAGMA) != 0)
|
||||
return NID_magma_ctr;
|
||||
else if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_KUZNYECHIK) != 0)
|
||||
return NID_kuznyechik_ctr;
|
||||
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
int gost_ukm(const SSL *s, unsigned char *dgst_buf)
|
||||
{
|
||||
EVP_MD_CTX * hash = NULL;
|
||||
unsigned int md_len;
|
||||
const EVP_MD *md = EVP_get_digestbynid(NID_id_GostR3411_2012_256);
|
||||
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
|
||||
if ((hash = EVP_MD_CTX_new()) == NULL
|
||||
|| EVP_DigestInit(hash, md) <= 0
|
||||
|| EVP_DigestUpdate(hash, s->s3.client_random, SSL3_RANDOM_SIZE) <= 0
|
||||
|| EVP_DigestUpdate(hash, s->s3.server_random, SSL3_RANDOM_SIZE) <= 0
|
||||
|| EVP_DigestFinal_ex(hash, dgst_buf, &md_len) <= 0) {
|
||||
EVP_MD_CTX_free(hash);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_free(hash);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
/* GOST 2018 key exchange message creation */
|
||||
unsigned char rnd_dgst[32], tmp[255];
|
||||
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||||
X509 *peer_cert;
|
||||
unsigned char *pms = NULL;
|
||||
size_t pmslen = 0;
|
||||
size_t msglen;
|
||||
int cipher_nid = gost18_cke_cipher_nid(s);
|
||||
|
||||
if (cipher_nid == NID_undef) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gost_ukm(s, rnd_dgst) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Pre-master secret - random bytes */
|
||||
pmslen = 32;
|
||||
pms = OPENSSL_malloc(pmslen);
|
||||
if (pms == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (RAND_bytes_ex(s->ctx->libctx, pms, (int)pmslen) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Get server certificate PKEY and create ctx from it */
|
||||
peer_cert = s->session->peer;
|
||||
if (peer_cert == NULL) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, X509_get0_pubkey(peer_cert), s->ctx->propq);
|
||||
if (pkey_ctx == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 ) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
};
|
||||
|
||||
/* Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code */
|
||||
if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT,
|
||||
EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) < 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
SSL_R_LIBRARY_BUG);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT,
|
||||
EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) < 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
SSL_R_LIBRARY_BUG);
|
||||
goto err;
|
||||
}
|
||||
|
||||
msglen = 255;
|
||||
if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
SSL_R_LIBRARY_BUG);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!WPACKET_memcpy(pkt, tmp, msglen)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_free(pkey_ctx);
|
||||
s->s3.tmp.pms = pms;
|
||||
s->s3.tmp.pmslen = pmslen;
|
||||
|
||||
return 1;
|
||||
err:
|
||||
EVP_PKEY_CTX_free(pkey_ctx);
|
||||
OPENSSL_clear_free(pms, pmslen);
|
||||
return 0;
|
||||
#else
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int tls_construct_cke_srp(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
@@ -3370,6 +3486,9 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt)
|
||||
} else if (alg_k & SSL_kGOST) {
|
||||
if (!tls_construct_cke_gost(s, pkt))
|
||||
goto err;
|
||||
} else if (alg_k & SSL_kGOST18) {
|
||||
if (!tls_construct_cke_gost18(s, pkt))
|
||||
goto err;
|
||||
} else if (alg_k & SSL_kSRP) {
|
||||
if (!tls_construct_cke_srp(s, pkt))
|
||||
goto err;
|
||||
|
||||
Reference in New Issue
Block a user