Skip to content

Commit

Permalink
Disable tls 1.3 for ephemeral keys
Browse files Browse the repository at this point in the history
  • Loading branch information
sfodagain committed Dec 9, 2024
1 parent 6b06194 commit 500609f
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 22 deletions.
3 changes: 2 additions & 1 deletion include/aws/io/private/pki_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ AWS_IO_API int aws_import_key_pair_to_cert_context(
HCERTSTORE *cert_store,
PCCERT_CONTEXT *certs,
HCRYPTPROV *crypto_provider,
HCRYPTKEY *private_key_handle);
HCRYPTKEY *private_key_handle,
bool *tls13_disabled);

#endif /* _WIN32 */

Expand Down
109 changes: 93 additions & 16 deletions source/windows/secure_channel_tls_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ struct common_credential_params {
DWORD dwFlags;
PCCERT_CONTEXT *paCred;
DWORD cCreds;
DWORD enabledProtocols;
};

struct secure_channel_ctx {
Expand All @@ -77,6 +76,8 @@ struct secure_channel_ctx {
HCRYPTKEY private_key;
bool verify_peer;
bool should_free_pcerts;
enum aws_tls_versions minimum_tls_version;
bool disable_tls13;
};

struct secure_channel_handler {
Expand Down Expand Up @@ -2034,10 +2035,68 @@ static struct aws_channel_handler *s_tls_handler_new_common(
return NULL;
}

static DWORD get_enabled_protocols(const struct aws_tls_ctx_options *options, bool is_client_mode) {
static DWORD s_get_disabled_protocols(
enum aws_tls_versions minimum_tls_version,
bool is_client_mode,
bool disable_tls13) {
DWORD bit_disabled_protocols = 0;
if (is_client_mode) {
switch (minimum_tls_version) {
case AWS_IO_TLSv1_3:
#if defined(SP_PROT_TLS1_2_CLIENT)
bit_disabled_protocols |= SP_PROT_TLS1_2_CLIENT;
#endif
case AWS_IO_TLSv1_2:
bit_disabled_protocols |= SP_PROT_TLS1_1_CLIENT;
case AWS_IO_TLSv1_1:
bit_disabled_protocols |= SP_PROT_TLS1_0_CLIENT;
case AWS_IO_TLSv1:
bit_disabled_protocols |= SP_PROT_SSL3_CLIENT;
case AWS_IO_SSLv3:
break;
case AWS_IO_TLS_VER_SYS_DEFAULTS:
bit_disabled_protocols = 0;
break;
}
#if defined(SP_PROT_TLS1_3_CLIENT)
if (disable_tls13) {
bit_disabled_protocols |= SP_PROT_TLS1_3_CLIENT;
}
#endif
} else {
switch (minimum_tls_version) {
case AWS_IO_TLSv1_3:
#if defined(SP_PROT_TLS1_2_SERVER)
bit_disabled_protocols |= SP_PROT_TLS1_2_SERVER;
#endif
case AWS_IO_TLSv1_2:
bit_disabled_protocols |= SP_PROT_TLS1_1_SERVER;
case AWS_IO_TLSv1_1:
bit_disabled_protocols |= SP_PROT_TLS1_0_SERVER;
case AWS_IO_TLSv1:
bit_disabled_protocols |= SP_PROT_SSL3_SERVER;
case AWS_IO_SSLv3:
break;
case AWS_IO_TLS_VER_SYS_DEFAULTS:
bit_disabled_protocols = 0;
break;
}
#if defined(SP_PROT_TLS1_3_SERVER)
if (!disable_tls13) {
bit_disabled_protocols |= SP_PROT_TLS1_3_SERVER;
}
#endif
}
return bit_disabled_protocols;
}

static DWORD s_get_enabled_protocols(
enum aws_tls_versions minimum_tls_version,
bool is_client_mode,
bool disable_tls13) {
DWORD bit_enabled_protocols = 0;
if (is_client_mode) {
switch (options->minimum_tls_version) {
switch (minimum_tls_version) {
case AWS_IO_SSLv3:
bit_enabled_protocols |= SP_PROT_SSL3_CLIENT;
case AWS_IO_TLSv1:
Expand All @@ -2050,15 +2109,21 @@ static DWORD get_enabled_protocols(const struct aws_tls_ctx_options *options, bo
#endif
case AWS_IO_TLSv1_3:
#if defined(SP_PROT_TLS1_3_CLIENT)
bit_enabled_protocols |= SP_PROT_TLS1_3_CLIENT;
if (!disable_tls13) {
bit_enabled_protocols |= SP_PROT_TLS1_3_CLIENT;
}
#endif
break;
case AWS_IO_TLS_VER_SYS_DEFAULTS:
bit_enabled_protocols = 0;
if (disable_tls13) {
bit_enabled_protocols = s_get_enabled_protocols(AWS_IO_SSLv3, is_client_mode, disable_tls13);
} else {
bit_enabled_protocols = 0;
}
break;
}
} else {
switch (options->minimum_tls_version) {
switch (minimum_tls_version) {
case AWS_IO_SSLv3:
bit_enabled_protocols |= SP_PROT_SSL3_SERVER;
case AWS_IO_TLSv1:
Expand All @@ -2071,11 +2136,17 @@ static DWORD get_enabled_protocols(const struct aws_tls_ctx_options *options, bo
#endif
case AWS_IO_TLSv1_3:
#if defined(SP_PROT_TLS1_3_SERVER)
bit_enabled_protocols |= SP_PROT_TLS1_3_SERVER;
if (!disable_tls13) {
bit_enabled_protocols |= SP_PROT_TLS1_3_SERVER;
}
#endif
break;
case AWS_IO_TLS_VER_SYS_DEFAULTS:
bit_enabled_protocols = 0;
if (disable_tls13) {
bit_enabled_protocols = s_get_enabled_protocols(AWS_IO_SSLv3, is_client_mode, disable_tls13);
} else {
bit_enabled_protocols = 0;
}
break;
}
}
Expand All @@ -2102,11 +2173,9 @@ static struct aws_channel_handler *s_tls_handler_sch_credentials_new(
ZeroMemory(&credentials, sizeof(SCH_CREDENTIALS));

TLS_PARAMETERS tls_params = {0};
if (sc_ctx->schannel_creds.enabledProtocols == 0) {
tls_params.grbitDisabledProtocols = 0;
} else {
tls_params.grbitDisabledProtocols = ~(sc_ctx->schannel_creds.enabledProtocols);
}
tls_params.grbitDisabledProtocols =
s_get_disabled_protocols(sc_ctx->minimum_tls_version, is_client_mode, sc_ctx->disable_tls13);

credentials.pTlsParameters = &tls_params;
credentials.cTlsParameters = 1;
credentials.dwSessionLifespan = 0; /* default 10 hours */
Expand Down Expand Up @@ -2170,7 +2239,8 @@ static struct aws_channel_handler *s_tls_handler_schannel_cred_new(
credentials.dwFlags = sc_ctx->schannel_creds.dwFlags;
credentials.paCred = sc_ctx->schannel_creds.paCred;
credentials.cCreds = sc_ctx->schannel_creds.cCreds;
credentials.grbitEnabledProtocols = sc_ctx->schannel_creds.enabledProtocols;
credentials.grbitEnabledProtocols =
s_get_enabled_protocols(sc_ctx->minimum_tls_version, is_client_mode, sc_ctx->disable_tls13);

aws_tls_channel_handler_shared_init(&sc_handler->shared_state, &sc_handler->handler, options);

Expand Down Expand Up @@ -2315,7 +2385,8 @@ struct aws_tls_ctx *s_ctx_new(

secure_channel_ctx->verify_peer = options->verify_peer;
secure_channel_ctx->should_free_pcerts = true;
secure_channel_ctx->schannel_creds.enabledProtocols = get_enabled_protocols(options, is_client_mode);
secure_channel_ctx->disable_tls13 = false;
secure_channel_ctx->minimum_tls_version = options->minimum_tls_version;

if (options->verify_peer && aws_tls_options_buf_is_set(&options->ca_file)) {
AWS_LOGF_DEBUG(AWS_LS_IO_TLS, "static: loading custom CA file.");
Expand Down Expand Up @@ -2386,14 +2457,20 @@ struct aws_tls_ctx *s_ctx_new(
&secure_channel_ctx->cert_store,
&secure_channel_ctx->pcerts,
&secure_channel_ctx->crypto_provider,
&secure_channel_ctx->private_key);
&secure_channel_ctx->private_key,
&secure_channel_ctx->disable_tls13);

if (err) {
AWS_LOGF_ERROR(
AWS_LS_IO_TLS, "static: failed to import certificate and private key with error %d.", aws_last_error());
goto clean_up;
}

if (secure_channel_ctx->disable_tls13 && options->minimum_tls_version == AWS_IO_TLSv1_3) {
AWS_LOGF_ERROR(AWS_LS_IO_TLS, "static: minimum TLS version is set to 1.3, but it can't be supported");
goto clean_up;
}

pa_cred = &secure_channel_ctx->pcerts;
creds = 1;
secure_channel_ctx->should_free_pcerts = false;
Expand Down
24 changes: 19 additions & 5 deletions source/windows/windows_pki_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ static int s_cert_context_import_rsa_private_key_to_key_container(
wchar_t uuid_wstr[AWS_UUID_STR_LEN],
enum aws_rsa_private_key_container_type key_container_type,
HCRYPTPROV *out_crypto_provider,
HCRYPTKEY *out_private_key_handle) {
HCRYPTKEY *out_private_key_handle,
bool *tls13_disabled) {

/* out-params will adopt these resources if the function is successful.
* if function fails these resources will be cleaned up before returning */
Expand Down Expand Up @@ -338,6 +339,9 @@ static int s_cert_context_import_rsa_private_key_to_key_container(
aws_raise_error(AWS_ERROR_SYS_CALL_FAILURE);
goto on_error;
}
/* Secure Channel doesn't support TLS 1.3 with ephemeral keys. */
AWS_LOGF_INFO(AWS_LS_IO_PKI, "static: TLS 1.3 does not support ephemeral keys, disabling TLS 1.3");
*tls13_disabled = true;
} else {
CRYPT_KEY_PROV_INFO key_prov_info;
AWS_ZERO_STRUCT(key_prov_info);
Expand Down Expand Up @@ -385,7 +389,8 @@ static int s_cert_context_import_rsa_private_key(
bool is_client_mode,
wchar_t uuid_wstr[AWS_UUID_STR_LEN],
HCRYPTPROV *out_crypto_provider,
HCRYPTKEY *out_private_key_handle) {
HCRYPTKEY *out_private_key_handle,
bool *tls13_disabled) {

const enum aws_rsa_private_key_container_type client_available_key_container_types[] = {
AWS_RPKCT_PERSIST_TO_USER_PROFILE,
Expand Down Expand Up @@ -414,7 +419,8 @@ static int s_cert_context_import_rsa_private_key(
uuid_wstr,
available_key_container_types[i],
out_crypto_provider,
out_private_key_handle) == AWS_OP_SUCCESS) {
out_private_key_handle,
tls13_disabled) == AWS_OP_SUCCESS) {
return AWS_OP_SUCCESS;
}
}
Expand Down Expand Up @@ -611,7 +617,8 @@ int aws_import_key_pair_to_cert_context(
HCERTSTORE *store,
PCCERT_CONTEXT *certs,
HCRYPTPROV *crypto_provider,
HCRYPTKEY *private_key_handle) {
HCRYPTKEY *private_key_handle,
bool *tls13_disabled) {

struct aws_array_list certificates, private_keys;
AWS_ZERO_STRUCT(certificates);
Expand Down Expand Up @@ -789,7 +796,14 @@ int aws_import_key_pair_to_cert_context(
switch (cert_type) {
case AWS_CT_X509_RSA:
result = s_cert_context_import_rsa_private_key(
*certs, key, decoded_len, is_client_mode, uuid_wstr, crypto_provider, private_key_handle);
*certs,
key,
decoded_len,
is_client_mode,
uuid_wstr,
crypto_provider,
private_key_handle,
tls13_disabled);
break;

#ifndef AWS_SUPPORT_WIN7
Expand Down

0 comments on commit 500609f

Please sign in to comment.