SharpDTLS 0.0.1
See the version list below for details.
dotnet add package SharpDTLS --version 0.0.1
NuGet\Install-Package SharpDTLS -Version 0.0.1
<PackageReference Include="SharpDTLS" Version="0.0.1" />
<PackageVersion Include="SharpDTLS" Version="0.0.1" />
<PackageReference Include="SharpDTLS" />
paket add SharpDTLS --version 0.0.1
#r "nuget: SharpDTLS, 0.0.1"
#:package SharpDTLS@0.0.1
#addin nuget:?package=SharpDTLS&version=0.0.1
#tool nuget:?package=SharpDTLS&version=0.0.1
SharpDTLS
DTLS 1.0/1.2/1.3 and TLS 1.0/1.1/1.2/1.3 client and server written in C#. The cryptography comes from BouncyCastle; the protocols are implemented here. Targets netstandard2.0, net472, net8.0 and net10.0.
A client offers every enabled version in one ClientHello and a server answers with the highest one both sides support. DTLS 1.2 and DTLS 1.3 are on by default, and so are TLS 1.2 and TLS 1.3. To enable the older versions, set MinimumVersion.
Implements the following RFCs:
- The Transport Layer Security (TLS) Protocol Version 1.3 RFC9846 (obsoletes RFC8446)
- The Datagram Transport Layer Security (DTLS) Protocol Version 1.3 RFC9147
- The Transport Layer Security (TLS) Protocol Version 1.2 RFC5246
- Datagram Transport Layer Security Version 1.2 RFC6347
- Connection Identifier for DTLS 1.2 RFC9146
- DTLS Extension to Establish Keys for the Secure Real-time Transport Protocol (SRTP) RFC5764
- TLS Extensions: server name, OCSP stapling and more RFC6066
- Application-Layer Protocol Negotiation RFC7301
- Raw Public Keys in TLS and DTLS RFC7250
- TLS Certificate Compression RFC8879
- Record Size Limit Extension for TLS RFC8449
- Keying Material Exporters for TLS RFC5705
- Session resumption with session tickets RFC5077, extended master secret RFC7627
- Pre-shared keys RFC4279, SRP RFC5054 and TLS-PWD RFC8492
DTLS
The DTLS server and client send and receive datagrams through a transport: ServerTransport and ClientTransport in SharpDTLS.UDP use a UDP socket. To run DTLS over something else, such as an ICE connection, implement IServerTransport or IClientTransport.
Create the server. Without a key pair and a certificate it generates a self-signed certificate:
var serverTransport = new ServerTransport(new IPEndPoint(IPAddress.Any, 8888));
var server = new DtlsServer(serverTransport);
server.ApplicationDataReceived += (sender, e) =>
{
Console.WriteLine($"Server received: {Encoding.UTF8.GetString(e.Data)}");
e.Connection.SendApplicationData(Encoding.UTF8.GetBytes("Hello from server!"));
};
To use your own certificate, pass it with its key pair: new DtlsServer(serverTransport, keyPair, certificate).
Create the client and start the handshake. The handshake runs in the background and HandshakeFinished is raised when it completes, or Failed when it does not:
var clientTransport = new ClientTransport(new IPEndPoint(IPAddress.Loopback, 8888));
var client = new DtlsClient(clientTransport);
client.HandshakeFinished += (sender, e) =>
{
Console.WriteLine($"Handshake finished: version 0x{client.NegotiatedVersion:X4}");
client.SendApplicationData(Encoding.UTF8.GetBytes("Hello from client!"));
};
client.ApplicationDataReceived += (sender, data) => Console.WriteLine($"Client received: {Encoding.UTF8.GetString(data)}");
client.Failed += (sender, ex) => Console.WriteLine($"Handshake failed: {ex.Message}");
client.BeginHandshake();
When done, call client.Close() and dispose of the transports.
TLS
TlsStream runs TLS over any Stream, such as a NetworkStream, and is a Stream itself:
using var tcp = new TcpClient();
await tcp.ConnectAsync("example.com", 443);
using var tls = await TlsStream.ConnectAsync(tcp.GetStream(), client =>
{
client.ServerName = "example.com";
client.ServerCertificateValidator = new CertificateValidator().ForServer("example.com");
});
await tls.WriteAsync(request, 0, request.Length);
int read = await tls.ReadAsync(buffer, 0, buffer.Length);
On the server side, TlsStream.AcceptAsync(new TlsServer(), stream) serves a client connected on the stream.
Certificate validation
By default, a client accepts any certificate from the server and only checks that the server holds its private key. To validate the chain against the operating system's trust store and check the host name, set ServerCertificateValidator:
client.ServerCertificateValidator = new CertificateValidator().ForServer("example.com");
To trust only your own CA, pass its certificate: new CertificateValidator(new[] { caCertificate }). A server checks client certificates the same way with ForClient().
CertificateValidator is the default implementation of ICertificateValidator. To validate some other way, implement Validate, which throws a DtlsException with the alert to send when the chain is not acceptable, and plug it in the same way:
client.ServerCertificateValidator = new MyCertificateValidator().ForServer("example.com");
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- BouncyCastle.Cryptography (>= 2.7.0)
- System.Memory (>= 4.6.3)
-
.NETStandard 2.0
- BouncyCastle.Cryptography (>= 2.7.0)
- System.Memory (>= 4.6.3)
-
net10.0
- BouncyCastle.Cryptography (>= 2.7.0)
-
net8.0
- BouncyCastle.Cryptography (>= 2.7.0)