internal static unsafe int BuildChain(IntPtr hChainEngine, System.Security.Cryptography.SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { if (pCertContext == null || pCertContext.IsInvalid) throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_InvalidContextHandle"), "pCertContext"); SafeCertStoreHandle hAdditionalStore = SafeCertStoreHandle.InvalidHandle; if (extraStore != null && extraStore.Count > 0) hAdditionalStore = X509Utils.ExportToMemoryStore(extraStore); CAPI.CERT_CHAIN_PARA pChainPara = new CAPI.CERT_CHAIN_PARA(); pChainPara.cbSize = (uint)Marshal.SizeOf((object)pChainPara); SafeLocalAllocHandle localAllocHandle1 = SafeLocalAllocHandle.InvalidHandle; if (applicationPolicy != null && applicationPolicy.Count > 0) { pChainPara.RequestedUsage.dwType = 0U; pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count; localAllocHandle1 = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = localAllocHandle1.DangerousGetHandle(); } SafeLocalAllocHandle localAllocHandle2 = SafeLocalAllocHandle.InvalidHandle; if (certificatePolicy != null && certificatePolicy.Count > 0) { pChainPara.RequestedIssuancePolicy.dwType = 0U; pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count; localAllocHandle2 = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = localAllocHandle2.DangerousGetHandle(); } pChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *(long*)&pTime = verificationTime.ToFileTime(); uint dwFlags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag); if (!CAPI.CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext)) return Marshal.GetHRForLastWin32Error(); localAllocHandle1.Dispose(); localAllocHandle2.Dispose(); return 0; }
public static ManifestSignatureInformationCollection VerifySignature(ActivationContext application, ManifestKinds manifests, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { if (application == null) { throw new ArgumentNullException("application"); } if ((revocationFlag < X509RevocationFlag.EndCertificateOnly) || (X509RevocationFlag.ExcludeRoot < revocationFlag)) { throw new ArgumentOutOfRangeException("revocationFlag"); } if ((revocationMode < X509RevocationMode.NoCheck) || (X509RevocationMode.Offline < revocationMode)) { throw new ArgumentOutOfRangeException("revocationMode"); } List<ManifestSignatureInformation> signatureInformation = new List<ManifestSignatureInformation>(); if ((manifests & ManifestKinds.Deployment) == ManifestKinds.Deployment) { ManifestSignedXml xml = new ManifestSignedXml(GetManifestXml(application, ManifestKinds.Deployment), ManifestKinds.Deployment); signatureInformation.Add(xml.VerifySignature(revocationFlag, revocationMode)); } if ((manifests & ManifestKinds.Application) == ManifestKinds.Application) { ManifestSignedXml xml2 = new ManifestSignedXml(GetManifestXml(application, ManifestKinds.Application), ManifestKinds.Application); signatureInformation.Add(xml2.VerifySignature(revocationFlag, revocationMode)); } return new ManifestSignatureInformationCollection(signatureInformation); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } TimeSpan remainingDownloadTime = timeout; var leaf = new X509Certificate2(cert.Handle); var downloaded = new HashSet<X509Certificate2>(); var systemTrusted = new HashSet<X509Certificate2>(); HashSet<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, systemTrusted, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, systemTrusted, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, ref remainingDownloadTime); if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } return chain; }
/// <summary> /// Does not throw on error. Returns null ChainPal instead. /// </summary> public static ChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CertificatePal certificatePal = (CertificatePal)cert; unsafe { using (SafeCertStoreHandle extraStoreHandle = ConvertExtraStoreToSafeHandle(extraStore)) { CERT_CHAIN_PARA chainPara = new CERT_CHAIN_PARA(); chainPara.cbSize = Marshal.SizeOf<CERT_CHAIN_PARA>(); int applicationPolicyCount; using (SafeHandle applicationPolicyOids = applicationPolicy.ToLpstrArray(out applicationPolicyCount)) { if (!applicationPolicyOids.IsInvalid) { chainPara.RequestedUsage.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedUsage.Usage.cUsageIdentifier = applicationPolicyCount; chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyOids.DangerousGetHandle(); } int certificatePolicyCount; using (SafeHandle certificatePolicyOids = certificatePolicy.ToLpstrArray(out certificatePolicyCount)) { if (!certificatePolicyOids.IsInvalid) { chainPara.RequestedIssuancePolicy.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = certificatePolicyCount; chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle(); } chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds); FILETIME ft = FILETIME.FromDateTime(verificationTime); CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag); ChainEngine chainEngine = useMachineContext ? ChainEngine.HCCE_LOCAL_MACHINE : ChainEngine.HCCE_CURRENT_USER; SafeX509ChainHandle chain; if (!Interop.crypt32.CertGetCertificateChain(chainEngine, certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain)) return null; return new ChainPal(chain); } } } } }
public void Reset() { this.m_applicationPolicy = new OidCollection(); this.m_certificatePolicy = new OidCollection(); this.m_revocationMode = X509RevocationMode.Online; this.m_revocationFlag = X509RevocationFlag.ExcludeRoot; this.m_verificationFlags = X509VerificationFlags.NoFlag; this.m_verificationTime = DateTime.Now; this.m_timeout = new TimeSpan(0, 0, 0); this.m_extraStore = new X509Certificate2Collection(); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { return new OpenSslX509ChainProcessor(); }
public override void ConfigureFromNode(XElement node) { base.ConfigureFromNode(node); AuthorityKey = XmlUtilities.GetTextFromAttribute(node, "authorityKey"); Store = XmlUtilities.GetEnumValueFromAttribute(node, "store", StoreName.My); Validate = XmlUtilities.GetEnumValueFromAttribute(node, "validate", X509RevocationFlag.EntireChain); Mode = XmlUtilities.GetEnumValueFromAttribute(node, "mode", X509RevocationMode.Online); Flags = XmlUtilities.GetEnumFlagsValueFromAttribute(node, "flags", X509VerificationFlags.NoFlag); Location = XmlUtilities.GetEnumValueFromAttribute(node, "location", StoreLocation.CurrentUser); Timeout = XmlUtilities.GetIntegerFromAttribute(node, "timeout", 30); }
internal void Execute( DateTime verificationTime, bool allowNetwork, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationFlag revocationFlag) { int osStatus; // Save the time code for determining which message to load for NotTimeValid. _verificationTime = verificationTime; int ret; using (SafeCFDateHandle cfEvaluationTime = Interop.CoreFoundation.CFDateCreate(verificationTime)) { ret = Interop.AppleCrypto.AppleCryptoNative_X509ChainEvaluate( _chainHandle, cfEvaluationTime, allowNetwork, out osStatus); } if (ret == 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } if (ret != 1) { Debug.Fail($"AppleCryptoNative_X509ChainEvaluate returned unknown result {ret}"); throw new CryptographicException(); } Tuple <X509Certificate2, int>[] elements = ParseResults(_chainHandle, _revocationMode); Debug.Assert(elements.Length > 0); if (!IsPolicyMatch(elements, applicationPolicy, certificatePolicy)) { Tuple <X509Certificate2, int> currentValue = elements[0]; elements[0] = Tuple.Create( currentValue.Item1, currentValue.Item2 | (int)X509ChainStatusFlags.NotValidForUsage); } FixupRevocationStatus(elements, revocationFlag); BuildAndSetProperties(elements); }
internal static partial IChainPal?BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection?extraStore, OidCollection?applicationPolicy, OidCollection?certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection?customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, bool disableAia) { throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection?extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, bool disableAia) { throw new NotImplementedException(nameof(BuildChain)); }
private X509ChainPolicy BuildChainPolicy(X509Certificate2 certificate) { // Now build the chain validation options. X509RevocationFlag revocationFlag = Options.RevocationFlag; X509RevocationMode revocationMode = Options.RevocationMode; if (certificate.IsSelfSigned()) { // Turn off chain validation, because we have a self signed certificate. revocationFlag = X509RevocationFlag.EntireChain; revocationMode = X509RevocationMode.NoCheck; } var chainPolicy = new X509ChainPolicy { RevocationFlag = revocationFlag, RevocationMode = revocationMode, }; if (Options.ValidateCertificateUse) { chainPolicy.ApplicationPolicy.Add(ClientCertificateOid); } if (certificate.IsSelfSigned()) { chainPolicy.VerificationFlags |= X509VerificationFlags.AllowUnknownCertificateAuthority; chainPolicy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; chainPolicy.ExtraStore.Add(certificate); } else { if (Options.CustomTrustStore != null) { chainPolicy.CustomTrustStore.AddRange(Options.CustomTrustStore); } chainPolicy.TrustMode = Options.ChainTrustValidationMode; } if (!Options.ValidateValidityPeriod) { chainPolicy.VerificationFlags |= X509VerificationFlags.IgnoreNotTimeValid; } return(chainPolicy); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection?extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, bool disableAia) { // If the time was given in Universal, it will stay Universal. // If the time was given in Local, it will be converted. // If the time was given in Unspecified, it will be assumed local, and converted. // // This matches the "assume Local unless explicitly Universal" implicit contract. verificationTime = verificationTime.ToUniversalTime(); SecTrustChainPal chainPal = new SecTrustChainPal(); try { chainPal.OpenTrustHandle( cert, extraStore, revocationMode, customTrustStore, trustMode); chainPal.Execute( verificationTime, !disableAia, applicationPolicy, certificatePolicy, revocationFlag); } catch { chainPal.Dispose(); throw; } return(chainPal); }
private static unsafe void BuildChain(IntPtr hChainEngine, IntPtr pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, out System.IdentityModel.SafeCertChainHandle ppChainContext) { System.IdentityModel.SafeCertStoreHandle hAdditionalStore = ExportToMemoryStore(extraStore, pCertContext); System.IdentityModel.CAPI.CERT_CHAIN_PARA pChainPara = new System.IdentityModel.CAPI.CERT_CHAIN_PARA { cbSize = (uint) Marshal.SizeOf(typeof(System.IdentityModel.CAPI.CERT_CHAIN_PARA)) }; SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle; SafeHGlobalHandle handle3 = SafeHGlobalHandle.InvalidHandle; try { if ((applicationPolicy != null) && (applicationPolicy.Count > 0)) { pChainPara.RequestedUsage.dwType = 0; pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint) applicationPolicy.Count; invalidHandle = CopyOidsToUnmanagedMemory(applicationPolicy); pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = invalidHandle.DangerousGetHandle(); } if ((certificatePolicy != null) && (certificatePolicy.Count > 0)) { pChainPara.RequestedIssuancePolicy.dwType = 0; pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint) certificatePolicy.Count; handle3 = CopyOidsToUnmanagedMemory(certificatePolicy); pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = handle3.DangerousGetHandle(); } pChainPara.dwUrlRetrievalTimeout = (uint) timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *((long*) &pTime) = verificationTime.ToFileTime(); uint dwFlags = MapRevocationFlags(revocationMode, revocationFlag); if (!System.IdentityModel.CAPI.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext)) { int hr = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(hr)); } } finally { if (invalidHandle != null) { invalidHandle.Dispose(); } if (handle3 != null) { handle3.Dispose(); } hAdditionalStore.Close(); } }
// this method maps X509RevocationFlag to crypto API flags. internal static uint MapRevocationFlags (X509RevocationMode revocationMode, X509RevocationFlag revocationFlag) { uint dwFlags = 0; if (revocationMode == X509RevocationMode.NoCheck) return dwFlags; if (revocationMode == X509RevocationMode.Offline) dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; if (revocationFlag == X509RevocationFlag.EndCertificateOnly) dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_END_CERT; else if (revocationFlag == X509RevocationFlag.EntireChain) dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_CHAIN; else dwFlags |= CAPI.CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; return dwFlags; }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CheckRevocationMode(revocationMode); // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } TimeSpan remainingDownloadTime = timeout; X509Certificate2 leaf = new X509Certificate2(cert.Handle); List<X509Certificate2> downloaded = new List<X509Certificate2>(); List<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, applicationPolicy, certificatePolicy, verificationTime); if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } return chain; }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CheckRevocationMode(revocationMode); // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } TimeSpan remainingDownloadTime = timeout; X509Certificate2 leaf = new X509Certificate2(cert.Handle); List <X509Certificate2> downloaded = new List <X509Certificate2>(); List <X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, applicationPolicy, certificatePolicy, verificationTime); if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } return(chain); }
private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer, XmlElement licenseNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { Debug.Assert(licenseNode != null, "licenseNode != null"); X509Chain signatureChain = null; if (signer.pChainContext != IntPtr.Zero) { signatureChain = new X509Chain(signer.pChainContext); } else if (signer.dwError == (int)SignatureVerificationResult.UntrustedRootCertificate) { // CertVerifyAuthenticodeLicense will not return the certificate chain for self signed certificates // so we'll need to extract the certificate from the signature ourselves. XmlElement x509Data = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data", m_namespaceManager) as XmlElement; if (x509Data != null) { XmlNodeList certificateNodes = x509Data.SelectNodes("ds:X509Certificate", m_namespaceManager); // A manifest could have many X509Certificate nodes in its X509Data, which may include the // signing certificate, links on the chain to a root, or certificates not used at all in // the chain. Since we don't know which certificate actually did the signing, we only // process the chain if we have a single certificate. if (certificateNodes.Count == 1 && certificateNodes[0] is XmlElement) { byte[] rawCertificate = Convert.FromBase64String(certificateNodes[0].InnerText.Trim()); X509Certificate2 signingCertificate = new X509Certificate2(rawCertificate); signatureChain = new X509Chain(); signatureChain.ChainPolicy.RevocationFlag = revocationFlag; signatureChain.ChainPolicy.RevocationMode = revocationMode; signatureChain.Build(signingCertificate); } } } return(signatureChain); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { // If the time was given in Universal, it will stay Universal. // If the time was given in Local, it will be converted. // If the time was given in Unspecified, it will be assumed local, and converted. // // This matches the "assume Local unless explicitly Universal" implicit contract. verificationTime = verificationTime.ToUniversalTime(); // The Windows (and other-Unix-PAL) behavior is to allow network until network operations // have exceeded the specified timeout. For Apple it's either on (and AIA fetching works), // or off (and AIA fetching doesn't work). And once an SSL policy is used, or revocation is // being checked, the value is on anyways. const bool allowNetwork = true; SecTrustChainPal chainPal = new SecTrustChainPal(); try { chainPal.OpenTrustHandle(cert, extraStore, revocationMode); chainPal.Execute( verificationTime, allowNetwork, applicationPolicy, certificatePolicy, revocationFlag); } catch { chainPal.Dispose(); throw; } return(chainPal); }
internal static partial IChainPal?BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection?extraStore, OidCollection?applicationPolicy, OidCollection?certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection?customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, bool disableAia) { if (OpenSslX509ChainEventSource.Log.IsEnabled()) { OpenSslX509ChainEventSource.Log.ChainStart(); } try { return(BuildChainCore( useMachineContext, cert, extraStore, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, customTrustStore, trustMode, verificationTime, timeout, disableAia)); } finally { if (OpenSslX509ChainEventSource.Log.IsEnabled()) { OpenSslX509ChainEventSource.Log.ChainStop(); } } }
private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer, XmlElement licenseNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { Debug.Assert(licenseNode != null, "licenseNode != null"); X509Chain signatureChain = null; if (signer.pChainContext != IntPtr.Zero) { signatureChain = new X509Chain(signer.pChainContext); } else if (signer.dwError == (int)SignatureVerificationResult.UntrustedRootCertificate) { // CertVerifyAuthenticodeLicense will not return the certificate chain for self signed certificates // so we'll need to extract the certificate from the signature ourselves. XmlElement x509Data = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data", m_namespaceManager) as XmlElement; if (x509Data != null) { XmlNodeList certificateNodes = x509Data.SelectNodes("ds:X509Certificate", m_namespaceManager); // A manifest could have many X509Certificate nodes in its X509Data, which may include the // signing certificate, links on the chain to a root, or certificates not used at all in // the chain. Since we don't know which certificate actually did the signing, we only // process the chain if we have a single certificate. if (certificateNodes.Count == 1 && certificateNodes[0] is XmlElement) { byte[] rawCertificate = Convert.FromBase64String(certificateNodes[0].InnerText.Trim()); X509Certificate2 signingCertificate = new X509Certificate2(rawCertificate); signatureChain = new X509Chain(); signatureChain.ChainPolicy.RevocationFlag = revocationFlag; signatureChain.ChainPolicy.RevocationMode = revocationMode; signatureChain.Build(signingCertificate); } } } return signatureChain; }
private static uint MapRevocationFlags(X509RevocationMode revocationMode, X509RevocationFlag revocationFlag) { uint num = 0; if (revocationMode == X509RevocationMode.NoCheck) { return(num); } if (revocationMode == X509RevocationMode.Offline) { num |= 0x80000000; } if (revocationFlag == X509RevocationFlag.EndCertificateOnly) { return(num | 0x10000000); } if (revocationFlag == X509RevocationFlag.EntireChain) { return(num | 0x20000000); } return(num | 0x40000000); }
/// <summary> /// Map X509 revocation flags to flags for the AXL verification APIs /// </summary> private static X509Native.AxlVerificationFlags MapRevocationFlags(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { X509Native.AxlVerificationFlags axlFlags = X509Native.AxlVerificationFlags.None; switch (revocationFlag) { case X509RevocationFlag.EndCertificateOnly: axlFlags |= X509Native.AxlVerificationFlags.RevocationCheckEndCertOnly; break; case X509RevocationFlag.EntireChain: axlFlags |= X509Native.AxlVerificationFlags.RevocationCheckEntireChain; break; case X509RevocationFlag.ExcludeRoot: default: axlFlags |= X509Native.AxlVerificationFlags.None; break; } switch (revocationMode) { case X509RevocationMode.NoCheck: axlFlags |= X509Native.AxlVerificationFlags.NoRevocationCheck; break; case X509RevocationMode.Offline: axlFlags |= X509Native.AxlVerificationFlags.UrlOnlyCacheRetrieval; break; case X509RevocationMode.Online: default: axlFlags |= X509Native.AxlVerificationFlags.None; break; } return(axlFlags); }
public ManifestSignatureInformation VerifySignature(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { XmlElement element = this.m_manifestXml.SelectSingleNode("//ds:Signature", this.m_namespaceManager) as XmlElement; if (element == null) { return(new ManifestSignatureInformation(this.m_manifest, null, null)); } base.LoadXml(element); StrongNameSignatureInformation strongNameSignature = this.VerifyStrongNameSignature(element); AuthenticodeSignatureInformation authenticodeSignature = null; if (strongNameSignature.VerificationResult != SignatureVerificationResult.BadDigest) { authenticodeSignature = this.VerifyAuthenticodeSignature(element, revocationFlag, revocationMode); } else { authenticodeSignature = new AuthenticodeSignatureInformation(SignatureVerificationResult.ContainingSignatureInvalid); } return(new ManifestSignatureInformation(this.m_manifest, strongNameSignature, authenticodeSignature)); }
private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer, XmlElement licenseNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { X509Chain chain = null; if (signer.dwError == -2146762487) { XmlElement element = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data", this.m_namespaceManager) as XmlElement; if (element != null) { X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String(element.InnerText.Trim())); chain = new X509Chain { ChainPolicy = { RevocationFlag = revocationFlag, RevocationMode = revocationMode } }; chain.Build(certificate); } return chain; } if (signer.pChainContext != IntPtr.Zero) { chain = new X509Chain(signer.pChainContext); } return chain; }
public static ManifestSignatureInformationCollection VerifySignature(ActivationContext application, ManifestKinds manifests, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { if (application == null) { throw new ArgumentNullException("application"); } if (revocationFlag < X509RevocationFlag.EndCertificateOnly || X509RevocationFlag.ExcludeRoot < revocationFlag) { throw new ArgumentOutOfRangeException("revocationFlag"); } if (revocationMode < X509RevocationMode.NoCheck || X509RevocationMode.Offline < revocationMode) { throw new ArgumentOutOfRangeException("revocationMode"); } List <ManifestSignatureInformation> signatures = new List <ManifestSignatureInformation>(); if ((manifests & ManifestKinds.Deployment) == ManifestKinds.Deployment) { XmlDocument deploymentManifest = GetManifestXml(application, ManifestKinds.Deployment); ManifestSignedXml deploymentSignature = new ManifestSignedXml(deploymentManifest, ManifestKinds.Deployment); signatures.Add(deploymentSignature.VerifySignature(revocationFlag, revocationMode)); } if ((manifests & ManifestKinds.Application) == ManifestKinds.Application) { XmlDocument applicationManifest = GetManifestXml(application, ManifestKinds.Application); ManifestSignedXml applicationSignature = new ManifestSignedXml(applicationManifest, ManifestKinds.Application); signatures.Add(applicationSignature.VerifySignature(revocationFlag, revocationMode)); } return(new ManifestSignatureInformationCollection(signatures)); }
internal void ProcessRevocation( X509RevocationMode revocationMode, X509RevocationFlag revocationFlag) { _revocationMode = revocationMode; if (revocationMode == X509RevocationMode.NoCheck) { return; } using (SafeX509StackHandle chainStack = Interop.Crypto.X509StoreCtxGetChain(_storeCtx)) { int chainSize = revocationFlag == X509RevocationFlag.EndCertificateOnly ? 1 : Interop.Crypto.GetX509StackFieldCount(chainStack); for (int i = 0; i < chainSize; i++) { using (SafeX509Handle cert = Interop.Crypto.X509UpRef(Interop.Crypto.GetX509StackField(chainStack, i))) { CrlCache.AddCrlForCertificate( cert, _store, revocationMode, _verificationTime, ref _remainingDownloadTime); } } } Interop.Crypto.X509StoreSetRevocationFlag(_store, revocationFlag); Interop.Crypto.X509StoreCtxRebuildChain(_storeCtx); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CheckRevocationMode(revocationMode); X509Certificate2 leaf = new X509Certificate2(cert.Handle); X509Certificate2Collection candidates = OpenSslX509ChainProcessor.FindCandidates(leaf, extraStore); return(OpenSslX509ChainProcessor.BuildChain( leaf, candidates, applicationPolicy, certificatePolicy, verificationTime)); }
private static void FixupRevocationStatus( Tuple <X509Certificate2, int>[] elements, X509RevocationFlag revocationFlag) { if (revocationFlag == X509RevocationFlag.ExcludeRoot) { // When requested int idx = elements.Length - 1; Tuple <X509Certificate2, int> element = elements[idx]; X509ChainStatusFlags statusFlags = (X509ChainStatusFlags)element.Item2; // Apple will terminate the chain at the first "root" or "trustAsRoot" certificate // it finds, which it refers to as "anchors". We'll consider a "trustAsRoot" cert // as a root for the purposes of ExcludeRoot. So as long as the last element doesn't // have PartialChain consider it the root. if ((statusFlags & X509ChainStatusFlags.PartialChain) == 0) { statusFlags &= ~RevocationRelevantFlags; elements[idx] = Tuple.Create(element.Item1, (int)statusFlags); } } else if (revocationFlag == X509RevocationFlag.EndCertificateOnly) { // In Windows the EndCertificateOnly flag (CERT_CHAIN_REVOCATION_CHECK_END_CERT) will apply // to a root if that's the only element, so we'll do the same. // Start at element 1, and move to the end. for (int i = 1; i < elements.Length; i++) { Tuple <X509Certificate2, int> element = elements[i]; X509ChainStatusFlags statusFlags = (X509ChainStatusFlags)element.Item2; statusFlags &= ~RevocationRelevantFlags; elements[i] = Tuple.Create(element.Item1, (int)statusFlags); } } }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } TimeSpan remainingDownloadTime = timeout; using (var leaf = new X509Certificate2(cert.Handle)) { var downloaded = new HashSet <X509Certificate2>(); var systemTrusted = new HashSet <X509Certificate2>(); HashSet <X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, systemTrusted, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, systemTrusted, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, ref remainingDownloadTime); #if DEBUG if (chain.ChainElements.Length > 0) { X509Certificate2 reportedLeaf = chain.ChainElements[0].Certificate; Debug.Assert(reportedLeaf != null, "reportedLeaf != null"); Debug.Assert(reportedLeaf.Equals(leaf), "reportedLeaf.Equals(leaf)"); Debug.Assert(!ReferenceEquals(reportedLeaf, leaf), "!ReferenceEquals(reportedLeaf, leaf)"); } #endif if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } // Everything we put into the chain has been cloned, dispose all the originals. systemTrusted.DisposeAll(); downloaded.DisposeAll(); // Candidate certs which came from extraStore should NOT be disposed, since they came // from outside. var extraStoreByReference = new HashSet <X509Certificate2>( ReferenceEqualityComparer <X509Certificate2> .Instance); foreach (X509Certificate2 extraCert in extraStore) { extraStoreByReference.Add(extraCert); } foreach (X509Certificate2 candidate in candidates) { if (!extraStoreByReference.Contains(candidate)) { candidate.Dispose(); } } return(chain); } }
// // Builds a certificate chain. // internal static unsafe int BuildChain(IntPtr hChainEngine, SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { if (pCertContext == null || pCertContext.IsInvalid) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidContextHandle), "pCertContext"); } SafeCertStoreHandle hCertStore = SafeCertStoreHandle.InvalidHandle; if (extraStore != null && extraStore.Count > 0) { hCertStore = X509Utils.ExportToMemoryStore(extraStore); } CAPI.CERT_CHAIN_PARA ChainPara = new CAPI.CERT_CHAIN_PARA(); // Initialize the structure size. ChainPara.cbSize = (uint)Marshal.SizeOf(ChainPara); SafeLocalAllocHandle applicationPolicyHandle = SafeLocalAllocHandle.InvalidHandle; SafeLocalAllocHandle certificatePolicyHandle = SafeLocalAllocHandle.InvalidHandle; try { // Application policy if (applicationPolicy != null && applicationPolicy.Count > 0) { ChainPara.RequestedUsage.dwType = CAPI.USAGE_MATCH_TYPE_AND; ChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count; applicationPolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyHandle.DangerousGetHandle(); } // Certificate policy if (certificatePolicy != null && certificatePolicy.Count > 0) { ChainPara.RequestedIssuancePolicy.dwType = CAPI.USAGE_MATCH_TYPE_AND; ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count; certificatePolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyHandle.DangerousGetHandle(); } ChainPara.dwUrlRetrievalTimeout = (uint)Math.Floor(timeout.TotalMilliseconds); _FILETIME ft = new _FILETIME(); *((long *)&ft) = verificationTime.ToFileTime(); uint flags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag); // Build the chain. if (!CAPI.CertGetCertificateChain(hChainEngine, pCertContext, ref ft, hCertStore, ref ChainPara, flags, IntPtr.Zero, ref ppChainContext)) { return(Marshal.GetHRForLastWin32Error()); } } finally { applicationPolicyHandle.Dispose(); certificatePolicyHandle.Dispose(); } return(CAPI.S_OK); }
internal static unsafe int BuildChain(IntPtr hChainEngine, System.Security.Cryptography.SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { CAPIBase.CERT_CHAIN_PARA cert_chain_para; if ((pCertContext == null) || pCertContext.IsInvalid) { throw new ArgumentException(SR.GetString("Cryptography_InvalidContextHandle"), "pCertContext"); } System.Security.Cryptography.SafeCertStoreHandle invalidHandle = System.Security.Cryptography.SafeCertStoreHandle.InvalidHandle; if ((extraStore != null) && (extraStore.Count > 0)) { invalidHandle = System.Security.Cryptography.X509Certificates.X509Utils.ExportToMemoryStore(extraStore); } cert_chain_para = new CAPIBase.CERT_CHAIN_PARA { cbSize = (uint) Marshal.SizeOf(cert_chain_para) }; SafeLocalAllocHandle handle2 = SafeLocalAllocHandle.InvalidHandle; if ((applicationPolicy != null) && (applicationPolicy.Count > 0)) { cert_chain_para.RequestedUsage.dwType = 0; cert_chain_para.RequestedUsage.Usage.cUsageIdentifier = (uint) applicationPolicy.Count; handle2 = System.Security.Cryptography.X509Certificates.X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); cert_chain_para.RequestedUsage.Usage.rgpszUsageIdentifier = handle2.DangerousGetHandle(); } SafeLocalAllocHandle handle3 = SafeLocalAllocHandle.InvalidHandle; if ((certificatePolicy != null) && (certificatePolicy.Count > 0)) { cert_chain_para.RequestedIssuancePolicy.dwType = 0; cert_chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint) certificatePolicy.Count; handle3 = System.Security.Cryptography.X509Certificates.X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); cert_chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = handle3.DangerousGetHandle(); } cert_chain_para.dwUrlRetrievalTimeout = (uint) timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *((long*) &pTime) = verificationTime.ToFileTime(); uint dwFlags = System.Security.Cryptography.X509Certificates.X509Utils.MapRevocationFlags(revocationMode, revocationFlag); if (!CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, invalidHandle, ref cert_chain_para, dwFlags, IntPtr.Zero, ref ppChainContext)) { return Marshal.GetHRForLastWin32Error(); } handle2.Dispose(); handle3.Dispose(); return 0; }
public ManifestSignatureInformation VerifySignature(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { XmlElement element = this.m_manifestXml.SelectSingleNode("//ds:Signature", this.m_namespaceManager) as XmlElement; if (element == null) { return new ManifestSignatureInformation(this.m_manifest, null, null); } base.LoadXml(element); StrongNameSignatureInformation strongNameSignature = this.VerifyStrongNameSignature(element); AuthenticodeSignatureInformation authenticodeSignature = null; if (strongNameSignature.VerificationResult != SignatureVerificationResult.BadDigest) { authenticodeSignature = this.VerifyAuthenticodeSignature(element, revocationFlag, revocationMode); } else { authenticodeSignature = new AuthenticodeSignatureInformation(SignatureVerificationResult.ContainingSignatureInvalid); } return new ManifestSignatureInformation(this.m_manifest, strongNameSignature, authenticodeSignature); }
public bool ChainPolicyUsed(X509RevocationFlag flag) { return Chain.ChainPolicy.RevocationFlag == flag; }
public static BooleanReason VerifyCertificate(X509Certificate2 certificate, X509RevocationFlag revocationFlag, X509RevocationMode mode, TimeSpan timeout, X509VerificationFlags verificationFlags) { try { var chain = new X509Chain { ChainPolicy = { RevocationFlag = revocationFlag, RevocationMode = mode, VerificationFlags = verificationFlags, UrlRetrievalTimeout = timeout } }; if (!chain.Build(certificate)) { if (!IsChainOk(chain)) return new BooleanReason(false, "Could not verify certificate"); } return new BooleanReason(true, "certificate verified"); } catch (Exception e) { return new BooleanReason(false, "An issue occurred while verifying certificate: {0}", e.Message); } }
/// <summary> /// Creates a trust manager that establishes trust based on system certificate stores with configurable hostname /// verification, revocation checks. /// </summary> /// <param name="verifyHostname">Whether to perform hostname verification</param> /// <param name="revocationMode">The revocation check mode</param> /// <param name="revocationFlag">How should the revocation check should behave</param> /// <param name="useMachineContext">Whether to use machine context instead of user's for certificate stores</param> /// <returns>An instance of <see cref="TrustManager"/></returns> public static TrustManager CreateChainTrust(bool verifyHostname, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, bool useMachineContext) => new ChainTrustManager(useMachineContext, verifyHostname, revocationMode, revocationFlag);
/// <summary> /// Validate certificate against policy chain /// </summary> /// <param name="certificate">certificate</param> /// <param name="revocationFlag">revocation flag</param> /// <param name="revocationMode">revocation mode</param> /// <param name="retrievalTimeout">retrieval timeout</param> /// <param name="verificationFlags">verification flags</param> /// <returns>certificate verification result</returns> public static CertificateVerificationResult Verify(X509Certificate2 certificate, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode, TimeSpan retrievalTimeout, X509VerificationFlags verificationFlags) { //chain information of the selected certificate. var chain = new X509Chain(); chain.ChainPolicy.RevocationFlag = revocationFlag; chain.ChainPolicy.RevocationMode = revocationMode; chain.ChainPolicy.UrlRetrievalTimeout = retrievalTimeout; chain.ChainPolicy.VerificationFlags = verificationFlags; var isValid = chain.Build(certificate); return(new CertificateVerificationResult { IsCertificateValid = isValid, ChainStatus = chain.ChainStatus }); }
public static IChainPal BuildChain( X509Certificate2 leaf, HashSet<X509Certificate2> candidates, HashSet<X509Certificate2> downloaded, HashSet<X509Certificate2> systemTrusted, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, ref TimeSpan remainingDownloadTime) { X509ChainElement[] elements; List<X509ChainStatus> overallStatus = new List<X509ChainStatus>(); WorkingChain workingChain = new WorkingChain(); Interop.Crypto.X509StoreVerifyCallback workingCallback = workingChain.VerifyCallback; // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes. // // (If you need to think of it as an X509Store, it's a volatile memory store) using (SafeX509StoreHandle store = Interop.Crypto.X509StoreCreate()) using (SafeX509StoreCtxHandle storeCtx = Interop.Crypto.X509StoreCtxCreate()) { Interop.Crypto.CheckValidOpenSslHandle(store); Interop.Crypto.CheckValidOpenSslHandle(storeCtx); bool lookupCrl = revocationMode != X509RevocationMode.NoCheck; foreach (X509Certificate2 cert in candidates) { OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal; if (!Interop.Crypto.X509StoreAddCert(store, pal.SafeHandle)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } if (lookupCrl) { CrlCache.AddCrlForCertificate( cert, store, revocationMode, verificationTime, ref remainingDownloadTime); // If we only wanted the end-entity certificate CRL then don't look up // any more of them. lookupCrl = revocationFlag != X509RevocationFlag.EndCertificateOnly; } } if (revocationMode != X509RevocationMode.NoCheck) { if (!Interop.Crypto.X509StoreSetRevocationFlag(store, revocationFlag)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } } SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle; if (!Interop.Crypto.X509StoreCtxInit(storeCtx, store, leafHandle)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } Interop.Crypto.X509StoreCtxSetVerifyCallback(storeCtx, workingCallback); Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime); int verify = Interop.Crypto.X509VerifyCert(storeCtx); if (verify < 0) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } // Because our callback tells OpenSSL that every problem is ignorable, it should tell us that the // chain is just fine (unless it returned a negative code for an exception) Debug.Assert(verify == 1, "verify == 1"); using (SafeX509StackHandle chainStack = Interop.Crypto.X509StoreCtxGetChain(storeCtx)) { int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack); elements = new X509ChainElement[chainSize]; int maybeRootDepth = chainSize - 1; // The leaf cert is 0, up to (maybe) the root at chainSize - 1 for (int i = 0; i < chainSize; i++) { List<X509ChainStatus> status = new List<X509ChainStatus>(); List<Interop.Crypto.X509VerifyStatusCode> elementErrors = i < workingChain.Errors.Count ? workingChain.Errors[i] : null; if (elementErrors != null) { AddElementStatus(elementErrors, status, overallStatus); } IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i); if (elementCertPtr == IntPtr.Zero) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } // Duplicate the certificate handle X509Certificate2 elementCert = new X509Certificate2(elementCertPtr); // If the last cert is self signed then it's the root cert, do any extra checks. if (i == maybeRootDepth && IsSelfSigned(elementCert)) { // If the root certificate was downloaded or the system // doesn't trust it, it's untrusted. if (downloaded.Contains(elementCert) || !systemTrusted.Contains(elementCert)) { AddElementStatus( Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED, status, overallStatus); } } elements[i] = new X509ChainElement(elementCert, status.ToArray(), ""); } } } GC.KeepAlive(workingCallback); if ((certificatePolicy != null && certificatePolicy.Count > 0) || (applicationPolicy != null && applicationPolicy.Count > 0)) { List<X509Certificate2> certsToRead = new List<X509Certificate2>(); foreach (X509ChainElement element in elements) { certsToRead.Add(element.Certificate); } CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead); bool failsPolicyChecks = false; if (certificatePolicy != null) { if (!policyChain.MatchesCertificatePolicies(certificatePolicy)) { failsPolicyChecks = true; } } if (applicationPolicy != null) { if (!policyChain.MatchesApplicationPolicies(applicationPolicy)) { failsPolicyChecks = true; } } if (failsPolicyChecks) { X509ChainElement leafElement = elements[0]; X509ChainStatus chainStatus = new X509ChainStatus { Status = X509ChainStatusFlags.NotValidForUsage, StatusInformation = SR.Chain_NoPolicyMatch, }; var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1); elementStatus.AddRange(leafElement.ChainElementStatus); AddUniqueStatus(elementStatus, ref chainStatus); AddUniqueStatus(overallStatus, ref chainStatus); elements[0] = new X509ChainElement( leafElement.Certificate, elementStatus.ToArray(), leafElement.Information); } } return new OpenSslX509ChainProcessor { ChainStatus = overallStatus.ToArray(), ChainElements = elements, }; }
internal static uint MapRevocationFlags(X509RevocationMode revocationMode, X509RevocationFlag revocationFlag) { uint num = 0U; if (revocationMode == X509RevocationMode.NoCheck) return num; if (revocationMode == X509RevocationMode.Offline) num |= (uint)int.MinValue; return revocationFlag != X509RevocationFlag.EndCertificateOnly ? (revocationFlag != X509RevocationFlag.EntireChain ? num | 1073741824U : num | 536870912U) : num | 268435456U; }
internal static unsafe int VerifyCertificate(System.Security.Cryptography.SafeCertContextHandle pCertContext, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, X509Certificate2Collection extraStore, IntPtr pszPolicy, IntPtr pdwErrorStatus) { if (pCertContext == null || pCertContext.IsInvalid) throw new ArgumentException("pCertContext"); CAPI.CERT_CHAIN_POLICY_PARA pPolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA))); CAPI.CERT_CHAIN_POLICY_STATUS pPolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS))); SafeCertChainHandle invalidHandle = SafeCertChainHandle.InvalidHandle; int num = X509Utils.BuildChain(new IntPtr(0L), pCertContext, extraStore, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, timeout, ref invalidHandle); if (num != 0) return num; if (!CAPI.CAPISafe.CertVerifyCertificateChainPolicy(pszPolicy, invalidHandle, ref pPolicyPara, out pPolicyStatus)) return Marshal.GetHRForLastWin32Error(); if (pdwErrorStatus != IntPtr.Zero) *(int*)(void*)pdwErrorStatus = (int)pPolicyStatus.dwError; return (int)pPolicyStatus.dwError != 0 ? 1 : 0; }
public static IChainPal BuildChain( X509Certificate2 leaf, List<X509Certificate2> candidates, List<X509Certificate2> downloaded, List<X509Certificate2> systemTrusted, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, ref TimeSpan remainingDownloadTime) { X509ChainElement[] elements; List<X509ChainStatus> overallStatus = new List<X509ChainStatus>(); // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes. // // (If you need to think of it as an X509Store, it's a volatile memory store) using (SafeX509StoreHandle store = Interop.libcrypto.X509_STORE_new()) using (SafeX509StoreCtxHandle storeCtx = Interop.libcrypto.X509_STORE_CTX_new()) { Interop.libcrypto.CheckValidOpenSslHandle(store); Interop.libcrypto.CheckValidOpenSslHandle(storeCtx); bool lookupCrl = revocationMode != X509RevocationMode.NoCheck; foreach (X509Certificate2 cert in candidates) { OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal; if (!Interop.libcrypto.X509_STORE_add_cert(store, pal.SafeHandle)) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } if (lookupCrl) { CrlCache.AddCrlForCertificate( cert, store, revocationMode, verificationTime, ref remainingDownloadTime); // If we only wanted the end-entity certificate CRL then don't look up // any more of them. lookupCrl = revocationFlag != X509RevocationFlag.EndCertificateOnly; } } if (revocationMode != X509RevocationMode.NoCheck) { Interop.libcrypto.X509VerifyFlags vfyFlags = Interop.libcrypto.X509VerifyFlags.X509_V_FLAG_CRL_CHECK; if (revocationFlag != X509RevocationFlag.EndCertificateOnly) { vfyFlags |= Interop.libcrypto.X509VerifyFlags.X509_V_FLAG_CRL_CHECK_ALL; } if (!Interop.libcrypto.X509_STORE_set_flags(store, vfyFlags)) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } } // When CRL checking support is added, it should be done before the call to // X509_STORE_CTX_init (aka here) by calling X509_STORE_set_flags(store, flags); SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle; if (!Interop.libcrypto.X509_STORE_CTX_init(storeCtx, store, leafHandle, IntPtr.Zero)) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime); int verify = Interop.libcrypto.X509_verify_cert(storeCtx); if (verify < 0) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } using (SafeX509StackHandle chainStack = Interop.libcrypto.X509_STORE_CTX_get1_chain(storeCtx)) { int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack); int errorDepth = -1; Interop.libcrypto.X509VerifyStatusCode errorCode = 0; if (verify == 0) { errorCode = Interop.libcrypto.X509_STORE_CTX_get_error(storeCtx); errorDepth = Interop.libcrypto.X509_STORE_CTX_get_error_depth(storeCtx); } elements = new X509ChainElement[chainSize]; int maybeRootDepth = chainSize - 1; // The leaf cert is 0, up to (maybe) the root at chainSize - 1 for (int i = 0; i < chainSize; i++) { List<X509ChainStatus> status = new List<X509ChainStatus>(); if (i == errorDepth) { AddElementStatus(errorCode, status, overallStatus); } IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i); if (elementCertPtr == IntPtr.Zero) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } // Duplicate the certificate handle X509Certificate2 elementCert = new X509Certificate2(elementCertPtr); // If the last cert is self signed then it's the root cert, do any extra checks. if (i == maybeRootDepth && IsSelfSigned(elementCert)) { // If the root certificate was downloaded or the system // doesn't trust it, it's untrusted. if (downloaded.Contains(elementCert) || !systemTrusted.Contains(elementCert)) { AddElementStatus( Interop.libcrypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED, status, overallStatus); } } elements[i] = new X509ChainElement(elementCert, status.ToArray(), ""); } } } if ((certificatePolicy != null && certificatePolicy.Count > 0) || (applicationPolicy != null && applicationPolicy.Count > 0)) { List<X509Certificate2> certsToRead = new List<X509Certificate2>(); foreach (X509ChainElement element in elements) { certsToRead.Add(element.Certificate); } CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead); bool failsPolicyChecks = false; if (certificatePolicy != null) { if (!policyChain.MatchesCertificatePolicies(certificatePolicy)) { failsPolicyChecks = true; } } if (applicationPolicy != null) { if (!policyChain.MatchesApplicationPolicies(applicationPolicy)) { failsPolicyChecks = true; } } if (failsPolicyChecks) { X509ChainElement leafElement = elements[0]; X509ChainStatus chainStatus = new X509ChainStatus { Status = X509ChainStatusFlags.InvalidPolicyConstraints, StatusInformation = SR.Chain_NoPolicyMatch, }; var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1); elementStatus.AddRange(leafElement.ChainElementStatus); AddUniqueStatus(elementStatus, ref chainStatus); AddUniqueStatus(overallStatus, ref chainStatus); elements[0] = new X509ChainElement( leafElement.Certificate, elementStatus.ToArray(), leafElement.Information); } } return new OpenSslX509ChainProcessor { ChainStatus = overallStatus.ToArray(), ChainElements = elements, }; }
internal static extern bool X509StoreSetRevocationFlag(SafeX509StoreHandle ctx, X509RevocationFlag revocationFlag);
/// <summary> /// Verify the signature of the manifest /// </summary> public ManifestSignatureInformation VerifySignature(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { XmlElement signatureNode = m_manifestXml.SelectSingleNode("//ds:Signature", m_namespaceManager) as XmlElement; if (signatureNode == null) { return new ManifestSignatureInformation(m_manifest, null, null); } LoadXml(signatureNode); StrongNameSignatureInformation strongName = VerifyStrongNameSignature(signatureNode); // Since the Authenticode signature is wrapped in the strong name signature, we do not want to // give a valid AuthenticodeSignatureInformation object for an Authenticode signature which is // contained within a strong name signature with an invalid hash value. AuthenticodeSignatureInformation authenticode = null; if (strongName.VerificationResult != SignatureVerificationResult.BadDigest) { authenticode = VerifyAuthenticodeSignature(signatureNode, revocationFlag, revocationMode); } else { authenticode = new AuthenticodeSignatureInformation(SignatureVerificationResult.ContainingSignatureInvalid); } return new ManifestSignatureInformation(m_manifest, strongName, authenticode); }
internal static unsafe int BuildChain (IntPtr hChainEngine, SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { if (pCertContext == null || pCertContext.IsInvalid) throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_InvalidContextHandle"), "pCertContext"); SafeCertStoreHandle hCertStore = SafeCertStoreHandle.InvalidHandle; if (extraStore != null && extraStore.Count > 0) hCertStore = X509Utils.ExportToMemoryStore(extraStore); CAPI.CERT_CHAIN_PARA ChainPara = new CAPI.CERT_CHAIN_PARA(); // Initialize the structure size. ChainPara.cbSize = (uint) Marshal.SizeOf(ChainPara); // Application policy SafeLocalAllocHandle applicationPolicyHandle = SafeLocalAllocHandle.InvalidHandle; if (applicationPolicy != null && applicationPolicy.Count > 0) { ChainPara.RequestedUsage.dwType = CAPI.USAGE_MATCH_TYPE_AND; ChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint) applicationPolicy.Count; applicationPolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyHandle.DangerousGetHandle(); } // Certificate policy SafeLocalAllocHandle certificatePolicyHandle = SafeLocalAllocHandle.InvalidHandle; if (certificatePolicy != null && certificatePolicy.Count > 0) { ChainPara.RequestedIssuancePolicy.dwType = CAPI.USAGE_MATCH_TYPE_AND; ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint) certificatePolicy.Count; certificatePolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyHandle.DangerousGetHandle(); } ChainPara.dwUrlRetrievalTimeout = (uint) timeout.Milliseconds; _FILETIME ft = new _FILETIME(); *((long*) &ft) = verificationTime.ToFileTime(); uint flags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag); // Build the chain. if (!CAPI.CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref ft, hCertStore, ref ChainPara, flags, IntPtr.Zero, ref ppChainContext)) return Marshal.GetHRForLastWin32Error(); applicationPolicyHandle.Dispose(); certificatePolicyHandle.Dispose(); return CAPI.S_OK; }
private AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { Debug.Assert(signatureNode != null, "signatureNode != null"); // See if there is an Authenticode signature on the manifest XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", m_namespaceManager) as XmlElement; if (licenseNode == null) { return null; } // Make sure that the signature is for this manifest SignatureVerificationResult identityVerification = VerifyAuthenticodeSignatureIdentity(licenseNode); if (identityVerification != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(identityVerification); } SignatureVerificationResult hashVerification = VerifyAuthenticodeExpectedHash(licenseNode); if (hashVerification != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(hashVerification); } // Verify the signature, extracting information about it AuthenticodeSignatureInformation authenticodeSignature = null; X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO(); signer.cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO)); X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO(); timestamper.cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO)); RuntimeHelpers.PrepareConstrainedRegions(); try { byte[] licenseXml = Encoding.UTF8.GetBytes(licenseNode.OuterXml); X509Native.AxlVerificationFlags verificationFlags = MapRevocationFlags(revocationFlag, revocationMode); unsafe { fixed (byte* pLicenseXml = licenseXml) { // Safe since we're verifying the size of this buffer is correct CapiNative.CRYPTOAPI_BLOB xmlBlob = new CapiNative.CRYPTOAPI_BLOB(); xmlBlob.cbData = licenseXml.Length; xmlBlob.pbData = new IntPtr(pLicenseXml); int hrVerify = X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref xmlBlob, verificationFlags, ref signer, ref timestamper); if (hrVerify == (int)SignatureVerificationResult.MissingSignature) { return new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature); } } } X509Chain signatureChain = BuildSignatureChain(signer, licenseNode, revocationFlag, revocationMode); TimestampInformation timestamp = GetTimestampInformation(timestamper, licenseNode); authenticodeSignature = new AuthenticodeSignatureInformation(signer, signatureChain, timestamp); } finally { X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref signer); X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref timestamper); } // Verify the signing certificate matches the expected publisher Debug.Assert(authenticodeSignature != null, "authenticodeSignature != null"); if (authenticodeSignature.SigningCertificate == null) { return new AuthenticodeSignatureInformation(authenticodeSignature.VerificationResult); } SignatureVerificationResult publisherMatch = VerifyAuthenticodePublisher(authenticodeSignature.SigningCertificate); if (publisherMatch != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(publisherMatch); } return authenticodeSignature; }
private static X509Native.AxlVerificationFlags MapRevocationFlags(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { X509Native.AxlVerificationFlags none = X509Native.AxlVerificationFlags.None; switch (revocationFlag) { case X509RevocationFlag.EndCertificateOnly: none |= X509Native.AxlVerificationFlags.RevocationCheckEndCertOnly; break; case X509RevocationFlag.EntireChain: none |= X509Native.AxlVerificationFlags.RevocationCheckEntireChain; break; default: break; } switch (revocationMode) { case X509RevocationMode.NoCheck: return (none | X509Native.AxlVerificationFlags.NoRevocationCheck); case X509RevocationMode.Online: return none; case X509RevocationMode.Offline: return (none | X509Native.AxlVerificationFlags.UrlOnlyCacheRetrieval); } return none; }
/// <summary> /// Map X509 revocation flags to flags for the AXL verification APIs /// </summary> private static X509Native.AxlVerificationFlags MapRevocationFlags(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { X509Native.AxlVerificationFlags axlFlags = X509Native.AxlVerificationFlags.None; switch (revocationFlag) { case X509RevocationFlag.EndCertificateOnly: axlFlags |= X509Native.AxlVerificationFlags.RevocationCheckEndCertOnly; break; case X509RevocationFlag.EntireChain: axlFlags |= X509Native.AxlVerificationFlags.RevocationCheckEntireChain; break; case X509RevocationFlag.ExcludeRoot: default: axlFlags |= X509Native.AxlVerificationFlags.None; break; } switch (revocationMode) { case X509RevocationMode.NoCheck: axlFlags |= X509Native.AxlVerificationFlags.NoRevocationCheck; break; case X509RevocationMode.Offline: axlFlags |= X509Native.AxlVerificationFlags.UrlOnlyCacheRetrieval; break; case X509RevocationMode.Online: default: axlFlags |= X509Native.AxlVerificationFlags.None; break; } return axlFlags; }
public static IChainPal BuildChain( X509Certificate2 leaf, HashSet <X509Certificate2> candidates, HashSet <X509Certificate2> downloaded, HashSet <X509Certificate2> systemTrusted, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, ref TimeSpan remainingDownloadTime) { X509ChainElement[] elements; List <X509ChainStatus> overallStatus = new List <X509ChainStatus>(); WorkingChain workingChain = new WorkingChain(); Interop.Crypto.X509StoreVerifyCallback workingCallback = workingChain.VerifyCallback; // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes. // // (If you need to think of it as an X509Store, it's a volatile memory store) using (SafeX509StoreHandle store = Interop.Crypto.X509StoreCreate()) using (SafeX509StoreCtxHandle storeCtx = Interop.Crypto.X509StoreCtxCreate()) { Interop.Crypto.CheckValidOpenSslHandle(store); Interop.Crypto.CheckValidOpenSslHandle(storeCtx); bool lookupCrl = revocationMode != X509RevocationMode.NoCheck; foreach (X509Certificate2 cert in candidates) { OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal; if (!Interop.Crypto.X509StoreAddCert(store, pal.SafeHandle)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } if (lookupCrl) { CrlCache.AddCrlForCertificate( cert, store, revocationMode, verificationTime, ref remainingDownloadTime); // If we only wanted the end-entity certificate CRL then don't look up // any more of them. lookupCrl = revocationFlag != X509RevocationFlag.EndCertificateOnly; } } if (revocationMode != X509RevocationMode.NoCheck) { if (!Interop.Crypto.X509StoreSetRevocationFlag(store, revocationFlag)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } } SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle; if (!Interop.Crypto.X509StoreCtxInit(storeCtx, store, leafHandle)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } Interop.Crypto.X509StoreCtxSetVerifyCallback(storeCtx, workingCallback); Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime); int verify = Interop.Crypto.X509VerifyCert(storeCtx); if (verify < 0) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } // Because our callback tells OpenSSL that every problem is ignorable, it should tell us that the // chain is just fine (unless it returned a negative code for an exception) Debug.Assert(verify == 1, "verify == 1"); using (SafeX509StackHandle chainStack = Interop.Crypto.X509StoreCtxGetChain(storeCtx)) { int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack); elements = new X509ChainElement[chainSize]; int maybeRootDepth = chainSize - 1; // The leaf cert is 0, up to (maybe) the root at chainSize - 1 for (int i = 0; i < chainSize; i++) { List <X509ChainStatus> status = new List <X509ChainStatus>(); List <Interop.Crypto.X509VerifyStatusCode> elementErrors = i < workingChain.Errors.Count ? workingChain.Errors[i] : null; if (elementErrors != null) { AddElementStatus(elementErrors, status, overallStatus); } IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i); if (elementCertPtr == IntPtr.Zero) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } // Duplicate the certificate handle X509Certificate2 elementCert = new X509Certificate2(elementCertPtr); // If the last cert is self signed then it's the root cert, do any extra checks. if (i == maybeRootDepth && IsSelfSigned(elementCert)) { // If the root certificate was downloaded or the system // doesn't trust it, it's untrusted. if (downloaded.Contains(elementCert) || !systemTrusted.Contains(elementCert)) { AddElementStatus( Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED, status, overallStatus); } } elements[i] = new X509ChainElement(elementCert, status.ToArray(), ""); } } } GC.KeepAlive(workingCallback); if ((certificatePolicy != null && certificatePolicy.Count > 0) || (applicationPolicy != null && applicationPolicy.Count > 0)) { List <X509Certificate2> certsToRead = new List <X509Certificate2>(); foreach (X509ChainElement element in elements) { certsToRead.Add(element.Certificate); } CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead); bool failsPolicyChecks = false; if (certificatePolicy != null) { if (!policyChain.MatchesCertificatePolicies(certificatePolicy)) { failsPolicyChecks = true; } } if (applicationPolicy != null) { if (!policyChain.MatchesApplicationPolicies(applicationPolicy)) { failsPolicyChecks = true; } } if (failsPolicyChecks) { X509ChainElement leafElement = elements[0]; X509ChainStatus chainStatus = new X509ChainStatus { Status = X509ChainStatusFlags.InvalidPolicyConstraints, StatusInformation = SR.Chain_NoPolicyMatch, }; var elementStatus = new List <X509ChainStatus>(leafElement.ChainElementStatus.Length + 1); elementStatus.AddRange(leafElement.ChainElementStatus); AddUniqueStatus(elementStatus, ref chainStatus); AddUniqueStatus(overallStatus, ref chainStatus); elements[0] = new X509ChainElement( leafElement.Certificate, elementStatus.ToArray(), leafElement.Information); } } return(new OpenSslX509ChainProcessor { ChainStatus = overallStatus.ToArray(), ChainElements = elements, }); }
// methods public void Reset () { _apps = new OidCollection (); _cert = new OidCollection (); _store = new X509Certificate2Collection (); _rflag = X509RevocationFlag.ExcludeRoot; _mode = X509RevocationMode.Online; _timeout = new TimeSpan (0); _vflags = X509VerificationFlags.NoFlag; _vtime = DateTime.Now; }
internal void Evaluate( DateTime verificationTime, OidCollection?applicationPolicy, OidCollection?certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag) { Debug.Assert(_chainContext != null); long timeInMsFromUnixEpoch = new DateTimeOffset(verificationTime).ToUnixTimeMilliseconds(); _isValid = Interop.AndroidCrypto.X509ChainBuild(_chainContext, timeInMsFromUnixEpoch); if (!_isValid) { // Android always validates name, time, signature, and trusted root. // There is no way bypass that validation and build a path. ChainElements = Array.Empty <X509ChainElement>(); Interop.AndroidCrypto.ValidationError[] errors = Interop.AndroidCrypto.X509ChainGetErrors(_chainContext); var chainStatus = new X509ChainStatus[errors.Length]; for (int i = 0; i < errors.Length; i++) { Interop.AndroidCrypto.ValidationError error = errors[i]; chainStatus[i] = ValidationErrorToChainStatus(error); Marshal.FreeHGlobal(error.Message); } ChainStatus = chainStatus; return; } byte checkedRevocation; int res = Interop.AndroidCrypto.X509ChainValidate(_chainContext, revocationMode, revocationFlag, out checkedRevocation); if (res != 1) { throw new CryptographicException(); } X509Certificate2[] certs = Interop.AndroidCrypto.X509ChainGetCertificates(_chainContext); List <X509ChainStatus> overallStatus = new List <X509ChainStatus>(); List <X509ChainStatus>[] statuses = new List <X509ChainStatus> [certs.Length]; // Android will stop checking after the first error it hits, so we track the first // instances of revocation and non-revocation errors to fix-up the status of elements // beyond the first error int firstNonRevocationErrorIndex = -1; int firstRevocationErrorIndex = -1; Dictionary <int, List <X509ChainStatus> > errorsByIndex = GetStatusByIndex(_chainContext); foreach (int index in errorsByIndex.Keys) { List <X509ChainStatus> errors = errorsByIndex[index]; for (int i = 0; i < errors.Count; i++) { X509ChainStatus status = errors[i]; AddUniqueStatus(overallStatus, ref status); } // -1 indicates that error is not tied to a specific index if (index != -1) { statuses[index] = errorsByIndex[index]; if (errorsByIndex[index].Exists(s => s.Status == X509ChainStatusFlags.Revoked || s.Status == X509ChainStatusFlags.RevocationStatusUnknown)) { firstRevocationErrorIndex = Math.Max(index, firstRevocationErrorIndex); } else { firstNonRevocationErrorIndex = Math.Max(index, firstNonRevocationErrorIndex); } } } if (firstNonRevocationErrorIndex > 0) { // Assign PartialChain to everything from the first non-revocation error to the end certificate X509ChainStatus partialChainStatus = new X509ChainStatus { Status = X509ChainStatusFlags.PartialChain, StatusInformation = SR.Chain_PartialChain, }; AddStatusFromIndexToEndCertificate(firstNonRevocationErrorIndex - 1, ref partialChainStatus, statuses, overallStatus); } if (firstRevocationErrorIndex > 0) { // Assign RevocationStatusUnknown to everything from the first revocation error to the end certificate X509ChainStatus revocationUnknownStatus = new X509ChainStatus { Status = X509ChainStatusFlags.RevocationStatusUnknown, StatusInformation = SR.Chain_RevocationStatusUnknown, }; AddStatusFromIndexToEndCertificate(firstRevocationErrorIndex - 1, ref revocationUnknownStatus, statuses, overallStatus); } if (revocationMode != X509RevocationMode.NoCheck && checkedRevocation == 0) { // Revocation checking was requested, but not performed (due to basic validation failing) // Assign RevocationStatusUnknown to everything X509ChainStatus revocationUnknownStatus = new X509ChainStatus { Status = X509ChainStatusFlags.RevocationStatusUnknown, StatusInformation = SR.Chain_RevocationStatusUnknown, }; AddStatusFromIndexToEndCertificate(statuses.Length - 1, ref revocationUnknownStatus, statuses, overallStatus); } if (!IsPolicyMatch(certs, applicationPolicy, certificatePolicy)) { // Assign NotValidForUsage to everything X509ChainStatus policyFailStatus = new X509ChainStatus { Status = X509ChainStatusFlags.NotValidForUsage, StatusInformation = SR.Chain_NoPolicyMatch, }; AddStatusFromIndexToEndCertificate(statuses.Length - 1, ref policyFailStatus, statuses, overallStatus); } X509ChainElement[] elements = new X509ChainElement[certs.Length]; for (int i = 0; i < certs.Length; i++) { X509ChainStatus[] elementStatus = statuses[i] == null?Array.Empty <X509ChainStatus>() : statuses[i].ToArray(); elements[i] = new X509ChainElement(certs[i], elementStatus, string.Empty); } ChainElements = elements; ChainStatus = overallStatus.ToArray(); }
internal static unsafe int VerifyCertificate (Cryptography.SafeCertContextHandle pCertContext, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, X509Certificate2Collection extraStore, IntPtr pszPolicy, IntPtr pdwErrorStatus) { if (pCertContext == null || pCertContext.IsInvalid) throw new ArgumentException("pCertContext"); CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA))); CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS))); // Build the chain. SafeX509ChainHandle pChainContext = SafeX509ChainHandle.InvalidHandle; int hr = X509Chain.BuildChain(new IntPtr(CAPI.HCCE_CURRENT_USER), pCertContext, extraStore, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, timeout, ref pChainContext); if (hr != CAPI.S_OK) return hr; // Verify the chain using the specified policy. if (CAPI.CertVerifyCertificateChainPolicy(pszPolicy, pChainContext, ref PolicyPara, ref PolicyStatus)) { if (pdwErrorStatus != IntPtr.Zero) *(uint*) pdwErrorStatus = PolicyStatus.dwError; if (PolicyStatus.dwError != 0) return CAPI.S_FALSE; } else { // The API failed. return Marshal.GetHRForLastWin32Error(); } return CAPI.S_OK; }
internal static unsafe int BuildChain(IntPtr hChainEngine, System.Security.Cryptography.SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { if (pCertContext == null || pCertContext.IsInvalid) { throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_InvalidContextHandle"), "pCertContext"); } SafeCertStoreHandle hAdditionalStore = SafeCertStoreHandle.InvalidHandle; if (extraStore != null && extraStore.Count > 0) { hAdditionalStore = X509Utils.ExportToMemoryStore(extraStore); } CAPI.CERT_CHAIN_PARA pChainPara = new CAPI.CERT_CHAIN_PARA(); pChainPara.cbSize = (uint)Marshal.SizeOf((object)pChainPara); SafeLocalAllocHandle localAllocHandle1 = SafeLocalAllocHandle.InvalidHandle; if (applicationPolicy != null && applicationPolicy.Count > 0) { pChainPara.RequestedUsage.dwType = 0U; pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count; localAllocHandle1 = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = localAllocHandle1.DangerousGetHandle(); } SafeLocalAllocHandle localAllocHandle2 = SafeLocalAllocHandle.InvalidHandle; if (certificatePolicy != null && certificatePolicy.Count > 0) { pChainPara.RequestedIssuancePolicy.dwType = 0U; pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count; localAllocHandle2 = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = localAllocHandle2.DangerousGetHandle(); } pChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *(long *)&pTime = verificationTime.ToFileTime(); uint dwFlags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag); if (!CAPI.CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext)) { return(Marshal.GetHRForLastWin32Error()); } localAllocHandle1.Dispose(); localAllocHandle2.Dispose(); return(0); }
private static extern bool CryptoNative_X509StoreSetRevocationFlag(SafeX509StoreHandle ctx, X509RevocationFlag revocationFlag);
internal static unsafe int VerifyCertificate(System.Security.Cryptography.SafeCertContextHandle pCertContext, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, X509Certificate2Collection extraStore, IntPtr pszPolicy, IntPtr pdwErrorStatus) { if (pCertContext == null || pCertContext.IsInvalid) { throw new ArgumentException("pCertContext"); } CAPI.CERT_CHAIN_POLICY_PARA pPolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA))); CAPI.CERT_CHAIN_POLICY_STATUS pPolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS))); SafeCertChainHandle invalidHandle = SafeCertChainHandle.InvalidHandle; int num = X509Utils.BuildChain(new IntPtr(0L), pCertContext, extraStore, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, timeout, ref invalidHandle); if (num != 0) { return(num); } if (!CAPI.CAPISafe.CertVerifyCertificateChainPolicy(pszPolicy, invalidHandle, ref pPolicyPara, out pPolicyStatus)) { return(Marshal.GetHRForLastWin32Error()); } if (pdwErrorStatus != IntPtr.Zero) { *(int *)(void *)pdwErrorStatus = (int)pPolicyStatus.dwError; } return((int)pPolicyStatus.dwError != 0 ? 1 : 0); }
private static unsafe void BuildChain(IntPtr hChainEngine, IntPtr pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, out System.IdentityModel.SafeCertChainHandle ppChainContext) { System.IdentityModel.SafeCertStoreHandle hAdditionalStore = ExportToMemoryStore(extraStore, pCertContext); System.IdentityModel.CAPI.CERT_CHAIN_PARA pChainPara = new System.IdentityModel.CAPI.CERT_CHAIN_PARA { cbSize = (uint)Marshal.SizeOf(typeof(System.IdentityModel.CAPI.CERT_CHAIN_PARA)) }; SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle; SafeHGlobalHandle handle3 = SafeHGlobalHandle.InvalidHandle; try { if ((applicationPolicy != null) && (applicationPolicy.Count > 0)) { pChainPara.RequestedUsage.dwType = 0; pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count; invalidHandle = CopyOidsToUnmanagedMemory(applicationPolicy); pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = invalidHandle.DangerousGetHandle(); } if ((certificatePolicy != null) && (certificatePolicy.Count > 0)) { pChainPara.RequestedIssuancePolicy.dwType = 0; pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count; handle3 = CopyOidsToUnmanagedMemory(certificatePolicy); pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = handle3.DangerousGetHandle(); } pChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *((long *)&pTime) = verificationTime.ToFileTime(); uint dwFlags = MapRevocationFlags(revocationMode, revocationFlag); if (!System.IdentityModel.CAPI.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext)) { int hr = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(hr)); } } finally { if (invalidHandle != null) { invalidHandle.Dispose(); } if (handle3 != null) { handle3.Dispose(); } hAdditionalStore.Close(); } }
internal static unsafe int BuildChain(IntPtr hChainEngine, System.Security.Cryptography.SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { CAPIBase.CERT_CHAIN_PARA cert_chain_para; if ((pCertContext == null) || pCertContext.IsInvalid) { throw new ArgumentException(SR.GetString("Cryptography_InvalidContextHandle"), "pCertContext"); } System.Security.Cryptography.SafeCertStoreHandle invalidHandle = System.Security.Cryptography.SafeCertStoreHandle.InvalidHandle; if ((extraStore != null) && (extraStore.Count > 0)) { invalidHandle = System.Security.Cryptography.X509Certificates.X509Utils.ExportToMemoryStore(extraStore); } cert_chain_para = new CAPIBase.CERT_CHAIN_PARA { cbSize = (uint)Marshal.SizeOf(cert_chain_para) }; SafeLocalAllocHandle handle2 = SafeLocalAllocHandle.InvalidHandle; if ((applicationPolicy != null) && (applicationPolicy.Count > 0)) { cert_chain_para.RequestedUsage.dwType = 0; cert_chain_para.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count; handle2 = System.Security.Cryptography.X509Certificates.X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); cert_chain_para.RequestedUsage.Usage.rgpszUsageIdentifier = handle2.DangerousGetHandle(); } SafeLocalAllocHandle handle3 = SafeLocalAllocHandle.InvalidHandle; if ((certificatePolicy != null) && (certificatePolicy.Count > 0)) { cert_chain_para.RequestedIssuancePolicy.dwType = 0; cert_chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count; handle3 = System.Security.Cryptography.X509Certificates.X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); cert_chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = handle3.DangerousGetHandle(); } cert_chain_para.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *((long *)&pTime) = verificationTime.ToFileTime(); uint dwFlags = System.Security.Cryptography.X509Certificates.X509Utils.MapRevocationFlags(revocationMode, revocationFlag); if (!CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, invalidHandle, ref cert_chain_para, dwFlags, IntPtr.Zero, ref ppChainContext)) { return(Marshal.GetHRForLastWin32Error()); } handle2.Dispose(); handle3.Dispose(); return(0); }
private AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { Debug.Assert(signatureNode != null, "signatureNode != null"); // See if there is an Authenticode signature on the manifest XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", m_namespaceManager) as XmlElement; if (licenseNode == null) { return(null); } // Make sure that the signature is for this manifest SignatureVerificationResult identityVerification = VerifyAuthenticodeSignatureIdentity(licenseNode); if (identityVerification != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(identityVerification)); } SignatureVerificationResult hashVerification = VerifyAuthenticodeExpectedHash(licenseNode); if (hashVerification != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(hashVerification)); } // Verify the signature, extracting information about it AuthenticodeSignatureInformation authenticodeSignature = null; X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO(); signer.cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO)); X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO(); timestamper.cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO)); RuntimeHelpers.PrepareConstrainedRegions(); try { byte[] licenseXml = Encoding.UTF8.GetBytes(licenseNode.OuterXml); X509Native.AxlVerificationFlags verificationFlags = MapRevocationFlags(revocationFlag, revocationMode); unsafe { fixed(byte *pLicenseXml = licenseXml) { // Safe since we're verifying the size of this buffer is correct CapiNative.CRYPTOAPI_BLOB xmlBlob = new CapiNative.CRYPTOAPI_BLOB(); xmlBlob.cbData = licenseXml.Length; xmlBlob.pbData = new IntPtr(pLicenseXml); int hrVerify = X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref xmlBlob, verificationFlags, ref signer, ref timestamper); if (hrVerify == (int)SignatureVerificationResult.MissingSignature) { return(new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature)); } } } X509Chain signatureChain = BuildSignatureChain(signer, licenseNode, revocationFlag, revocationMode); TimestampInformation timestamp = GetTimestampInformation(timestamper, licenseNode); authenticodeSignature = new AuthenticodeSignatureInformation(signer, signatureChain, timestamp); } finally { X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref signer); X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref timestamper); } // Verify the signing certificate matches the expected publisher Debug.Assert(authenticodeSignature != null, "authenticodeSignature != null"); if (authenticodeSignature.SigningCertificate == null) { return(new AuthenticodeSignatureInformation(authenticodeSignature.VerificationResult)); } SignatureVerificationResult publisherMatch = VerifyAuthenticodePublisher(authenticodeSignature.SigningCertificate); if (publisherMatch != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(publisherMatch)); } return(authenticodeSignature); }
// methods public void Reset () { apps = new OidCollection (); cert = new OidCollection (); store2 = null; rflag = X509RevocationFlag.ExcludeRoot; mode = X509RevocationMode.Online; timeout = TimeSpan.Zero; vflags = X509VerificationFlags.NoFlag; vtime = DateTime.Now; }
private static CertChainFlags MapRevocationFlags(X509RevocationMode revocationMode, X509RevocationFlag revocationFlag) { CertChainFlags dwFlags = CertChainFlags.None; if (revocationMode == X509RevocationMode.NoCheck) { return(dwFlags); } if (revocationMode == X509RevocationMode.Offline) { dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; } if (revocationFlag == X509RevocationFlag.EndCertificateOnly) { dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_END_CERT; } else if (revocationFlag == X509RevocationFlag.EntireChain) { dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CHAIN; } else { dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; } return(dwFlags); }
private unsafe AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", this.m_namespaceManager) as XmlElement; if (licenseNode == null) { return null; } SignatureVerificationResult error = this.VerifyAuthenticodeSignatureIdentity(licenseNode); if (error != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(error); } SignatureVerificationResult result2 = this.VerifyAuthenticodeExpectedHash(licenseNode); if (result2 != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(result2); } AuthenticodeSignatureInformation information = null; X509Native.AXL_AUTHENTICODE_SIGNER_INFO pSignerInfo = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO { cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO)) }; X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO pTimestamperInfo = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO { cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO)) }; RuntimeHelpers.PrepareConstrainedRegions(); try { byte[] bytes = Encoding.UTF8.GetBytes(licenseNode.OuterXml); X509Native.AxlVerificationFlags dwFlags = MapRevocationFlags(revocationFlag, revocationMode); try { fixed (byte* numRef = bytes) { CapiNative.CRYPTOAPI_BLOB pLicenseBlob = new CapiNative.CRYPTOAPI_BLOB { cbData = bytes.Length, pbData = new IntPtr((void*) numRef) }; if (X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref pLicenseBlob, dwFlags, ref pSignerInfo, ref pTimestamperInfo) == -2146762496) { return new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature); } } } finally { numRef = null; } X509Chain signatureChain = this.BuildSignatureChain(pSignerInfo, licenseNode, revocationFlag, revocationMode); TimestampInformation timestampInformation = this.GetTimestampInformation(pTimestamperInfo, licenseNode); information = new AuthenticodeSignatureInformation(pSignerInfo, signatureChain, timestampInformation); } finally { X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref pSignerInfo); X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref pTimestamperInfo); } if (information.SigningCertificate == null) { return new AuthenticodeSignatureInformation(information.VerificationResult); } SignatureVerificationResult result3 = this.VerifyAuthenticodePublisher(information.SigningCertificate); if (result3 != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(result3); } return information; }