Class Overview

Specifies the authentication types that can be used with the SslStream class.

Syntax

[Flags]
public enum AuthenticationTypes

Members

Member Description
None No authentication is performed.
MutualAuthClient Client authentication is performed using a certificate.
MutualAuthServer Server authentication is performed using a certificate.

Remarks

  • The AuthenticationTypes enumeration is used to specify the authentication mechanisms that are supported for a secure network connection.
  • When you create an instance of the SslStream class, you can specify the desired authentication types using the SslStreamConstructor(Stream, Boolean, RemoteCertificateValidationCallback, LocalCertificateSelectionCallback) constructor.
  • The FlagsAttribute attribute allows multiple values from the enumeration to be combined using the bitwise OR operator (|).
  • For example, to specify both client and server mutual authentication, you would use AuthenticationTypes.MutualAuthClient | AuthenticationTypes.MutualAuthServer.

Example

The following C# code example demonstrates how to configure an SslStream to support both client and server mutual authentication.

using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

public class SslServerExample
{
    public static async Task StartServerAsync()
    {
        TcpListener listener = new TcpListener(System.Net.IPAddress.Any, 12345);
        listener.Start();
        Console.WriteLine("Server started. Waiting for connections...");

        while (true)
        {
            TcpClient client = await listener.AcceptTcpClientAsync();
            _ = HandleClientAsync(client); // Process client asynchronously
        }
    }

    private static async Task HandleClientAsync(TcpClient tcpClient)
    {
        using (NetworkStream stream = tcpClient.GetStream())
        {
            // Load server certificate (replace with your actual certificate path and password)
            X509Certificate2 serverCertificate = new X509Certificate2("server.pfx", "password");

            // Configure SslStream for mutual authentication
            SslStream sslStream = new SslStream(
                stream,
                false,
                new RemoteCertificateValidationCallback(ValidateClientCertificate),
                new LocalCertificateSelectionCallback(SelectClientCertificate)
            );

            try
            {
                // Authenticate the server
                await sslStream.AuthenticateAsServerAsync(serverCertificate,
                                                        clientCertificateRequired: true,
                                                        enabledSslProtocols: System.Security.Authentication.SslProtocols.Tls12,
                                                        checkCertificateRevocation: true);

                Console.WriteLine("Client authenticated successfully.");

                // ... proceed with secure communication ...
                byte[] buffer = new byte[1024];
                int bytesRead = await sslStream.ReadAsync(buffer, 0, buffer.Length);
                string message = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
                Console.WriteLine($"Received: {message}");

                string response = "Hello from server!";
                byte[] responseBytes = System.Text.Encoding.UTF8.GetBytes(response);
                await sslStream.WriteAsync(responseBytes, 0, responseBytes.Length);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Authentication failed: {ex.Message}");
            }
            finally
            {
                sslStream.Close();
            }
        }
    }

    // Callback to validate the client certificate
    public static bool ValidateClientCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            Console.WriteLine("Client certificate is valid.");
            return true; // Trust the client certificate
        }

        Console.WriteLine($"Client certificate validation errors: {sslPolicyErrors}");
        return false; // Do not trust the client certificate
    }

    // Callback to select the client certificate (if the server needs to present one to the client, though typically the client selects)
    public static X509Certificate SelectClientCertificate(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers)
    {
        // In a real-world scenario, you'd have logic here to select an appropriate client certificate.
        // For this example, we'll assume the client presents a certificate that's already trusted.
        // If you need to present a client certificate *from* the server *to* the client, adjust this.
        Console.WriteLine("Server is selecting a client certificate (typically handled by client).");
        return null; // Indicate no server-provided client cert is needed for this example
    }

    public static async Task Main(string[] args)
    {
        await StartServerAsync();
    }
}