Beispiel #1
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;
        }
        static unsafe void BuildChain(IntPtr hChainEngine,
                                     IntPtr pCertContext,
                                     X509Certificate2Collection extraStore,
                                     OidCollection applicationPolicy,
                                     OidCollection certificatePolicy,
                                     X509RevocationMode revocationMode,
                                     X509RevocationFlag revocationFlag,
                                     DateTime verificationTime,
                                     TimeSpan timeout,
                                     out SafeCertChainHandle ppChainContext)
        {
            SafeCertStoreHandle hCertStore = ExportToMemoryStore(extraStore, pCertContext);

            CAPI.CERT_CHAIN_PARA ChainPara = new CAPI.CERT_CHAIN_PARA();
            ChainPara.cbSize = (uint)Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_PARA));

            // Application policy
            SafeHGlobalHandle applicationPolicyHandle = SafeHGlobalHandle.InvalidHandle;
            SafeHGlobalHandle certificatePolicyHandle = SafeHGlobalHandle.InvalidHandle;
            try
            {
                if (applicationPolicy != null && applicationPolicy.Count > 0)
                {
                    ChainPara.RequestedUsage.dwType = CAPI.USAGE_MATCH_TYPE_AND;
                    ChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count;
                    applicationPolicyHandle = 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 = CopyOidsToUnmanagedMemory(certificatePolicy);
                    ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyHandle.DangerousGetHandle();
                }

                ChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds;

                FILETIME ft = new FILETIME();
                *((long*)&ft) = verificationTime.ToFileTime();

                uint flags = MapRevocationFlags(revocationMode, revocationFlag);

                // Build the chain.
                if (!CAPI.CertGetCertificateChain(hChainEngine,
                                                  pCertContext,
                                                  ref ft,
                                                  hCertStore,
                                                  ref ChainPara,
                                                  flags,
                                                  IntPtr.Zero,
                                                  out ppChainContext))
                {
                    int error = Marshal.GetLastWin32Error();
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
                }
            }
            finally
            {
                if (applicationPolicyHandle != null)
                    applicationPolicyHandle.Dispose();
                if (certificatePolicyHandle != null)
                    certificatePolicyHandle.Dispose();
                hCertStore.Close();
            }
        }