Skip to content

Commit 7b58d2e

Browse files
rzikmIEvangelist
andauthored
Apply suggestions from code review
Co-authored-by: David Pine <[email protected]>
1 parent c56a7ef commit 7b58d2e

File tree

4 files changed

+39
-38
lines changed

4 files changed

+39
-38
lines changed

docs/core/extensions/sslstream-best-practices.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
---
22
title: TLS/SSL best practices
3-
description: Learn best practices to using SslStream in .NET
3+
description: Learn the best practices when using SslStream in .NET.
44
author: rzikm
55
ms.author: radekzikmund
6-
ms.date: 10/25/2022
6+
ms.date: 1/9/2023
77
---
88

99
# TLS/SSL best practices
1010

1111
TLS (Transport Layer Security) is a cryptographic protocol designed to secure communication between two computers over the internet. The TLS protocol is exposed in .NET via the <xref:System.Net.Security.SslStream> class.
1212

13-
This article presents best practices for setting up secure communication between client and server and assumes use of .NET Core. For best practices for .NET Framework, see [Transport Layer Security (TLS) best practices with the .NET Framework](/dotnet/framework/network-programming/tls).
13+
This article presents best practices for setting up secure communication between client and server and assumes use of .NET. For best practices with .NET Framework, see [Transport Layer Security (TLS) best practices with the .NET Framework](/dotnet/framework/network-programming/tls).
1414

15-
## Selecting TLS version
15+
## Select TLS version
1616

1717
While it is possible to specify the version of the TLS protocol to be used via the SslProtocols property, it is recommended to defer to the operating system settings by using <xref:System.Security.Authentication.SslProtocols.None> value (this is the default).
1818

1919
Deferring the decision to the OS automatically uses the most recent version of TLS available and lets the application pick up changes after OS upgrades. The operating system may also prevent use of TLS versions which are no longer considered secure.
2020

21-
## Selecting cipher suites
21+
## Select cipher suites
2222

23-
SslStream allows users to specify which cipher suites can be negotiated by the TLS handshake via the <xref:System.Net.Security.CipherSuitesPolicy> class. As with TLS versions, we recommend letting the operating system decide which are the best cipher suites to negotiate with and, therefore, we recommend avoiding the use of <xref:System.Net.Security.CipherSuitesPolicy>.
23+
`SslStream` allows users to specify which cipher suites can be negotiated by the TLS handshake via the <xref:System.Net.Security.CipherSuitesPolicy> class. As with TLS versions, it's recommended to let the OS decide which are the best cipher suites to negotiate with, and, therefore, it's recommended to avoid using <xref:System.Net.Security.CipherSuitesPolicy>.
2424

25-
Note that <xref:System.Net.Security.CipherSuitesPolicy> is not supported on Windows and attempts to instantiate it will cause <xref:System.NotSupportedException> to be thrown.
25+
> [!NOTE]
26+
> <xref:System.Net.Security.CipherSuitesPolicy> is not supported on Windows and attempts to instantiate it will cause <xref:System.NotSupportedException> to be thrown.
2627
27-
## Specifying a Server Certificate
28+
## Specify a server certificate
2829

2930
When authenticating as a server, <xref:System.Net.Security.SslStream> requires an <xref:System.Security.Cryptography.X509Certificates.X509Certificate2> instance. It is recommended to always use an <xref:System.Security.Cryptography.X509Certificates.X509Certificate2> instance which also contains the private key.
3031

31-
There are multiple ways how the server certificate can be passed to <xref:System.Net.Security.SslStream>:
32+
There are multiple ways that a server certificate can be passed to <xref:System.Net.Security.SslStream>:
3233

3334
- Directly as a parameter to <xref:System.Net.Security.SslStream.AuthenticateAsServerAsync%2A?displayProperty=nameWithType> or via <xref:System.Net.Security.SslServerAuthenticationOptions.ServerCertificate?displayProperty=nameWithType> property
3435
- From a selection callback in <xref:System.Net.Security.SslServerAuthenticationOptions.ServerCertificateSelectionCallback?displayProperty=nameWithType> property
@@ -38,33 +39,34 @@ The recommended approach is to use the <xref:System.Net.Security.SslServerAuthen
3839

