| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using CoreWCF.IdentityModel.Selectors; |
| | | 6 | | using System.Security.Cryptography.X509Certificates; |
| | | 7 | | using CoreWCF.Security; |
| | | 8 | | |
| | | 9 | | namespace CoreWCF.IdentityModel |
| | | 10 | | { |
| | | 11 | | /// <summary> |
| | | 12 | | /// This class wraps the four WCF validator types (Peer, Chain, PeerOrChain, and None). |
| | | 13 | | /// This class also resets the validation time each time a certificate is validated, to fix a .NET issue |
| | | 14 | | /// where certificates created after the validator is created will not chain. |
| | | 15 | | /// </summary> |
| | | 16 | | internal class X509CertificateValidatorEx : X509CertificateValidator |
| | | 17 | | { |
| | | 18 | | private X509CertificateValidationMode _certificateValidationMode; |
| | | 19 | | private X509ChainPolicy _chainPolicy; |
| | | 20 | | private X509CertificateValidator _validator; |
| | | 21 | | |
| | 2 | 22 | | public X509CertificateValidatorEx( |
| | 2 | 23 | | X509CertificateValidationMode certificateValidationMode, |
| | 2 | 24 | | X509RevocationMode revocationMode, |
| | 2 | 25 | | StoreLocation trustedStoreLocation) |
| | | 26 | | { |
| | 2 | 27 | | _certificateValidationMode = certificateValidationMode; |
| | | 28 | | |
| | 2 | 29 | | switch (_certificateValidationMode) |
| | | 30 | | { |
| | | 31 | | case X509CertificateValidationMode.None: |
| | | 32 | | { |
| | 0 | 33 | | _validator = X509CertificateValidator.None; |
| | 0 | 34 | | break; |
| | | 35 | | } |
| | | 36 | | |
| | | 37 | | case X509CertificateValidationMode.PeerTrust: |
| | | 38 | | { |
| | 0 | 39 | | _validator = X509CertificateValidator.PeerTrust; |
| | 0 | 40 | | break; |
| | | 41 | | } |
| | | 42 | | |
| | | 43 | | case X509CertificateValidationMode.ChainTrust: |
| | | 44 | | { |
| | 0 | 45 | | bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine; |
| | 0 | 46 | | _chainPolicy = new X509ChainPolicy(); |
| | 0 | 47 | | _chainPolicy.RevocationMode = revocationMode; |
| | | 48 | | |
| | 0 | 49 | | _validator = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, _chainPolicy) |
| | 0 | 50 | | break; |
| | | 51 | | } |
| | | 52 | | |
| | | 53 | | case X509CertificateValidationMode.PeerOrChainTrust: |
| | | 54 | | { |
| | 2 | 55 | | bool useMachineContext = trustedStoreLocation == StoreLocation.LocalMachine; |
| | 2 | 56 | | _chainPolicy = new X509ChainPolicy(); |
| | 2 | 57 | | _chainPolicy.RevocationMode = revocationMode; |
| | | 58 | | |
| | 2 | 59 | | _validator = X509CertificateValidator.CreatePeerOrChainTrustValidator(useMachineContext, _chainP |
| | 2 | 60 | | break; |
| | | 61 | | } |
| | | 62 | | |
| | | 63 | | case X509CertificateValidationMode.Custom: |
| | | 64 | | default: |
| | 0 | 65 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR |
| | | 66 | | } |
| | | 67 | | } |
| | | 68 | | |
| | | 69 | | public override void Validate(X509Certificate2 certificate) |
| | | 70 | | { |
| | 0 | 71 | | if (_certificateValidationMode == X509CertificateValidationMode.ChainTrust || |
| | 0 | 72 | | _certificateValidationMode == X509CertificateValidationMode.PeerOrChainTrust) |
| | | 73 | | { |
| | | 74 | | // This is needed due to a .NET issue where the validation time is not properly set, |
| | | 75 | | // causing certificates created after the creation of the validator to fail chain trust. |
| | 0 | 76 | | _chainPolicy.VerificationTime = DateTime.Now; |
| | | 77 | | } |
| | | 78 | | |
| | 0 | 79 | | _validator.Validate(certificate); |
| | 0 | 80 | | } |
| | | 81 | | } |
| | | 82 | | } |