Beispiel #1
0
 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);
 }
Beispiel #3
0
        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();
 }
Beispiel #6
0
 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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
 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);
 }
Beispiel #10
0
 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));
 }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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();
     }
 }
Beispiel #14
0
        // 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;
        }
Beispiel #15
0
        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;
        }
Beispiel #16
0
        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);
        }
Beispiel #18
0
        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);
        }
Beispiel #19
0
        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;
        }
Beispiel #21
0
        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);
        }
Beispiel #23
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));
        }
 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;
 }
Beispiel #25
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> 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);
        }
Beispiel #27
0
        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));
        }
Beispiel #28
0
        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);
                }
            }
        }
Beispiel #29
0
        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);
            }
        }
Beispiel #35
0
 /// <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);
Beispiel #36
0
        /// <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,
            };
        }
Beispiel #38
0
 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;
 }
Beispiel #39
0
 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,
            };
        }
Beispiel #41
0
 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);
        }
Beispiel #43
0
        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;
        }
Beispiel #47
0
        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;
		}
Beispiel #49
0
 internal static extern bool X509StoreSetRevocationFlag(SafeX509StoreHandle ctx, X509RevocationFlag revocationFlag);
Beispiel #50
0
            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;
        }
Beispiel #52
0
        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);
        }
Beispiel #53
0
 private static extern bool CryptoNative_X509StoreSetRevocationFlag(SafeX509StoreHandle ctx, X509RevocationFlag revocationFlag);
Beispiel #54
0
        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);
        }
Beispiel #55
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);
        }
Beispiel #58
0
		// 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;
		}
Beispiel #59
0
        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;
 }