3940
Reusing <xref:System.Net.Security.SslStreamCertificateContext> instances also enables additional features such us [TLS session resumption](https://datatracker.ietf.org/doc/html/rfc5077) on Linux servers.
4041

41-
## Custom X509Certificate validation
42+
## Custom `X509Certificate` validation
4243

43-
There are certain scenarios in which the default certificate validation procedure is not adequate and some custom validation logic is required. Parts of the validation logic can be customized by specifying <xref:System.Net.Security.SslClientAuthenticationOptions.CertificateChainPolicy?displayProperty=nameWithType> or <xref:System.Net.Security.SslServerAuthenticationOptions.CertificateChainPolicy?displayProperty=nameWithType> (available since .NET 7). Alternatively, completely custom logic can be provided via the <System.Net.Security.SslClientAuthenticationOptions.RemoteCertificateValidationCallback> property. As an illustration, following sections provide some examples.
44+
There are certain scenarios in which the default certificate validation procedure isn't adequate and some custom validation logic is required. Parts of the validation logic can be customized by specifying <xref:System.Net.Security.SslClientAuthenticationOptions.CertificateChainPolicy?displayProperty=nameWithType> or <xref:System.Net.Security.SslServerAuthenticationOptions.CertificateChainPolicy?displayProperty=nameWithType>. Alternatively, completely custom logic can be provided via the <System.Net.Security.SslClientAuthenticationOptions.RemoteCertificateValidationCallback> property. For more information, see [Custom certificate trust](#custom-certificate-trust).
4445

45-
### Custom Certificate Trust
46+
### Custom certificate trust
4647

47-
When encountering a certificate which was not issued by any of the certificate authorities trusted by the machine (including self-signed certificates), the default certificate validation procedure will fail. One possible way to resolve this is add the necessary issuer certificates to the machine trusted store. That, however, might affect other applications on the system and is not always possible.
48+
When encountering a certificate that wasn't issued by any of the certificate authorities trusted by the machine (including self-signed certificates), the default certificate validation procedure will fail. One possible way to resolve this is to add the necessary issuer certificates to the machine's trusted store. That, however, might affect other applications on the system and is not always possible.
4849

49-
The alternative solution is to specify custom trusted root certificates via an <xref:System.Security.Cryptography.X509Certificates.X509ChainPolicy>. The example below specifies custom trust list which will be used instead of the system trust list during validation.
50+
The alternative solution is to specify custom trusted root certificates via an <xref:System.Security.Cryptography.X509Certificates.X509ChainPolicy>. To specify a custom trust list that will be used instead of the system trust list during validation, consider the following example:
5051

5152
```csharp
5253
SslClientAuthenticationOptions clientOptions = new();
5354

5455
clientOptions.CertificateChainPolicy = new X509ChainPolicy()
5556
{
5657
TrustMode = X509ChainTrustMode.CustomRootTrust,
57-
CustomTrustStore = {
58+
CustomTrustStore =
59+
{
5860
customIssuerCert
5961
}
6062
};
6163
```
6264

63-
Note that clients configured with the policy above would accept *only* certificates trusted by `customIssuerCert`.
65+
Clients configured with the preceding policy would only accept certificates trusted by `customIssuerCert`.
6466

65-
### Ignoring specific validation errors
67+
### Ignore specific validation errors
6668

67-
Consider an IoT device without a persistent clock. After powering on, the clock of the device would start many years in the past and, therefore, all certificates would be considered "not yet valid". The following code shows a validation callback implementation which ignores validity period violations.
69+
Consider an IoT device without a persistent clock. After powering on, the clock of the device would start many years in the past and, therefore, all certificates would be considered "not yet valid". Consider the following code that shows a validation callback implementation ignoring validity period violations.
6870

6971
```csharp
7072
static bool CustomCertificateValidationCallback(
@@ -139,4 +141,4 @@ static bool CustomCertificateValidationCallback(
139141

140142
Server applications need to be careful when requiring and validating client certificates. Certificates may contain the [AIA (Authority Information Access)](http://www.pkiglobe.org/auth_info_access.html) extension which specifies where the issuer certificate can be downloaded. The server may therefore attempt to download the issuer certificate from external server when building the <xref:System.Security.Cryptography.X509Certificates.X509Chain> for the client certificate. Similarly, servers may need to contact external servers to ensure that the client certificate has not been revoked.
141143

142-
The need to contact external servers when building and validating the <xref:System.Security.Cryptography.X509Certificates.X509Chain> may expose the application to denial of service attacks if the external servers are slow to respond. Therefore, server applications should configure the <xref:System.Security.Cryptography.X509Certificates.X509Chain> building behavior using the <xref:System.Net.Security.SslServerAuthenticationOptions.CertificateChainPolicy> (available since .NET 7).
144+
The need to contact external servers when building and validating the <xref:System.Security.Cryptography.X509Certificates.X509Chain> may expose the application to denial of service attacks if the external servers are slow to respond. Therefore, server applications should configure the <xref:System.Security.Cryptography.X509Certificates.X509Chain> building behavior using the <xref:System.Net.Security.SslServerAuthenticationOptions.CertificateChainPolicy>.
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
---
2-
title: Migrating from .NET Framework to .NET
3-
description: How to migrate code using SslStream from .NET Framework to .NET
2+
title: Migrate from .NET Framework to .NET
3+
description: Learn how to migrate code using SslStream in .NET Framework to .NET.
44
author: rzikm
55
ms.author: radekzikmund
6-
ms.date: 11/04/2022
6+
ms.date: 1/9/2023
77
---
88

9-
# Migrating from .NET Framework to .NET
9+
# Migrate from .NET Framework to .NET
1010

11-
.NET Core brought many improvements as well as breaking changes to how <xref:System.Net.Security.SslStream> works. The most important change related to network security is that
12-
the <xref:System.Net.ServicePointManager> class has been mostly obsoleted and affects only the legacy <xref:System.Net.WebRequest> interface.
11+
.NET Core brought many improvements as well as breaking changes to how <xref:System.Net.Security.SslStream> works. The most important change related to network security is that the <xref:System.Net.ServicePointManager> class has been mostly obsoleted and affects only the legacy <xref:System.Net.WebRequest> interface.
1312

1413
Since .NET, allowed SSL/TLS protocols and certificate validation callbacks must be configured separately for each <xref:System.Net.Security.SslStream> instance via the <xref:System.Net.Security.SslServerAuthenticationOptions> or <xref:System.Net.Security.SslClientAuthenticationOptions>. In order to configure network security options used in HTTPS in <xref:System.Net.Http.HttpClient>, you need to configure the security options in the underlying handler, such as <xref:System.Net.Http.SocketsHttpHandler.SslOptions?displayName=nameWithType>.

docs/core/extensions/sslstream-troubleshooting.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
---
22
title: Troubleshoot SslStream authentication issues
3-
description: Learn how to troubleshoot and investigate issues when performing authentication with SslStream in .NET
3+
description: Learn how to troubleshoot and investigate issues when performing authentication with SslStream in .NET.
44
author: rzikm
55
ms.author: radekzikmund
6-
ms.date: 10/25/2022
6+
ms.date: 1/9/2023
77
---
88

9-
# Troubleshoot SslStream authentication issues
9+
# Troubleshoot `SslStream` authentication issues
1010

11-
This article presents the most frequent authentication issues when using <xref:System.Net.Security.SslStream> Cryptography and Security related functionalities in .NET are implemented by interop with either the Operating System API (such as Schannel on Windows) or low level system libraries (like OpenSSL on Linux). The behavior of .NET application, including exception messages and error codes may therefore change depending on which platform it is run.
11+
This article presents the most frequent authentication issues when using <xref:System.Net.Security.SslStream> cryptography- and security-related functionalities in .NET are implemented by interop with either the OS API (such as Schannel on Windows) or low-level system libraries (like OpenSSL on Linux). The behavior of .NET application, including exception messages and error codes may therefore change depending on which platform it is run.
1212

13-
Some issues may be therefore more easily investigated and troubleshooted by observing the actual messages exchanged over the wire using tools such as WireShark or `tcpdump`. These tools can be used to inspect the `ClientHello`, `ServerHello` and other messages for advertised supported TLS versions, allowed and negotiated cipher suites and the certificates exchanged for authentication.
13+
Some issues may be easier to investigate and troubleshoot by observing the actual messages exchanged over the wire using tools such as [Wireshark](https://www.wireshark.org) or [tcpdump](https://www.tcpdump.org). These tools can be used to inspect the `ClientHello`, `ServerHello`, and other messages for advertised supported TLS versions allowed and negotiated cipher suites and the certificates exchanged for authentication.
1414

15-
## Intermediate Certificates are not sent
15+
## Intermediate certificates are not sent
1616

17-
During the TLS handshake, the server (and client too, if client authentication is requested) sends its certificate to prove its identity to the client. In order to validate the authenticity of the certificate, a chain of certificates needs to be built and verified. The root of the chain must be one of the trusted Root Certificate Authority (CA), certificate of which is stored in the machine certificate store.
17+
During the TLS handshake, the server (and the client too, if client authentication is requested) sends its certificate to prove its identity to the client. In order to validate the authenticity of the certificate, a chain of certificates needs to be built and verified. The root of the chain must be one of the trusted root certificate authority (CA), the certificate of which is stored in the machine certificate store.
1818

19-
If the peers certificate has not been issued by one of the trusted CAs an intermediate CA certificate is necessary to build the certificate chain. However, if the intermediate certificate is not available, it is not possible to validate the certificate and the TLS handshake may fail.
19+
If the peer certificate hasn't been issued by one of the trusted CAs an intermediate CA certificate is necessary to build the certificate chain. However, if the intermediate certificate isn't available, it isn't possible to validate the certificate and the TLS handshake may fail.
2020

21-
This issue is most frequently encountered on Windows. Even though application provided intermediate certificates via the authentication options, they will not be sent to the peer unless they are are stored in the Windows certificate store. This limitation is due to fact that the actual TLS handshake occurs outside of the application process.
21+
This issue is most frequently encountered on Windows. Even though the application provided intermediate certificates via the authentication options, they will not be sent to the peer unless they are stored in the Windows certificate store. This limitation is due to the fact that the actual TLS handshake occurs outside of the application process.
2222

2323
For server applications, it is possible to pass an <xref:System.Net.Security.SslStreamCertificateContext> as <xref:System.Net.Security.SslServerAuthenticationOptions.ServerCertificateContext?displayProperty=nameWithType>. During construction of the <xref:System.Net.Security.SslStreamCertificateContext> instance, you can pass additional intermediate certificates and these will be temporarily added into the certificate store.
2424

2525
Unfortunately, for client application the only solution is to add the certificates to the certificate store manually.
2626

2727
## Handshake failed with ephemeral keys
2828

29-
On Windows, you may encounter error message `(0x8009030E): No credentials are available in the security package` when attempting to use certificates with ephemeral keys. This behavior is due to bug in the underlying OS API (Schannel). More relevant info and workarounds can be found on the associated [GitHub issue](https://github.com/dotnet/runtime/issues/23749).
29+
On Windows, you may encounter the `(0x8009030E): No credentials are available in the security package` error message when attempting to use certificates with ephemeral keys. This behavior is due to a bug in the underlying OS API (Schannel). More relevant info and workarounds can be found on the associated [GitHub issue](https://github.com/dotnet/runtime/issues/23749).
3030

3131
## Client and server do not possess a common algorithm
3232

docs/fundamentals/toc.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,11 +2703,11 @@ items:
27032703
href: networking/websockets.md
27042704
- name: Security
27052705
items:
2706-
- name: TLS/SSL Best Practices
2706+
- name: TLS/SSL best practices
27072707
href: ../core/extensions/sslstream-best-practices.md
2708-
- name: Troubleshooting SslStream Authentication Issues
2708+
- name: Troubleshoot SslStream authentication issues
27092709
href: ../core/extensions/sslstream-troubleshooting.md
2710-
- name: Migrating from .NET Framework to .NET Core
2710+
- name: Migrate from .NET Framework to .NET
27112711
href: ../core/extensions/sslstream-migration-from-framework.md
27122712
- name: File globbing
27132713
href: ../core/extensions/file-globbing.md

0 commit comments

Comments
 (0)