Schannel ‐ Everything you never wanted to know - ToddMaxey/Technical-Documentation GitHub Wiki


Schannel

============

Secure Channel, also known as Schannel, is a security support provider (SSP) that contains a set of security protocols that provide identity authentication and secure, private communication through encryption.

Schannel is primarily used for Internet applications that require secure Hypertext Transfer Protocol (HTTP) communications.


Schannel MSDN Overview


This is a list of all top level MSDN documents for schannel.


Schannel Protocols by Platform


While Schannel implements several protocols, it may or may not support them depending on the OS. The following table lists whether or not Schannel supports a protocol given the OS, as well as whether or not the protocol is turned On or Off by default.

Please refer to MSDN: Protocols in TLS/SSL (Schannel SSP) for the updated list.

For completeness, newer versions of Windows 10 (e.g., 20H2, 21H1, 21H2, 22H2), Windows 11, and Windows Server 2022 include support for TLS 1.3. By default, TLS 1.2 and TLS 1.3 are enabled. TLS 1.0 and 1.1 remain enabled by default for backward compatibility, and SSL2/SSL3 remain removed or off.

| Windows OS | SSL2 Client | SSL2 Server | Uni Client | Uni Server | SSL3 Client | SSL3 Server | TLS 1.0 Client | TLS 1.0 Server | TLS 1.1 Client | TLS 1.1 Server | TLS 1.2 Client | TLS 1.2 Server | DTLS 1.0 Client | DTLS 1.0 Server | DTLS 1.2 Client | DTLS 1.2 Server |

| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |

| Vista/2008 | Off | On | Off | On | On | On | On | On | Off | Off | Off | Off | N/A | N/A | N/A | N/A |

| Win 7/2008R2 | Off | On | Off | On | On | On | On | On | Off | Off | Off | Off | On | On | N/A | N/A |

| Win 8/2012 | Off | Off | Off | On | On | On | On | On | On | On | On | On | On | On | N/A | N/A |

| Win 8.1/2012R2 | Off | Off | Off | On | On | On | On | On | On | On | On | On | On | On | N/A | N/A |

| Win10 v1507 (TH1) | Off | Off | Off | On | On | On | On | On | On | On | On | On | On | On | N/A | N/A |

| Win10 v1607/2016 (RS1) | Removed | Removed | Off | On | Off | Off | On | On | On | On | On | On | On | On | On | On |

| Win10 v1809/2019 (RS5) | Removed | Removed | Off | On | Off | Off | On | On | On | On | On | On | On | On | On | On |

| Win11 / 2022 (21H2 & up) | Removed | Removed | Off | On | Off | Off | On | On | On | On | On | On | On | On | On | On | On | On |

On : On by default.

Off : Off by default.

N/A : Not Available.

Removed : Removed from the operating system entirely.


Schannel CipherSuites by Platform


The most updated list can be found at MSDN: Cipher Suites in TLS/SSL (Schannel SSP)

Additional Note for Windows 11


Schannel Elliptic Curves by Platform


The most updated list can be found at MSDN: Elliptic Curves in TLS (Schannel SSP)

(Windows 11 and Windows Server 2022 also follow the “later” pattern, with additional or updated curves. In most cases, the registry or the Enable-TlsEccCurve/Disable-TlsEccCurve cmdlets can be used to configure curve preference.)


SDL Guidance for Microsoft Internal Teams


Internal teams should follow the SDL guidance for configuring their TLS settings.


For Schannel Users


Terminology

Configuration

There are three ways to configure schannel.

  1. System-wide settings are specified via the registry.

  2. Settings specified when opening the credential handle. This applies to all connections opened using that handle.

  3. Settings specified when opening individual connections using ISC and ASC (see above).

The TLS cmdlets (Windows 10/Server 2016 and later) provide an easy way to configure from PowerShell.


Typical Handshake flow

In both the TLS client and TLS server handshake flows, the SSPI caller (who can be a TLS client or server) must first call ACH to get a credential handle. They then enter the SSPI negotiate loop calling ISC/ASC repeatedly until the OK code is returned. ISC/ASC will return a context handle which represents the connection.

A TLS client will then call ISC with the credential handle. It returns a buffer representing the client hello message. The client will send that data to the server who will then send a response. The client will then subsequently call ISC with the server's response. ISC may return further data buffers which should be sent to the server. This cycle repeats until SEC_E_OK or other success code (see MSDN above) is returned from ISC.

