-/* $OpenBSD: ssl_clnt.c,v 1.84 2021/02/22 15:59:10 jsing Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.85 2021/03/10 18:27:01 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
goto end;
}
- /* s->version=SSL3_VERSION; */
+ if (!ssl_supported_tls_version_range(s,
+ &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
+ SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
+ ret = -1;
+ goto end;
+ }
+
s->internal->type = SSL_ST_CONNECT;
if (!ssl3_setup_init_buffer(s)) {
}
s->version = server_version;
+ S3I(s)->hs.negotiated_tls_version = ssl_tls_version(server_version);
+ if (S3I(s)->hs.negotiated_tls_version == 0) {
+ SSLerror(s, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
if ((method = ssl_get_method(server_version)) == NULL) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
goto err;
/* TLS v1.2 only ciphersuites require v1.2 or later. */
if ((cipher->algorithm_ssl & SSL_TLSV1_2) &&
- (TLS1_get_version(s) < TLS1_2_VERSION)) {
+ S3I(s)->hs.negotiated_tls_version < TLS1_2_VERSION) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerror(s, SSL_R_WRONG_CIPHER_RETURNED);
goto fatal_err;
goto err;
}
+ /* XXX - our max protocol version. */
pms[0] = s->client_version >> 8;
pms[1] = s->client_version & 0xff;
arc4random_buf(&pms[2], sizeof(pms) - 2);
-/* $OpenBSD: ssl_locl.h,v 1.324 2021/02/27 14:20:50 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.325 2021/03/10 18:27:01 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
#define SSI(s) (s->session->internal)
typedef struct ssl_handshake_st {
+ /*
+ * Minimum and maximum versions supported for this handshake. These are
+ * initialised at the start of a handshake based on the method in use
+ * and the current protocol version configuration.
+ */
+ uint16_t our_min_tls_version;
+ uint16_t our_max_tls_version;
+
+ /*
+ * Version negotiated for this session. For a client this is set once
+ * the server selected version is parsed from the ServerHello (either
+ * from the legacy version or supported versions extension). For a
+ * server this is set once we select the version we will use with the
+ * client.
+ */
+ uint16_t negotiated_tls_version;
+
/* state contains one of the SSL3_ST_* values. */
int state;
} CERT_PKEY;
typedef struct ssl_handshake_tls13_st {
- uint16_t min_version;
- uint16_t max_version;
- uint16_t version;
-
int use_legacy;
int hrr;
EVP_MD_CTX *clienthello_md_ctx;
unsigned char *clienthello_hash;
unsigned int clienthello_hash_len;
-
} SSL_HANDSHAKE_TLS13;
struct tls12_record_layer;
uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver);
int ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver);
int ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver);
+uint16_t ssl_tls_version(uint16_t version);
+uint16_t ssl_effective_tls_version(SSL *s);
int ssl_downgrade_max_version(SSL *s, uint16_t *max_ver);
int ssl_max_supported_version(SSL *s, uint16_t *max_ver);
int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver);
-/* $OpenBSD: ssl_pkt.c,v 1.36 2021/02/20 14:14:16 tb Exp $ */
+/* $OpenBSD: ssl_pkt.c,v 1.37 2021/03/10 18:27:02 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* bytes and record version number > TLS 1.0.
*/
version = s->version;
- if (S3I(s)->hs.state == SSL3_ST_CW_CLNT_HELLO_B && !s->internal->renegotiate &&
- TLS1_get_version(s) > TLS1_VERSION)
+ if (S3I(s)->hs.state == SSL3_ST_CW_CLNT_HELLO_B &&
+ !s->internal->renegotiate &&
+ S3I(s)->hs.our_max_tls_version > TLS1_VERSION)
version = TLS1_VERSION;
/*
-/* $OpenBSD: ssl_sigalgs.c,v 1.22 2020/10/11 01:13:04 guenther Exp $ */
+/* $OpenBSD: ssl_sigalgs.c,v 1.23 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org>
*
int check_curve = 0;
CBS cbs;
- if (TLS1_get_version(s) >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
check_curve = 1;
* RFC 5246 allows a TLS 1.2 client to send no sigalgs, in
* which case the server must use the the default.
*/
- if (TLS1_get_version(s) < TLS1_3_VERSION &&
+ if (S3I(s)->hs.negotiated_tls_version < TLS1_3_VERSION &&
S3I(s)->hs.sigalgs == NULL) {
switch (pkey->type) {
case EVP_PKEY_RSA:
continue;
/* RSA cannot be used without PSS in TLSv1.3. */
- if (TLS1_get_version(s) >= TLS1_3_VERSION &&
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION &&
sigalg->key_type == EVP_PKEY_RSA &&
(sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
continue;
-/* $OpenBSD: ssl_srvr.c,v 1.95 2021/02/20 14:16:56 tb Exp $ */
+/* $OpenBSD: ssl_srvr.c,v 1.96 2021/03/10 18:27:02 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
goto end;
}
+ if (!ssl_supported_tls_version_range(s,
+ &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
+ SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
+ ret = -1;
+ goto end;
+ }
+
s->internal->type = SSL_ST_ACCEPT;
if (!ssl3_setup_init_buffer(s)) {
*/
if (!ssl_downgrade_max_version(s, &max_version))
goto err;
- if (ssl_max_shared_version(s, client_version, &shared_version) != 1) {
+ if (!ssl_max_shared_version(s, client_version, &shared_version)) {
if ((s->client_version >> 8) == SSL3_VERSION_MAJOR &&
!tls12_record_layer_write_protected(s->internal->rl)) {
/*
s->client_version = client_version;
s->version = shared_version;
+ S3I(s)->hs.negotiated_tls_version = ssl_tls_version(shared_version);
+ if (S3I(s)->hs.negotiated_tls_version == 0) {
+ SSLerror(s, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
if ((method = ssl_get_method(shared_version)) == NULL) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
goto err;
int al = -1;
arc4random_buf(fakekey, sizeof(fakekey));
+
+ /* XXX - peer max protocol version. */
fakekey[0] = s->client_version >> 8;
fakekey[1] = s->client_version & 0xff;
/* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */
}
+ /* XXX - peer max version. */
if ((al == -1) && !((pms[0] == (s->client_version >> 8)) &&
(pms[1] == (s->client_version & 0xff)))) {
/*
-/* $OpenBSD: ssl_tlsext.c,v 1.86 2021/02/08 17:20:47 jsing Exp $ */
+/* $OpenBSD: ssl_tlsext.c,v 1.87 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type)
{
return ssl_has_ecc_ciphers(s) ||
- (S3I(s)->hs_tls13.max_version >= TLS1_3_VERSION);
+ (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION);
}
int
int
tlsext_ri_server_needs(SSL *s, uint16_t msg_type)
{
- return (s->version < TLS1_3_VERSION && S3I(s)->send_connection_binding);
+ return (S3I(s)->hs.negotiated_tls_version < TLS1_3_VERSION &&
+ S3I(s)->send_connection_binding);
}
int
int
tlsext_sigalgs_client_needs(SSL *s, uint16_t msg_type)
{
- return (TLS1_get_client_version(s) >= TLS1_2_VERSION);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_2_VERSION);
}
int
size_t tls_sigalgs_len = tls12_sigalgs_len;
CBB sigalgs;
- if (TLS1_get_client_version(s) >= TLS1_3_VERSION &&
- S3I(s)->hs_tls13.min_version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.our_min_tls_version >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
}
int
tlsext_sigalgs_server_needs(SSL *s, uint16_t msg_type)
{
- return (s->version >= TLS1_3_VERSION);
+ return (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION);
}
int
size_t tls_sigalgs_len = tls12_sigalgs_len;
CBB sigalgs;
- if (s->version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
}
{
CBS sigalgs;
- if (s->version < TLS1_3_VERSION)
+ if (ssl_effective_tls_version(s) < TLS1_3_VERSION)
return 0;
if (!CBS_get_u16_length_prefixed(cbs, &sigalgs))
int
tlsext_ocsp_server_needs(SSL *s, uint16_t msg_type)
{
- if (s->version >= TLS1_3_VERSION &&
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION &&
s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
s->ctx->internal->tlsext_status_cb != NULL) {
s->internal->tlsext_status_expected = 0;
{
CBB ocsp_response;
- if (s->version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION) {
if (!CBB_add_u8(cbb, TLSEXT_STATUSTYPE_ocsp))
return 0;
if (!CBB_add_u24_length_prefixed(cbb, &ocsp_response))
int
tlsext_ocsp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
{
- CBS response;
- uint16_t version = TLS1_get_client_version(s);
uint8_t status_type;
+ CBS response;
- if (version >= TLS1_3_VERSION) {
+ if (ssl_effective_tls_version(s) >= TLS1_3_VERSION) {
if (msg_type == SSL_TLSEXT_MSG_CR) {
/*
* RFC 8446, 4.4.2.1 - the server may request an OCSP
int
tlsext_keyshare_client_needs(SSL *s, uint16_t msg_type)
{
- /* XXX once this gets initialized when we get tls13_client.c */
- if (S3I(s)->hs_tls13.max_version == 0)
- return 0;
- return (!SSL_is_dtls(s) && S3I(s)->hs_tls13.max_version >=
- TLS1_3_VERSION);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION);
}
int
* Ignore this client share if we're using earlier than TLSv1.3
* or we've already selected a key share.
*/
- if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION)
+ if (S3I(s)->hs.our_max_tls_version < TLS1_3_VERSION)
continue;
if (S3I(s)->hs_tls13.key_share != NULL)
continue;
int
tlsext_keyshare_server_needs(SSL *s, uint16_t msg_type)
{
- if (SSL_is_dtls(s) || s->version < TLS1_3_VERSION)
- return 0;
-
- return tlsext_extension_seen(s, TLSEXT_TYPE_key_share);
+ return (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION &&
+ tlsext_extension_seen(s, TLSEXT_TYPE_key_share));
}
int
int
tlsext_versions_client_needs(SSL *s, uint16_t msg_type)
{
- if (SSL_is_dtls(s))
- return 0;
- return (S3I(s)->hs_tls13.max_version >= TLS1_3_VERSION);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION);
}
int
uint16_t version;
CBB versions;
- max = S3I(s)->hs_tls13.max_version;
- min = S3I(s)->hs_tls13.min_version;
-
- if (min < TLS1_VERSION)
- return 0;
+ max = S3I(s)->hs.our_max_tls_version;
+ min = S3I(s)->hs.our_min_tls_version;
if (!CBB_add_u8_length_prefixed(cbb, &versions))
return 0;
uint16_t max, min;
uint16_t matched_version = 0;
- max = S3I(s)->hs_tls13.max_version;
- min = S3I(s)->hs_tls13.min_version;
+ max = S3I(s)->hs.our_max_tls_version;
+ min = S3I(s)->hs.our_min_tls_version;
if (!CBS_get_u8_length_prefixed(cbs, &versions))
goto err;
matched_version = version;
}
- /*
- * XXX if we haven't matched a version we should
- * fail - but we currently need to succeed to
- * ignore this before the server code for 1.3
- * is set up and initialized.
- */
- if (max == 0)
- return 1; /* XXX */
-
- if (matched_version != 0) {
+ if (matched_version > 0) {
+ /* XXX - this should be stored for later processing. */
s->version = matched_version;
return 1;
}
int
tlsext_versions_server_needs(SSL *s, uint16_t msg_type)
{
- return (!SSL_is_dtls(s) && s->version >= TLS1_3_VERSION);
+ return (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION);
}
int
tlsext_versions_server_build(SSL *s, uint16_t msg_type, CBB *cbb)
{
- if (!CBB_add_u16(cbb, TLS1_3_VERSION))
- return 0;
- /* XXX set 1.2 in legacy version? */
-
- return 1;
+ return CBB_add_u16(cbb, TLS1_3_VERSION);
}
int
return 0;
}
+ /* XXX - need to fix for DTLS 1.3 */
if (selected_version < TLS1_3_VERSION) {
*alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
int
tlsext_cookie_client_needs(SSL *s, uint16_t msg_type)
{
- if (SSL_is_dtls(s))
- return 0;
- if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION)
- return 0;
- return (S3I(s)->hs_tls13.cookie_len > 0 &&
- S3I(s)->hs_tls13.cookie != NULL);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION &&
+ S3I(s)->hs_tls13.cookie_len > 0 && S3I(s)->hs_tls13.cookie != NULL);
}
int
int
tlsext_cookie_server_needs(SSL *s, uint16_t msg_type)
{
-
- if (SSL_is_dtls(s))
- return 0;
- if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION)
- return 0;
/*
* Server needs to set cookie value in tls13 handshake
* in order to send one, should only be sent with HRR.
*/
- return (S3I(s)->hs_tls13.cookie_len > 0 &&
- S3I(s)->hs_tls13.cookie != NULL);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION &&
+ S3I(s)->hs_tls13.cookie_len > 0 && S3I(s)->hs_tls13.cookie != NULL);
}
int
const struct tls_extension *tlsext;
CBB extensions, extension_data;
int extensions_present = 0;
+ uint16_t tls_version;
size_t i;
- uint16_t version;
- if (is_server)
- version = s->version;
- else
- version = TLS1_get_client_version(s);
+ tls_version = ssl_effective_tls_version(s);
if (!CBB_add_u16_length_prefixed(cbb, &extensions))
return 0;
ext = tlsext_funcs(tlsext, is_server);
/* RFC 8446 Section 4.2 */
- if (version >= TLS1_3_VERSION &&
+ if (tls_version >= TLS1_3_VERSION &&
!(tlsext->messages & msg_type))
continue;
CBS extensions, extension_data;
uint16_t type;
size_t idx;
- uint16_t version;
+ uint16_t tls_version;
int alert_desc;
- S3I(s)->hs.extensions_seen = 0;
+ tls_version = ssl_effective_tls_version(s);
- if (is_server)
- version = s->version;
- else
- version = TLS1_get_client_version(s);
+ S3I(s)->hs.extensions_seen = 0;
/* An empty extensions block is valid. */
if (CBS_len(cbs) == 0)
CBS_len(&extension_data),
s->internal->tlsext_debug_arg);
- if (!SSL_is_dtls(s) && version >= TLS1_3_VERSION && is_server &&
+ if (tls_version >= TLS1_3_VERSION && is_server &&
msg_type == SSL_TLSEXT_MSG_CH) {
if (!tlsext_clienthello_hash_extension(s, type,
&extension_data))
continue;
/* RFC 8446 Section 4.2 */
- if (version >= TLS1_3_VERSION &&
+ if (tls_version >= TLS1_3_VERSION &&
!(tlsext->messages & msg_type)) {
alert_desc = SSL_AD_ILLEGAL_PARAMETER;
goto err;
-/* $OpenBSD: ssl_versions.c,v 1.13 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: ssl_versions.c,v 1.14 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
*
return 1;
}
+uint16_t
+ssl_tls_version(uint16_t version)
+{
+ if (version == TLS1_VERSION || version == TLS1_1_VERSION ||
+ version == TLS1_2_VERSION || version == TLS1_3_VERSION)
+ return version;
+
+ if (version == DTLS1_VERSION)
+ return TLS1_1_VERSION;
+ if (version == DTLS1_2_VERSION)
+ return TLS1_2_VERSION;
+
+ return 0;
+}
+
+uint16_t
+ssl_effective_tls_version(SSL *s)
+{
+ if (S3I(s)->hs.negotiated_tls_version > 0)
+ return S3I(s)->hs.negotiated_tls_version;
+
+ return S3I(s)->hs.our_max_tls_version;
+}
+
int
ssl_max_supported_version(SSL *s, uint16_t *max_ver)
{
-/* $OpenBSD: tls13_client.c,v 1.73 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: tls13_client.c,v 1.74 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
size_t groups_len;
SSL *s = ctx->ssl;
- if (!ssl_supported_tls_version_range(s, &ctx->hs->min_version,
- &ctx->hs->max_version)) {
+ if (!ssl_supported_tls_version_range(s, &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return 0;
}
- s->client_version = s->version = ctx->hs->max_version;
+ s->client_version = s->version = S3I(s)->hs.our_max_tls_version;
tls13_record_layer_set_retry_after_phh(ctx->rl,
(s->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
* legacy session identifier triggers compatibility mode (see RFC 8446
* Appendix D.4). In the pre-TLSv1.3 case a zero length value is used.
*/
- if (ctx->middlebox_compat && ctx->hs->max_version >= TLS1_3_VERSION) {
+ if (ctx->middlebox_compat &&
+ S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION) {
arc4random_buf(ctx->hs->legacy_session_id,
sizeof(ctx->hs->legacy_session_id));
ctx->hs->legacy_session_id_len =
SSL *s = ctx->ssl;
/* Legacy client version is capped at TLS 1.2. */
- client_version = ctx->hs->max_version;
+ client_version = S3I(s)->hs.our_max_tls_version;
if (client_version > TLS1_2_VERSION)
client_version = TLS1_2_VERSION;
int
tls13_client_hello_send(struct tls13_ctx *ctx, CBB *cbb)
{
- if (ctx->hs->min_version < TLS1_2_VERSION)
+ SSL *s = ctx->ssl;
+
+ if (S3I(s)->hs.our_min_tls_version < TLS1_2_VERSION)
tls13_record_layer_set_legacy_version(ctx->rl, TLS1_VERSION);
/* We may receive a pre-TLSv1.3 alert in response to the client hello. */
goto err;
if (tls13_server_hello_is_legacy(cbs)) {
- if (ctx->hs->max_version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION) {
/*
* RFC 8446 section 4.1.3: we must not downgrade if
* the server random value contains the TLS 1.2 or 1.1
ctx->alert = TLS13_ALERT_PROTOCOL_VERSION;
goto err;
}
+ S3I(s)->hs.negotiated_tls_version = ctx->hs->server_version;
/* The session_id must match. */
if (!CBS_mem_equal(&session_id, ctx->hs->legacy_session_id,
-/* $OpenBSD: tls13_server.c,v 1.70 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: tls13_server.c,v 1.71 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
{
SSL *s = ctx->ssl;
- if (!ssl_supported_tls_version_range(s, &ctx->hs->min_version,
- &ctx->hs->max_version)) {
+ if (!ssl_supported_tls_version_range(s, &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return 0;
}
- s->version = ctx->hs->max_version;
+ s->version = S3I(s)->hs.our_max_tls_version;
tls13_record_layer_set_retry_after_phh(ctx->rl,
(s->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
goto err;
return tls13_use_legacy_server(ctx);
}
+ S3I(s)->hs.negotiated_tls_version = TLS1_3_VERSION;
/* Add decoded values to the current ClientHello hash */
if (!tls13_clienthello_hash_init(ctx)) {