Update crypto negotation to draft 15.
BUG=77 Change-Id: If568412655aae240b072c29d763a5b17bb5ca3f7 Reviewed-on: https://boringssl-review.googlesource.com/10840 Reviewed-by: Steven Valdez <svaldez@google.com> Reviewed-by: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
committed by
CQ bot account: commit-bot@chromium.org
parent
5b9860827f
commit
803c77a681
@@ -95,6 +95,7 @@ SSL,181,NO_PRIVATE_KEY_ASSIGNED
|
||||
SSL,182,NO_RENEGOTIATION
|
||||
SSL,183,NO_REQUIRED_DIGEST
|
||||
SSL,184,NO_SHARED_CIPHER
|
||||
SSL,266,NO_SHARED_GROUP
|
||||
SSL,185,NULL_SSL_CTX
|
||||
SSL,186,NULL_SSL_METHOD_PASSED
|
||||
SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED
|
||||
|
||||
@@ -562,7 +562,7 @@ OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
|
||||
#define DTLS1_VERSION 0xfeff
|
||||
#define DTLS1_2_VERSION 0xfefd
|
||||
|
||||
#define TLS1_3_DRAFT_VERSION 0x7f0e
|
||||
#define TLS1_3_DRAFT_VERSION 0x7f0f
|
||||
|
||||
/* SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to
|
||||
* |version|. If |version| is zero, the default minimum version is used. It
|
||||
@@ -1197,7 +1197,8 @@ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher);
|
||||
OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
|
||||
|
||||
/* SSL_CIPHER_get_kx_name returns a string that describes the key-exchange
|
||||
* method used by |cipher|. For example, "ECDHE_ECDSA". */
|
||||
* method used by |cipher|. For example, "ECDHE_ECDSA". TLS 1.3 AEAD-only
|
||||
* ciphers return the string "GENERIC". */
|
||||
OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
|
||||
|
||||
/* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
|
||||
@@ -4807,6 +4808,7 @@ BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
|
||||
#define SSL_R_RENEGOTIATION_EMS_MISMATCH 263
|
||||
#define SSL_R_DUPLICATE_KEY_SHARE 264
|
||||
#define SSL_R_NO_GROUPS_SPECIFIED 265
|
||||
#define SSL_R_NO_SHARED_GROUP 266
|
||||
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
|
||||
#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
|
||||
#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
|
||||
|
||||
@@ -413,15 +413,16 @@ extern "C" {
|
||||
#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA9
|
||||
#define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0x0300CCAC
|
||||
|
||||
/* PSK ciphersuites from mattsson-tls-ecdhe-psk-aead */
|
||||
#define TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256 0x0300D001
|
||||
#define TLS1_CK_ECDHE_PSK_WITH_AES_256_GCM_SHA384 0x0300D002
|
||||
|
||||
/* TODO(davidben): Remove this. Historically, the CK names for CHACHA20_POLY1305
|
||||
* were missing 'WITH' and 'SHA256'. */
|
||||
#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 \
|
||||
TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
|
||||
/* TLS 1.3 ciphersuites from draft-ietf-tls-tls13-15 */
|
||||
#define TLS1_CK_AES_128_GCM_SHA256 0x03001301
|
||||
#define TLS1_CK_AES_256_GCM_SHA384 0x03001302
|
||||
#define TLS1_CK_CHACHA20_POLY1305_SHA256 0x03001303
|
||||
|
||||
/* CECPQ1 ciphersuites. These are specific to BoringSSL and not standard. */
|
||||
#define TLS1_CK_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256 0x030016B7
|
||||
#define TLS1_CK_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0x030016B8
|
||||
@@ -608,9 +609,10 @@ extern "C" {
|
||||
#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 \
|
||||
TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
|
||||
/* PSK ciphersuites from mattsson-tls-ecdhe-psk-aead */
|
||||
#define TLS1_TXT_ECDHE_PSK_WITH_AES_128_GCM_SHA256 "ECDHE-PSK-AES128-GCM-SHA256"
|
||||
#define TLS1_TXT_ECDHE_PSK_WITH_AES_256_GCM_SHA384 "ECDHE-PSK-AES256-GCM-SHA384"
|
||||
/* TLS 1.3 ciphersuites from draft-ietf-tls-tls13-15 */
|
||||
#define TLS1_TXT_AES_128_GCM_SHA256 "AEAD-AES128-GCM-SHA256"
|
||||
#define TLS1_TXT_AES_256_GCM_SHA384 "AEAD-AES256-GCM-SHA384"
|
||||
#define TLS1_TXT_CHACHA20_POLY1305_SHA256 "AEAD-CHACHA20-POLY1305-SHA256"
|
||||
|
||||
/* CECPQ1 ciphersuites. These are specific to BoringSSL and not standard. */
|
||||
#define TLS1_TXT_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256 \
|
||||
|
||||
+5
-17
@@ -626,18 +626,6 @@ static int ssl_write_client_cipher_list(SSL *ssl, CBB *out,
|
||||
if (!CBB_add_u16(&child, ssl_cipher_get_value(cipher))) {
|
||||
return 0;
|
||||
}
|
||||
/* Add PSK ciphers for TLS 1.3 resumption. */
|
||||
uint16_t session_version;
|
||||
if (ssl->session != NULL &&
|
||||
ssl->method->version_from_wire(&session_version,
|
||||
ssl->session->ssl_version) &&
|
||||
session_version >= TLS1_3_VERSION) {
|
||||
uint16_t resumption_cipher;
|
||||
if (ssl_cipher_get_ecdhe_psk_cipher(cipher, &resumption_cipher) &&
|
||||
!CBB_add_u16(&child, resumption_cipher)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If all ciphers were disabled, return the error to the caller. */
|
||||
@@ -952,16 +940,16 @@ static int ssl3_get_server_hello(SSL *ssl) {
|
||||
}
|
||||
|
||||
if (ssl->session != NULL) {
|
||||
if (ssl->session->cipher != c) {
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
|
||||
goto f_err;
|
||||
}
|
||||
if (ssl->session->ssl_version != ssl->version) {
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
|
||||
goto f_err;
|
||||
}
|
||||
if (ssl->session->cipher != c) {
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
|
||||
goto f_err;
|
||||
}
|
||||
if (!ssl_session_is_context_valid(ssl, ssl->session)) {
|
||||
/* This is actually a client application bug. */
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
|
||||
+2
-5
@@ -172,12 +172,14 @@ extern "C" {
|
||||
/* SSL_kPSK is only set for plain PSK, not ECDHE_PSK. */
|
||||
#define SSL_kPSK 0x00000008L
|
||||
#define SSL_kCECPQ1 0x00000010L
|
||||
#define SSL_kGENERIC 0x00000020L
|
||||
|
||||
/* Bits for |algorithm_auth| (server authentication). */
|
||||
#define SSL_aRSA 0x00000001L
|
||||
#define SSL_aECDSA 0x00000002L
|
||||
/* SSL_aPSK is set for both PSK and ECDHE_PSK. */
|
||||
#define SSL_aPSK 0x00000004L
|
||||
#define SSL_aGENERIC 0x00000008L
|
||||
|
||||
#define SSL_aCERT (SSL_aRSA | SSL_aECDSA)
|
||||
|
||||
@@ -241,11 +243,6 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
|
||||
/* ssl_cipher_get_value returns the cipher suite id of |cipher|. */
|
||||
uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher);
|
||||
|
||||
/* ssl_cipher_get_resumption_cipher returns the cipher suite id of the cipher
|
||||
* matching |cipher| with PSK enabled. */
|
||||
int ssl_cipher_get_ecdhe_psk_cipher(const SSL_CIPHER *cipher,
|
||||
uint16_t *out_cipher);
|
||||
|
||||
/* ssl_cipher_get_key_type returns the |EVP_PKEY_*| value corresponding to the
|
||||
* server key used in |cipher| or |EVP_PKEY_NONE| if there is none. */
|
||||
int ssl_cipher_get_key_type(const SSL_CIPHER *cipher);
|
||||
|
||||
+74
-69
@@ -343,6 +343,41 @@ static const SSL_CIPHER kCiphers[] = {
|
||||
SSL_HANDSHAKE_MAC_SHA384,
|
||||
},
|
||||
|
||||
/* TLS 1.3 suites. */
|
||||
|
||||
/* Cipher 1301 */
|
||||
{
|
||||
TLS1_TXT_AES_128_GCM_SHA256,
|
||||
TLS1_CK_AES_128_GCM_SHA256,
|
||||
SSL_kGENERIC,
|
||||
SSL_aGENERIC,
|
||||
SSL_AES128GCM,
|
||||
SSL_AEAD,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
},
|
||||
|
||||
/* Cipher 1302 */
|
||||
{
|
||||
TLS1_TXT_AES_256_GCM_SHA384,
|
||||
TLS1_CK_AES_256_GCM_SHA384,
|
||||
SSL_kGENERIC,
|
||||
SSL_aGENERIC,
|
||||
SSL_AES256GCM,
|
||||
SSL_AEAD,
|
||||
SSL_HANDSHAKE_MAC_SHA384,
|
||||
},
|
||||
|
||||
/* Cipher 1303 */
|
||||
{
|
||||
TLS1_TXT_CHACHA20_POLY1305_SHA256,
|
||||
TLS1_CK_CHACHA20_POLY1305_SHA256,
|
||||
SSL_kGENERIC,
|
||||
SSL_aGENERIC,
|
||||
SSL_CHACHA20POLY1305,
|
||||
SSL_AEAD,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
},
|
||||
|
||||
/* CECPQ1 (combined elliptic curve + post-quantum) suites. */
|
||||
|
||||
/* Cipher 16B7 */
|
||||
@@ -608,28 +643,6 @@ static const SSL_CIPHER kCiphers[] = {
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
},
|
||||
|
||||
/* Cipher D001 */
|
||||
{
|
||||
TLS1_TXT_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
|
||||
TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
|
||||
SSL_kECDHE,
|
||||
SSL_aPSK,
|
||||
SSL_AES128GCM,
|
||||
SSL_AEAD,
|
||||
SSL_HANDSHAKE_MAC_SHA256,
|
||||
},
|
||||
|
||||
/* Cipher D002 */
|
||||
{
|
||||
TLS1_TXT_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
|
||||
TLS1_CK_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
|
||||
SSL_kECDHE,
|
||||
SSL_aPSK,
|
||||
SSL_AES256GCM,
|
||||
SSL_AEAD,
|
||||
SSL_HANDSHAKE_MAC_SHA384,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static const size_t kCiphersLen = OPENSSL_ARRAY_SIZE(kCiphers);
|
||||
@@ -1063,14 +1076,6 @@ static void ssl_cipher_apply_rule(
|
||||
(min_version != 0 && SSL_CIPHER_get_min_version(cp) != min_version)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The following ciphers are internal implementation details of TLS 1.3
|
||||
* resumption but are not yet finalized. Disable them by default until
|
||||
* then. */
|
||||
if (cp->id == TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256 ||
|
||||
cp->id == TLS1_CK_ECDHE_PSK_WITH_AES_256_GCM_SHA384) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* add the cipher if it has not been added yet. */
|
||||
@@ -1410,15 +1415,17 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
|
||||
/* Now arrange all ciphers by preference:
|
||||
* TODO(davidben): Compute this order once and copy it. */
|
||||
|
||||
/* Everything else being equal, prefer ECDHE_ECDSA then ECDHE_RSA over other
|
||||
* key exchange mechanisms */
|
||||
/* Everything else being equal, prefer TLS 1.3 ciphers then ECDHE_ECDSA then
|
||||
* ECDHE_RSA over other key exchange mechanisms */
|
||||
|
||||
ssl_cipher_apply_rule(0, SSL_kGENERIC, SSL_aGENERIC, ~0u, ~0u, 0, CIPHER_ADD,
|
||||
-1, 0, &head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1,
|
||||
0, &head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0,
|
||||
&head, &tail);
|
||||
ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0,
|
||||
&head, &tail);
|
||||
ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0, &head,
|
||||
&tail);
|
||||
|
||||
/* Order the bulk ciphers. First the preferred AEAD ciphers. We prefer
|
||||
* CHACHA20 unless there is hardware support for fast and constant-time
|
||||
@@ -1458,7 +1465,7 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
|
||||
&tail);
|
||||
|
||||
/* Move ciphers without forward secrecy to the end. */
|
||||
ssl_cipher_apply_rule(0, ~(SSL_kDHE | SSL_kECDHE), ~0u, ~0u, ~0u, 0,
|
||||
ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0,
|
||||
CIPHER_ORD, -1, 0, &head, &tail);
|
||||
|
||||
/* Now disable everything (maintaining the ordering!) */
|
||||
@@ -1569,30 +1576,6 @@ uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) {
|
||||
return id & 0xffff;
|
||||
}
|
||||
|
||||
int ssl_cipher_get_ecdhe_psk_cipher(const SSL_CIPHER *cipher,
|
||||
uint16_t *out_cipher) {
|
||||
switch (cipher->id) {
|
||||
case TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
|
||||
case TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
|
||||
case TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
|
||||
*out_cipher = TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 & 0xffff;
|
||||
return 1;
|
||||
|
||||
case TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
|
||||
case TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
|
||||
case TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256:
|
||||
*out_cipher = TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256 & 0xffff;
|
||||
return 1;
|
||||
|
||||
case TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
|
||||
case TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
|
||||
case TLS1_CK_ECDHE_PSK_WITH_AES_256_GCM_SHA384:
|
||||
*out_cipher = TLS1_CK_ECDHE_PSK_WITH_AES_256_GCM_SHA384 & 0xffff;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher) {
|
||||
return (cipher->algorithm_enc & SSL_AES) != 0;
|
||||
}
|
||||
@@ -1656,6 +1639,11 @@ int SSL_CIPHER_is_CECPQ1(const SSL_CIPHER *cipher) {
|
||||
}
|
||||
|
||||
uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) {
|
||||
if (cipher->algorithm_mkey == SSL_kGENERIC ||
|
||||
cipher->algorithm_auth == SSL_aGENERIC) {
|
||||
return TLS1_3_VERSION;
|
||||
}
|
||||
|
||||
if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) {
|
||||
/* Cipher suites before TLS 1.2 use the default PRF, while all those added
|
||||
* afterwards specify a particular hash. */
|
||||
@@ -1665,11 +1653,8 @@ uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) {
|
||||
}
|
||||
|
||||
uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher) {
|
||||
if (cipher->algorithm_mac == SSL_AEAD &&
|
||||
(cipher->algorithm_enc & SSL_CHACHA20POLY1305_OLD) == 0 &&
|
||||
(cipher->algorithm_mkey & SSL_kECDHE) != 0 &&
|
||||
/* TODO(davidben,svaldez): Support PSK-based ciphers in TLS 1.3. */
|
||||
(cipher->algorithm_auth & SSL_aCERT) != 0) {
|
||||
if (cipher->algorithm_mkey == SSL_kGENERIC ||
|
||||
cipher->algorithm_auth == SSL_aGENERIC) {
|
||||
return TLS1_3_VERSION;
|
||||
}
|
||||
return TLS1_2_VERSION;
|
||||
@@ -1730,6 +1715,10 @@ const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) {
|
||||
assert(cipher->algorithm_auth == SSL_aPSK);
|
||||
return "PSK";
|
||||
|
||||
case SSL_kGENERIC:
|
||||
assert(cipher->algorithm_auth == SSL_aGENERIC);
|
||||
return "GENERIC";
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return "UNKNOWN";
|
||||
@@ -1788,16 +1777,23 @@ char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
|
||||
const char *enc_name = ssl_cipher_get_enc_name(cipher);
|
||||
const char *prf_name = ssl_cipher_get_prf_name(cipher);
|
||||
|
||||
/* The final name is TLS_{kx_name}_WITH_{enc_name}_{prf_name}. */
|
||||
size_t len = 4 + strlen(kx_name) + 6 + strlen(enc_name) + 1 +
|
||||
strlen(prf_name) + 1;
|
||||
/* The final name is TLS_{kx_name}_WITH_{enc_name}_{prf_name} or
|
||||
* TLS_{enc_name}_{prf_name} depending on whether the cipher is AEAD-only. */
|
||||
size_t len = 4 + strlen(enc_name) + 1 + strlen(prf_name) + 1;
|
||||
|
||||
if (cipher->algorithm_mkey != SSL_kGENERIC) {
|
||||
len += strlen(kx_name) + 6;
|
||||
}
|
||||
|
||||
char *ret = OPENSSL_malloc(len);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (BUF_strlcpy(ret, "TLS_", len) >= len ||
|
||||
BUF_strlcat(ret, kx_name, len) >= len ||
|
||||
BUF_strlcat(ret, "_WITH_", len) >= len ||
|
||||
(cipher->algorithm_mkey != SSL_kGENERIC &&
|
||||
(BUF_strlcat(ret, kx_name, len) >= len ||
|
||||
BUF_strlcat(ret, "_WITH_", len) >= len)) ||
|
||||
BUF_strlcat(ret, enc_name, len) >= len ||
|
||||
BUF_strlcat(ret, "_", len) >= len ||
|
||||
BUF_strlcat(ret, prf_name, len) >= len) {
|
||||
@@ -1805,6 +1801,7 @@ char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(strlen(ret) + 1 == len);
|
||||
return ret;
|
||||
}
|
||||
@@ -1885,6 +1882,10 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
|
||||
kx = "PSK";
|
||||
break;
|
||||
|
||||
case SSL_kGENERIC:
|
||||
kx = "GENERIC";
|
||||
break;
|
||||
|
||||
default:
|
||||
kx = "unknown";
|
||||
}
|
||||
@@ -1902,6 +1903,10 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
|
||||
au = "PSK";
|
||||
break;
|
||||
|
||||
case SSL_aGENERIC:
|
||||
au = "GENERIC";
|
||||
break;
|
||||
|
||||
default:
|
||||
au = "unknown";
|
||||
break;
|
||||
|
||||
+8
-1
@@ -1515,7 +1515,8 @@ uint16_t SSL_get_curve_id(const SSL *ssl) {
|
||||
SSL_SESSION *session = SSL_get_session(ssl);
|
||||
if (session == NULL ||
|
||||
session->cipher == NULL ||
|
||||
!SSL_CIPHER_is_ECDHE(session->cipher)) {
|
||||
(ssl3_protocol_version(ssl) < TLS1_3_VERSION &&
|
||||
!SSL_CIPHER_is_ECDHE(session->cipher))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2030,6 +2031,12 @@ size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
|
||||
|
||||
void ssl_get_compatible_server_ciphers(SSL *ssl, uint32_t *out_mask_k,
|
||||
uint32_t *out_mask_a) {
|
||||
if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
|
||||
*out_mask_k = SSL_kGENERIC;
|
||||
*out_mask_a = SSL_aGENERIC;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t mask_k = 0;
|
||||
uint32_t mask_a = 0;
|
||||
|
||||
|
||||
+28
-24
@@ -814,30 +814,34 @@ typedef struct {
|
||||
} CIPHER_RFC_NAME_TEST;
|
||||
|
||||
static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
|
||||
{ SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
|
||||
{ TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
|
||||
{ TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
|
||||
{ TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
|
||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
|
||||
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
|
||||
{ TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
|
||||
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
|
||||
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
|
||||
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
|
||||
{ TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
|
||||
{ TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
|
||||
// These names are non-standard:
|
||||
{ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
|
||||
{ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
|
||||
{SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
|
||||
{TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
|
||||
{TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
|
||||
{TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
|
||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
|
||||
{TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
|
||||
{TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
|
||||
{TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
|
||||
{TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
|
||||
{TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
|
||||
{TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
|
||||
{TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
|
||||
{TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
|
||||
{TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
|
||||
{TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
|
||||
|
||||
// These names are non-standard:
|
||||
{TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
|
||||
{TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
|
||||
};
|
||||
|
||||
static bool TestCipherGetRFCName(void) {
|
||||
|
||||
+19
-13
@@ -1240,13 +1240,10 @@ static int ext_ocsp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* OCSP stapling is forbidden on a non-certificate cipher. */
|
||||
if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
|
||||
if (CBS_len(contents) != 0) {
|
||||
/* OCSP stapling is forbidden on non-certificate ciphers. */
|
||||
if (CBS_len(contents) != 0 ||
|
||||
!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1258,6 +1255,11 @@ static int ext_ocsp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* In TLS 1.3, OCSP stapling is forbidden on resumption. */
|
||||
if (ssl->s3->session_reused) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t status_type;
|
||||
CBS ocsp_response;
|
||||
if (!CBS_get_u8(contents, &status_type) ||
|
||||
@@ -1298,7 +1300,9 @@ static int ext_ocsp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
|
||||
static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
|
||||
if (!ssl->s3->tmp.ocsp_stapling_requested ||
|
||||
ssl->ctx->ocsp_response_length == 0 ||
|
||||
!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
|
||||
ssl->s3->session_reused ||
|
||||
(ssl3_protocol_version(ssl) < TLS1_3_VERSION &&
|
||||
!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2231,8 +2235,13 @@ int ssl_ext_key_share_parse_clienthello(SSL *ssl, int *out_found,
|
||||
uint8_t *out_alert, CBS *contents) {
|
||||
uint16_t group_id;
|
||||
CBS key_shares;
|
||||
if (!tls1_get_shared_group(ssl, &group_id) ||
|
||||
!CBS_get_u16_length_prefixed(contents, &key_shares) ||
|
||||
if (!tls1_get_shared_group(ssl, &group_id)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP);
|
||||
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CBS_get_u16_length_prefixed(contents, &key_shares) ||
|
||||
CBS_len(contents) != 0) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
||||
return 0;
|
||||
@@ -2286,6 +2295,7 @@ int ssl_ext_key_share_parse_clienthello(SSL *ssl, int *out_found,
|
||||
OPENSSL_free(secret);
|
||||
SSL_ECDH_CTX_cleanup(&group);
|
||||
CBB_cleanup(&public_key);
|
||||
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2298,10 +2308,6 @@ int ssl_ext_key_share_parse_clienthello(SSL *ssl, int *out_found,
|
||||
}
|
||||
|
||||
int ssl_ext_key_share_add_serverhello(SSL *ssl, CBB *out) {
|
||||
if (ssl->s3->tmp.new_cipher->algorithm_mkey != SSL_kECDHE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t group_id;
|
||||
CBB kse_bytes, public_key;
|
||||
if (!tls1_get_shared_group(ssl, &group_id) ||
|
||||
|
||||
@@ -101,38 +101,20 @@ func (cs cipherSuite) hash() crypto.Hash {
|
||||
return crypto.SHA256
|
||||
}
|
||||
|
||||
// TODO(nharper): Remove this function when TLS 1.3 cipher suites get
|
||||
// refactored to break out the AEAD/PRF from everything else. Once that's
|
||||
// done, this won't be necessary anymore.
|
||||
func ecdhePSKSuite(id uint16) uint16 {
|
||||
switch id {
|
||||
case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
|
||||
return TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256:
|
||||
return TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384:
|
||||
return TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var cipherSuites = []*cipherSuite{
|
||||
// Ciphersuite order is chosen so that ECDHE comes before plain RSA
|
||||
// and RC4 comes before AES (because of the Lucky13 attack).
|
||||
{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteTLS13, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteTLS13, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, nil, suiteTLS13, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, nil, suiteTLS13, nil, nil, aeadAESGCM},
|
||||
{TLS_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, nil, suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, noIV, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old},
|
||||
{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, noIV, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteTLS13, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteTLS13, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, noIV, ecdheRSAKA, suiteECDHE | suiteNoDTLS, cipherRC4, macSHA1, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, noIV, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteNoDTLS, cipherRC4, macSHA1, nil},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
|
||||
@@ -164,9 +146,7 @@ var cipherSuites = []*cipherSuite{
|
||||
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, ivLen3DES, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
|
||||
{TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, ivLen3DES, dheRSAKA, 0, cipher3DES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, ivLen3DES, rsaKA, 0, cipher3DES, macSHA1, nil},
|
||||
{TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12 | suiteTLS13, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12 | suiteTLS13, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12 | suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
|
||||
{TLS_PSK_WITH_RC4_128_SHA, 16, 20, noIV, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil},
|
||||
@@ -562,8 +542,9 @@ const (
|
||||
const (
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD uint16 = 0xcc13
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD uint16 = 0xcc14
|
||||
TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0xd001
|
||||
TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0xd002
|
||||
TLS_AES_128_GCM_SHA256 uint16 = 0x1301
|
||||
TLS_AES_256_GCM_SHA384 uint16 = 0x1302
|
||||
TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
|
||||
TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0x16b7
|
||||
TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0x16b8
|
||||
TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x16b9
|
||||
|
||||
@@ -27,7 +27,7 @@ const (
|
||||
)
|
||||
|
||||
// A draft version of TLS 1.3 that is sent over the wire for the current draft.
|
||||
const tls13DraftVersion = 0x7f0e
|
||||
const tls13DraftVersion = 0x7f0f
|
||||
|
||||
const (
|
||||
maxPlaintext = 16384 // maximum plaintext payload length
|
||||
@@ -1026,6 +1026,18 @@ type ProtocolBugs struct {
|
||||
// advertised in server extensions
|
||||
AdvertiseTicketExtension bool
|
||||
|
||||
// NegotiatePSKResumption, if true, causes the server to attempt pure PSK
|
||||
// resumption.
|
||||
NegotiatePSKResumption bool
|
||||
|
||||
// OmitServerHelloSignatureAlgorithms, if true, causes the server to omit the
|
||||
// signature_algorithms extension in the ServerHello.
|
||||
OmitServerHelloSignatureAlgorithms bool
|
||||
|
||||
// IncludeServerHelloSignatureAlgorithms, if true, causes the server to
|
||||
// include the signature_algorithms extension in all ServerHellos.
|
||||
IncludeServerHelloSignatureAlgorithms bool
|
||||
|
||||
// MissingKeyShare, if true, causes the TLS 1.3 implementation to skip
|
||||
// sending a key_share extension and use the zero ECDHE secret
|
||||
// instead.
|
||||
|
||||
@@ -217,24 +217,10 @@ NextCipherSuite:
|
||||
// Check that the ciphersuite/version used for the
|
||||
// previous session are still valid.
|
||||
cipherSuiteOk := false
|
||||
if candidateSession.vers >= VersionTLS13 {
|
||||
// Account for ciphers changing on resumption.
|
||||
//
|
||||
// TODO(davidben): This will be gone with the
|
||||
// new cipher negotiation scheme.
|
||||
resumeCipher := ecdhePSKSuite(candidateSession.cipherSuite)
|
||||
for _, id := range hello.cipherSuites {
|
||||
if ecdhePSKSuite(id) == resumeCipher {
|
||||
cipherSuiteOk = true
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, id := range hello.cipherSuites {
|
||||
if id == candidateSession.cipherSuite {
|
||||
cipherSuiteOk = true
|
||||
break
|
||||
}
|
||||
for _, id := range hello.cipherSuites {
|
||||
if id == candidateSession.cipherSuite {
|
||||
cipherSuiteOk = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +260,6 @@ NextCipherSuite:
|
||||
}
|
||||
|
||||
hello.pskIdentities = []pskIdentity{psk}
|
||||
hello.cipherSuites = append(hello.cipherSuites, ecdhePSKSuite(session.cipherSuite))
|
||||
}
|
||||
|
||||
if session.vers < VersionTLS13 || c.config.Bugs.SendBothTickets {
|
||||
@@ -606,10 +591,10 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
// TODO(davidben): This will need to be handled slightly earlier once
|
||||
// 0-RTT is implemented.
|
||||
var psk []byte
|
||||
if hs.suite.flags&suitePSK != 0 {
|
||||
if !hs.serverHello.hasPSKIdentity {
|
||||
c.sendAlert(alertMissingExtension)
|
||||
return errors.New("tls: server omitted the PSK identity extension")
|
||||
if hs.serverHello.hasPSKIdentity {
|
||||
if hs.serverHello.useCertAuth || !hs.serverHello.hasKeyShare {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
return errors.New("tls: server omitted KeyShare or included SignatureAlgorithms on resumption.")
|
||||
}
|
||||
|
||||
// We send at most one PSK identity.
|
||||
@@ -617,17 +602,17 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
c.sendAlert(alertUnknownPSKIdentity)
|
||||
return errors.New("tls: server sent unknown PSK identity")
|
||||
}
|
||||
if ecdhePSKSuite(hs.session.cipherSuite) != hs.suite.id {
|
||||
if hs.session.cipherSuite != hs.suite.id {
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
return errors.New("tls: server sent invalid cipher suite for PSK")
|
||||
return errors.New("tls: server sent invalid cipher suite")
|
||||
}
|
||||
psk = deriveResumptionPSK(hs.suite, hs.session.masterSecret)
|
||||
hs.finishedHash.setResumptionContext(deriveResumptionContext(hs.suite, hs.session.masterSecret))
|
||||
c.didResume = true
|
||||
} else {
|
||||
if hs.serverHello.hasPSKIdentity {
|
||||
if !hs.serverHello.useCertAuth || !hs.serverHello.hasKeyShare {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
return errors.New("tls: server sent unexpected PSK identity")
|
||||
return errors.New("tls: server omitted KeyShare and SignatureAlgorithms on non-resumption.")
|
||||
}
|
||||
|
||||
psk = zeroSecret
|
||||
@@ -638,12 +623,7 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
|
||||
// Resolve ECDHE and compute the handshake secret.
|
||||
var ecdheSecret []byte
|
||||
if hs.suite.flags&suiteECDHE != 0 && !c.config.Bugs.MissingKeyShare && !c.config.Bugs.SecondClientHelloMissingKeyShare {
|
||||
if !hs.serverHello.hasKeyShare {
|
||||
c.sendAlert(alertMissingExtension)
|
||||
return errors.New("tls: server omitted the key share extension")
|
||||
}
|
||||
|
||||
if !c.config.Bugs.MissingKeyShare && !c.config.Bugs.SecondClientHelloMissingKeyShare {
|
||||
curve, ok := hs.keyShares[hs.serverHello.keyShare.group]
|
||||
if !ok {
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
@@ -657,11 +637,6 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if hs.serverHello.hasKeyShare {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
return errors.New("tls: server sent unexpected key share extension")
|
||||
}
|
||||
|
||||
ecdheSecret = zeroSecret
|
||||
}
|
||||
|
||||
@@ -692,7 +667,7 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
|
||||
var chainToSend *Certificate
|
||||
var certReq *certificateRequestMsg
|
||||
if hs.suite.flags&suitePSK != 0 {
|
||||
if !hs.serverHello.useCertAuth {
|
||||
if encryptedExtensions.extensions.ocspResponse != nil {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
return errors.New("tls: server sent OCSP response without a certificate")
|
||||
|
||||
@@ -779,6 +779,7 @@ type serverHelloMsg struct {
|
||||
keyShare keyShareEntry
|
||||
hasPSKIdentity bool
|
||||
pskIdentity uint16
|
||||
useCertAuth bool
|
||||
earlyDataIndication bool
|
||||
compressionMethod uint8
|
||||
extensions serverExtensions
|
||||
@@ -831,6 +832,10 @@ func (m *serverHelloMsg) marshal() []byte {
|
||||
extensions.addU16(2) // Length
|
||||
extensions.addU16(m.pskIdentity)
|
||||
}
|
||||
if m.useCertAuth {
|
||||
extensions.addU16(extensionSignatureAlgorithms)
|
||||
extensions.addU16(0) // Length
|
||||
}
|
||||
if m.earlyDataIndication {
|
||||
extensions.addU16(extensionEarlyData)
|
||||
extensions.addU16(0) // Length
|
||||
@@ -928,6 +933,11 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
|
||||
m.hasPSKIdentity = true
|
||||
case extensionSignatureAlgorithms:
|
||||
if len(d) != 0 {
|
||||
return false
|
||||
}
|
||||
m.useCertAuth = true
|
||||
case extensionEarlyData:
|
||||
if len(d) != 0 {
|
||||
return false
|
||||
|
||||
@@ -396,7 +396,10 @@ Curves:
|
||||
}
|
||||
}
|
||||
|
||||
_, ecdsaOk := hs.cert.PrivateKey.(*ecdsa.PrivateKey)
|
||||
if !supportedCurve {
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
return errors.New("tls: no curve supported by both client and server")
|
||||
}
|
||||
|
||||
pskIdentities := hs.clientHello.pskIdentities
|
||||
if len(pskIdentities) == 0 && len(hs.clientHello.sessionTicket) > 0 && c.config.Bugs.AcceptAnySession {
|
||||
@@ -431,46 +434,43 @@ Curves:
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if !config.Bugs.AcceptAnySession {
|
||||
if config.Bugs.AcceptAnySession {
|
||||
// Replace the cipher suite with one known to work, to
|
||||
// test cross-version resumption attempts.
|
||||
sessionState.cipherSuite = TLS_AES_128_GCM_SHA256
|
||||
} else {
|
||||
if sessionState.vers != c.vers && c.config.Bugs.AcceptAnySession {
|
||||
continue
|
||||
}
|
||||
if sessionState.ticketExpiration.Before(c.config.time()) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
suiteId := ecdhePSKSuite(sessionState.cipherSuite)
|
||||
|
||||
// Check the client offered the cipher.
|
||||
clientCipherSuites := hs.clientHello.cipherSuites
|
||||
if config.Bugs.AcceptAnySession {
|
||||
clientCipherSuites = []uint16{suiteId}
|
||||
}
|
||||
suite := mutualCipherSuite(clientCipherSuites, suiteId)
|
||||
|
||||
// Check the cipher is enabled by the server or is a resumption
|
||||
// suite of one enabled by the server. Account for the cipher
|
||||
// change on resume.
|
||||
//
|
||||
// TODO(davidben): The ecdhePSKSuite mess will be gone with the
|
||||
// new cipher negotiation scheme.
|
||||
var found bool
|
||||
for _, id := range config.cipherSuites() {
|
||||
if ecdhePSKSuite(id) == suiteId {
|
||||
found = true
|
||||
break
|
||||
cipherSuiteOk := false
|
||||
// Check that the client is still offering the ciphersuite in the session.
|
||||
for _, id := range hs.clientHello.cipherSuites {
|
||||
if id == sessionState.cipherSuite {
|
||||
cipherSuiteOk = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !cipherSuiteOk {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if suite != nil && found {
|
||||
hs.sessionState = sessionState
|
||||
hs.suite = suite
|
||||
hs.hello.hasPSKIdentity = true
|
||||
hs.hello.pskIdentity = uint16(i)
|
||||
c.didResume = true
|
||||
break
|
||||
// Check that we also support the ciphersuite from the session.
|
||||
suite := c.tryCipherSuite(sessionState.cipherSuite, c.config.cipherSuites(), c.vers, true, true)
|
||||
if suite == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
hs.sessionState = sessionState
|
||||
hs.suite = suite
|
||||
hs.hello.hasPSKIdentity = true
|
||||
hs.hello.pskIdentity = uint16(i)
|
||||
c.didResume = true
|
||||
break
|
||||
}
|
||||
|
||||
// If not resuming, select the cipher suite.
|
||||
@@ -485,7 +485,7 @@ Curves:
|
||||
}
|
||||
|
||||
for _, id := range preferenceList {
|
||||
if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, supportedCurve, ecdsaOk, false); hs.suite != nil {
|
||||
if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, true, true); hs.suite != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -505,9 +505,11 @@ Curves:
|
||||
hs.finishedHash.discardHandshakeBuffer()
|
||||
hs.writeClientHash(hs.clientHello.marshal())
|
||||
|
||||
hs.hello.useCertAuth = hs.sessionState == nil
|
||||
|
||||
// Resolve PSK and compute the early secret.
|
||||
var psk []byte
|
||||
if hs.suite.flags&suitePSK != 0 {
|
||||
if hs.sessionState != nil {
|
||||
psk = deriveResumptionPSK(hs.suite, hs.sessionState.masterSecret)
|
||||
hs.finishedHash.setResumptionContext(deriveResumptionContext(hs.suite, hs.sessionState.masterSecret))
|
||||
} else {
|
||||
@@ -517,9 +519,23 @@ Curves:
|
||||
|
||||
earlySecret := hs.finishedHash.extractKey(hs.finishedHash.zeroSecret(), psk)
|
||||
|
||||
if config.Bugs.OmitServerHelloSignatureAlgorithms {
|
||||
hs.hello.useCertAuth = false
|
||||
} else if config.Bugs.IncludeServerHelloSignatureAlgorithms {
|
||||
hs.hello.useCertAuth = true
|
||||
}
|
||||
|
||||
hs.hello.hasKeyShare = true
|
||||
if hs.sessionState != nil && config.Bugs.NegotiatePSKResumption {
|
||||
hs.hello.hasKeyShare = false
|
||||
}
|
||||
if config.Bugs.MissingKeyShare {
|
||||
hs.hello.hasKeyShare = false
|
||||
}
|
||||
|
||||
// Resolve ECDHE and compute the handshake secret.
|
||||
var ecdheSecret []byte
|
||||
if hs.suite.flags&suiteECDHE != 0 && !config.Bugs.MissingKeyShare {
|
||||
if hs.hello.hasKeyShare {
|
||||
// Look for the key share corresponding to our selected curve.
|
||||
var selectedKeyShare *keyShareEntry
|
||||
for i := range hs.clientHello.keyShares {
|
||||
@@ -671,7 +687,7 @@ Curves:
|
||||
c.out.useTrafficSecret(c.vers, hs.suite, handshakeTrafficSecret, handshakePhase, serverWrite)
|
||||
c.in.useTrafficSecret(c.vers, hs.suite, handshakeTrafficSecret, handshakePhase, clientWrite)
|
||||
|
||||
if hs.suite.flags&suitePSK == 0 {
|
||||
if hs.hello.useCertAuth {
|
||||
if hs.clientHello.ocspStapling {
|
||||
encryptedExtensions.extensions.ocspResponse = hs.cert.OCSPStaple
|
||||
}
|
||||
@@ -696,7 +712,7 @@ Curves:
|
||||
c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal())
|
||||
}
|
||||
|
||||
if hs.suite.flags&suitePSK == 0 {
|
||||
if hs.hello.useCertAuth {
|
||||
if config.ClientAuth >= RequestClientCert {
|
||||
// Request a client certificate
|
||||
certReq := &certificateRequestMsg{
|
||||
@@ -757,7 +773,7 @@ Curves:
|
||||
|
||||
hs.writeServerHash(certVerify.marshal())
|
||||
c.writeRecord(recordTypeHandshake, certVerify.marshal())
|
||||
} else {
|
||||
} else if hs.sessionState != nil {
|
||||
// Pick up certificates from the session instead.
|
||||
if len(hs.sessionState.certificates) > 0 {
|
||||
if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
|
||||
@@ -968,7 +984,7 @@ Curves:
|
||||
}
|
||||
|
||||
for _, id := range preferenceList {
|
||||
if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk, true); hs.suite != nil {
|
||||
if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -1134,7 +1150,11 @@ func (hs *serverHandshakeState) checkForResumption() bool {
|
||||
}
|
||||
}
|
||||
|
||||
if !c.config.Bugs.AcceptAnySession {
|
||||
if c.config.Bugs.AcceptAnySession {
|
||||
// Replace the cipher suite with one known to work, to test
|
||||
// cross-version resumption attempts.
|
||||
hs.sessionState.cipherSuite = TLS_RSA_WITH_AES_128_CBC_SHA
|
||||
} else {
|
||||
// Never resume a session for a different SSL version.
|
||||
if c.vers != hs.sessionState.vers {
|
||||
return false
|
||||
@@ -1154,7 +1174,8 @@ func (hs *serverHandshakeState) checkForResumption() bool {
|
||||
}
|
||||
|
||||
// Check that we also support the ciphersuite from the session.
|
||||
hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk, true)
|
||||
hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), c.vers, hs.ellipticOk, hs.ecdsaOk)
|
||||
|
||||
if hs.suite == nil {
|
||||
return false
|
||||
}
|
||||
@@ -1726,7 +1747,7 @@ func (hs *serverHandshakeState) writeHash(msg []byte, seqno uint16) {
|
||||
|
||||
// tryCipherSuite returns a cipherSuite with the given id if that cipher suite
|
||||
// is acceptable to use.
|
||||
func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk, pskOk bool) *cipherSuite {
|
||||
func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite {
|
||||
for _, supported := range supportedCipherSuites {
|
||||
if id == supported {
|
||||
var candidate *cipherSuite
|
||||
@@ -1740,10 +1761,14 @@ func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version
|
||||
if candidate == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Don't select a ciphersuite which we can't
|
||||
// support for this client.
|
||||
if (candidate.flags&suitePSK != 0) && !pskOk {
|
||||
continue
|
||||
if version >= VersionTLS13 || candidate.flags&suiteTLS13 != 0 {
|
||||
if version < VersionTLS13 || candidate.flags&suiteTLS13 == 0 {
|
||||
continue
|
||||
}
|
||||
return candidate
|
||||
}
|
||||
if (candidate.flags&suiteECDHE != 0) && !ellipticOk {
|
||||
continue
|
||||
@@ -1754,9 +1779,6 @@ func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version
|
||||
if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
|
||||
continue
|
||||
}
|
||||
if version >= VersionTLS13 && candidate.flags&suiteTLS13 == 0 {
|
||||
continue
|
||||
}
|
||||
if c.isDTLS && candidate.flags&suiteNoDTLS != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
+115
-101
@@ -789,6 +789,14 @@ func translateExpectedError(errorStr string) string {
|
||||
}
|
||||
|
||||
func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
|
||||
// Help debugging panics on the Go side.
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Fprintf(os.Stderr, "Test '%s' panicked.\n", test.name)
|
||||
panic(r)
|
||||
}
|
||||
}()
|
||||
|
||||
if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
|
||||
panic("Error expected without shouldFail in " + test.name)
|
||||
}
|
||||
@@ -1059,8 +1067,9 @@ var testCipherSuites = []struct {
|
||||
{"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
|
||||
{"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
|
||||
{"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256},
|
||||
{"ECDHE-PSK-AES128-GCM-SHA256", TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256},
|
||||
{"ECDHE-PSK-AES256-GCM-SHA384", TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384},
|
||||
{"AEAD-CHACHA20-POLY1305", TLS_CHACHA20_POLY1305_SHA256},
|
||||
{"AEAD-AES128-GCM-SHA256", TLS_AES_128_GCM_SHA256},
|
||||
{"AEAD-AES256-GCM-SHA384", TLS_AES_256_GCM_SHA384},
|
||||
{"NULL-SHA", TLS_RSA_WITH_NULL_SHA},
|
||||
}
|
||||
|
||||
@@ -1076,24 +1085,7 @@ func isTLS12Only(suiteName string) bool {
|
||||
}
|
||||
|
||||
func isTLS13Suite(suiteName string) bool {
|
||||
// Only AEADs.
|
||||
if !hasComponent(suiteName, "GCM") && !hasComponent(suiteName, "POLY1305") {
|
||||
return false
|
||||
}
|
||||
// No old CHACHA20_POLY1305.
|
||||
if hasComponent(suiteName, "CHACHA20-POLY1305-OLD") {
|
||||
return false
|
||||
}
|
||||
// Must have ECDHE.
|
||||
// TODO(davidben,svaldez): Add pure PSK support.
|
||||
if !hasComponent(suiteName, "ECDHE") {
|
||||
return false
|
||||
}
|
||||
// TODO(davidben,svaldez): Add PSK support.
|
||||
if hasComponent(suiteName, "PSK") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return strings.HasPrefix(suiteName, "AEAD-")
|
||||
}
|
||||
|
||||
func isDTLSCipher(suiteName string) bool {
|
||||
@@ -1417,19 +1409,6 @@ func addBasicTests() {
|
||||
shouldFail: true,
|
||||
expectedError: ":WRONG_CERTIFICATE_TYPE:",
|
||||
},
|
||||
{
|
||||
name: "CertMismatchRSA-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
Certificates: []Certificate{ecdsaP256Certificate},
|
||||
Bugs: ProtocolBugs{
|
||||
SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":WRONG_CERTIFICATE_TYPE:",
|
||||
},
|
||||
{
|
||||
name: "CertMismatchECDSA",
|
||||
config: Config{
|
||||
@@ -1443,24 +1422,10 @@ func addBasicTests() {
|
||||
shouldFail: true,
|
||||
expectedError: ":WRONG_CERTIFICATE_TYPE:",
|
||||
},
|
||||
{
|
||||
name: "CertMismatchECDSA-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
Certificates: []Certificate{rsaCertificate},
|
||||
Bugs: ProtocolBugs{
|
||||
SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":WRONG_CERTIFICATE_TYPE:",
|
||||
},
|
||||
{
|
||||
name: "EmptyCertificateList",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS12,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS12,
|
||||
Bugs: ProtocolBugs{
|
||||
EmptyCertificateList: true,
|
||||
},
|
||||
@@ -1471,8 +1436,7 @@ func addBasicTests() {
|
||||
{
|
||||
name: "EmptyCertificateList-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
Bugs: ProtocolBugs{
|
||||
EmptyCertificateList: true,
|
||||
},
|
||||
@@ -2427,6 +2391,10 @@ func addCipherSuiteTests() {
|
||||
shouldClientFail = true
|
||||
shouldServerFail = true
|
||||
}
|
||||
if isTLS13Suite(suite.name) && ver.version < VersionTLS13 {
|
||||
shouldClientFail = true
|
||||
shouldServerFail = true
|
||||
}
|
||||
if !isDTLSCipher(suite.name) && protocol == dtls {
|
||||
shouldClientFail = true
|
||||
shouldServerFail = true
|
||||
@@ -2622,18 +2590,21 @@ func addCipherSuiteTests() {
|
||||
testType: serverTest,
|
||||
name: "UnknownCipher",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS12,
|
||||
CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
Bugs: ProtocolBugs{
|
||||
AdvertiseAllConfiguredCiphers: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// The server must be tolerant to bogus ciphers.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: serverTest,
|
||||
name: "UnknownCipher-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CipherSuites: []uint16{bogusCipher, TLS_AES_128_GCM_SHA256},
|
||||
Bugs: ProtocolBugs{
|
||||
AdvertiseAllConfiguredCiphers: true,
|
||||
},
|
||||
@@ -2761,6 +2732,7 @@ func addBadECDSASignatureTests() {
|
||||
testCases = append(testCases, testCase{
|
||||
name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS12,
|
||||
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
Certificates: []Certificate{ecdsaP256Certificate},
|
||||
Bugs: ProtocolBugs{
|
||||
@@ -2771,6 +2743,19 @@ func addBadECDSASignatureTests() {
|
||||
shouldFail: true,
|
||||
expectedError: ":BAD_SIGNATURE:",
|
||||
})
|
||||
testCases = append(testCases, testCase{
|
||||
name: fmt.Sprintf("BadECDSA-%d-%d-TLS13", badR, badS),
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
Certificates: []Certificate{ecdsaP256Certificate},
|
||||
Bugs: ProtocolBugs{
|
||||
BadECDSAR: badR,
|
||||
BadECDSAS: badS,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":BAD_SIGNATURE:",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5271,15 +5256,12 @@ func addExtensionTests() {
|
||||
func addResumptionVersionTests() {
|
||||
for _, sessionVers := range tlsVersions {
|
||||
for _, resumeVers := range tlsVersions {
|
||||
cipher := TLS_RSA_WITH_AES_128_CBC_SHA
|
||||
if sessionVers.version >= VersionTLS13 || resumeVers.version >= VersionTLS13 {
|
||||
// TLS 1.3 only shares ciphers with TLS 1.2, so
|
||||
// we skip certain combinations and use a
|
||||
// different cipher to test with.
|
||||
cipher = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
if sessionVers.version < VersionTLS12 || resumeVers.version < VersionTLS12 {
|
||||
continue
|
||||
}
|
||||
// SSL 3.0 does not have tickets and TLS 1.3 does not
|
||||
// have session IDs, so skip their cross-resumption
|
||||
// tests.
|
||||
if (sessionVers.version >= VersionTLS13 && resumeVers.version == VersionSSL30) ||
|
||||
(resumeVers.version >= VersionTLS13 && sessionVers.version == VersionSSL30) {
|
||||
continue
|
||||
}
|
||||
|
||||
protocols := []protocol{tls}
|
||||
@@ -5298,8 +5280,7 @@ func addResumptionVersionTests() {
|
||||
name: "Resume-Client" + suffix,
|
||||
resumeSession: true,
|
||||
config: Config{
|
||||
MaxVersion: sessionVers.version,
|
||||
CipherSuites: []uint16{cipher},
|
||||
MaxVersion: sessionVers.version,
|
||||
Bugs: ProtocolBugs{
|
||||
ExpectNoTLS12Session: sessionVers.version >= VersionTLS13,
|
||||
ExpectNoTLS13PSK: sessionVers.version < VersionTLS13,
|
||||
@@ -5324,13 +5305,11 @@ func addResumptionVersionTests() {
|
||||
name: "Resume-Client-Mismatch" + suffix,
|
||||
resumeSession: true,
|
||||
config: Config{
|
||||
MaxVersion: sessionVers.version,
|
||||
CipherSuites: []uint16{cipher},
|
||||
MaxVersion: sessionVers.version,
|
||||
},
|
||||
expectedVersion: sessionVers.version,
|
||||
resumeConfig: &Config{
|
||||
MaxVersion: resumeVers.version,
|
||||
CipherSuites: []uint16{cipher},
|
||||
MaxVersion: resumeVers.version,
|
||||
Bugs: ProtocolBugs{
|
||||
AcceptAnySession: true,
|
||||
},
|
||||
@@ -5346,13 +5325,11 @@ func addResumptionVersionTests() {
|
||||
name: "Resume-Client-NoResume" + suffix,
|
||||
resumeSession: true,
|
||||
config: Config{
|
||||
MaxVersion: sessionVers.version,
|
||||
CipherSuites: []uint16{cipher},
|
||||
MaxVersion: sessionVers.version,
|
||||
},
|
||||
expectedVersion: sessionVers.version,
|
||||
resumeConfig: &Config{
|
||||
MaxVersion: resumeVers.version,
|
||||
CipherSuites: []uint16{cipher},
|
||||
MaxVersion: resumeVers.version,
|
||||
},
|
||||
newSessionsOnResume: true,
|
||||
expectResumeRejected: true,
|
||||
@@ -5365,14 +5342,12 @@ func addResumptionVersionTests() {
|
||||
name: "Resume-Server" + suffix,
|
||||
resumeSession: true,
|
||||
config: Config{
|
||||
MaxVersion: sessionVers.version,
|
||||
CipherSuites: []uint16{cipher},
|
||||
MaxVersion: sessionVers.version,
|
||||
},
|
||||
expectedVersion: sessionVers.version,
|
||||
expectResumeRejected: sessionVers.version != resumeVers.version,
|
||||
resumeConfig: &Config{
|
||||
MaxVersion: resumeVers.version,
|
||||
CipherSuites: []uint16{cipher},
|
||||
MaxVersion: resumeVers.version,
|
||||
Bugs: ProtocolBugs{
|
||||
SendBothTickets: true,
|
||||
},
|
||||
@@ -5406,13 +5381,13 @@ func addResumptionVersionTests() {
|
||||
resumeSession: true,
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
|
||||
},
|
||||
resumeConfig: &Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
|
||||
Bugs: ProtocolBugs{
|
||||
SendCipherSuite: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
|
||||
SendCipherSuite: TLS_AES_256_GCM_SHA384,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
@@ -5841,6 +5816,7 @@ func addSignatureAlgorithmTests() {
|
||||
// Not all ciphers involve a signature. Advertise a list which gives all
|
||||
// versions a signing cipher.
|
||||
signingCiphers := []uint16{
|
||||
TLS_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
@@ -6113,8 +6089,7 @@ func addSignatureAlgorithmTests() {
|
||||
testType: serverTest,
|
||||
name: "ServerAuth-SignatureType-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
VerifySignatureAlgorithms: []signatureAlgorithm{
|
||||
signatureECDSAWithP521AndSHA512,
|
||||
signatureRSAPKCS1WithSHA384,
|
||||
@@ -6185,8 +6160,7 @@ func addSignatureAlgorithmTests() {
|
||||
testCases = append(testCases, testCase{
|
||||
name: "Verify-ServerAuth-SignatureType-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
SignSignatureAlgorithms: []signatureAlgorithm{
|
||||
signatureRSAPSSWithSHA256,
|
||||
},
|
||||
@@ -6299,8 +6273,7 @@ func addSignatureAlgorithmTests() {
|
||||
testType: serverTest,
|
||||
name: "ServerAuth-NoFallback-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
VerifySignatureAlgorithms: []signatureAlgorithm{
|
||||
signatureRSAPKCS1WithSHA1,
|
||||
},
|
||||
@@ -6369,8 +6342,7 @@ func addSignatureAlgorithmTests() {
|
||||
testCases = append(testCases, testCase{
|
||||
name: "ServerAuth-Enforced-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
SignSignatureAlgorithms: []signatureAlgorithm{
|
||||
signatureRSAPKCS1WithMD5,
|
||||
},
|
||||
@@ -6532,7 +6504,6 @@ func addSignatureAlgorithmTests() {
|
||||
name: "CheckLeafCurve-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
Certificates: []Certificate{ecdsaP256Certificate},
|
||||
},
|
||||
flags: []string{"-p384-only"},
|
||||
@@ -6556,7 +6527,6 @@ func addSignatureAlgorithmTests() {
|
||||
name: "ECDSACurveMismatch-Verify-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
Certificates: []Certificate{ecdsaP256Certificate},
|
||||
SignSignatureAlgorithms: []signatureAlgorithm{
|
||||
signatureECDSAWithP384AndSHA384,
|
||||
@@ -6575,8 +6545,7 @@ func addSignatureAlgorithmTests() {
|
||||
testType: serverTest,
|
||||
name: "ECDSACurveMismatch-Sign-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
VerifySignatureAlgorithms: []signatureAlgorithm{
|
||||
signatureECDSAWithP384AndSHA384,
|
||||
signatureECDSAWithP256AndSHA256,
|
||||
@@ -7207,7 +7176,6 @@ func addCurveTests() {
|
||||
name: "CurveTest-Client-" + curve.name + "-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CurvePreferences: []CurveID{curve.id},
|
||||
},
|
||||
flags: []string{
|
||||
@@ -7235,7 +7203,6 @@ func addCurveTests() {
|
||||
name: "CurveTest-Server-" + curve.name + "-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CurvePreferences: []CurveID{curve.id},
|
||||
},
|
||||
flags: []string{
|
||||
@@ -7251,11 +7218,22 @@ func addCurveTests() {
|
||||
testType: serverTest,
|
||||
name: "UnknownCurve",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS12,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CurvePreferences: []CurveID{bogusCurve, CurveP256},
|
||||
},
|
||||
})
|
||||
|
||||
// The server must be tolerant to bogus curves.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: serverTest,
|
||||
name: "UnknownCurve-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CurvePreferences: []CurveID{bogusCurve, CurveP256},
|
||||
},
|
||||
})
|
||||
|
||||
// The server must not consider ECDHE ciphers when there are no
|
||||
// supported curves.
|
||||
testCases = append(testCases, testCase{
|
||||
@@ -7275,14 +7253,13 @@ func addCurveTests() {
|
||||
testType: serverTest,
|
||||
name: "NoSupportedCurves-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
Bugs: ProtocolBugs{
|
||||
NoSupportedCurves: true,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":NO_SHARED_CIPHER:",
|
||||
expectedError: ":NO_SHARED_GROUP:",
|
||||
})
|
||||
|
||||
// The server must fall back to another cipher when there are no
|
||||
@@ -7317,8 +7294,7 @@ func addCurveTests() {
|
||||
testCases = append(testCases, testCase{
|
||||
name: "BadECDHECurve-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
Bugs: ProtocolBugs{
|
||||
SendCurve: bogusCurve,
|
||||
},
|
||||
@@ -7347,8 +7323,7 @@ func addCurveTests() {
|
||||
// HelloRetryRequest requests an unsupported curve.
|
||||
name: "UnsupportedCurve-ServerHello-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS12,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
MaxVersion: VersionTLS13,
|
||||
CurvePreferences: []CurveID{CurveP384},
|
||||
Bugs: ProtocolBugs{
|
||||
SendCurve: CurveP256,
|
||||
@@ -7377,7 +7352,6 @@ func addCurveTests() {
|
||||
name: "InvalidECDHPoint-Client-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CurvePreferences: []CurveID{CurveP256},
|
||||
Bugs: ProtocolBugs{
|
||||
InvalidECDHPoint: true,
|
||||
@@ -7405,7 +7379,6 @@ func addCurveTests() {
|
||||
name: "InvalidECDHPoint-Server-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
CurvePreferences: []CurveID{CurveP256},
|
||||
Bugs: ProtocolBugs{
|
||||
InvalidECDHPoint: true,
|
||||
@@ -8298,6 +8271,47 @@ func addTrailingMessageDataTests() {
|
||||
}
|
||||
|
||||
func addTLS13HandshakeTests() {
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "NegotiatePSKResumption-TLS13",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
Bugs: ProtocolBugs{
|
||||
NegotiatePSKResumption: true,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
shouldFail: true,
|
||||
expectedError: ":UNEXPECTED_EXTENSION:",
|
||||
})
|
||||
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "OmitServerHelloSignatureAlgorithms",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
Bugs: ProtocolBugs{
|
||||
OmitServerHelloSignatureAlgorithms: true,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":UNEXPECTED_EXTENSION:",
|
||||
})
|
||||
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "IncludeServerHelloSignatureAlgorithms",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
Bugs: ProtocolBugs{
|
||||
IncludeServerHelloSignatureAlgorithms: true,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
shouldFail: true,
|
||||
expectedError: ":UNEXPECTED_EXTENSION:",
|
||||
})
|
||||
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "MissingKeyShare-Client",
|
||||
@@ -8308,7 +8322,7 @@ func addTLS13HandshakeTests() {
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":MISSING_KEY_SHARE:",
|
||||
expectedError: ":UNEXPECTED_EXTENSION:",
|
||||
})
|
||||
|
||||
testCases = append(testCases, testCase{
|
||||
|
||||
+76
-99
@@ -145,9 +145,30 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
assert(ssl->s3->have_version);
|
||||
memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
|
||||
|
||||
const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite);
|
||||
if (cipher == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
/* Check if the cipher is disabled. */
|
||||
if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
|
||||
(cipher->algorithm_auth & ssl->cert->mask_a) ||
|
||||
SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
|
||||
SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
|
||||
!sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
/* Parse out the extensions. */
|
||||
int have_key_share = 0, have_pre_shared_key = 0;
|
||||
CBS key_share, pre_shared_key;
|
||||
int have_key_share = 0, have_pre_shared_key = 0, have_sigalgs = 0;
|
||||
CBS key_share, pre_shared_key, sigalgs;
|
||||
while (CBS_len(&extensions) != 0) {
|
||||
uint16_t type;
|
||||
CBS extension;
|
||||
@@ -177,6 +198,15 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
pre_shared_key = extension;
|
||||
have_pre_shared_key = 1;
|
||||
break;
|
||||
case TLSEXT_TYPE_signature_algorithms:
|
||||
if (have_sigalgs) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
sigalgs = extension;
|
||||
have_sigalgs = 1;
|
||||
break;
|
||||
default:
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
|
||||
@@ -184,8 +214,12 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
}
|
||||
}
|
||||
|
||||
assert(ssl->s3->have_version);
|
||||
memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
|
||||
/* We only support PSK_AUTH and PSK_DHE_KE. */
|
||||
if (!have_key_share || have_sigalgs == have_pre_shared_key) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
uint8_t alert = SSL_AD_DECODE_ERROR;
|
||||
if (have_pre_shared_key) {
|
||||
@@ -207,6 +241,12 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
if (ssl->session->cipher != cipher) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
if (!ssl_session_is_context_valid(ssl, ssl->session)) {
|
||||
/* This is actually a client application bug. */
|
||||
OPENSSL_PUT_ERROR(SSL,
|
||||
@@ -224,109 +264,56 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
ssl_set_session(ssl, NULL);
|
||||
} else {
|
||||
if (!ssl_get_new_session(ssl, 0)) {
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
}
|
||||
|
||||
const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite);
|
||||
if (cipher == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
} else if (!ssl_get_new_session(ssl, 0)) {
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
if (!ssl->s3->session_reused) {
|
||||
/* Check if the cipher is disabled. */
|
||||
if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
|
||||
(cipher->algorithm_auth & ssl->cert->mask_a) ||
|
||||
SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
|
||||
SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
|
||||
!sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
} else {
|
||||
uint16_t resumption_cipher;
|
||||
if (!ssl_cipher_get_ecdhe_psk_cipher(ssl->s3->new_session->cipher,
|
||||
&resumption_cipher) ||
|
||||
resumption_cipher != ssl_cipher_get_value(cipher)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
}
|
||||
|
||||
ssl->s3->new_session->cipher = cipher;
|
||||
ssl->s3->tmp.new_cipher = cipher;
|
||||
|
||||
/* The PRF hash is now known. Set up the key schedule. */
|
||||
static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
|
||||
size_t resumption_ctx_len =
|
||||
size_t hash_len =
|
||||
EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
|
||||
|
||||
/* Derive resumption material. */
|
||||
uint8_t resumption_ctx[EVP_MAX_MD_SIZE] = {0};
|
||||
uint8_t psk_secret[EVP_MAX_MD_SIZE] = {0};
|
||||
if (ssl->s3->session_reused) {
|
||||
uint8_t resumption_ctx[EVP_MAX_MD_SIZE];
|
||||
if (!tls13_resumption_context(ssl, resumption_ctx, resumption_ctx_len,
|
||||
if (!tls13_resumption_context(ssl, resumption_ctx, hash_len,
|
||||
ssl->s3->new_session) ||
|
||||
!tls13_init_key_schedule(ssl, resumption_ctx, resumption_ctx_len)) {
|
||||
!tls13_resumption_psk(ssl, psk_secret, hash_len,
|
||||
ssl->s3->new_session)) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
} else if (!tls13_init_key_schedule(ssl, kZeroes, resumption_ctx_len)) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
/* Resolve PSK and incorporate it into the secret. */
|
||||
if (cipher->algorithm_auth == SSL_aPSK) {
|
||||
if (!ssl->s3->session_reused) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
uint8_t resumption_psk[EVP_MAX_MD_SIZE];
|
||||
if (!tls13_resumption_psk(ssl, resumption_psk, hs->hash_len,
|
||||
ssl->s3->new_session) ||
|
||||
!tls13_advance_key_schedule(ssl, resumption_psk, hs->hash_len)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
} else if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
|
||||
/* Set up the key schedule, hash in the ClientHello, and incorporate the PSK
|
||||
* into the running secret. */
|
||||
if (!tls13_init_key_schedule(ssl, resumption_ctx, hash_len) ||
|
||||
!tls13_advance_key_schedule(ssl, psk_secret, hash_len)) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
/* Resolve ECDHE and incorporate it into the secret. */
|
||||
if (cipher->algorithm_mkey == SSL_kECDHE) {
|
||||
if (!have_key_share) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
uint8_t *dhe_secret;
|
||||
size_t dhe_secret_len;
|
||||
if (!ssl_ext_key_share_parse_serverhello(ssl, &dhe_secret, &dhe_secret_len,
|
||||
&alert, &key_share)) {
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
uint8_t *dhe_secret;
|
||||
size_t dhe_secret_len;
|
||||
if (!ssl_ext_key_share_parse_serverhello(ssl, &dhe_secret, &dhe_secret_len,
|
||||
&alert, &key_share)) {
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
int ok = tls13_advance_key_schedule(ssl, dhe_secret, dhe_secret_len);
|
||||
if (!tls13_advance_key_schedule(ssl, dhe_secret, dhe_secret_len)) {
|
||||
OPENSSL_free(dhe_secret);
|
||||
if (!ok) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
} else {
|
||||
if (have_key_share) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
return ssl_hs_error;
|
||||
}
|
||||
OPENSSL_free(dhe_secret);
|
||||
|
||||
if (have_sigalgs &&
|
||||
CBS_len(&sigalgs) != 0) {
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
/* If there was no HelloRetryRequest, the version negotiation logic has
|
||||
@@ -374,8 +361,8 @@ static enum ssl_hs_wait_t do_process_certificate_request(SSL *ssl,
|
||||
SSL_HANDSHAKE *hs) {
|
||||
ssl->s3->tmp.cert_request = 0;
|
||||
|
||||
/* CertificateRequest may only be sent in certificate-based ciphers. */
|
||||
if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
|
||||
/* CertificateRequest may only be sent in non-resumption handshakes. */
|
||||
if (ssl->s3->session_reused) {
|
||||
hs->state = state_process_server_finished;
|
||||
return ssl_hs_ok;
|
||||
}
|
||||
@@ -436,15 +423,6 @@ static enum ssl_hs_wait_t do_process_server_certificate(SSL *ssl,
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
/* Check the certificate matches the cipher suite.
|
||||
*
|
||||
* TODO(davidben): Remove this check when switching to the new TLS 1.3 cipher
|
||||
* suite negotiation. */
|
||||
if (!ssl_check_leaf_certificate(ssl, ssl->s3->new_session->peer)) {
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
hs->state = state_process_server_certificate_verify;
|
||||
return ssl_hs_read_message;
|
||||
}
|
||||
@@ -464,7 +442,6 @@ static enum ssl_hs_wait_t do_process_server_certificate_verify(
|
||||
static enum ssl_hs_wait_t do_process_server_finished(SSL *ssl,
|
||||
SSL_HANDSHAKE *hs) {
|
||||
static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
|
||||
|
||||
if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
|
||||
!tls13_process_finished(ssl) ||
|
||||
!ssl->method->hash_current_message(ssl) ||
|
||||
|
||||
+38
-55
@@ -51,32 +51,11 @@ enum server_hs_state_t {
|
||||
|
||||
static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
|
||||
|
||||
static int resolve_psk_secret(SSL *ssl) {
|
||||
SSL_HANDSHAKE *hs = ssl->s3->hs;
|
||||
|
||||
if (ssl->s3->tmp.new_cipher->algorithm_auth != SSL_aPSK) {
|
||||
return tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len);
|
||||
}
|
||||
|
||||
uint8_t resumption_psk[EVP_MAX_MD_SIZE];
|
||||
if (!tls13_resumption_psk(ssl, resumption_psk, hs->hash_len,
|
||||
ssl->s3->new_session) ||
|
||||
!tls13_advance_key_schedule(ssl, resumption_psk, hs->hash_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int resolve_ecdhe_secret(SSL *ssl, int *out_need_retry,
|
||||
struct ssl_early_callback_ctx *early_ctx) {
|
||||
*out_need_retry = 0;
|
||||
SSL_HANDSHAKE *hs = ssl->s3->hs;
|
||||
|
||||
if (ssl->s3->tmp.new_cipher->algorithm_mkey != SSL_kECDHE) {
|
||||
return tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len);
|
||||
}
|
||||
|
||||
/* We only support connections that include an ECDHE key exchange. */
|
||||
CBS key_share;
|
||||
if (!ssl_early_callback_get_extension(early_ctx, &key_share,
|
||||
TLSEXT_TYPE_key_share)) {
|
||||
@@ -139,13 +118,11 @@ static enum ssl_hs_wait_t do_process_client_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t resumption_cipher;
|
||||
if (session != NULL &&
|
||||
/* Only resume if the session's version matches. */
|
||||
(session->ssl_version != ssl->version ||
|
||||
!ssl_cipher_get_ecdhe_psk_cipher(session->cipher, &resumption_cipher) ||
|
||||
!ssl_client_cipher_list_contains_cipher(&client_hello,
|
||||
resumption_cipher))) {
|
||||
!ssl_client_cipher_list_contains_cipher(
|
||||
&client_hello, (uint16_t)SSL_CIPHER_get_id(session->cipher)))) {
|
||||
SSL_SESSION_free(session);
|
||||
session = NULL;
|
||||
}
|
||||
@@ -227,39 +204,32 @@ static enum ssl_hs_wait_t do_select_parameters(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
}
|
||||
|
||||
ssl->s3->new_session->cipher = cipher;
|
||||
ssl->s3->tmp.new_cipher = cipher;
|
||||
} else {
|
||||
uint16_t resumption_cipher;
|
||||
if (!ssl_cipher_get_ecdhe_psk_cipher(ssl->s3->new_session->cipher,
|
||||
&resumption_cipher)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
ssl->s3->tmp.new_cipher = SSL_get_cipher_by_value(resumption_cipher);
|
||||
}
|
||||
|
||||
ssl->s3->tmp.new_cipher = ssl->s3->new_session->cipher;
|
||||
ssl->method->received_flight(ssl);
|
||||
|
||||
/* The PRF hash is now known. Set up the key schedule and hash the
|
||||
* ClientHello. */
|
||||
size_t resumption_ctx_len =
|
||||
|
||||
/* The PRF hash is now known. */
|
||||
size_t hash_len =
|
||||
EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
|
||||
|
||||
/* Derive resumption material. */
|
||||
uint8_t resumption_ctx[EVP_MAX_MD_SIZE] = {0};
|
||||
uint8_t psk_secret[EVP_MAX_MD_SIZE] = {0};
|
||||
if (ssl->s3->session_reused) {
|
||||
uint8_t resumption_ctx[EVP_MAX_MD_SIZE];
|
||||
if (!tls13_resumption_context(ssl, resumption_ctx, resumption_ctx_len,
|
||||
if (!tls13_resumption_context(ssl, resumption_ctx, hash_len,
|
||||
ssl->s3->new_session) ||
|
||||
!tls13_init_key_schedule(ssl, resumption_ctx, resumption_ctx_len)) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
} else {
|
||||
if (!tls13_init_key_schedule(ssl, kZeroes, resumption_ctx_len)) {
|
||||
!tls13_resumption_psk(ssl, psk_secret, hash_len,
|
||||
ssl->s3->new_session)) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Resolve PSK and incorporate it into the secret. */
|
||||
if (!resolve_psk_secret(ssl)) {
|
||||
/* Set up the key schedule, hash in the ClientHello, and incorporate the PSK
|
||||
* into the running secret. */
|
||||
if (!tls13_init_key_schedule(ssl, resumption_ctx, hash_len) ||
|
||||
!tls13_advance_key_schedule(ssl, psk_secret, hash_len)) {
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
@@ -345,14 +315,27 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
!CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
|
||||
!CBB_add_u16_length_prefixed(&body, &extensions) ||
|
||||
!ssl_ext_pre_shared_key_add_serverhello(ssl, &extensions) ||
|
||||
!ssl_ext_key_share_add_serverhello(ssl, &extensions) ||
|
||||
!ssl->method->finish_message(ssl, &cbb)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return ssl_hs_error;
|
||||
!ssl_ext_key_share_add_serverhello(ssl, &extensions)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ssl->s3->session_reused) {
|
||||
if (!CBB_add_u16(&extensions, TLSEXT_TYPE_signature_algorithms) ||
|
||||
!CBB_add_u16(&extensions, 0)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ssl->method->finish_message(ssl, &cbb)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
hs->state = state_send_encrypted_extensions;
|
||||
return ssl_hs_write_message;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
|
||||
static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL *ssl,
|
||||
@@ -378,8 +361,8 @@ static enum ssl_hs_wait_t do_send_certificate_request(SSL *ssl,
|
||||
SSL_HANDSHAKE *hs) {
|
||||
/* Determine whether to request a client certificate. */
|
||||
ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
|
||||
/* CertificateRequest may only be sent in certificate-based ciphers. */
|
||||
if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
|
||||
/* CertificateRequest may only be sent in non-resumption handshakes. */
|
||||
if (ssl->s3->session_reused) {
|
||||
ssl->s3->tmp.cert_request = 0;
|
||||
}
|
||||
|
||||
@@ -424,7 +407,7 @@ err:
|
||||
|
||||
static enum ssl_hs_wait_t do_send_server_certificate(SSL *ssl,
|
||||
SSL_HANDSHAKE *hs) {
|
||||
if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
|
||||
if (ssl->s3->session_reused) {
|
||||
hs->state = state_send_server_finished;
|
||||
return ssl_hs_ok;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user