The TLS server flow is almost exactly the same as the client. It will call ASC passing in the first message from the client. ASC will generate buffers to send to the client. The server will send the buffers and pass the client's response in the next ASC call. Like the clients flow, this loops until SEC_E_OK or other success code (see MSDN above) is returned from ASC.

At this point, the handshake is complete and the context is exported to the caller's process which can be user or kernel mode. The client or server can call EncryptMessage/DecryptMessage using their new context handle to encrypt and decrypt messages respectively and send and receive messages over the network.

Remember when debugging that it is not necessarily the case that both the client and the server are using schannel. Schannel is a TLS protocol implementation and can interoperate with OpenSSL/chrome/firefox amongst other clients. Be sure to collect the right traces for the TLS implementation in use.

More details are available at MSDN: User Mode Initialization


For Schannel Developers


Spec Document Locations

Schannel Telemetry

Events

  • Microsoft.Windows.Security.Schannel.TlsHandshakeInfoClientAggregated

  • Microsoft.Windows.Security.Schannel.TlsErrorClientAggregated

  • Microsoft.Windows.Security.Schannel.TlsHandshakeInfoServerCipherSuiteAggregated

  • Microsoft.Windows.Security.Schannel.TlsErrorServerAggregated

Workflow

COSMOS

Dashboard


Schannel Testing Tips


  • OneNote link: onenote:///\winsect\scratch\APWiki\Windows%20Core%20AP%20OneNote%20NoteBook\Testing%20Tips.one#section-id={A3795EFF-4D6D-4D28-84C7-E65D617A4B2C}&end

ENABLE SSL TESTING

Navigate to the build share location of the OS you have installed, and run the following scripts as administrator.

\\winbuilds\release\FBL_SEC_OSS1\9805.0.140806-0524\amd64fre\bin\security\test\schannel\scripts\setup.cmd 

 

\\winbuilds\release\FBL_SEC_OSS1\9805.0.140806-0524\amd64fre\bin\security\test\schannel\scripts\installtestcerts.cmd 

 

\\winbuilds\release\FBL_SEC_OSS1\9805.0.140806-0524\amd64fre\bin\security\test\schannel\scripts\startocspresponder.cmd 

Then run SSLTest.exe. See the /? switch to run selective tests. For example:

SSLTest.exe -FVT (FVT Tests) 

SSLTest.exe -BVT (BVT Tests) 

SSLTest.exe (All regression tests) 

The log file is ssl.log.wtl.

  • Notes: The test machine should have bcdedit debug setting set to yes (bcdedit /debug on)

Testing Protected Process Library (PPL)

The schannel test binaries (ssltest.exe, webcli.exe, websrv.exe) can be run as a protected process to test PPL specific functionality. To do this, you need to sign the binaries and use a special tool to launch the exe as a PP per the following instructions.

  1. Copy PplLauncher.exe from [Build]\amd64fre\bin\vmtest\vstack\vid\PplLauncher.exe to your test machine.

  2. Enable Test signing with BCDEdit on your test machine.

  3. Install [Build]\amd64fre\bin\testroot-sha2.cer to the local machine Trusted Root Store on your test machine.

  4. Attach Kernel Debugger.

  5. Sign the executable to launch as well as all binaries loaded into the process from your local razzle with:

    ntsign -e:tcbppl -h:PAGE "<path>\*.dll" "<path>\*.exe" 
    
  6. From an admin command prompt run:

    PplLauncher.exe [exe] [arguments] 
    

If there are problems running PPLLauncher with the test binaries, verify that the test binaries are correctly signed using signtool.exe verify /all <binary>. The leaf certificate used to sign the executable should be "Microsoft Windows Publisher".


Frequently Asked Questions


Your documentation is missing X, can you fix that?

Please send us an email at the discussion alias and mention the documentation gap so that we can fix it!

What cipher suites are supported in X OS version?

Please refer to the cipher suite list on MSDN: Cipher Suites in TLS/SSL (Schannel SSP)

Can we ignore the certificate validation check in Schannel and/or implement our own custom validation logic?

Yes, you can customize Schannel's certificate validation rules. To specify behavior at the credential handle level by using SCH_CRED_IGNORE_NO_REVOCATION_CHECK, SCH_CRED_IGNORE_REVOCATION_OFFLINE, SCH_CRED_NO_SERVERNAME_CHECK, SCH_CRED_REVOCATION_CHECK_*. You can also request that the certificate validation not be performed at all using SCH_CRED_MANUAL_CRED_VALIDATION.

