mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-18 20:49:28 +00:00
108 lines
3.2 KiB
C
108 lines
3.2 KiB
C
/* Provenance: openssl/openssl tls_construct_cke_gost18 (fixed).
|
|||
|
|
* repo: openssl/openssl
|
||
|
|
* commit: 373de40f3f76c63e4f2684abd86706f3863347ca
|
||
|
|
* parent: 3be529cd2eb4eb3eaaa7913af619fb9c918d4581
|
||
|
|
* commit_url: https://github.com/openssl/openssl/commit/373de40f3f76c63e4f2684abd86706f3863347ca
|
||
|
|
* cve: CVE-2022-29242
|
||
|
|
* license: Apache-2.0
|
||
|
|
* function: tls_construct_cke_gost18
|
||
|
|
* relpath: ssl/statem/statem_clnt.c
|
||
|
|
*/
|
||
|
|
|
||
|
|
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];
|
||
|
|
unsigned char *encdata = NULL;
|
||
|
|
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||
|
|
X509 *peer_cert;
|
||
|
|
unsigned char *pms = NULL;
|
||
|
|
size_t pmslen = 0;
|
||
|
|
size_t msglen;
|
||
|
|
int cipher_nid = ossl_gost18_cke_cipher_nid(s);
|
||
|
|
|
||
|
|
if (cipher_nid == NID_undef) {
|
||
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ossl_gost_ukm(s, rnd_dgst) <= 0) {
|
||
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, 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, ERR_R_MALLOC_FAILURE);
|
||
|
|
goto err;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (RAND_bytes_ex(s->ctx->libctx, pms, pmslen, 0) <= 0) {
|
||
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, 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_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
|
||
|
|
goto err;
|
||
|
|
}
|
||
|
|
|
||
|
|
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, ERR_R_MALLOC_FAILURE);
|
||
|
|
goto err;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 ) {
|
||
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, 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_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_R_LIBRARY_BUG);
|
||
|
|
goto err;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (EVP_PKEY_encrypt(pkey_ctx, NULL, &msglen, pms, pmslen) <= 0) {
|
||
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
|
||
|
|
goto err;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!WPACKET_allocate_bytes(pkt, msglen, &encdata)
|
||
|
|
|| EVP_PKEY_encrypt(pkey_ctx, encdata, &msglen, pms, pmslen) <= 0) {
|
||
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
|
||
|
|
goto err;
|
||
|
|
}
|
||
|
|
|
||
|
|
EVP_PKEY_CTX_free(pkey_ctx);
|
||
|
|
pkey_ctx = NULL;
|
||
|
|
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, ERR_R_INTERNAL_ERROR);
|
||
|
|
return 0;
|
||
|
|
#endif
|
||
|
|
}
|