MSDN Library

DnsIdentityConstraint Class

Namespace: System.Net.Security

Inheritance hierarchy: ObjectIdentityConstraintDnsIdentityConstraint

Note: This class is available starting with .NET Framework 4.5.

Represents a DNS identity constraint for an X.509 certificate. This class allows for the validation of a certificate's Subject Alternative Name (SAN) against a specified DNS name.

Syntax

public class DnsIdentityConstraint : IdentityConstraint

Remarks

The DnsIdentityConstraint class is used to ensure that the DNS name specified in a certificate's Subject Alternative Name (SAN) extension matches the expected DNS name. This is crucial for establishing secure network connections, particularly in scenarios involving TLS/SSL, to prevent man-in-the-middle attacks. When creating an instance of this class, you provide the expected DNS name. The validation logic will then compare this with the DNS names present in the certificate's SAN extension.

If the certificate does not contain a SAN extension or if none of the DNS names within the SAN extension match the constraint, the validation will fail.

Constructors

DnsIdentityConstraint(string)

Initializes a new instance of the DnsIdentityConstraint class with the specified DNS name.

public DnsIdentityConstraint(string dnsName)
Parameters
Name Type Description
dnsName System.String The DNS name to use for the identity constraint.

Members

DnsName

Gets the DNS name specified for this constraint.

public string DnsName { get; }
Property Value

System.String The DNS name specified for this constraint.

Example

The following example demonstrates how to create a DnsIdentityConstraint and use it to validate a certificate.

using System;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public class DnsConstraintExample
{
    public static void Main(string[] args)
    {
        // Assume 'certificate' is an X509Certificate2 object loaded with a server certificate.
        // For demonstration purposes, we'll use a placeholder.
        // In a real application, you would obtain the certificate from a secure connection.
        X509Certificate2 certificate = GetServerCertificate(); // Placeholder

        string expectedDnsName = "www.example.com";

        try
        {
            // Create a DnsIdentityConstraint
            DnsIdentityConstraint dnsConstraint = new DnsIdentityConstraint(expectedDnsName);

            // Validate the certificate against the constraint
            // The `Validate` method is typically called internally by the .NET security infrastructure.
            // This is a conceptual example. Direct invocation of `Validate` is not common.
            // You would typically see this used in an `X509ChainPolicy` or similar.

            // For a direct check (conceptual):
            if (certificate != null)
            {
                bool isValid = ValidateCertificateWithDnsConstraint(certificate, dnsConstraint);
                if (isValid)
                {
                    Console.WriteLine($"Certificate is valid for DNS name: {expectedDnsName}");
                }
                else
                {
                    Console.WriteLine($"Certificate is NOT valid for DNS name: {expectedDnsName}");
                }
            }
            else
            {
                Console.WriteLine("Could not retrieve server certificate.");
            }
        }
        catch (ArgumentException ex)
        {
            Console.WriteLine($"Error creating DnsIdentityConstraint: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An unexpected error occurred: {ex.Message}");
        }
    }

    // Placeholder method to simulate getting a certificate.
    // In a real scenario, you'd get this from a network stream.
    private static X509Certificate2 GetServerCertificate()
    {
        // This is a dummy certificate and will not pass validation.
        // Replace with actual certificate loading logic.
        try
        {
            // Attempt to load a common system certificate (e.g., for demonstration)
            // This might require specific permissions or environment setup.
            // A more robust example would involve network calls.
            return new X509Certificate2("path/to/your/server.cer"); // Replace with actual path or network retrieval
        }
        catch
        {
            Console.WriteLine("Warning: Could not load a sample certificate. Using null for demonstration.");
            return null; // Return null if a certificate cannot be loaded
        }
    }

    // Conceptual method to demonstrate validation logic.
    // Actual validation is more complex and integrated into the SChannel/TLS stack.
    private static bool ValidateCertificateWithDnsConstraint(X509Certificate2 certificate, DnsIdentityConstraint constraint)
    {
        Console.WriteLine($"Checking certificate for DNS name: {certificate.GetNameInfo(X509NameType.DnsName, false)}");
        // This is a simplified check. Real validation involves checking SAN extensions.
        if (certificate.GetNameInfo(X509NameType.DnsName, false) == constraint.DnsName)
        {
            return true;
        }

        // A more complete check would involve iterating through X509Extension.AllExtensions
        // and finding the Subject Alternative Name extension, then checking its DNS names.
        foreach (var extension in certificate.Extensions)
        {
            if (extension.Oid.FriendlyName == "Subject Alternative Name")
            {
                var san = extension as X509Extension; // Need to cast correctly based on actual type
                // Parse SAN and check for constraint.DnsName...
                // This parsing is complex and omitted for brevity.
            }
        }

        return false; // Default to false if no match found
    }
}