If you wish to implement your own custom certificate validation logic, you can use QueryContextAttributes with SECPKG_ATTR_REMOTE_CERT_CONTEXT or SECPKG_ATTR_REMOTE_CERT_CHAIN to retrieve the peer's certificate for inspection. This is particularly useful when specifying SCH_CRED_MANUAL_CRED_VALIDATION.

For TLS clients, you can instruct Schannel to perform the validation but allow the caller to manually inspect the result of the validation using SCH_CRED_DEFERRED_CRED_VALIDATION. You can also modify the behavior for individual connections by using ISC_REQ_MANUAL_CRED_VALIDATION and ISC_REQ_DEFERRED_CRED_VALIDATION for ISC. With this flag, certificate validation will happen but errors will not cause the handshake to fail. You can then use QueryContextAttributes with SECPKG_ATTR_CERT_CHECK_RESULT[_INPROC] to inspect the result of the certificate validation.

Please see the MSDN articles linked in Schannel MSDN Overview for more details on each of these parameters.

How do I use my own certificate authority store for validation?

For server machines, you can specify the store containing the trusted CAs for the application using the hRootStore field of the SCH_CREDENTIALS passed into ACH.

Please see the MSDN articles linked in Schannel MSDN Overview for more details on ACH.

What are the best practices for cipher / cipher suites we can use to be more secure?

Schannel's default cipher suite configuration is the recommended configuration from the dev team for general use.

Users can trim the cipher suite list from the bottom (removing low-priority cipher suites), if they wish to reduce options/reduce legacy crypto usage. Be sure to test interoperability and make sure TLS connections still work as cipher suite configuration changes can break OS, application and service functionality. Pay attention to SEC_E_ALGORITHM_MISMATCH errors as it can be indicative of breakage from making cipher suites changes.

What are the _P cipher suites in Schannel?*

_PXXX suffixes appended to cipher suite strings are a legacy Schannel convention to prioritize elliptic curves, now deprecated. Windows 10 uses proper cipher suite names, and has separate knobs for configuring elliptic curves. You can configure the priority of elliptic curves using the TLS cmdlets (Enable-TlsEccCurve/Disable-TlsEccCurve) or the registry. Windows 10 still supports legacy cipher suite strings with EC suffixes, so that the admin can specify one GP for a deployment that includes Win10 and earlier machines.

Please see the MSDN articles linked in Schannel MSDN Overview for more details on the TLS cmdlets or registry settings. Also see Schannel Elliptic Curves by Platform for a list of which curves are supported by your OS version.

Where is the documentation for DTLS?

We have a known documentation gap for DTLS, until that is addressed, here are the most common questions we receive.

What are the meanings of the values returned in SecPkgContext_StreamSizes for DTLS?

  • cbHeader – Unchanged from TLS.

  • cbTrailer – Unchanged from TLS.

  • cbMaximumMessage – for DTLS, this value is set to the PMTU. Note that this value includes the header and trailer.

  • cBuffers – Unchanged from TLS. Indicates the number of SecBuffers required when calling EncryptMessage and DecryptMessage.

  • cbBlockSize – Unchanged from TLS. Specifies the preferred integral size of the messages. For this it is set to the block size of the symmetric cipher used in the connection. Messages of exactly this size do not require padding.

See MSDN: SecPkgContext_StreamSizes structure (sspi.h) for more details.

The most important detail is that each EncryptMessage call can operate on at most (cbMaximumMessage - cbHeader - cbTrailer) bytes of message data. When encrypting a large amount of data that doesn't fit in a single record, break up the data to encrypt across multiple EncryptMessage calls, each one of size := (cbMaximumMessage - cbHeader - cbTrailer) until you run out of data.

Can I adopt an existing TLS SSPI client to use DTLS?

Yes, an existing TLS SSPI client can be adopted to use DTLS with several minor changes. A high-level overview of the differences are available in this StackOverflow (answer accurate as of 2021-07-23) DTLS using Schannel

Why is my certificate invalid

Follow the steps here to troubleshoot invalid certificate errors: Troubleshooting PKI Problems on Windows Vista

The steps are still valid for newer OS releases despite the title of the page.


Troubleshooting


