Namespace: System.Net.Security
Indicates the result of a certificate validation operation.
public enum ValidationResultCode
The ValidationResultCode enumeration contains the following members:
| Member | Description |
|---|---|
Success |
The certificate validation succeeded. |
InvalidChain |
The certificate chain is invalid. This could be due to a missing intermediate certificate or a self-signed root certificate that is not trusted. |
Expired |
The certificate has expired. |
InvalidPurpose |
The certificate is not valid for the intended purpose (e.g., it's an email certificate being used for SSL/TLS). |
Revoked |
The certificate has been revoked by the issuing Certificate Authority. |
UntrustedRoot |
The certificate chain does not end with a trusted root certificate. |
NotTimeValid |
The certificate is not currently valid within its validity period (either not yet valid or expired). |
UnknownError |
An unspecified error occurred during certificate validation. |
InvalidCertificateUsage |
The certificate's usage is invalid for the requested operation. |
PartialChain |
The certificate chain is incomplete. |
BadSignature |
The certificate's signature is invalid. |
InvalidName |
The certificate's subject name does not match the host name. |
The ValidationResultCode enumeration is used by the SslCertValidationCallback delegate to communicate the outcome of a certificate validation process. When a certificate needs to be validated, the .NET runtime invokes this callback, providing a X509Certificate2 object and the results of the validation, including a ValidationResultCode.
Developers can implement custom certificate validation logic by providing a delegate for SslCertValidationCallback. This allows for more granular control over which certificates are trusted in different scenarios.
The following example shows how to use the ValidationResultCode within a custom certificate validation callback.
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
public class CertificateValidator
{
public static void SetupValidation()
{
// For HttpClient
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = ValidateServerCertificate;
using (var client = new HttpClient(httpClientHandler))
{
// Use the client to make requests
}
// For ServicePointManager (older APIs)
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
}
private static bool ValidateServerCertificate(
object sender,
X509Certificate? certificate,
X509Chain? chain,
SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine($"SSL Policy Errors: {sslPolicyErrors}");
if (certificate == null || chain == null)
{
Console.WriteLine("Certificate or chain is null.");
return false;
}
// Get the validation result code from the chain
// Note: In newer .NET versions, you might get more specific results directly
// from sslPolicyErrors or by inspecting the chain.elements.
// For demonstration, let's simulate checking common issues.
// A simple check: if there are no policy errors, it's usually good.
if (sslPolicyErrors == SslPolicyErrors.None)
{
Console.WriteLine("Certificate validation succeeded (no policy errors).");
return true;
}
// Manually inspect chain status for more details if needed
foreach (var status in chain.ChainStatus)
{
Console.WriteLine($"Chain Status Error: {status.Status} - {status.StatusInformation}");
// Here you would map chain status information to ValidationResultCode
// For a true mapping, you'd need to parse status.Status flags.
// This is a simplified example.
switch (status.Status)
{
case X509ChainStatusFlags.NotTimeValid:
Console.WriteLine("Validation Result: NotTimeValid");
break;
case X509ChainStatusFlags.Expired:
Console.WriteLine("Validation Result: Expired");
break;
case X509ChainStatusFlags.Revoked:
Console.WriteLine("Validation Result: Revoked");
break;
case X509ChainStatusFlags.UntrustedRoot:
Console.WriteLine("Validation Result: UntrustedRoot");
break;
case X509ChainStatusFlags.InvalidCertificateAuthority:
Console.WriteLine("Validation Result: InvalidChain (or UntrustedRoot)");
break;
case X509ChainStatusFlags.CyclicName:
case X509ChainStatusFlags.InvalidNameConstraints:
case X509ChainStatusFlags.InvalidPolicy:
case X509ChainStatusFlags.InvalidUsage:
Console.WriteLine("Validation Result: InvalidCertificateUsage / InvalidPurpose");
break;
case X509ChainStatusFlags.PartialChain:
Console.WriteLine("Validation Result: PartialChain");
break;
case X509ChainStatusFlags.BadSignature:
Console.WriteLine("Validation Result: BadSignature");
break;
case X509ChainStatusFlags.NameMismatch:
Console.WriteLine("Validation Result: InvalidName");
break;
// Add more mappings as needed
default:
Console.WriteLine("Validation Result: UnknownError (or other)");
break;
}
}
// In a real application, you would decide based on the errors whether to allow the connection.
// For this example, we'll allow it if the specific errors are ones we've decided to ignore,
// otherwise deny. For simplicity, let's deny if there are any errors not explicitly handled.
// A common scenario is ignoring untrusted root for internal testing.
bool allowConnection = true; // Default to allow, or deny based on your policy
if (sslPolicyErrors != SslPolicyErrors.None)
{
Console.WriteLine("Certificate validation encountered errors. Decide whether to proceed.");
// Example: Allow if only untrusted root, otherwise deny
// if (!sslPolicyErrors.HasFlag(SslPolicyErrors.UntrustedRoot))
// {
// allowConnection = false;
// }
}
return allowConnection;
}
}
ValidationResultCode itself is not directly returned by the standard ServerCertificateCustomValidationCallback. Instead, you typically inspect the SslPolicyErrors enum and the X509ChainStatus array within the callback to determine the validation status and map it to conceptual outcomes similar to those in ValidationResultCode. The ValidationResultCode is more of an internal representation or used in specific APIs that might abstract this process.
Namespace: System.Net.Security
Assembly: System.Net.Primitives (in .NET Core and .NET 5+)
Assembly: System (in .NET Framework)