Latest update (add quic)

This commit is contained in:
2020-07-12 19:52:18 +09:00
parent 3a6d64bb68
commit e85ee33eee
501 changed files with 19166 additions and 10232 deletions
+43 -1
View File
@@ -56,6 +56,10 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent);
static int final_early_data(SSL *s, unsigned int context, int sent);
static int final_maxfragmentlen(SSL *s, unsigned int context, int sent);
static int init_post_handshake_auth(SSL *s, unsigned int context);
#ifndef OPENSSL_NO_QUIC
static int init_quic_transport_params(SSL *s, unsigned int context);
static int final_quic_transport_params(SSL *s, unsigned int context, int sent);
#endif
/* Structure to define a built-in extension */
typedef struct extensions_definition_st {
@@ -374,6 +378,19 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_construct_certificate_authorities,
tls_construct_certificate_authorities, NULL,
},
#ifndef OPENSSL_NO_QUIC
{
TLSEXT_TYPE_quic_transport_parameters,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS
| SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY,
init_quic_transport_params,
tls_parse_ctos_quic_transport_params, tls_parse_stoc_quic_transport_params,
tls_construct_stoc_quic_transport_params, tls_construct_ctos_quic_transport_params,
final_quic_transport_params,
},
#else
INVALID_EXTENSION,
#endif
{
/* Must be immediately before pre_shared_key */
TLSEXT_TYPE_padding,
@@ -1169,13 +1186,26 @@ static int init_etm(SSL *s, unsigned int context)
static int init_ems(SSL *s, unsigned int context)
{
s->s3.flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) {
s->s3.flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
s->s3.flags |= TLS1_FLAGS_REQUIRED_EXTMS;
}
return 1;
}
static int final_ems(SSL *s, unsigned int context, int sent)
{
/*
* Check extended master secret extension is not dropped on
* renegotiation.
*/
if (!(s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS)
&& (s->s3.flags & TLS1_FLAGS_REQUIRED_EXTMS)) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_EMS,
SSL_R_INCONSISTENT_EXTMS);
return 0;
}
if (!s->server && s->hit) {
/*
* Check extended master secret extension is consistent with
@@ -1701,3 +1731,15 @@ static int init_post_handshake_auth(SSL *s, unsigned int context)
return 1;
}
#ifndef OPENSSL_NO_QUIC
static int init_quic_transport_params(SSL *s, unsigned int context)
{
return 1;
}
static int final_quic_transport_params(SSL *s, unsigned int context, int sent)
{
return 1;
}
#endif
+52 -31
View File
@@ -648,21 +648,6 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id)
/* SSLfatal() already called */
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(key_share_key);
if (EVP_PKEY_id(key_share_key) == EVP_PKEY_NONE) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_ADD_KEY_SHARE,
ERR_R_EC_LIB);
goto err;
}
}
/* Encode the public key. */
@@ -1273,7 +1258,28 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt,
#endif
}
#ifndef OPENSSL_NO_QUIC
/* SAME AS tls_construct_stoc_quic_transport_params() */
EXT_RETURN tls_construct_ctos_quic_transport_params(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
if (s->ext.quic_transport_params == NULL
|| s->ext.quic_transport_params_len == 0) {
return EXT_RETURN_NOT_SENT;
}
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_quic_transport_parameters)
|| !WPACKET_sub_memcpy_u16(pkt, s->ext.quic_transport_params,
s->ext.quic_transport_params_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_CTOS_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
return EXT_RETURN_SENT;
}
#endif
/*
* Parse the server's renegotiation binding and abort if it's not right
*/
@@ -1926,22 +1932,6 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
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(skey);
if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) {
EVP_PKEY_free(skey);
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
ERR_R_INTERNAL_ERROR);
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,
@@ -1990,6 +1980,18 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context,
return 0;
}
#ifndef OPENSSL_NO_QUIC
/*
* QUIC server must send 0xFFFFFFFF or it's a PROTOCOL_VIOLATION
* per draft-ietf-quic-tls-24 S4.5
*/
if (s->quic_method != NULL && max_early_data != 0xFFFFFFFF) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_EARLY_DATA,
SSL_R_INVALID_MAX_EARLY_DATA);
return 0;
}
#endif
s->session->ext.max_early_data = max_early_data;
return 1;
@@ -2077,3 +2079,22 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
return 1;
}
#ifndef OPENSSL_NO_QUIC
/* SAME AS tls_parse_ctos_quic_transport_params() */
int tls_parse_stoc_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context,
X509 *x, size_t chainidx)
{
OPENSSL_free(s->ext.peer_quic_transport_params);
s->ext.peer_quic_transport_params = NULL;
s->ext.peer_quic_transport_params_len = 0;
if (!PACKET_memdup(pkt,
&s->ext.peer_quic_transport_params,
&s->ext.peer_quic_transport_params_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PARSE_STOC_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
+56 -33
View File
@@ -715,21 +715,6 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
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_PARSE_CTOS_KEY_SHARE,
ERR_R_INTERNAL_ERROR);
return 0;
}
s->s3.group_id = group_id;
if (!EVP_PKEY_set1_tls_encodedpoint(s->s3.peer_tmp,
@@ -1326,6 +1311,26 @@ int tls_parse_ctos_post_handshake_auth(SSL *s, PACKET *pkt, unsigned int context
return 1;
}
#ifndef OPENSSL_NO_QUIC
/* SAME AS tls_parse_stoc_quic_transport_params() */
int tls_parse_ctos_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context,
X509 *x, size_t chainidx)
{
OPENSSL_free(s->ext.peer_quic_transport_params);
s->ext.peer_quic_transport_params = NULL;
s->ext.peer_quic_transport_params_len = 0;
if (!PACKET_memdup(pkt,
&s->ext.peer_quic_transport_params,
&s->ext.peer_quic_transport_params_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PARSE_CTOS_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
/*
* Add the server's renegotiation binding
*/
@@ -1647,7 +1652,9 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context,
if (s->s3.tmp.new_cipher->algorithm_mac == SSL_AEAD
|| s->s3.tmp.new_cipher->algorithm_enc == SSL_RC4
|| s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT
|| s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) {
|| s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12
|| s->s3.tmp.new_cipher->algorithm_enc == SSL_MAGMA
|| s->s3.tmp.new_cipher->algorithm_enc == SSL_KUZNYECHIK) {
s->ext.use_etm = 0;
return EXT_RETURN_NOT_SENT;
}
@@ -1754,21 +1761,6 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt,
return EXT_RETURN_FAIL;
}
/*
* 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(skey);
if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE,
ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
/* Generate encoding of server key */
encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint);
if (encoded_pt_len == 0) {
@@ -1966,12 +1958,20 @@ EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt,
size_t chainidx)
{
if (context == SSL_EXT_TLS1_3_NEW_SESSION_TICKET) {
if (s->max_early_data == 0)
uint32_t max_early_data = s->max_early_data;
if (max_early_data == 0)
return EXT_RETURN_NOT_SENT;
#ifndef OPENSSL_NO_QUIC
/* QUIC server must always send 0xFFFFFFFF, per draft-ietf-quic-tls-24 S4.5 */
if (s->quic_method != NULL)
max_early_data = 0xFFFFFFFF;
#endif
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data)
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_put_bytes_u32(pkt, s->max_early_data)
|| !WPACKET_put_bytes_u32(pkt, max_early_data)
|| !WPACKET_close(pkt)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR);
@@ -2012,3 +2012,26 @@ EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context,
return EXT_RETURN_SENT;
}
#ifndef OPENSSL_NO_QUIC
/* SAME AS tls_construct_ctos_quic_transport_params() */
EXT_RETURN tls_construct_stoc_quic_transport_params(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx)
{
if (s->ext.quic_transport_params == NULL
|| s->ext.quic_transport_params_len == 0) {
return EXT_RETURN_NOT_SENT;
}
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_quic_transport_parameters)
|| !WPACKET_sub_memcpy_u16(pkt, s->ext.quic_transport_params,
s->ext.quic_transport_params_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_STOC_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
return EXT_RETURN_SENT;
}
#endif
+18 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -576,6 +576,10 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
* In DTLS we get the whole message in one go - header and body
*/
ret = dtls_get_message(s, &mt, &len);
#ifndef OPENSSL_NO_QUIC
} else if (SSL_IS_QUIC(s)) {
ret = quic_get_message(s, &mt, &len);
#endif
} else {
ret = tls_get_message_header(s, &mt);
}
@@ -605,8 +609,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
return SUB_STATE_ERROR;
}
/* dtls_get_message already did this */
if (!SSL_IS_DTLS(s)
/* dtls_get_message/quic_get_message already did this */
if (!SSL_IS_DTLS(s) && !SSL_IS_QUIC(s)
&& s->s3.tmp.message_size > 0
&& !grow_init_buf(s, s->s3.tmp.message_size
+ SSL3_HM_HEADER_LENGTH)) {
@@ -619,8 +623,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
/* Fall through */
case READ_STATE_BODY:
if (!SSL_IS_DTLS(s)) {
/* We already got this above for DTLS */
if (!SSL_IS_DTLS(s) && !SSL_IS_QUIC(s)) {
/* We already got this above for DTLS & QUIC */
ret = tls_get_message_body(s, &len);
if (ret == 0) {
/* Could be non-blocking IO */
@@ -901,6 +905,15 @@ static SUB_STATE_RETURN write_state_machine(SSL *s)
int statem_flush(SSL *s)
{
s->rwstate = SSL_WRITING;
#ifndef OPENSSL_NO_QUIC
if (SSL_IS_QUIC(s)) {
if (!s->quic_method->flush_flight(s)) {
/* NOTE: BIO_flush() does not generate an error */
SSLerr(SSL_F_STATEM_FLUSH, ERR_R_INTERNAL_ERROR);
return 0;
}
} else
#endif
if (BIO_flush(s->wbio) <= 0) {
return 0;
}
+149 -30
View File
@@ -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;
+17 -2
View File
@@ -48,9 +48,23 @@ int ssl3_do_write(SSL *s, int type)
{
int ret;
size_t written = 0;
#ifndef OPENSSL_NO_QUIC
if (SSL_IS_QUIC(s) && type == SSL3_RT_HANDSHAKE) {
ret = s->quic_method->add_handshake_data(s, s->quic_write_level,
(const uint8_t*)&s->init_buf->data[s->init_off],
s->init_num);
if (!ret) {
ret = -1;
/* QUIC can't sent anything out sice the above failed */
SSLerr(SSL_F_SSL3_DO_WRITE, SSL_R_INTERNAL_ERROR);
} else {
written = s->init_num;
}
} else
#endif
ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off],
s->init_num, &written);
ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off],
s->init_num, &written);
if (ret < 0)
return -1;
if (type == SSL3_RT_HANDSHAKE)
@@ -1183,6 +1197,7 @@ int tls_get_message_header(SSL *s, int *mt)
do {
while (s->init_num < SSL3_HM_HEADER_LENGTH) {
/* QUIC: either create a special ssl_read_bytes... or if/else this */
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type,
&p[s->init_num],
SSL3_HM_HEADER_LENGTH - s->init_num,
+25 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -93,6 +93,7 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst);
__owur int tls_get_message_header(SSL *s, int *mt);
__owur int tls_get_message_body(SSL *s, size_t *len);
__owur int dtls_get_message(SSL *s, int *mt, size_t *len);
__owur int quic_get_message(SSL *s, int *mt, size_t *len);
/* Message construction and processing functions */
__owur int tls_process_initial_server_flight(SSL *s);
@@ -153,6 +154,11 @@ __owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt);
__owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt);
MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt);
#ifndef OPENSSL_NO_GOST
/* These functions are used in GOST18 CKE, both for client and server */
int gost18_cke_cipher_nid(const SSL *s);
int gost_ukm(const SSL *s, unsigned char *dgst_buf);
#endif
/* Extension processing */
@@ -236,6 +242,10 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
size_t chainidx);
int tls_parse_ctos_post_handshake_auth(SSL *, PACKET *pkt, unsigned int context,
X509 *x, size_t chainidx);
#ifndef OPENSSL_NO_QUIC
int tls_parse_ctos_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context,
X509 *x, size_t chainidx);
#endif
EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
@@ -298,6 +308,11 @@ EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt,
size_t chainidx);
EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx);
#ifndef OPENSSL_NO_QUIC
EXT_RETURN tls_construct_stoc_quic_transport_params(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx);
#endif
/* Client Extension processing */
EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context,
@@ -369,6 +384,11 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx);
EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx);
#ifndef OPENSSL_NO_QUIC
EXT_RETURN tls_construct_ctos_quic_transport_params(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
size_t chainidx);
#endif
int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context,
X509 *x, size_t chainidx);
@@ -414,6 +434,10 @@ int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
size_t chainidx);
int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
size_t chainidx);
#ifndef OPENSSL_NO_QUIC
int tls_parse_stoc_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context,
X509 *x, size_t chainidx);
#endif
int tls_handle_alpn(SSL *s);
+109
View File
@@ -0,0 +1,109 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include "../ssl_local.h"
#include "statem_local.h"
#include "internal/cryptlib.h"
#ifdef OPENSSL_NO_QUIC
NON_EMPTY_TRANSLATION_UNIT
#else
int quic_get_message(SSL *s, int *mt, size_t *len)
{
size_t l;
QUIC_DATA *qd = s->quic_input_data_head;
uint8_t *p;
if (qd == NULL || (qd->length - qd->offset) != 0) {
s->rwstate = SSL_READING;
*len = 0;
return 0;
}
/* This is where we check for the proper level, not when data is given */
if (qd->level != s->quic_read_level) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_GET_MESSAGE,
SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED);
*len = 0;
return 0;
}
if (!BUF_MEM_grow_clean(s->init_buf, (int)qd->length)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_GET_MESSAGE,
ERR_R_BUF_LIB);
*len = 0;
return 0;
}
/* Copy buffered data */
memcpy(s->init_buf->data, (void*)(qd + 1), qd->length);
s->init_buf->length = qd->length;
s->quic_input_data_head = qd->next;
if (s->quic_input_data_head == NULL)
s->quic_input_data_tail = NULL;
OPENSSL_free(qd);
s->s3.tmp.message_type = *mt = *(s->init_buf->data);
p = (uint8_t*)s->init_buf->data + 1;
n2l3(p, l);
s->init_num = s->s3.tmp.message_size = *len = l;
s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
/* No CCS in QUIC/TLSv1.3? */
if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
SSL_F_QUIC_GET_MESSAGE,
SSL_R_CCS_RECEIVED_EARLY);
*len = 0;
return 0;
}
/*
* If receiving Finished, record MAC of prior handshake messages for
* Finished verification.
*/
if (*mt == SSL3_MT_FINISHED && !ssl3_take_mac(s)) {
/* SSLfatal() already called */
*len = 0;
return 0;
}
/*
* We defer feeding in the HRR until later. We'll do it as part of
* processing the message
* The TLsv1.3 handshake transcript stops at the ClientFinished
* message.
*/
#define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2)
/* KeyUpdate and NewSessionTicket do not need to be added */
if (!SSL_IS_TLS13(s) || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET
&& s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) {
if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO
|| s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE
|| memcmp(hrrrandom,
s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET,
SSL3_RANDOM_SIZE) != 0) {
if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
s->init_num + SSL3_HM_HEADER_LENGTH)) {
/* SSLfatal() already called */
*len = 0;
return 0;
}
}
}
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
(size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s,
s->msg_callback_arg);
return 1;
}
#endif
+94 -30
View File
@@ -77,7 +77,8 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt)
return 1;
}
break;
} else if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
} else if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED
&& !SSL_IS_QUIC(s)) {
if (mt == SSL3_MT_END_OF_EARLY_DATA) {
st->hand_state = TLS_ST_SR_END_OF_EARLY_DATA;
return 1;
@@ -2637,20 +2638,6 @@ int tls_construct_server_key_exchange(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(s->s3.tmp.pkey);
if (EVP_PKEY_id(s->s3.tmp.pkey) == EVP_PKEY_NONE) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, 0, ERR_R_EC_LIB);
goto err;
}
/* Encode the public key. */
encodedlen = EVP_PKEY_get1_tls_encodedpoint(s->s3.tmp.pkey,
&encodedPoint);
@@ -3235,21 +3222,6 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *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(ckey) == EVP_PKEY_NONE) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
ERR_R_INTERNAL_ERROR);
goto err;
}
if (EVP_PKEY_set1_tls_encodedpoint(ckey, data, i) == 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
ERR_R_EC_LIB);
@@ -3431,6 +3403,93 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt)
#endif
}
static int tls_process_cke_gost18(SSL *s, PACKET *pkt)
{
#ifndef OPENSSL_NO_GOST
unsigned char rnd_dgst[32];
EVP_PKEY_CTX *pkey_ctx = NULL;
EVP_PKEY *pk = NULL;
unsigned char premaster_secret[32];
const unsigned char *start = NULL;
size_t outlen = 32, inlen = 0;
int ret = 0;
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;
}
/* Get our certificate private key */
pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey != NULL ?
s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey :
s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey;
if (pk == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18,
SSL_R_BAD_HANDSHAKE_STATE);
goto err;
}
pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pk, s->ctx->propq);
if (pkey_ctx == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18,
ERR_R_MALLOC_FAILURE);
goto err;
}
if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18,
ERR_R_INTERNAL_ERROR);
goto err;
}
/* Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code depending on size */
if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_DECRYPT,
EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) < 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18,
SSL_R_LIBRARY_BUG);
goto err;
}
if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_DECRYPT,
EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) < 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18,
SSL_R_LIBRARY_BUG);
goto err;
}
inlen = PACKET_remaining(pkt);
start = PACKET_data(pkt);
if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18,
SSL_R_DECRYPTION_FAILED);
goto err;
}
/* Generate master secret */
if (!ssl_generate_master_secret(s, premaster_secret,
sizeof(premaster_secret), 0)) {
/* SSLfatal() already called */
goto err;
}
ret = 1;
err:
EVP_PKEY_CTX_free(pkey_ctx);
return ret;
#else
/* Should never happen */
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18,
ERR_R_INTERNAL_ERROR);
return 0;
#endif
}
MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
{
unsigned long alg_k;
@@ -3481,6 +3540,11 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
/* SSLfatal() already called */
goto err;
}
} else if (alg_k & SSL_kGOST18) {
if (!tls_process_cke_gost18(s, pkt)) {
/* SSLfatal() already called */
goto err;
}
} else {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,