When diagnosing an Schannel issue the following is important information to have:

Script to collect registry settings and Schannel traces at the same time.

  1. Copy and unzip SchannelTracing.zip folder to machine.

  2. Run startauth.cmd from an elevated command prompt.

  3. Run scenario.

  4. Run stopauth.cmd

  5. Share out the logs folder.


Common issues and solutions:

There are errors in the event log.

A fatal error occurred while creating a TLS client credential. The internal error state is 10013.

  • The intersection of the set of enabled protocols on the system, protocols with enabled cipher suites, and protocols enabled on the credential handle minus the protocols filtered by the TLS parameters and CREDENTIALS_VERSION resulted in an empty set. There are no TLS versions available for the handshake.

  • This is a misconfiguration issue. For TLS 1.3, you must use SCH_CREDENTIALS in AcquireCredentialsHandle. Make sure that the desired TLS versions are enabled in the registry and ensure that the credential handle’s enabled/disabled protocols field is correct. Also, double check the TLS_PARAMETERS passed in with the credential handle to ensure they are not filtering out desired protocol versions, if applicable. Lastly, ensure that there are cipher suites enabled on the system compatible with the desired TLS versions. Check the MSDN links above for how to configure schannel via the registry.

Problem: Some applications won't negotiate TLS 1.2.

Solution: Enable Transport Layer Security (TLS) 1.2 overview - Configuration Manager | Microsoft Docs.

Problem: MS SQL Server won't negotiate TLS 1.2.

Solution: KB3135244 - TLS 1.2 support for Microsoft SQL Server.

Problem: Connections intermittently fail when negotiating a TLS_DHE_ cipher suite.

Solution: Either upgrade the customer to at least Server 2016 (RS1) or disable those cipher suites using TLS cmdlets or group policy. https://docs.microsoft.com/en-us/windows-server/security/tls/manage-tls.

Problem: RDP stops working on a client or server.

Solution: Make sure the MinEncryptionLevel is not set to 4 under:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp 

If the customer has to have the MinEncryptionLevel set to 4, then make sure no algorithms are disabled under:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers 

Problem: RDP Stops working on RS4 or below after disabling TLS 1.0.

Solution: Check to see if the RDP server is using RDS Connection Broker or RDMS. Both of these applications require TLS 1.0 to function properly.

RDS Connection Broker or RDMS fails - Windows Server | Microsoft Docs

Problem: RDP Won't Negotiate PFS Cipher suites.

Make sure that MinEncryptionLevel (if present) is set to a max of 3 in the following locations:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp 

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services 

Problem: Connections start failing on Server 2012R2 or below platforms.

Solution: Check to ensure all the ECDHE cipher suites listed in:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002!Functions 

and/or

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002!Functions 

contain the _PXXX suffix.

If they do not, put the cipher suites back to the default order for the platform:

Cipher Suites in TLS/SSL (Schannel SSP) - Win32 apps | Microsoft Docs

Problem: Schannel client or server starts negotiating TLS 1.3 on an unsupported platform (released before Server 2022).

Solution: Disable TLS 1.3 in the registry using the commands below.

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" /v Enabled /t REG_DWORD /d 0 /f 

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" /v Enabled /t REG_DWORD /d 0 /f 

Problem: Client certificate for authentication fails to be retrieved from TPM when using TLS1.3

Solution: Check to see if the TPM supports RSA_PSS padding for signatures.

Connection failure when using a TPM based certificate to authenticate to a TLS 1.3 web site (microsoft.com)

Problem: TLS post-handshake client authentication configured in IIS/HTTP.SYS, server drops connections from 3rd-party TLS 1.3 clients.

  • Schannel trace shows SEC_I_NO_RENEGOTIATION. HTTP.SYS currently errors out on this code and disconnects the client.

  • 3rd-party TLS 1.3 clients often don’t support TLS 1.3 post-handshake client authentication (can confirm by the absence of the post-handshake client authentication extension in the ClientHello).

Solution: Disable TLS 1.3 on those endpoints doing post-handshake client auth, or configure in-handshake client authentication, where possible/advisable.

For IIS/HTTP.SYS you can enable in-handshake client authentication by setting ClientCertNegotation=Enable when calling netsh http add sslcert

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc725882(v=ws.10)


See Also

Crypto

Collecting_Crypto/PKI/Auth_Logs


⚠️ **GitHub.com Fallback** ⚠️