Skip to content

Commit

Permalink
Add support for TLS v1.3
Browse files Browse the repository at this point in the history
TLS v1.3 is available on windows 10.0.17763 and above version.
  • Loading branch information
windowsair authored and laudrup committed Oct 16, 2024
1 parent 10e9bc4 commit 9613e5c
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 16 deletions.
71 changes: 71 additions & 0 deletions include/wintls/detail/sspi_compat.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef WINTLS_DETAIL_SSPI_COMPAT_HPP
#define WINTLS_DETAIL_SSPI_COMPAT_HPP

// for SCH_CREDENTIALS
#ifndef SCHANNEL_USE_BLACKLISTS
#define SCHANNEL_USE_BLACKLISTS
#define WINTLS_SCHANNEL_USE_BLACKLISTS_DEFINED
#endif // SCHANNEL_USE_BLACKLISTS

#include <sdkddkver.h>
#include <SubAuth.h>
#include <schannel.h>

#if (WDK_NTDDI_VERSION < NTDDI_WIN10_19H1)
typedef enum _eTlsAlgorithmUsage
{
TlsParametersCngAlgUsageKeyExchange,
TlsParametersCngAlgUsageSignature,
TlsParametersCngAlgUsageCipher,
TlsParametersCngAlgUsageDigest,
TlsParametersCngAlgUsageCertSig
} eTlsAlgorithmUsage;

typedef struct _CRYPTO_SETTINGS
{
eTlsAlgorithmUsage eAlgorithmUsage;
UNICODE_STRING strCngAlgId;
DWORD cChainingModes;
PUNICODE_STRING rgstrChainingModes;
DWORD dwMinBitLength;
DWORD dwMaxBitLength;
} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;

typedef struct _TLS_PARAMETERS
{
DWORD cAlpnIds;
PUNICODE_STRING rgstrAlpnIds;
DWORD grbitDisabledProtocols;
DWORD cDisabledCrypto;
PCRYPTO_SETTINGS pDisabledCrypto;
DWORD dwFlags;
} TLS_PARAMETERS, * PTLS_PARAMETERS;

typedef struct _SCH_CREDENTIALS
{
DWORD dwVersion;
DWORD dwCredFormat;
DWORD cCreds;
PCCERT_CONTEXT* paCred;
HCERTSTORE hRootStore;

DWORD cMappers;
struct _HMAPPER **aphMappers;

DWORD dwSessionLifespan;
DWORD dwFlags;
DWORD cTlsParameters;
PTLS_PARAMETERS pTlsParameters;
} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
#endif // (NTDDI_VERSION < NTDDI_WIN10_19H1)

#ifdef WINTLS_SCHANNEL_USE_BLACKLISTS_DEFINED
#undef SCHANNEL_USE_BLACKLISTS
#endif // WINTLS_SCHANNEL_USE_BLACKLISTS_DEFINED

#endif // WINTLS_DETAIL_SSPI_COMPAT_HPP
73 changes: 58 additions & 15 deletions include/wintls/detail/sspi_handshake.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,10 @@ class sspi_handshake {
void operator()(handshake_type type) {
handshake_type_ = type;

TLS_PARAMETERS tls_parameters{};
SCH_CREDENTIALS credentials{};
SCHANNEL_CRED creds{};
creds.dwVersion = SCHANNEL_CRED_VERSION;
creds.grbitEnabledProtocols = static_cast<DWORD>(context_.method_);
creds.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS;
// If revocation checking is enables, specify SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
// to cause the TLS certificate status request extension (commonly known as OCSP stapling)
// to be sent. This flag matches the CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
// flag that we pass to the CertGetCertificateChain calls during our manual authentication.
if (check_revocation_) {
creds.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
}
void* cred = nullptr;

auto usage = [this]() {
switch (handshake_type_) {
Expand All @@ -69,21 +62,71 @@ class sspi_handshake {
WINTLS_UNREACHABLE_RETURN(0);
}();

auto server_cert = context_.server_cert();
bool is_tlsv13 = [this]() {
switch (context_.method_) {
case method::tlsv13:
case method::tlsv13_client:
case method::tlsv13_server:
return true;
default:
return false;
}
WINTLS_UNREACHABLE_RETURN(0);
}();

DWORD version = is_tlsv13 ? SCH_CREDENTIALS_VERSION : SCHANNEL_CRED_VERSION;
DWORD flags = is_tlsv13 ? SCH_USE_STRONG_CRYPTO : (SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS);
DWORD protocols = static_cast<DWORD>(context_.method_);

// If revocation checking is enables, specify SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
// to cause the TLS certificate status request extension (commonly known as OCSP stapling)
// to be sent. This flag matches the CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
// flag that we pass to the CertGetCertificateChain calls during our manual authentication.
if (check_revocation_) {
flags |= SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
}

DWORD num_creds = 0;
decltype(&server_cert) creds_list = nullptr;

if (handshake_type_ == handshake_type::server && server_cert != nullptr) {
num_creds = 1;
creds_list = &server_cert;
}

// TODO: rename server_cert field since it is also used for client cert.
// Note: if client cert is set, sspi will auto validate server cert with it.
// Even though verify_server_certificate_ in context is set to false.
auto server_cert = context_.server_cert();
if (server_cert != nullptr) {
creds.cCreds = 1;
creds.paCred = &server_cert;
if (handshake_type_ == handshake_type::client && server_cert != nullptr) {
num_creds = 1;
creds_list = &server_cert;
}

if (!is_tlsv13) {
cred = &creds;
creds.dwVersion = version;
creds.grbitEnabledProtocols = protocols;
creds.dwFlags = flags;
creds.cCreds = num_creds;
creds.paCred = creds_list;
} else {
cred = &credentials;
credentials.dwVersion = version;
credentials.dwFlags = flags;
credentials.cTlsParameters = 1;
credentials.pTlsParameters = &tls_parameters;
credentials.pTlsParameters->grbitDisabledProtocols = ~protocols;
credentials.cCreds = num_creds;
credentials.paCred = creds_list;
}

TimeStamp expiry;
last_error_ = detail::sspi_functions::AcquireCredentialsHandleA(nullptr,
const_cast<SEC_CHAR*>(UNISP_NAME),
static_cast<unsigned>(usage),
nullptr,
&creds,
cred,
nullptr,
nullptr,
cred_handle_.get(),
Expand Down
3 changes: 2 additions & 1 deletion include/wintls/detail/sspi_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define WINTLS_UNICODE_UNDEFINED
#endif // UNICODE

#include <schannel.h>
#include <wintls/detail/sspi_compat.hpp>
#include <security.h>

#ifdef WINTLS_SECURITY_WIN32_DEFINED
Expand All @@ -29,4 +29,5 @@
#define UNICODE
#endif // WINTLS_UNICODE_UNDEFINED


#endif // WINTLS_DETAIL_SSPI_TYPES_HPP

0 comments on commit 9613e5c

Please sign in to comment.