提交 a011b586 编写于 作者: N Nicola Tuveri

[ssl] Support ssl_decapsulate on client side

Reviewed-by: NMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13018)
上级 c1a74f59
......@@ -1401,6 +1401,7 @@ SSL_F_SSL_CTX_USE_SERVERINFO_EX:543:SSL_CTX_use_serverinfo_ex
SSL_F_SSL_CTX_USE_SERVERINFO_FILE:337:SSL_CTX_use_serverinfo_file
SSL_F_SSL_DANE_DUP:403:ssl_dane_dup
SSL_F_SSL_DANE_ENABLE:395:SSL_dane_enable
SSL_F_SSL_DECAPSULATE:643:
SSL_F_SSL_DERIVE:590:ssl_derive
SSL_F_SSL_DO_CONFIG:391:ssl_do_config
SSL_F_SSL_DO_HANDSHAKE:180:SSL_do_handshake
......
......@@ -183,6 +183,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 0
# define SSL_F_SSL_DANE_DUP 0
# define SSL_F_SSL_DANE_ENABLE 0
# define SSL_F_SSL_DECAPSULATE 0
# define SSL_F_SSL_DERIVE 0
# define SSL_F_SSL_DO_CONFIG 0
# define SSL_F_SSL_DO_HANDSHAKE 0
......
......@@ -4832,6 +4832,33 @@ EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id)
return pkey;
}
/* Generate secrets from pms */
__owur static
int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen)
{
int rv = 0;
/* SSLfatal() called as appropriate in the below functions */
if (SSL_IS_TLS13(s)) {
/*
* If we are resuming then we already generated the early secret
* when we created the ClientHello, so don't recreate it.
*/
if (!s->hit)
rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL,
0,
(unsigned char *)&s->early_secret);
else
rv = 1;
rv = rv && tls13_generate_handshake_secret(s, pms, pmslen);
} else {
rv = ssl_generate_master_secret(s, pms, pmslen, 0);
}
return rv;
}
/* Derive secrets for ECDH/DH */
int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
{
......@@ -4876,22 +4903,62 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
if (gensecret) {
/* SSLfatal() called as appropriate in the below functions */
if (SSL_IS_TLS13(s)) {
/*
* If we are resuming then we already generated the early secret
* when we created the ClientHello, so don't recreate it.
*/
if (!s->hit)
rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL,
0,
(unsigned char *)&s->early_secret);
else
rv = 1;
rv = rv && tls13_generate_handshake_secret(s, pms, pmslen);
} else {
rv = ssl_generate_master_secret(s, pms, pmslen, 0);
}
rv = ssl_gensecret(s, pms, pmslen);
} else {
/* Save premaster secret */
s->s3.tmp.pms = pms;
s->s3.tmp.pmslen = pmslen;
pms = NULL;
rv = 1;
}
err:
OPENSSL_clear_free(pms, pmslen);
EVP_PKEY_CTX_free(pctx);
return rv;
}
/* Decapsulate secrets for KEM */
int ssl_decapsulate(SSL *s, EVP_PKEY *privkey,
const unsigned char *ct, size_t ctlen,
int gensecret)
{
int rv = 0;
unsigned char *pms = NULL;
size_t pmslen = 0;
EVP_PKEY_CTX *pctx;
if (privkey == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE,
ERR_R_INTERNAL_ERROR);
return 0;
}
pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq);
if (EVP_PKEY_decapsulate_init(pctx) <= 0
|| EVP_PKEY_decapsulate(pctx, NULL, &pmslen, ct, ctlen) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE,
ERR_R_INTERNAL_ERROR);
goto err;
}
pms = OPENSSL_malloc(pmslen);
if (pms == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE,
ERR_R_MALLOC_FAILURE);
goto err;
}
if (EVP_PKEY_decapsulate(pctx, pms, &pmslen, ct, ctlen) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE,
ERR_R_INTERNAL_ERROR);
goto err;
}
if (gensecret) {
/* SSLfatal() called as appropriate in the below functions */
rv = ssl_gensecret(s, pms, pmslen);
} else {
/* Save premaster secret */
s->s3.tmp.pms = pms;
......
......@@ -2456,6 +2456,9 @@ __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
__owur EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm);
__owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey,
int genmaster);
__owur int ssl_decapsulate(SSL *s, EVP_PKEY *privkey,
const unsigned char *ct, size_t ctlen,
int gensecret);
__owur EVP_PKEY *ssl_dh_to_pkey(DH *dh);
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl);
__owur unsigned int ssl_get_split_send_fragment(const SSL *ssl);
......
......@@ -1830,6 +1830,7 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
unsigned int group_id;
PACKET encoded_pt;
EVP_PKEY *ckey = s->s3.tmp.pkey, *skey = NULL;
const TLS_GROUP_INFO *ginf = NULL;
/* Sanity check */
if (ckey == NULL || s->s3.peer_tmp != NULL) {
......@@ -1893,6 +1894,12 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
return 0;
}
if ((ginf = tls1_group_id_lookup(s->ctx, group_id)) == NULL) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
SSL_R_BAD_KEY_SHARE);
return 0;
}
if (!PACKET_as_length_prefixed_2(pkt, &encoded_pt)
|| PACKET_remaining(&encoded_pt) == 0) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
......@@ -1900,27 +1907,39 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
return 0;
}
skey = EVP_PKEY_new();
if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
SSL_R_COPY_PARAMETERS_FAILED);
return 0;
}
if (!ginf->is_kem) {
/* Regular KEX */
skey = EVP_PKEY_new();
if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
SSL_R_COPY_PARAMETERS_FAILED);
return 0;
}
if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
PACKET_remaining(&encoded_pt))) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
SSL_R_BAD_ECPOINT);
EVP_PKEY_free(skey);
return 0;
}
if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
PACKET_remaining(&encoded_pt))) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
SSL_R_BAD_ECPOINT);
EVP_PKEY_free(skey);
return 0;
}
if (ssl_derive(s, ckey, skey, 1) == 0) {
/* SSLfatal() already called */
EVP_PKEY_free(skey);
return 0;
if (ssl_derive(s, ckey, skey, 1) == 0) {
/* SSLfatal() already called */
EVP_PKEY_free(skey);
return 0;
}
s->s3.peer_tmp = skey;
} else {
/* KEM Mode */
const unsigned char *ct = PACKET_data(&encoded_pt);
size_t ctlen = PACKET_remaining(&encoded_pt);
if (ssl_decapsulate(s, ckey, ct, ctlen, 1) == 0) {
/* SSLfatal() already called */
return 0;
}
}
s->s3.peer_tmp = skey;
#endif
return 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册