Latest update (add quic)
This commit is contained in:
+2
-1
@@ -27,5 +27,6 @@ SOURCE[../libssl]=\
|
||||
ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \
|
||||
bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \
|
||||
record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
|
||||
statem/statem.c record/ssl3_record_tls13.c
|
||||
statem/statem.c record/ssl3_record_tls13.c \
|
||||
ssl_quic.c statem/statem_quic.c
|
||||
DEFINE[../libssl]=$AESDEF
|
||||
@@ -303,8 +303,13 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold,
|
||||
if (ret <= 0
|
||||
&& !BIO_should_retry(s->rbio)
|
||||
&& BIO_eof(s->rbio)) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_READ_N,
|
||||
SSL_R_UNEXPECTED_EOF_WHILE_READING);
|
||||
if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) {
|
||||
SSL_set_shutdown(s, SSL_RECEIVED_SHUTDOWN);
|
||||
s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY;
|
||||
} else {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_READ_N,
|
||||
SSL_R_UNEXPECTED_EOF_WHILE_READING);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_N,
|
||||
@@ -940,6 +945,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
}
|
||||
|
||||
if (SSL_TREAT_AS_TLS13(s)
|
||||
&& !BIO_get_ktls_send(s->wbio)
|
||||
&& s->enc_write_ctx != NULL
|
||||
&& (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS
|
||||
|| type != SSL3_RT_ALERT)) {
|
||||
|
||||
@@ -977,6 +977,8 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
|
||||
unsigned char padval;
|
||||
int imac_size;
|
||||
const EVP_CIPHER *enc;
|
||||
int tlstree_enc = sending ? (s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE)
|
||||
: (s->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE);
|
||||
|
||||
if (n_recs == 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC,
|
||||
@@ -1156,6 +1158,27 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
|
||||
}
|
||||
}
|
||||
|
||||
if (!SSL_IS_DTLS(s) && tlstree_enc) {
|
||||
unsigned char *seq;
|
||||
int decrement_seq = 0;
|
||||
|
||||
/*
|
||||
* When sending, seq is incremented after MAC calculation.
|
||||
* So if we are in ETM mode, we use seq 'as is' in the ctrl-function.
|
||||
* Otherwise we have to decrease it in the implementation
|
||||
*/
|
||||
if (sending && !SSL_WRITE_ETM(s))
|
||||
decrement_seq = 1;
|
||||
|
||||
seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer)
|
||||
: RECORD_LAYER_get_read_sequence(&s->rlayer);
|
||||
if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, seq) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO(size_t): Convert this call */
|
||||
tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input,
|
||||
(unsigned int)reclen[0]);
|
||||
@@ -1319,8 +1342,10 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
|
||||
int i;
|
||||
EVP_MD_CTX *hmac = NULL, *mac_ctx;
|
||||
unsigned char header[13];
|
||||
int stream_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
|
||||
: (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
|
||||
int stream_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
|
||||
: (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM);
|
||||
int tlstree_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE)
|
||||
: (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE);
|
||||
int t;
|
||||
|
||||
if (sending) {
|
||||
@@ -1348,6 +1373,11 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
|
||||
mac_ctx = hmac;
|
||||
}
|
||||
|
||||
if (!SSL_IS_DTLS(ssl) && tlstree_mac && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) {
|
||||
EVP_MD_CTX_free(hmac);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (SSL_IS_DTLS(ssl)) {
|
||||
unsigned char dtlsseq[8], *p = dtlsseq;
|
||||
|
||||
|
||||
+5
-3
@@ -17,7 +17,7 @@
|
||||
|
||||
static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
|
||||
{
|
||||
EVP_MD *md5;
|
||||
EVP_MD *md5, *sha1;
|
||||
EVP_MD_CTX *m5;
|
||||
EVP_MD_CTX *s1;
|
||||
unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
|
||||
@@ -30,9 +30,10 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
|
||||
#endif
|
||||
k = 0;
|
||||
md5 = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_MD5, "-fips");
|
||||
sha1 = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA1, "-fips");
|
||||
m5 = EVP_MD_CTX_new();
|
||||
s1 = EVP_MD_CTX_new();
|
||||
if (md5 == NULL || m5 == NULL || s1 == NULL) {
|
||||
if (md5 == NULL || sha1 == NULL || m5 == NULL || s1 == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
@@ -49,7 +50,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
|
||||
for (j = 0; j < k; j++)
|
||||
buf[j] = c;
|
||||
c++;
|
||||
if (!EVP_DigestInit_ex(s1, EVP_sha1(), NULL)
|
||||
if (!EVP_DigestInit_ex(s1, sha1, NULL)
|
||||
|| !EVP_DigestUpdate(s1, buf, k)
|
||||
|| !EVP_DigestUpdate(s1, s->session->master_key,
|
||||
s->session->master_key_length)
|
||||
@@ -87,6 +88,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
|
||||
EVP_MD_CTX_free(m5);
|
||||
EVP_MD_CTX_free(s1);
|
||||
EVP_MD_free(md5);
|
||||
EVP_MD_free(sha1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+43
-5
@@ -2741,6 +2741,38 @@ static SSL_CIPHER ssl3_ciphers[] = {
|
||||
0,
|
||||
0,
|
||||
},
|
||||
{
|
||||
1,
|
||||
"GOST2012-KUZNYECHIK-KUZNYECHIKOMAC",
|
||||
NULL,
|
||||
0x0300C100,
|
||||
SSL_kGOST18,
|
||||
SSL_aGOST12,
|
||||
SSL_KUZNYECHIK,
|
||||
SSL_KUZNYECHIKOMAC,
|
||||
TLS1_2_VERSION, TLS1_2_VERSION,
|
||||
0, 0,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
{
|
||||
1,
|
||||
"GOST2012-MAGMA-MAGMAOMAC",
|
||||
NULL,
|
||||
0x0300C101,
|
||||
SSL_kGOST18,
|
||||
SSL_aGOST12,
|
||||
SSL_MAGMA,
|
||||
SSL_MAGMAOMAC,
|
||||
TLS1_2_VERSION, TLS1_2_VERSION,
|
||||
0, 0,
|
||||
SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
#endif /* OPENSSL_NO_GOST */
|
||||
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
@@ -4427,11 +4459,17 @@ int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt)
|
||||
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
if (s->version >= TLS1_VERSION && (alg_k & SSL_kGOST))
|
||||
return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN)
|
||||
&& WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN)
|
||||
&& WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN)
|
||||
&& WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_SIGN)
|
||||
&& WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_512_SIGN);
|
||||
if (!WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN)
|
||||
|| !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN)
|
||||
|| !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN)
|
||||
|| !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_SIGN)
|
||||
|| !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_512_SIGN))
|
||||
return 0;
|
||||
|
||||
if (s->version >= TLS1_2_VERSION && (alg_k & SSL_kGOST18))
|
||||
if (!WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN)
|
||||
|| !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if ((s->version == SSL3_VERSION) && (alg_k & SSL_kDHE)) {
|
||||
|
||||
+11
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-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
|
||||
@@ -79,6 +79,16 @@ int ssl3_dispatch_alert(SSL *s)
|
||||
|
||||
s->s3.alert_dispatch = 0;
|
||||
alertlen = 2;
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (SSL_IS_QUIC(s)) {
|
||||
if (!s->quic_method->send_alert(s, s->quic_write_level,
|
||||
s->s3.send_alert[1])) {
|
||||
SSLerr(SSL_F_SSL3_DISPATCH_ALERT, SSL_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
i = 1;
|
||||
} else
|
||||
#endif
|
||||
i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3.send_alert[0], &alertlen, 1, 0,
|
||||
&written);
|
||||
if (i <= 0) {
|
||||
|
||||
+80
-13
@@ -47,8 +47,10 @@ DEFINE_STACK_OF_CONST(SSL_CIPHER)
|
||||
#define SSL_ENC_CHACHA_IDX 19
|
||||
#define SSL_ENC_ARIA128GCM_IDX 20
|
||||
#define SSL_ENC_ARIA256GCM_IDX 21
|
||||
#define SSL_ENC_CHACHA20_D_IDX 22
|
||||
#define SSL_ENC_NUM_IDX 23
|
||||
#define SSL_ENC_MAGMA_IDX 22
|
||||
#define SSL_ENC_KUZNYECHIK_IDX 23
|
||||
#define SSL_ENC_CHACHA20_D_IDX 24
|
||||
#define SSL_ENC_NUM_IDX 25
|
||||
|
||||
/* NB: make sure indices in these tables match values above */
|
||||
|
||||
@@ -81,7 +83,9 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = {
|
||||
{SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */
|
||||
{SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */
|
||||
{SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */
|
||||
{SSL_CHACHA20POLY1305_D, NID_chacha20_poly1305_draft}, /* SSL_ENC_CHACHA20POLY1305_IDX 22 */
|
||||
{SSL_MAGMA, NID_magma_ctr_acpkm}, /* SSL_ENC_MAGMA_IDX 22 */
|
||||
{SSL_KUZNYECHIK, NID_kuznyechik_ctr_acpkm}, /* SSL_ENC_KUZNYECHIK_IDX 23 */
|
||||
{SSL_CHACHA20POLY1305_D, NID_chacha20_poly1305_draft}, /* SSL_ENC_CHACHA20POLY1305_IDX 24 */
|
||||
};
|
||||
|
||||
static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX];
|
||||
@@ -116,7 +120,9 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
|
||||
{SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */
|
||||
{0, NID_md5_sha1}, /* SSL_MD_MD5_SHA1_IDX 9 */
|
||||
{0, NID_sha224}, /* SSL_MD_SHA224_IDX 10 */
|
||||
{0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */
|
||||
{0, NID_sha512}, /* SSL_MD_SHA512_IDX 11 */
|
||||
{SSL_MAGMAOMAC, NID_magma_mac}, /* sSL_MD_MAGMAOMAC_IDX */
|
||||
{SSL_KUZNYECHIKOMAC, NID_kuznyechik_mac} /* SSL_MD_KUZNYECHIKOMAC_IDX */
|
||||
};
|
||||
|
||||
static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = {
|
||||
@@ -134,6 +140,7 @@ static const ssl_cipher_table ssl_cipher_table_kx[] = {
|
||||
{SSL_kPSK, NID_kx_psk},
|
||||
{SSL_kSRP, NID_kx_srp},
|
||||
{SSL_kGOST, NID_kx_gost},
|
||||
{SSL_kGOST18, NID_kx_gost18},
|
||||
{SSL_kANY, NID_kx_any}
|
||||
};
|
||||
|
||||
@@ -177,8 +184,8 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = {
|
||||
EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef,
|
||||
/* GOST2012_512 */
|
||||
EVP_PKEY_HMAC,
|
||||
/* MD5/SHA1, SHA224, SHA512 */
|
||||
NID_undef, NID_undef, NID_undef
|
||||
/* MD5/SHA1, SHA224, SHA512, MAGMAOMAC, KUZNYECHIKOMAC */
|
||||
NID_undef, NID_undef, NID_undef, NID_undef, NID_undef
|
||||
};
|
||||
|
||||
static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX];
|
||||
@@ -235,6 +242,7 @@ static const SSL_CIPHER cipher_aliases[] = {
|
||||
{0, SSL_TXT_kDHEPSK, NULL, 0, SSL_kDHEPSK},
|
||||
{0, SSL_TXT_kSRP, NULL, 0, SSL_kSRP},
|
||||
{0, SSL_TXT_kGOST, NULL, 0, SSL_kGOST},
|
||||
{0, SSL_TXT_kGOST18, NULL, 0, SSL_kGOST18},
|
||||
|
||||
/* server authentication aliases */
|
||||
{0, SSL_TXT_aRSA, NULL, 0, 0, SSL_aRSA},
|
||||
@@ -268,7 +276,8 @@ static const SSL_CIPHER cipher_aliases[] = {
|
||||
{0, SSL_TXT_IDEA, NULL, 0, 0, 0, SSL_IDEA},
|
||||
{0, SSL_TXT_SEED, NULL, 0, 0, 0, SSL_SEED},
|
||||
{0, SSL_TXT_eNULL, NULL, 0, 0, 0, SSL_eNULL},
|
||||
{0, SSL_TXT_GOST, NULL, 0, 0, 0, SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12},
|
||||
{0, SSL_TXT_GOST, NULL, 0, 0, 0,
|
||||
SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12 | SSL_MAGMA | SSL_KUZNYECHIK},
|
||||
{0, SSL_TXT_AES128, NULL, 0, 0, 0,
|
||||
SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8},
|
||||
{0, SSL_TXT_AES256, NULL, 0, 0, 0,
|
||||
@@ -283,13 +292,13 @@ static const SSL_CIPHER cipher_aliases[] = {
|
||||
{0, SSL_TXT_CAMELLIA, NULL, 0, 0, 0, SSL_CAMELLIA},
|
||||
{0, SSL_TXT_CHACHA20, NULL, 0, 0, 0, SSL_CHACHA20},
|
||||
{0, SSL_TXT_CHACHA20_D, NULL, 0, 0, 0, SSL_CHACHA20POLY1305_D},
|
||||
|
||||
{0, SSL_TXT_GOST2012_GOST8912_GOST8912, NULL, 0, 0, 0, SSL_eGOST2814789CNT12},
|
||||
|
||||
{0, SSL_TXT_ARIA, NULL, 0, 0, 0, SSL_ARIA},
|
||||
{0, SSL_TXT_ARIA_GCM, NULL, 0, 0, 0, SSL_ARIA128GCM | SSL_ARIA256GCM},
|
||||
{0, SSL_TXT_ARIA128, NULL, 0, 0, 0, SSL_ARIA128GCM},
|
||||
{0, SSL_TXT_ARIA256, NULL, 0, 0, 0, SSL_ARIA256GCM},
|
||||
{0, SSL_TXT_CBC, NULL, 0, 0, 0, SSL_CBC},
|
||||
|
||||
/* MAC aliases */
|
||||
{0, SSL_TXT_MD5, NULL, 0, 0, 0, 0, SSL_MD5},
|
||||
@@ -430,24 +439,38 @@ int ssl_load_ciphers(void)
|
||||
* Check for presence of GOST 34.10 algorithms, and if they are not
|
||||
* present, disable appropriate auth and key exchange
|
||||
*/
|
||||
ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
|
||||
ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id(SN_id_Gost28147_89_MAC);
|
||||
if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX])
|
||||
ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32;
|
||||
else
|
||||
disabled_mac_mask |= SSL_GOST89MAC;
|
||||
|
||||
ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] =
|
||||
get_optional_pkey_id("gost-mac-12");
|
||||
get_optional_pkey_id(SN_gost_mac_12);
|
||||
if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX])
|
||||
ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
|
||||
else
|
||||
disabled_mac_mask |= SSL_GOST89MAC12;
|
||||
|
||||
if (!get_optional_pkey_id("gost2001"))
|
||||
ssl_mac_pkey_id[SSL_MD_MAGMAOMAC_IDX] =
|
||||
get_optional_pkey_id(SN_magma_mac);
|
||||
if (ssl_mac_pkey_id[SSL_MD_MAGMAOMAC_IDX])
|
||||
ssl_mac_secret_size[SSL_MD_MAGMAOMAC_IDX] = 32;
|
||||
else
|
||||
disabled_mac_mask |= SSL_MAGMAOMAC;
|
||||
|
||||
ssl_mac_pkey_id[SSL_MD_KUZNYECHIKOMAC_IDX] =
|
||||
get_optional_pkey_id(SN_kuznyechik_mac);
|
||||
if (ssl_mac_pkey_id[SSL_MD_KUZNYECHIKOMAC_IDX])
|
||||
ssl_mac_secret_size[SSL_MD_KUZNYECHIKOMAC_IDX] = 32;
|
||||
else
|
||||
disabled_mac_mask |= SSL_KUZNYECHIKOMAC;
|
||||
|
||||
if (!get_optional_pkey_id(SN_id_GostR3410_2001))
|
||||
disabled_auth_mask |= SSL_aGOST01 | SSL_aGOST12;
|
||||
if (!get_optional_pkey_id("gost2012_256"))
|
||||
if (!get_optional_pkey_id(SN_id_GostR3410_2012_256))
|
||||
disabled_auth_mask |= SSL_aGOST12;
|
||||
if (!get_optional_pkey_id("gost2012_512"))
|
||||
if (!get_optional_pkey_id(SN_id_GostR3410_2012_512))
|
||||
disabled_auth_mask |= SSL_aGOST12;
|
||||
/*
|
||||
* Disable GOST key exchange if no GOST signature algs are available *
|
||||
@@ -456,6 +479,9 @@ int ssl_load_ciphers(void)
|
||||
(SSL_aGOST01 | SSL_aGOST12))
|
||||
disabled_mkey_mask |= SSL_kGOST;
|
||||
|
||||
if ((disabled_auth_mask & SSL_aGOST12) == SSL_aGOST12)
|
||||
disabled_mkey_mask |= SSL_kGOST18;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1778,6 +1804,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
|
||||
case SSL_kGOST:
|
||||
kx = "GOST";
|
||||
break;
|
||||
case SSL_kGOST18:
|
||||
kx = "GOST18";
|
||||
break;
|
||||
case SSL_kANY:
|
||||
kx = "any";
|
||||
break;
|
||||
@@ -1881,6 +1910,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
|
||||
case SSL_eGOST2814789CNT12:
|
||||
enc = "GOST89(256)";
|
||||
break;
|
||||
case SSL_MAGMA:
|
||||
enc = "MAGMA";
|
||||
break;
|
||||
case SSL_KUZNYECHIK:
|
||||
enc = "KUZNYECHIK";
|
||||
break;
|
||||
case SSL_CHACHA20POLY1305:
|
||||
enc = "CHACHA20/POLY1305(256)";
|
||||
break;
|
||||
@@ -2276,3 +2311,35 @@ const char *OSSL_default_ciphersuites(void)
|
||||
#endif
|
||||
"TLS_AES_128_GCM_SHA256";
|
||||
}
|
||||
|
||||
int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *c)
|
||||
{
|
||||
switch (c->algorithm2 & (0xFF << TLS1_PRF_DGST_SHIFT)) {
|
||||
default:
|
||||
break;
|
||||
case TLS1_PRF_SHA1_MD5: /* TLS1_PRF */
|
||||
return NID_md5_sha1;
|
||||
case TLS1_PRF_SHA256:
|
||||
return NID_sha256;
|
||||
case TLS1_PRF_SHA384:
|
||||
return NID_sha384;
|
||||
case TLS1_PRF_GOST94:
|
||||
return NID_id_GostR3411_94_prf;
|
||||
case TLS1_PRF_GOST12_256:
|
||||
return NID_id_GostR3411_2012_256;
|
||||
case TLS1_PRF_GOST12_512:
|
||||
return NID_id_GostR3411_2012_512;
|
||||
}
|
||||
/* TLSv1.3 ciphers don't specify separate PRF */
|
||||
switch (c->algorithm2 & SSL_HANDSHAKE_MAC_MASK) {
|
||||
default:
|
||||
break;
|
||||
case SSL_HANDSHAKE_MAC_MD5_SHA1: /* SSL_HANDSHAKE_MAC_DEFAULT */
|
||||
return NID_md5_sha1;
|
||||
case SSL_HANDSHAKE_MAC_SHA256:
|
||||
return NID_sha256;
|
||||
case SSL_HANDSHAKE_MAC_SHA384:
|
||||
return NID_sha384;
|
||||
}
|
||||
return NID_undef;
|
||||
}
|
||||
@@ -195,6 +195,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EXTMS), "inconsistent extms"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INSUFFICIENT_SECURITY),
|
||||
"insufficient security"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INTERNAL_ERROR), "internal error"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_ALERT), "invalid alert"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CCS_MESSAGE),
|
||||
"invalid ccs message"},
|
||||
@@ -543,6 +544,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CIPHER_RETURNED),
|
||||
"wrong cipher returned"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CURVE), "wrong curve"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED),
|
||||
"wrong encryption level received"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_LENGTH),
|
||||
"wrong signature length"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_SIZE),
|
||||
|
||||
+51
-7
@@ -852,6 +852,10 @@ SSL *SSL_new(SSL_CTX *ctx)
|
||||
|
||||
s->job = NULL;
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
s->quic_method = ctx->quic_method;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_CT
|
||||
if (!SSL_set_ct_validation_callback(s, ctx->ct_validation_callback,
|
||||
ctx->ct_validation_callback_arg))
|
||||
@@ -1287,6 +1291,18 @@ void SSL_free(SSL *s)
|
||||
OPENSSL_free(s->pha_context);
|
||||
EVP_MD_CTX_free(s->pha_dgst);
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
OPENSSL_free(s->ext.quic_transport_params);
|
||||
OPENSSL_free(s->ext.peer_quic_transport_params);
|
||||
while (s->quic_input_data_head != NULL) {
|
||||
QUIC_DATA *qd;
|
||||
|
||||
qd = s->quic_input_data_head;
|
||||
s->quic_input_data_head = qd->next;
|
||||
OPENSSL_free(qd);
|
||||
}
|
||||
#endif
|
||||
|
||||
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
|
||||
sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free);
|
||||
|
||||
@@ -1863,6 +1879,12 @@ static int ssl_io_intern(void *vargs)
|
||||
|
||||
int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
|
||||
{
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (SSL_IS_QUIC(s)) {
|
||||
SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (s->handshake_func == NULL) {
|
||||
SSLerr(SSL_F_SSL_READ_INTERNAL, SSL_R_UNINITIALIZED);
|
||||
return -1;
|
||||
@@ -1995,6 +2017,12 @@ int SSL_get_early_data_status(const SSL *s)
|
||||
|
||||
static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
|
||||
{
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (SSL_IS_QUIC(s)) {
|
||||
SSLerr(SSL_F_SSL_PEEK_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (s->handshake_func == NULL) {
|
||||
SSLerr(SSL_F_SSL_PEEK_INTERNAL, SSL_R_UNINITIALIZED);
|
||||
return -1;
|
||||
@@ -2055,6 +2083,12 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes)
|
||||
|
||||
int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
|
||||
{
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (SSL_IS_QUIC(s)) {
|
||||
SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (s->handshake_func == NULL) {
|
||||
SSLerr(SSL_F_SSL_WRITE_INTERNAL, SSL_R_UNINITIALIZED);
|
||||
return -1;
|
||||
@@ -3544,11 +3578,11 @@ void ssl_set_masks(SSL *s)
|
||||
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) {
|
||||
mask_k |= SSL_kGOST;
|
||||
mask_k |= SSL_kGOST | SSL_kGOST18;
|
||||
mask_a |= SSL_aGOST12;
|
||||
}
|
||||
if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) {
|
||||
mask_k |= SSL_kGOST;
|
||||
mask_k |= SSL_kGOST | SSL_kGOST18;
|
||||
mask_a |= SSL_aGOST12;
|
||||
}
|
||||
if (ssl_has_cert(s, SSL_PKEY_GOST01)) {
|
||||
@@ -3782,6 +3816,11 @@ int SSL_get_error(const SSL *s, int i)
|
||||
}
|
||||
|
||||
if (SSL_want_read(s)) {
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (SSL_IS_QUIC(s)) {
|
||||
return SSL_ERROR_WANT_READ;
|
||||
}
|
||||
#endif
|
||||
bio = SSL_get_rbio(s);
|
||||
if (BIO_should_read(bio))
|
||||
return SSL_ERROR_WANT_READ;
|
||||
@@ -4162,7 +4201,7 @@ EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx)
|
||||
|
||||
const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
|
||||
{
|
||||
if ((s->session != NULL) && (s->session->cipher != NULL))
|
||||
if (s->session != NULL)
|
||||
return s->session->cipher;
|
||||
return NULL;
|
||||
}
|
||||
@@ -4390,7 +4429,6 @@ int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore)
|
||||
return X509_STORE_load_store(ctx->cert_store, CAstore);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
|
||||
const char *CApath)
|
||||
{
|
||||
@@ -4402,7 +4440,6 @@ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SSL_set_info_callback(SSL *ssl,
|
||||
void (*cb) (const SSL *ssl, int type, int val))
|
||||
@@ -4692,11 +4729,18 @@ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SSL_set_record_padding_callback(SSL *ssl,
|
||||
int SSL_set_record_padding_callback(SSL *ssl,
|
||||
size_t (*cb) (SSL *ssl, int type,
|
||||
size_t len, void *arg))
|
||||
{
|
||||
ssl->record_padding_cb = cb;
|
||||
BIO *b;
|
||||
|
||||
b = SSL_get_wbio(ssl);
|
||||
if (b == NULL || !BIO_get_ktls_send(b)) {
|
||||
ssl->record_padding_cb = cb;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg)
|
||||
|
||||
+60
-2
@@ -180,6 +180,8 @@
|
||||
# define SSL_kRSAPSK 0x00000040U
|
||||
# define SSL_kECDHEPSK 0x00000080U
|
||||
# define SSL_kDHEPSK 0x00000100U
|
||||
/* GOST KDF key exchange, draft-smyshlyaev-tls12-gost-suites */
|
||||
# define SSL_kGOST18 0x00000200U
|
||||
|
||||
/* all PSK */
|
||||
|
||||
@@ -234,7 +236,9 @@
|
||||
# define SSL_CHACHA20POLY1305 0x00080000U
|
||||
# define SSL_ARIA128GCM 0x00100000U
|
||||
# define SSL_ARIA256GCM 0x00200000U
|
||||
# define SSL_CHACHA20POLY1305_D 0x00400000U
|
||||
# define SSL_MAGMA 0x00400000U
|
||||
# define SSL_KUZNYECHIK 0x00800000U
|
||||
# define SSL_CHACHA20POLY1305_D 0x01000000U
|
||||
|
||||
# define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM)
|
||||
# define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8)
|
||||
@@ -243,6 +247,9 @@
|
||||
# define SSL_CHACHA20 (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_D)
|
||||
# define SSL_ARIAGCM (SSL_ARIA128GCM | SSL_ARIA256GCM)
|
||||
# define SSL_ARIA (SSL_ARIAGCM)
|
||||
# define SSL_CBC (SSL_DES | SSL_3DES | SSL_RC2 | SSL_IDEA \
|
||||
| SSL_AES128 | SSL_AES256 | SSL_CAMELLIA128 \
|
||||
| SSL_CAMELLIA256 | SSL_SEED)
|
||||
|
||||
/* Bits for algorithm_mac (symmetric authentication) */
|
||||
|
||||
@@ -257,6 +264,8 @@
|
||||
# define SSL_GOST12_256 0x00000080U
|
||||
# define SSL_GOST89MAC12 0x00000100U
|
||||
# define SSL_GOST12_512 0x00000200U
|
||||
# define SSL_MAGMAOMAC 0x00000400U
|
||||
# define SSL_KUZNYECHIKOMAC 0x00000800U
|
||||
|
||||
/*
|
||||
* When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make
|
||||
@@ -275,7 +284,9 @@
|
||||
# define SSL_MD_MD5_SHA1_IDX 9
|
||||
# define SSL_MD_SHA224_IDX 10
|
||||
# define SSL_MD_SHA512_IDX 11
|
||||
# define SSL_MAX_DIGEST 12
|
||||
# define SSL_MD_MAGMAOMAC_IDX 12
|
||||
# define SSL_MD_KUZNYECHIKOMAC_IDX 13
|
||||
# define SSL_MAX_DIGEST 14
|
||||
|
||||
/* Bits for algorithm2 (handshake digests and other extra flags) */
|
||||
|
||||
@@ -304,6 +315,11 @@
|
||||
* goes into algorithm2)
|
||||
*/
|
||||
# define TLS1_STREAM_MAC 0x10000
|
||||
/*
|
||||
* TLSTREE cipher/mac key derivation from draft-smyshlyaev-tls12-gost-suites
|
||||
* (currently this also goes into algorithm2)
|
||||
*/
|
||||
# define TLS1_TLSTREE 0x20000
|
||||
|
||||
# define SSL_STRONG_MASK 0x0000001FU
|
||||
# define SSL_DEFAULT_MASK 0X00000020U
|
||||
@@ -320,6 +336,13 @@
|
||||
/* Flag used on OpenSSL ciphersuite ids to indicate they are for SSLv3+ */
|
||||
# define SSL3_CK_CIPHERSUITE_FLAG 0x03000000
|
||||
|
||||
/* Check if an SSL structure is using QUIC (which uses TLSv1.3) */
|
||||
# ifndef OPENSSL_NO_QUIC
|
||||
# define SSL_IS_QUIC(s) (s->quic_method != NULL)
|
||||
# else
|
||||
# define SSL_IS_QUIC(s) 0
|
||||
# endif
|
||||
|
||||
/* Check if an SSL structure is using DTLS */
|
||||
# define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)
|
||||
|
||||
@@ -720,6 +743,7 @@ typedef enum tlsext_index_en {
|
||||
TLSEXT_IDX_cryptopro_bug,
|
||||
TLSEXT_IDX_early_data,
|
||||
TLSEXT_IDX_certificate_authorities,
|
||||
TLSEXT_IDX_quic_transport_params,
|
||||
TLSEXT_IDX_padding,
|
||||
TLSEXT_IDX_psk,
|
||||
/* Dummy index - must always be the last entry */
|
||||
@@ -1147,11 +1171,26 @@ struct ssl_ctx_st {
|
||||
SSL_async_callback_fn async_cb;
|
||||
void *async_cb_arg;
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
const SSL_QUIC_METHOD *quic_method;
|
||||
#endif
|
||||
|
||||
char *propq;
|
||||
};
|
||||
|
||||
typedef struct cert_pkey_st CERT_PKEY;
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
struct quic_data_st {
|
||||
struct quic_data_st *next;
|
||||
OSSL_ENCRYPTION_LEVEL level;
|
||||
size_t offset;
|
||||
size_t length;
|
||||
};
|
||||
typedef struct quic_data_st QUIC_DATA;
|
||||
int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level);
|
||||
#endif
|
||||
|
||||
struct ssl_st {
|
||||
/*
|
||||
* protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
|
||||
@@ -1411,6 +1450,11 @@ struct ssl_st {
|
||||
unsigned char handshake_traffic_hash[EVP_MAX_MD_SIZE];
|
||||
unsigned char client_app_traffic_secret[EVP_MAX_MD_SIZE];
|
||||
unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE];
|
||||
# ifndef OPENSSL_NO_QUIC
|
||||
unsigned char client_hand_traffic_secret[EVP_MAX_MD_SIZE];
|
||||
unsigned char server_hand_traffic_secret[EVP_MAX_MD_SIZE];
|
||||
unsigned char client_early_traffic_secret[EVP_MAX_MD_SIZE];
|
||||
# endif
|
||||
unsigned char exporter_master_secret[EVP_MAX_MD_SIZE];
|
||||
unsigned char early_exporter_master_secret[EVP_MAX_MD_SIZE];
|
||||
EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
|
||||
@@ -1625,8 +1669,22 @@ struct ssl_st {
|
||||
* selected.
|
||||
*/
|
||||
int tick_identity;
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
uint8_t *quic_transport_params;
|
||||
size_t quic_transport_params_len;
|
||||
uint8_t *peer_quic_transport_params;
|
||||
size_t peer_quic_transport_params_len;
|
||||
#endif
|
||||
} ext;
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
OSSL_ENCRYPTION_LEVEL quic_read_level;
|
||||
OSSL_ENCRYPTION_LEVEL quic_write_level;
|
||||
QUIC_DATA *quic_input_data_head;
|
||||
QUIC_DATA *quic_input_data_tail;
|
||||
const SSL_QUIC_METHOD *quic_method;
|
||||
#endif
|
||||
/*
|
||||
* Parsed form of the ClientHello, kept around across client_hello_cb
|
||||
* calls.
|
||||
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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 "internal/cryptlib.h"
|
||||
#include "internal/refcount.h"
|
||||
|
||||
#ifdef OPENSSL_NO_QUIC
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params,
|
||||
size_t params_len)
|
||||
{
|
||||
uint8_t *tmp;
|
||||
|
||||
if (params == NULL || params_len == 0) {
|
||||
tmp = NULL;
|
||||
params_len = 0;
|
||||
} else {
|
||||
tmp = OPENSSL_memdup(params, params_len);
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPENSSL_free(ssl->ext.quic_transport_params);
|
||||
ssl->ext.quic_transport_params = tmp;
|
||||
ssl->ext.quic_transport_params_len = params_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SSL_get_peer_quic_transport_params(const SSL *ssl,
|
||||
const uint8_t **out_params,
|
||||
size_t *out_params_len)
|
||||
{
|
||||
*out_params = ssl->ext.peer_quic_transport_params;
|
||||
*out_params_len = ssl->ext.peer_quic_transport_params_len;
|
||||
}
|
||||
|
||||
size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, OSSL_ENCRYPTION_LEVEL level)
|
||||
{
|
||||
/*
|
||||
* Limits flights to 16K by default when there are no large
|
||||
* (certificate-carrying) messages.
|
||||
*/
|
||||
static const size_t DEFAULT_FLIGHT_LIMIT = 16384;
|
||||
|
||||
switch (level) {
|
||||
case ssl_encryption_initial:
|
||||
return DEFAULT_FLIGHT_LIMIT;
|
||||
case ssl_encryption_early_data:
|
||||
/* QUIC does not send EndOfEarlyData. */
|
||||
return 0;
|
||||
case ssl_encryption_handshake:
|
||||
if (ssl->server) {
|
||||
/*
|
||||
* Servers may receive Certificate message if configured to request
|
||||
* client certificates.
|
||||
*/
|
||||
if ((ssl->verify_mode & SSL_VERIFY_PEER)
|
||||
&& ssl->max_cert_list > DEFAULT_FLIGHT_LIMIT)
|
||||
return ssl->max_cert_list;
|
||||
} else {
|
||||
/*
|
||||
* Clients may receive both Certificate message and a CertificateRequest
|
||||
* message.
|
||||
*/
|
||||
if (2*ssl->max_cert_list > DEFAULT_FLIGHT_LIMIT)
|
||||
return 2 * ssl->max_cert_list;
|
||||
}
|
||||
return DEFAULT_FLIGHT_LIMIT;
|
||||
case ssl_encryption_application:
|
||||
return DEFAULT_FLIGHT_LIMIT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSSL_ENCRYPTION_LEVEL SSL_quic_read_level(const SSL *ssl)
|
||||
{
|
||||
return ssl->quic_read_level;
|
||||
}
|
||||
|
||||
OSSL_ENCRYPTION_LEVEL SSL_quic_write_level(const SSL *ssl)
|
||||
{
|
||||
return ssl->quic_write_level;
|
||||
}
|
||||
|
||||
int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level,
|
||||
const uint8_t *data, size_t len)
|
||||
{
|
||||
size_t l;
|
||||
|
||||
if (!SSL_IS_QUIC(ssl)) {
|
||||
SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Level can be different than the current read, but not less */
|
||||
if (level < ssl->quic_read_level
|
||||
|| (ssl->quic_input_data_tail != NULL && level < ssl->quic_input_data_tail->level)) {
|
||||
SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Split the QUIC messages up, if necessary */
|
||||
while (len > 0) {
|
||||
QUIC_DATA *qd;
|
||||
const uint8_t *p = data + 1;
|
||||
|
||||
/* Check for an incomplete block */
|
||||
qd = ssl->quic_input_data_tail;
|
||||
if (qd != NULL) {
|
||||
l = qd->length - qd->offset;
|
||||
if (l != 0) {
|
||||
/* we still need to copy `l` bytes into the last data block */
|
||||
if (l > len)
|
||||
l = len;
|
||||
memcpy((char*)(qd+1) + qd->offset, data, l);
|
||||
qd->offset += l;
|
||||
len -= l;
|
||||
data += l;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
n2l3(p, l);
|
||||
l += SSL3_HM_HEADER_LENGTH;
|
||||
|
||||
qd = OPENSSL_zalloc(sizeof(QUIC_DATA) + l);
|
||||
if (qd == NULL) {
|
||||
SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qd->next = NULL;
|
||||
qd->length = l;
|
||||
qd->level = level;
|
||||
/* partial data received? */
|
||||
if (l > len)
|
||||
l = len;
|
||||
qd->offset = l;
|
||||
|
||||
memcpy((void*)(qd + 1), data, l);
|
||||
if (ssl->quic_input_data_tail != NULL)
|
||||
ssl->quic_input_data_tail->next = qd;
|
||||
else
|
||||
ssl->quic_input_data_head = qd;
|
||||
ssl->quic_input_data_tail = qd;
|
||||
|
||||
data += l;
|
||||
len -= l;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method)
|
||||
{
|
||||
switch (ctx->method->version) {
|
||||
case DTLS1_VERSION:
|
||||
case DTLS1_2_VERSION:
|
||||
case DTLS_ANY_VERSION:
|
||||
case DTLS1_BAD_VER:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ctx->quic_method = quic_method;
|
||||
ctx->options &= ~SSL_OP_ENABLE_MIDDLEBOX_COMPAT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method)
|
||||
{
|
||||
switch (ssl->method->version) {
|
||||
case DTLS1_VERSION:
|
||||
case DTLS1_2_VERSION:
|
||||
case DTLS_ANY_VERSION:
|
||||
case DTLS1_BAD_VER:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ssl->quic_method = quic_method;
|
||||
ssl->options &= ~SSL_OP_ENABLE_MIDDLEBOX_COMPAT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level)
|
||||
{
|
||||
uint8_t *c2s_secret = NULL;
|
||||
uint8_t *s2c_secret = NULL;
|
||||
size_t len;
|
||||
const EVP_MD *md;
|
||||
|
||||
if (!SSL_IS_QUIC(ssl))
|
||||
return 1;
|
||||
|
||||
/* secrets from the POV of the client */
|
||||
switch (level) {
|
||||
case ssl_encryption_early_data:
|
||||
c2s_secret = ssl->client_early_traffic_secret;
|
||||
break;
|
||||
case ssl_encryption_handshake:
|
||||
c2s_secret = ssl->client_hand_traffic_secret;
|
||||
s2c_secret = ssl->server_hand_traffic_secret;
|
||||
break;
|
||||
case ssl_encryption_application:
|
||||
c2s_secret = ssl->client_app_traffic_secret;
|
||||
s2c_secret = ssl->server_app_traffic_secret;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
md = ssl_handshake_md(ssl);
|
||||
if (md == NULL) {
|
||||
/* May not have selected cipher, yet */
|
||||
const SSL_CIPHER *c = NULL;
|
||||
|
||||
if (ssl->session != NULL)
|
||||
c = SSL_SESSION_get0_cipher(ssl->session);
|
||||
else if (ssl->psksession != NULL)
|
||||
c = SSL_SESSION_get0_cipher(ssl->psksession);
|
||||
|
||||
if (c != NULL)
|
||||
md = SSL_CIPHER_get_handshake_digest(c);
|
||||
}
|
||||
|
||||
if ((len = EVP_MD_size(md)) <= 0) {
|
||||
SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_SET_ENCRYPTION_SECRETS,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl->server) {
|
||||
if (!ssl->quic_method->set_encryption_secrets(ssl, level, c2s_secret,
|
||||
s2c_secret, len)) {
|
||||
SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_SET_ENCRYPTION_SECRETS,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!ssl->quic_method->set_encryption_secrets(ssl, level, s2c_secret,
|
||||
c2s_secret, len)) {
|
||||
SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_SET_ENCRYPTION_SECRETS,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_process_quic_post_handshake(SSL *ssl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (SSL_in_init(ssl) || !SSL_IS_QUIC(ssl)) {
|
||||
SSLerr(SSL_F_SSL_PROCESS_QUIC_POST_HANDSHAKE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ossl_statem_set_in_init(ssl, 1);
|
||||
ret = ssl->handshake_func(ssl);
|
||||
ossl_statem_set_in_init(ssl, 0);
|
||||
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_is_quic(SSL* ssl)
|
||||
{
|
||||
return SSL_IS_QUIC(ssl);
|
||||
}
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -1115,7 +1115,7 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr
|
||||
else
|
||||
#endif
|
||||
/* check that key <-> cert match */
|
||||
if (EVP_PKEY_cmp(pubkey, privatekey) != 1) {
|
||||
if (EVP_PKEY_eq(pubkey, privatekey) != 1) {
|
||||
SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH);
|
||||
goto out;
|
||||
}
|
||||
|
||||
+43
-1
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
+44
-32
@@ -49,7 +49,7 @@ static int tls1_PRF(SSL *s,
|
||||
kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_PRF, s->ctx->propq);
|
||||
if (kdf == NULL)
|
||||
goto err;
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
kctx = EVP_KDF_new_ctx(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL)
|
||||
goto err;
|
||||
@@ -70,9 +70,9 @@ static int tls1_PRF(SSL *s,
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
|
||||
(void *)seed5, (size_t)seed5_len);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
if (EVP_KDF_CTX_set_params(kctx, params)
|
||||
if (EVP_KDF_set_ctx_params(kctx, params)
|
||||
&& EVP_KDF_derive(kctx, out, olen)) {
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ static int tls1_PRF(SSL *s,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
else
|
||||
SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR);
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num)
|
||||
* record layer. If read_ahead is enabled, then this might be false and this
|
||||
* function will fail.
|
||||
*/
|
||||
# ifndef OPENSSL_NO_KTLS_RX
|
||||
static int count_unprocessed_records(SSL *s)
|
||||
{
|
||||
SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
|
||||
@@ -132,6 +133,7 @@ static int count_unprocessed_records(SSL *s)
|
||||
|
||||
return count;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int tls1_change_cipher_state(SSL *s, int which)
|
||||
@@ -154,10 +156,13 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
# ifdef __FreeBSD__
|
||||
struct tls_enable crypto_info;
|
||||
# else
|
||||
struct tls12_crypto_info_aes_gcm_128 crypto_info;
|
||||
unsigned char geniv[12];
|
||||
struct tls_crypto_info_all crypto_info;
|
||||
unsigned char *rec_seq;
|
||||
void *rl_sequence;
|
||||
# ifndef OPENSSL_NO_KTLS_RX
|
||||
int count_unprocessed;
|
||||
int bit;
|
||||
# endif
|
||||
# endif
|
||||
BIO *bio;
|
||||
#endif
|
||||
@@ -180,6 +185,11 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
else
|
||||
s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
|
||||
|
||||
if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE)
|
||||
s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE;
|
||||
else
|
||||
s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE;
|
||||
|
||||
if (s->enc_read_ctx != NULL) {
|
||||
reuse_dd = 1;
|
||||
} else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
@@ -230,6 +240,11 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
|
||||
else
|
||||
s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
|
||||
|
||||
if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE)
|
||||
s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE;
|
||||
else
|
||||
s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE;
|
||||
if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) {
|
||||
reuse_dd = 1;
|
||||
} else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
@@ -431,14 +446,12 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
crypto_info.iv = iv;
|
||||
crypto_info.tls_vmajor = (s->version >> 8) & 0x000000ff;
|
||||
crypto_info.tls_vminor = (s->version & 0x000000ff);
|
||||
# else
|
||||
/* check that cipher is AES_GCM_128 */
|
||||
if (EVP_CIPHER_nid(c) != NID_aes_128_gcm
|
||||
|| EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE
|
||||
|| EVP_CIPHER_key_length(c) != TLS_CIPHER_AES_GCM_128_KEY_SIZE)
|
||||
# else /* !defined(__FreeBSD__) */
|
||||
/* check that cipher is supported */
|
||||
if (!ktls_check_supported_cipher(c, dd))
|
||||
goto skip_ktls;
|
||||
|
||||
/* check version is 1.2 */
|
||||
/* check version */
|
||||
if (s->version != TLS1_2_VERSION)
|
||||
goto skip_ktls;
|
||||
# endif
|
||||
@@ -469,25 +482,17 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
}
|
||||
|
||||
# ifndef __FreeBSD__
|
||||
memset(&crypto_info, 0, sizeof(crypto_info));
|
||||
crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
|
||||
crypto_info.info.version = s->version;
|
||||
|
||||
EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV,
|
||||
EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN,
|
||||
geniv);
|
||||
memcpy(crypto_info.iv, geniv + EVP_GCM_TLS_FIXED_IV_LEN,
|
||||
TLS_CIPHER_AES_GCM_128_IV_SIZE);
|
||||
memcpy(crypto_info.salt, geniv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
|
||||
memcpy(crypto_info.key, key, EVP_CIPHER_key_length(c));
|
||||
if (which & SSL3_CC_WRITE)
|
||||
memcpy(crypto_info.rec_seq, &s->rlayer.write_sequence,
|
||||
TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
|
||||
rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer);
|
||||
else
|
||||
memcpy(crypto_info.rec_seq, &s->rlayer.read_sequence,
|
||||
TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
|
||||
rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer);
|
||||
|
||||
if (!ktls_configure_crypto(c, s->version, dd, rl_sequence, &crypto_info,
|
||||
&rec_seq, iv, key))
|
||||
goto skip_ktls;
|
||||
|
||||
if (which & SSL3_CC_READ) {
|
||||
# ifndef OPENSSL_NO_KTLS_RX
|
||||
count_unprocessed = count_unprocessed_records(s);
|
||||
if (count_unprocessed < 0)
|
||||
goto skip_ktls;
|
||||
@@ -495,14 +500,17 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
/* increment the crypto_info record sequence */
|
||||
while (count_unprocessed) {
|
||||
for (bit = 7; bit >= 0; bit--) { /* increment */
|
||||
++crypto_info.rec_seq[bit];
|
||||
if (crypto_info.rec_seq[bit] != 0)
|
||||
++rec_seq[bit];
|
||||
if (rec_seq[bit] != 0)
|
||||
break;
|
||||
}
|
||||
count_unprocessed--;
|
||||
}
|
||||
# else
|
||||
goto skip_ktls;
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
# endif /* !__FreeBSD__ */
|
||||
|
||||
/* ktls works with user provided buffers directly */
|
||||
if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) {
|
||||
@@ -615,6 +623,10 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen,
|
||||
{
|
||||
size_t hashlen;
|
||||
unsigned char hash[EVP_MAX_MD_SIZE];
|
||||
size_t finished_size = TLS1_FINISH_MAC_LENGTH;
|
||||
|
||||
if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kGOST18)
|
||||
finished_size = 32;
|
||||
|
||||
if (!ssl3_digest_cached_records(s, 0)) {
|
||||
/* SSLfatal() already called */
|
||||
@@ -628,12 +640,12 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen,
|
||||
|
||||
if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0,
|
||||
s->session->master_key, s->session->master_key_length,
|
||||
out, TLS1_FINISH_MAC_LENGTH, 1)) {
|
||||
out, finished_size, 1)) {
|
||||
/* SSLfatal() already called */
|
||||
return 0;
|
||||
}
|
||||
OPENSSL_cleanse(hash, hashlen);
|
||||
return TLS1_FINISH_MAC_LENGTH;
|
||||
return finished_size;
|
||||
}
|
||||
|
||||
int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
|
||||
|
||||
+59
-54
@@ -621,7 +621,7 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
|
||||
*/
|
||||
return 1;
|
||||
} else {
|
||||
int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(grp));
|
||||
int field_type = EC_GROUP_get_field_type(grp);
|
||||
|
||||
if (field_type == NID_X9_62_prime_field)
|
||||
comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
|
||||
@@ -1000,6 +1000,21 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used
|
||||
* with new (aGOST12-only) ciphersuites, we should find out which one is available really.
|
||||
*/
|
||||
else if (idx == SSL_PKEY_GOST12_256) {
|
||||
int real_idx;
|
||||
|
||||
for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256;
|
||||
real_idx--) {
|
||||
if (s->cert->pkeys[real_idx].privatekey != NULL) {
|
||||
idx = real_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
idx = s->cert->key - s->cert->pkeys;
|
||||
}
|
||||
@@ -1119,17 +1134,6 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
|
||||
int pkeyid = -1;
|
||||
const SIGALG_LOOKUP *lu;
|
||||
|
||||
/*
|
||||
* TODO(3.0) Remove this when we adapted this function for provider
|
||||
* side keys. We know that EVP_PKEY_get0() downgrades an EVP_PKEY
|
||||
* to contain a legacy key.
|
||||
*
|
||||
* THIS IS TEMPORARY
|
||||
*/
|
||||
EVP_PKEY_get0(pkey);
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE)
|
||||
return 0;
|
||||
|
||||
pkeyid = EVP_PKEY_id(pkey);
|
||||
/* Should never happen */
|
||||
if (pkeyid == -1)
|
||||
@@ -1719,7 +1723,6 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
|
||||
unsigned char sigalgstr[2];
|
||||
int secbits;
|
||||
|
||||
/* See if sigalgs is recognised and if hash is enabled */
|
||||
if (!tls1_lookup_md(lu, NULL))
|
||||
return 0;
|
||||
/* DSA is not allowed in TLS 1.3 */
|
||||
@@ -1767,7 +1770,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
|
||||
if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0))
|
||||
continue;
|
||||
|
||||
if ((c->algorithm_mkey & SSL_kGOST) != 0)
|
||||
if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0)
|
||||
break;
|
||||
}
|
||||
if (i == num)
|
||||
@@ -2563,46 +2566,48 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
|
||||
#ifndef OPENSSL_NO_DH
|
||||
DH *ssl_get_auto_dh(SSL *s)
|
||||
{
|
||||
DH *dhp;
|
||||
BIGNUM *p, *g;
|
||||
int dh_secbits = 80;
|
||||
if (s->cert->dh_tmp_auto == 2)
|
||||
return DH_get_1024_160();
|
||||
if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
|
||||
if (s->s3.tmp.new_cipher->strength_bits == 256)
|
||||
dh_secbits = 128;
|
||||
else
|
||||
dh_secbits = 80;
|
||||
} else {
|
||||
if (s->s3.tmp.cert == NULL)
|
||||
return NULL;
|
||||
dh_secbits = EVP_PKEY_security_bits(s->s3.tmp.cert->privatekey);
|
||||
if (s->cert->dh_tmp_auto != 2) {
|
||||
if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
|
||||
if (s->s3.tmp.new_cipher->strength_bits == 256)
|
||||
dh_secbits = 128;
|
||||
else
|
||||
dh_secbits = 80;
|
||||
} else {
|
||||
if (s->s3.tmp.cert == NULL)
|
||||
return NULL;
|
||||
dh_secbits = EVP_PKEY_security_bits(s->s3.tmp.cert->privatekey);
|
||||
}
|
||||
}
|
||||
|
||||
if (dh_secbits >= 128) {
|
||||
DH *dhp = DH_new();
|
||||
BIGNUM *p, *g;
|
||||
if (dhp == NULL)
|
||||
return NULL;
|
||||
g = BN_new();
|
||||
if (g == NULL || !BN_set_word(g, 2)) {
|
||||
DH_free(dhp);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
if (dh_secbits >= 192)
|
||||
p = BN_get_rfc3526_prime_8192(NULL);
|
||||
else
|
||||
p = BN_get_rfc3526_prime_3072(NULL);
|
||||
if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) {
|
||||
DH_free(dhp);
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
return dhp;
|
||||
dhp = DH_new();
|
||||
if (dhp == NULL)
|
||||
return NULL;
|
||||
g = BN_new();
|
||||
if (g == NULL || !BN_set_word(g, 2)) {
|
||||
DH_free(dhp);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
if (dh_secbits >= 112)
|
||||
return DH_get_2048_224();
|
||||
return DH_get_1024_160();
|
||||
if (dh_secbits >= 192)
|
||||
p = BN_get_rfc3526_prime_8192(NULL);
|
||||
else if (dh_secbits >= 152)
|
||||
p = BN_get_rfc3526_prime_4096(NULL);
|
||||
else if (dh_secbits >= 128)
|
||||
p = BN_get_rfc3526_prime_3072(NULL);
|
||||
else if (dh_secbits >= 112)
|
||||
p = BN_get_rfc3526_prime_2048(NULL);
|
||||
else
|
||||
p = BN_get_rfc2409_prime_1024(NULL);
|
||||
if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) {
|
||||
DH_free(dhp);
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
return dhp;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3064,12 +3069,12 @@ SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx)
|
||||
}
|
||||
#endif
|
||||
mac = EVP_MAC_fetch(ctx->libctx, "HMAC", NULL);
|
||||
if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL)
|
||||
if (mac == NULL || (ret->ctx = EVP_MAC_new_ctx(mac)) == NULL)
|
||||
goto err;
|
||||
EVP_MAC_free(mac);
|
||||
return ret;
|
||||
err:
|
||||
EVP_MAC_CTX_free(ret->ctx);
|
||||
EVP_MAC_free_ctx(ret->ctx);
|
||||
EVP_MAC_free(mac);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
@@ -3078,7 +3083,7 @@ SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx)
|
||||
void ssl_hmac_free(SSL_HMAC *ctx)
|
||||
{
|
||||
if (ctx != NULL) {
|
||||
EVP_MAC_CTX_free(ctx->ctx);
|
||||
EVP_MAC_free_ctx(ctx->ctx);
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
HMAC_CTX_free(ctx->old_ctx);
|
||||
#endif
|
||||
@@ -3106,7 +3111,7 @@ int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md)
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0);
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key, len);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
if (EVP_MAC_CTX_set_params(ctx->ctx, params) && EVP_MAC_init(ctx->ctx))
|
||||
if (EVP_MAC_set_ctx_params(ctx->ctx, params) && EVP_MAC_init(ctx->ctx))
|
||||
return 1;
|
||||
}
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
|
||||
+31
-7
@@ -444,6 +444,9 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = {
|
||||
{0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"},
|
||||
{0xFF85, "LEGACY-GOST2012-GOST8912-GOST8912"},
|
||||
{0xFF87, "GOST2012-NULL-GOST12"},
|
||||
{0xC100, "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC"},
|
||||
{0xC101, "GOST2012-MAGMA-MAGMAOMAC"},
|
||||
{0xC102, "GOST2012-GOST8912-IANA"},
|
||||
};
|
||||
|
||||
/* Compression methods */
|
||||
@@ -593,7 +596,9 @@ static const ssl_trace_tbl ssl_ctype_tbl[] = {
|
||||
{20, "fortezza_dms"},
|
||||
{64, "ecdsa_sign"},
|
||||
{65, "rsa_fixed_ecdh"},
|
||||
{66, "ecdsa_fixed_ecdh"}
|
||||
{66, "ecdsa_fixed_ecdh"},
|
||||
{67, "gost_sign256"},
|
||||
{68, "gost_sign512"},
|
||||
};
|
||||
|
||||
static const ssl_trace_tbl ssl_psk_kex_modes_tbl[] = {
|
||||
@@ -665,7 +670,10 @@ static int ssl_print_random(BIO *bio, int indent,
|
||||
|
||||
if (*pmsglen < 32)
|
||||
return 0;
|
||||
tm = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
tm = ((unsigned int)p[0] << 24)
|
||||
| ((unsigned int)p[1] << 16)
|
||||
| ((unsigned int)p[2] << 8)
|
||||
| (unsigned int)p[3];
|
||||
p += 4;
|
||||
BIO_indent(bio, indent, 80);
|
||||
BIO_puts(bio, "Random:\n");
|
||||
@@ -870,8 +878,10 @@ static int ssl_print_extension(BIO *bio, int indent, int server,
|
||||
break;
|
||||
if (extlen != 4)
|
||||
return 0;
|
||||
max_early_data = (ext[0] << 24) | (ext[1] << 16) | (ext[2] << 8)
|
||||
| ext[3];
|
||||
max_early_data = ((unsigned int)ext[0] << 24)
|
||||
| ((unsigned int)ext[1] << 16)
|
||||
| ((unsigned int)ext[2] << 8)
|
||||
| (unsigned int)ext[3];
|
||||
BIO_indent(bio, indent + 2, 80);
|
||||
BIO_printf(bio, "max_early_data=%u\n", max_early_data);
|
||||
break;
|
||||
@@ -1078,6 +1088,10 @@ static int ssl_get_keyex(const char **pname, const SSL *ssl)
|
||||
*pname = "GOST";
|
||||
return SSL_kGOST;
|
||||
}
|
||||
if (alg_k & SSL_kGOST18) {
|
||||
*pname = "GOST18";
|
||||
return SSL_kGOST18;
|
||||
}
|
||||
*pname = "UNKNOWN";
|
||||
return 0;
|
||||
}
|
||||
@@ -1124,7 +1138,11 @@ static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl,
|
||||
ssl_print_hex(bio, indent + 2, "GostKeyTransportBlob", msg, msglen);
|
||||
msglen = 0;
|
||||
break;
|
||||
|
||||
case SSL_kGOST18:
|
||||
ssl_print_hex(bio, indent + 2,
|
||||
"GOST-wrapped PreMasterSecret", msg, msglen);
|
||||
msglen = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return !msglen;
|
||||
@@ -1366,7 +1384,10 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl,
|
||||
}
|
||||
if (msglen < 4)
|
||||
return 0;
|
||||
tick_life = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3];
|
||||
tick_life = ((unsigned int)msg[0] << 24)
|
||||
| ((unsigned int)msg[1] << 16)
|
||||
| ((unsigned int)msg[2] << 8)
|
||||
| (unsigned int)msg[3];
|
||||
msglen -= 4;
|
||||
msg += 4;
|
||||
BIO_indent(bio, indent + 2, 80);
|
||||
@@ -1377,7 +1398,10 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl,
|
||||
if (msglen < 4)
|
||||
return 0;
|
||||
ticket_age_add =
|
||||
(msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3];
|
||||
((unsigned int)msg[0] << 24)
|
||||
| ((unsigned int)msg[1] << 16)
|
||||
| ((unsigned int)msg[2] << 8)
|
||||
| (unsigned int)msg[3];
|
||||
msglen -= 4;
|
||||
msg += 4;
|
||||
BIO_indent(bio, indent + 2, 80);
|
||||
|
||||
+220
-44
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "ssl_local.h"
|
||||
#include "internal/ktls.h"
|
||||
#include "record/record_local.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
@@ -54,7 +56,7 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
|
||||
+ 1 + EVP_MAX_MD_SIZE];
|
||||
WPACKET pkt;
|
||||
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
kctx = EVP_KDF_new_ctx(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL)
|
||||
return 0;
|
||||
@@ -70,7 +72,7 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
|
||||
*/
|
||||
SSLerr(SSL_F_TLS13_HKDF_EXPAND, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
|
||||
}
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -85,7 +87,7 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
|
||||
|| !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen)
|
||||
|| !WPACKET_get_total_written(&pkt, &hkdflabellen)
|
||||
|| !WPACKET_finish(&pkt)) {
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
WPACKET_cleanup(&pkt);
|
||||
if (fatal)
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND,
|
||||
@@ -104,10 +106,10 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
|
||||
hkdflabel, hkdflabellen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = EVP_KDF_CTX_set_params(kctx, params) <= 0
|
||||
ret = EVP_KDF_set_ctx_params(kctx, params) <= 0
|
||||
|| EVP_KDF_derive(kctx, out, outlen) <= 0;
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
|
||||
if (ret != 0) {
|
||||
if (fatal)
|
||||
@@ -195,7 +197,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
|
||||
unsigned char preextractsec[EVP_MAX_MD_SIZE];
|
||||
|
||||
kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_HKDF, NULL);
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
kctx = EVP_KDF_new_ctx(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
|
||||
@@ -208,7 +210,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
|
||||
if (!ossl_assert(mdleni >= 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
return 0;
|
||||
}
|
||||
mdlen = (size_t)mdleni;
|
||||
@@ -231,7 +233,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
return 0;
|
||||
}
|
||||
EVP_MD_CTX_free(mctx);
|
||||
@@ -242,7 +244,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
|
||||
sizeof(derived_secret_label) - 1, hash, mdlen,
|
||||
preextractsec, mdlen, 1)) {
|
||||
/* SSLfatal() already called */
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -261,14 +263,14 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
|
||||
prevsecretlen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = EVP_KDF_CTX_set_params(kctx, params) <= 0
|
||||
ret = EVP_KDF_set_ctx_params(kctx, params) <= 0
|
||||
|| EVP_KDF_derive(kctx, outsecret, mdlen) <= 0;
|
||||
|
||||
if (ret != 0)
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
if (prevsecret == preextractsec)
|
||||
OPENSSL_cleanse(preextractsec, mdlen);
|
||||
return ret == 0;
|
||||
@@ -386,9 +388,9 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
|
||||
const unsigned char *hash,
|
||||
const unsigned char *label,
|
||||
size_t labellen, unsigned char *secret,
|
||||
unsigned char *iv, EVP_CIPHER_CTX *ciph_ctx)
|
||||
unsigned char *key, unsigned char *iv,
|
||||
EVP_CIPHER_CTX *ciph_ctx)
|
||||
{
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
size_t ivlen, keylen, taglen;
|
||||
int hashleni = EVP_MD_size(md);
|
||||
size_t hashlen;
|
||||
@@ -397,14 +399,14 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
|
||||
if (!ossl_assert(hashleni >= 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV,
|
||||
ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
hashlen = (size_t)hashleni;
|
||||
|
||||
if (!tls13_hkdf_expand(s, md, insecret, label, labellen, hash, hashlen,
|
||||
secret, hashlen, 1)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO(size_t): convert me */
|
||||
@@ -424,7 +426,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
|
||||
} else {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV,
|
||||
ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8))
|
||||
taglen = EVP_CCM8_TLS_TAG_LEN;
|
||||
@@ -438,7 +440,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
|
||||
if (!tls13_derive_key(s, md, secret, key, keylen)
|
||||
|| !tls13_derive_iv(s, md, secret, iv, ivlen)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
|
||||
@@ -448,37 +450,148 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
|
||||
|| EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV,
|
||||
ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
err:
|
||||
OPENSSL_cleanse(key, sizeof(key));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CHARSET_EBCDIC
|
||||
static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||
static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||
static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||
#else
|
||||
static const unsigned char client_early_traffic[] = "c e traffic";
|
||||
static const unsigned char client_handshake_traffic[] = "c hs traffic";
|
||||
static const unsigned char client_application_traffic[] = "c ap traffic";
|
||||
static const unsigned char server_handshake_traffic[] = "s hs traffic";
|
||||
static const unsigned char server_application_traffic[] = "s ap traffic";
|
||||
static const unsigned char exporter_master_secret[] = "exp master";
|
||||
static const unsigned char resumption_master_secret[] = "res master";
|
||||
static const unsigned char early_exporter_master_secret[] = "e exp master";
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
static int quic_change_cipher_state(SSL *s, int which)
|
||||
{
|
||||
unsigned char hash[EVP_MAX_MD_SIZE];
|
||||
size_t hashlen = 0;
|
||||
int hashleni;
|
||||
int ret = 0;
|
||||
const EVP_MD *md = NULL;
|
||||
OSSL_ENCRYPTION_LEVEL level = ssl_encryption_initial;
|
||||
int is_handshake = ((which & SSL3_CC_HANDSHAKE) == SSL3_CC_HANDSHAKE);
|
||||
int is_client_read = ((which & SSL3_CHANGE_CIPHER_CLIENT_READ) == SSL3_CHANGE_CIPHER_CLIENT_READ);
|
||||
int is_server_write = ((which & SSL3_CHANGE_CIPHER_SERVER_WRITE) == SSL3_CHANGE_CIPHER_SERVER_WRITE);
|
||||
int is_early = (which & SSL3_CC_EARLY);
|
||||
|
||||
md = ssl_handshake_md(s);
|
||||
if (!ssl3_digest_cached_records(s, 1)
|
||||
|| !ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
|
||||
/* SSLfatal() already called */;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Ensure cast to size_t is safe */
|
||||
hashleni = EVP_MD_size(md);
|
||||
if (!ossl_assert(hashleni >= 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_CHANGE_CIPHER_STATE,
|
||||
ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
hashlen = (size_t)hashleni;
|
||||
|
||||
if (is_client_read || is_server_write) {
|
||||
if (is_handshake) {
|
||||
level = ssl_encryption_handshake;
|
||||
|
||||
if (!tls13_hkdf_expand(s, md, s->handshake_secret, client_handshake_traffic,
|
||||
sizeof(client_handshake_traffic)-1, hash, hashlen,
|
||||
s->client_hand_traffic_secret, hashlen, 1)
|
||||
|| !ssl_log_secret(s, CLIENT_HANDSHAKE_LABEL, s->client_hand_traffic_secret, hashlen)
|
||||
|| !tls13_derive_finishedkey(s, md, s->client_hand_traffic_secret,
|
||||
s->client_finished_secret, hashlen)
|
||||
|| !tls13_hkdf_expand(s, md, s->handshake_secret, server_handshake_traffic,
|
||||
sizeof(server_handshake_traffic)-1, hash, hashlen,
|
||||
s->server_hand_traffic_secret, hashlen, 1)
|
||||
|| !ssl_log_secret(s, SERVER_HANDSHAKE_LABEL, s->server_hand_traffic_secret, hashlen)
|
||||
|| !tls13_derive_finishedkey(s, md, s->server_hand_traffic_secret,
|
||||
s->server_finished_secret, hashlen)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
level = ssl_encryption_application;
|
||||
|
||||
if (!tls13_hkdf_expand(s, md, s->master_secret, client_application_traffic,
|
||||
sizeof(client_application_traffic)-1, hash, hashlen,
|
||||
s->client_app_traffic_secret, hashlen, 1)
|
||||
|| !ssl_log_secret(s, CLIENT_APPLICATION_LABEL, s->client_app_traffic_secret, hashlen)
|
||||
|| !tls13_hkdf_expand(s, md, s->master_secret, server_application_traffic,
|
||||
sizeof(server_application_traffic)-1, hash, hashlen,
|
||||
s->server_app_traffic_secret, hashlen, 1)
|
||||
|| !ssl_log_secret(s, SERVER_APPLICATION_LABEL, s->server_app_traffic_secret, hashlen)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!quic_set_encryption_secrets(s, level)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
if (s->server)
|
||||
s->quic_write_level = level;
|
||||
else
|
||||
s->quic_read_level = level;
|
||||
} else {
|
||||
/* is_client_write || is_server_read */
|
||||
|
||||
if (is_early) {
|
||||
level = ssl_encryption_early_data;
|
||||
|
||||
if (!tls13_hkdf_expand(s, md, s->early_secret, client_early_traffic,
|
||||
sizeof(client_early_traffic)-1, hash, hashlen,
|
||||
s->client_early_traffic_secret, hashlen, 1)
|
||||
|| !ssl_log_secret(s, CLIENT_EARLY_LABEL, s->client_early_traffic_secret, hashlen)
|
||||
|| !quic_set_encryption_secrets(s, level)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
} else if (is_handshake) {
|
||||
level = ssl_encryption_handshake;
|
||||
} else {
|
||||
level = ssl_encryption_application;
|
||||
/*
|
||||
* We also create the resumption master secret, but this time use the
|
||||
* hash for the whole handshake including the Client Finished
|
||||
*/
|
||||
if (!tls13_hkdf_expand(s, md, s->master_secret, resumption_master_secret,
|
||||
sizeof(resumption_master_secret)-1, hash, hashlen,
|
||||
s->resumption_master_secret, hashlen, 1)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->server)
|
||||
s->quic_read_level = level;
|
||||
else
|
||||
s->quic_write_level = level;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
#endif /* OPENSSL_NO_QUIC */
|
||||
int tls13_change_cipher_state(SSL *s, int which)
|
||||
{
|
||||
#ifdef CHARSET_EBCDIC
|
||||
static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
|
||||
static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||
static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||
static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
|
||||
#else
|
||||
static const unsigned char client_early_traffic[] = "c e traffic";
|
||||
static const unsigned char client_handshake_traffic[] = "c hs traffic";
|
||||
static const unsigned char client_application_traffic[] = "c ap traffic";
|
||||
static const unsigned char server_handshake_traffic[] = "s hs traffic";
|
||||
static const unsigned char server_application_traffic[] = "s ap traffic";
|
||||
static const unsigned char exporter_master_secret[] = "exp master";
|
||||
static const unsigned char resumption_master_secret[] = "res master";
|
||||
static const unsigned char early_exporter_master_secret[] = "e exp master";
|
||||
#endif
|
||||
unsigned char *iv;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
unsigned char secret[EVP_MAX_MD_SIZE];
|
||||
unsigned char hashval[EVP_MAX_MD_SIZE];
|
||||
unsigned char *hash = hashval;
|
||||
@@ -492,6 +605,17 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
int ret = 0;
|
||||
const EVP_MD *md = NULL;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13)
|
||||
# ifndef __FreeBSD__
|
||||
struct tls_crypto_info_all crypto_info;
|
||||
BIO *bio;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (SSL_IS_QUIC(s))
|
||||
return quic_change_cipher_state(s, which);
|
||||
#endif
|
||||
|
||||
if (which & SSL3_CC_READ) {
|
||||
if (s->enc_read_ctx != NULL) {
|
||||
@@ -583,6 +707,7 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
cipher = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(sslcipher));
|
||||
md = ssl_md(sslcipher->algorithm2);
|
||||
if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL)
|
||||
@@ -694,9 +819,13 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
}
|
||||
}
|
||||
|
||||
/* check whether cipher is known */
|
||||
if(!ossl_assert(cipher != NULL))
|
||||
goto err;
|
||||
|
||||
if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
|
||||
insecret, hash, label, labellen, secret, iv,
|
||||
ciph_ctx)) {
|
||||
insecret, hash, label, labellen, secret, key,
|
||||
iv, ciph_ctx)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
@@ -737,8 +866,53 @@ int tls13_change_cipher_state(SSL *s, int which)
|
||||
s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS;
|
||||
else
|
||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
# if defined(OPENSSL_KTLS_TLS13)
|
||||
# ifndef __FreeBSD__
|
||||
if (!(which & SSL3_CC_WRITE) || !(which & SSL3_CC_APPLICATION)
|
||||
|| ((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX)))
|
||||
goto skip_ktls;
|
||||
|
||||
/* ktls supports only the maximum fragment size */
|
||||
if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
goto skip_ktls;
|
||||
|
||||
/* ktls does not support record padding */
|
||||
if (s->record_padding_cb != NULL)
|
||||
goto skip_ktls;
|
||||
|
||||
/* check that cipher is supported */
|
||||
if (!ktls_check_supported_cipher(cipher, ciph_ctx))
|
||||
goto skip_ktls;
|
||||
|
||||
bio = s->wbio;
|
||||
|
||||
if (!ossl_assert(bio != NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
|
||||
if (BIO_flush(bio) <= 0)
|
||||
goto skip_ktls;
|
||||
|
||||
/* configure kernel crypto structure */
|
||||
if (!ktls_configure_crypto(cipher, s->version, ciph_ctx,
|
||||
RECORD_LAYER_get_write_sequence(&s->rlayer),
|
||||
&crypto_info, NULL, iv, key))
|
||||
goto skip_ktls;
|
||||
|
||||
/* ktls works with user provided buffers directly */
|
||||
if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE))
|
||||
ssl3_release_write_buffer(s);
|
||||
# endif
|
||||
skip_ktls:
|
||||
# endif
|
||||
#endif
|
||||
ret = 1;
|
||||
err:
|
||||
OPENSSL_cleanse(key, sizeof(key));
|
||||
OPENSSL_cleanse(secret, sizeof(secret));
|
||||
return ret;
|
||||
}
|
||||
@@ -752,6 +926,7 @@ int tls13_update_key(SSL *s, int sending)
|
||||
#endif
|
||||
const EVP_MD *md = ssl_handshake_md(s);
|
||||
size_t hashlen = EVP_MD_size(md);
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
unsigned char *insecret, *iv;
|
||||
unsigned char secret[EVP_MAX_MD_SIZE];
|
||||
EVP_CIPHER_CTX *ciph_ctx;
|
||||
@@ -776,8 +951,8 @@ int tls13_update_key(SSL *s, int sending)
|
||||
if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s),
|
||||
s->s3.tmp.new_sym_enc, insecret, NULL,
|
||||
application_traffic,
|
||||
sizeof(application_traffic) - 1, secret, iv,
|
||||
ciph_ctx)) {
|
||||
sizeof(application_traffic) - 1, secret, key,
|
||||
iv, ciph_ctx)) {
|
||||
/* SSLfatal() already called */
|
||||
goto err;
|
||||
}
|
||||
@@ -787,6 +962,7 @@ int tls13_update_key(SSL *s, int sending)
|
||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
||||
ret = 1;
|
||||
err:
|
||||
OPENSSL_cleanse(key, sizeof(key));
|
||||
OPENSSL_cleanse(secret, sizeof(secret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user