e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
86 lines
3.7 KiB
C#
86 lines
3.7 KiB
C#
//-----------------------------------------------------------------------
|
|
// <copyright file="X509CertificateValidatorEx.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//-----------------------------------------------------------------------
|
|
|
|
namespace System.IdentityModel
|
|
{
|
|
using System;
|
|
using System.IdentityModel.Selectors;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.ServiceModel.Security;
|
|
|
|
/// <summary>
|
|
/// This class wraps the four WCF validator types (Peer, Chain, PeerOrChain, and None).
|
|
/// This class also resets the validation time each time a certificate is validated, to fix a .NET issue
|
|
/// where certificates created after the validator is created will not chain.
|
|
/// </summary>
|
|
internal class X509CertificateValidatorEx : X509CertificateValidator
|
|
{
|
|
private X509CertificateValidationMode certificateValidationMode;
|
|
private X509ChainPolicy chainPolicy;
|
|
private X509CertificateValidator validator;
|
|
|
|
public X509CertificateValidatorEx(
|
|
X509CertificateValidationMode certificateValidationMode,
|
|
X509RevocationMode revocationMode,
|
|
StoreLocation trustedStoreLocation)
|
|
{
|
|
this.certificateValidationMode = certificateValidationMode;
|
|
|
|
switch (this.certificateValidationMode)
|
|
{
|
|
case X509CertificateValidationMode.None:
|
|
{
|
|
this.validator = X509CertificateValidator.None;
|
|
break;
|
|
}
|
|
|
|
case X509CertificateValidationMode.PeerTrust:
|
|
{
|
|
this.validator = X509CertificateValidator.PeerTrust;
|
|
break;
|
|
}
|
|
|
|
case X509CertificateValidationMode.ChainTrust:
|
|
{
|
|
bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine;
|
|
this.chainPolicy = new X509ChainPolicy();
|
|
this.chainPolicy.RevocationMode = revocationMode;
|
|
|
|
this.validator = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, this.chainPolicy);
|
|
break;
|
|
}
|
|
|
|
case X509CertificateValidationMode.PeerOrChainTrust:
|
|
{
|
|
bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine;
|
|
this.chainPolicy = new X509ChainPolicy();
|
|
this.chainPolicy.RevocationMode = revocationMode;
|
|
|
|
this.validator = X509CertificateValidator.CreatePeerOrChainTrustValidator(useMachineContext, this.chainPolicy);
|
|
break;
|
|
}
|
|
|
|
case X509CertificateValidationMode.Custom:
|
|
default:
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4256)));
|
|
}
|
|
}
|
|
|
|
public override void Validate(X509Certificate2 certificate)
|
|
{
|
|
if (this.certificateValidationMode == X509CertificateValidationMode.ChainTrust ||
|
|
this.certificateValidationMode == X509CertificateValidationMode.PeerOrChainTrust)
|
|
{
|
|
// This is needed due to a .NET issue where the validation time is not properly set,
|
|
// causing certificates created after the creation of the validator to fail chain trust.
|
|
this.chainPolicy.VerificationTime = DateTime.Now;
|
|
}
|
|
|
|
this.validator.Validate(certificate);
|
|
}
|
|
}
|
|
}
|