Ejemplo n.º 1
0
 internal static void X509StoreSetRevocationFlag(SafeX509StoreHandle ctx, X509RevocationFlag revocationFlag)
 {
     if (!CryptoNative_X509StoreSetRevocationFlag(ctx, revocationFlag))
     {
         throw CreateOpenSslCryptographicException();
     }
 }
Ejemplo n.º 2
0
        public static void AddCrlForCertificate(
            X509Certificate2 cert,
            SafeX509StoreHandle store,
            X509RevocationMode revocationMode,
            DateTime verificationTime,
            ref TimeSpan remainingDownloadTime)
        {
            // In Offline mode, accept any cached CRL we have.
            // "CRL is Expired" is a better match for Offline than "Could not find CRL"
            if (revocationMode != X509RevocationMode.Online)
            {
                verificationTime = DateTime.MinValue;
            }

            if (AddCachedCrl(cert, store, verificationTime))
            {
                return;
            }

            // Don't do any work if we're over limit or prohibited from fetching new CRLs
            if (remainingDownloadTime <= TimeSpan.Zero ||
                revocationMode != X509RevocationMode.Online)
            {
                return;
            }

            DownloadAndAddCrl(cert, store, ref remainingDownloadTime);
        }
Ejemplo n.º 3
0
        private static bool AddCachedCrl(X509Certificate2 cert, SafeX509StoreHandle store, DateTime verificationTime)
        {
            string crlFile = GetCachedCrlPath(cert);

            using (SafeBioHandle bio = Interop.Crypto.BioNewFile(crlFile, "rb"))
            {
                if (bio.IsInvalid)
                {
                    Interop.Crypto.ErrClearError();
                    return(false);
                }

                // X509_STORE_add_crl will increase the refcount on the CRL object, so we should still
                // dispose our copy.
                using (SafeX509CrlHandle crl = Interop.Crypto.PemReadBioX509Crl(bio))
                {
                    if (crl.IsInvalid)
                    {
                        Interop.Crypto.ErrClearError();
                        return(false);
                    }

                    // If crl.LastUpdate is in the past, downloading a new version isn't really going
                    // to help, since we can't rewind the Internet. So this is just going to fail, but
                    // at least it can fail without using the network.
                    //
                    // If crl.NextUpdate is in the past, try downloading a newer version.
                    DateTime nextUpdate = OpenSslX509CertificateReader.ExtractValidityDateTime(
                        Interop.Crypto.GetX509CrlNextUpdate(crl));

                    // OpenSSL is going to convert our input time to universal, so we should be in Local or
                    // Unspecified (local-assumed).
                    Debug.Assert(
                        verificationTime.Kind != DateTimeKind.Utc,
                        "UTC verificationTime should have been normalized to Local");

                    // In the event that we're to-the-second accurate on the match, OpenSSL will consider this
                    // to be already expired.
                    if (nextUpdate <= verificationTime)
                    {
                        return(false);
                    }

                    if (!Interop.Crypto.X509StoreAddCrl(store, crl))
                    {
                        // Ignore error "cert already in store", throw on anything else. In any case the error queue will be cleared.
                        if (X509_R_CERT_ALREADY_IN_HASH_TABLE == Interop.Crypto.ErrPeekLastError())
                        {
                            Interop.Crypto.ErrClearError();
                        }
                        else
                        {
                            throw Interop.Crypto.CreateOpenSslCryptographicException();
                        }
                    }

                    return(true);
                }
            }
        }
Ejemplo n.º 4
0
 private static extern int CryptoNative_X509StoreSetVerifyTime(
     SafeX509StoreHandle ctx,
     int year,
     int month,
     int day,
     int hour,
     int minute,
     int second,
     [MarshalAs(UnmanagedType.Bool)] bool isDst);
Ejemplo n.º 5
0
        internal static SafeX509StoreHandle X509ChainNew(SafeX509StackHandle systemTrust, SafeX509StackHandle userTrust)
        {
            SafeX509StoreHandle store = CryptoNative_X509ChainNew(systemTrust, userTrust);

            if (store.IsInvalid)
            {
                throw CreateOpenSslCryptographicException();
            }

            return(store);
        }
Ejemplo n.º 6
0
        private static void DownloadAndAddCrl(
            X509Certificate2 cert,
            SafeX509StoreHandle store,
            ref TimeSpan remainingDownloadTime)
        {
            string url = GetCdpUrl(cert);

            if (url == null)
            {
                return;
            }

            // X509_STORE_add_crl will increase the refcount on the CRL object, so we should still
            // dispose our copy.
            using (SafeX509CrlHandle crl = CertificateAssetDownloader.DownloadCrl(url, ref remainingDownloadTime))
            {
                // null is a valid return (e.g. no remainingDownloadTime)
                if (crl != null && !crl.IsInvalid)
                {
                    if (!Interop.Crypto.X509StoreAddCrl(store, crl))
                    {
                        // Ignore error "cert already in store", throw on anything else. In any case the error queue will be cleared.
                        if (X509_R_CERT_ALREADY_IN_HASH_TABLE == Interop.Crypto.ErrPeekLastError())
                        {
                            Interop.Crypto.ErrClearError();
                        }
                        else
                        {
                            throw Interop.Crypto.CreateOpenSslCryptographicException();
                        }
                    }

                    // Saving the CRL to the disk is just a performance optimization for later requests to not
                    // need to use the network again, so failure to save shouldn't throw an exception or mark
                    // the chain as invalid.
                    try
                    {
                        string crlFile = GetCachedCrlPath(cert, mkDir: true);

                        using (SafeBioHandle bio = Interop.Crypto.BioNewFile(crlFile, "wb"))
                        {
                            if (bio.IsInvalid || Interop.Crypto.PemWriteBioX509Crl(bio, crl) == 0)
                            {
                                // No bio, or write failed
                                Interop.Crypto.ErrClearError();
                            }
                        }
                    }
                    catch (UnauthorizedAccessException) { }
                    catch (IOException) { }
                }
            }
        }
            public static AndroidKeyStore OpenDefault(OpenFlags openFlags)
            {
                SafeX509StoreHandle store = Interop.AndroidCrypto.X509StoreOpenDefault();

                if (store.IsInvalid)
                {
                    store.Dispose();
                    throw new CryptographicException();
                }

                return(new AndroidKeyStore(store, openFlags));
            }
Ejemplo n.º 8
0
        internal static OpenSslX509ChainProcessor InitiateChain(
            SafeX509Handle leafHandle,
            X509Certificate2Collection customTrustStore,
            X509ChainTrustMode trustMode,
            DateTime verificationTime,
            TimeSpan remainingDownloadTime)
        {
            CachedSystemStoreProvider.GetNativeCollections(
                out SafeX509StackHandle systemTrust,
                out SafeX509StackHandle systemIntermediate);

            SafeX509StoreHandle    store     = null;
            SafeX509StackHandle    untrusted = null;
            SafeX509StoreCtxHandle storeCtx  = null;

            try
            {
                untrusted = Interop.Crypto.NewX509Stack();
                Interop.Crypto.X509StackAddMultiple(untrusted, s_userIntermediateStore.GetNativeCollection());
                Interop.Crypto.X509StackAddMultiple(untrusted, s_userPersonalStore.GetNativeCollection());

                store = GetTrustStore(trustMode, customTrustStore, untrusted, systemTrust);

                Interop.Crypto.X509StackAddMultiple(untrusted, systemIntermediate);
                Interop.Crypto.X509StoreSetVerifyTime(store, verificationTime);

                storeCtx = Interop.Crypto.X509StoreCtxCreate();

                if (!Interop.Crypto.X509StoreCtxInit(storeCtx, store, leafHandle, untrusted))
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                return(new OpenSslX509ChainProcessor(
                           leafHandle,
                           store,
                           untrusted,
                           storeCtx,
                           verificationTime,
                           remainingDownloadTime));
            }
            catch
            {
                store?.Dispose();
                untrusted?.Dispose();
                storeCtx?.Dispose();
                throw;
            }
        }
Ejemplo n.º 9
0
        private static bool AddCachedCrl(X509Certificate2 cert, SafeX509StoreHandle store, DateTime verificationTime)
        {
            string crlFile = GetCachedCrlPath(cert);

            using (SafeBioHandle bio = Interop.libcrypto.BIO_new_file(crlFile, "rb"))
            {
                if (bio.IsInvalid)
                {
                    return(false);
                }

                // X509_STORE_add_crl will increase the refcount on the CRL object, so we should still
                // dispose our copy.
                using (SafeX509CrlHandle crl = Interop.libcrypto.PEM_read_bio_X509_CRL(bio))
                {
                    if (crl.IsInvalid)
                    {
                        return(false);
                    }

                    // If crl.LastUpdate is in the past, downloading a new version isn't really going
                    // to help, since we can't rewind the Internet. So this is just going to fail, but
                    // at least it can fail without using the network.
                    //
                    // If crl.NextUpdate is in the past, try downloading a newer version.
                    DateTime nextUpdate = OpenSslX509CertificateReader.ExtractValidityDateTime(
                        Interop.Crypto.GetX509CrlNextUpdate(crl));

                    // OpenSSL is going to convert our input time to universal, so we should be in Local or
                    // Unspecified (local-assumed).
                    Debug.Assert(
                        verificationTime.Kind != DateTimeKind.Utc,
                        "UTC verificationTime should have been normalized to Local");

                    // In the event that we're to-the-second accurate on the match, OpenSSL will consider this
                    // to be already expired.
                    if (nextUpdate <= verificationTime)
                    {
                        return(false);
                    }

                    // TODO (#3063): Check the return value of X509_STORE_add_crl, and throw on any error other
                    // than X509_R_CERT_ALREADY_IN_HASH_TABLE
                    Interop.libcrypto.X509_STORE_add_crl(store, crl);

                    return(true);
                }
            }
        }
Ejemplo n.º 10
0
 private OpenSslX509ChainProcessor(
     SafeX509Handle leafHandle,
     SafeX509StoreHandle store,
     SafeX509StackHandle untrusted,
     SafeX509StoreCtxHandle storeCtx,
     DateTime verificationTime,
     TimeSpan remainingDownloadTime)
 {
     _leafHandle            = leafHandle;
     _store                 = store;
     _untrustedLookup       = untrusted;
     _storeCtx              = storeCtx;
     _verificationTime      = verificationTime;
     _remainingDownloadTime = remainingDownloadTime;
 }
Ejemplo n.º 11
0
        internal static void X509StoreCtxResetForSignatureError(
            SafeX509StoreCtxHandle ctx,
            out SafeX509StoreHandle newStore)
        {
            if (CryptoNative_X509StoreCtxResetForSignatureError(ctx, out newStore) != 1)
            {
                newStore.Dispose();
                newStore = null;
                throw CreateOpenSslCryptographicException();
            }

            if (newStore.IsInvalid)
            {
                newStore.Dispose();
                newStore = null;
            }
        }
Ejemplo n.º 12
0
        internal static OpenSslX509ChainProcessor InitiateChain(
            SafeX509Handle leafHandle,
            DateTime verificationTime,
            TimeSpan remainingDownloadTime)
        {
            SafeX509StackHandle systemTrust        = StorePal.GetMachineRoot().GetNativeCollection();
            SafeX509StackHandle systemIntermediate = StorePal.GetMachineIntermediate().GetNativeCollection();

            SafeX509StoreHandle    store     = null;
            SafeX509StackHandle    untrusted = null;
            SafeX509StoreCtxHandle storeCtx  = null;

            try
            {
                store = Interop.Crypto.X509ChainNew(systemTrust, s_userRootPath);

                untrusted = Interop.Crypto.NewX509Stack();
                Interop.Crypto.X509StackAddDirectoryStore(untrusted, s_userIntermediatePath);
                Interop.Crypto.X509StackAddDirectoryStore(untrusted, s_userPersonalPath);
                Interop.Crypto.X509StackAddMultiple(untrusted, systemIntermediate);
                Interop.Crypto.X509StoreSetVerifyTime(store, verificationTime);

                storeCtx = Interop.Crypto.X509StoreCtxCreate();

                if (!Interop.Crypto.X509StoreCtxInit(storeCtx, store, leafHandle, untrusted))
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                return(new OpenSslX509ChainProcessor(
                           leafHandle,
                           store,
                           untrusted,
                           storeCtx,
                           verificationTime,
                           remainingDownloadTime));
            }
            catch
            {
                store?.Dispose();
                untrusted?.Dispose();
                storeCtx?.Dispose();
                throw;
            }
        }
Ejemplo n.º 13
0
        private static void DownloadAndAddCrl(
            X509Certificate2 cert,
            SafeX509StoreHandle store,
            ref TimeSpan remainingDownloadTime)
        {
            string url = GetCdpUrl(cert);

            if (url == null)
            {
                return;
            }

            // X509_STORE_add_crl will increase the refcount on the CRL object, so we should still
            // dispose our copy.
            using (SafeX509CrlHandle crl = CertificateAssetDownloader.DownloadCrl(url, ref remainingDownloadTime))
            {
                // null is a valid return (e.g. no remainingDownloadTime)
                if (crl != null && !crl.IsInvalid)
                {
                    // TODO (#3063): Check the return value of X509_STORE_add_crl, and throw on any error other
                    // than X509_R_CERT_ALREADY_IN_HASH_TABLE
                    Interop.libcrypto.X509_STORE_add_crl(store, crl);

                    // Saving the CRL to the disk is just a performance optimization for later requests to not
                    // need to use the network again, so failure to save shouldn't throw an exception or mark
                    // the chain as invalid.
                    try
                    {
                        string crlFile = GetCachedCrlPath(cert, mkDir: true);

                        using (SafeBioHandle bio = Interop.libcrypto.BIO_new_file(crlFile, "wb"))
                        {
                            if (!bio.IsInvalid)
                            {
                                Interop.libcrypto.PEM_write_bio_X509_CRL(bio, crl);
                            }
                        }
                    }
                    catch (IOException)
                    {
                    }
                }
            }
        }
Ejemplo n.º 14
0
        internal static void X509StoreSetVerifyTime(SafeX509StoreHandle ctx, DateTime verifyTime)
        {
            // OpenSSL is going to convert our input time to universal, so we should be in Local or
            // Unspecified (local-assumed).
            Debug.Assert(verifyTime.Kind != DateTimeKind.Utc, "UTC verifyTime should have been normalized to Local");

            int succeeded = CryptoNative_X509StoreSetVerifyTime(
                ctx,
                verifyTime.Year,
                verifyTime.Month,
                verifyTime.Day,
                verifyTime.Hour,
                verifyTime.Minute,
                verifyTime.Second,
                verifyTime.IsDaylightSavingTime());

            if (succeeded != 1)
            {
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }
        }
Ejemplo n.º 15
0
        public static void AddCrlForCertificate(
            SafeX509Handle cert,
            SafeX509StoreHandle store,
            X509RevocationMode revocationMode,
            DateTime verificationTime,
            TimeSpan downloadTimeout)
        {
            // In Offline mode, accept any cached CRL we have.
            // "CRL is Expired" is a better match for Offline than "Could not find CRL"
            if (revocationMode != X509RevocationMode.Online)
            {
                verificationTime = DateTime.MinValue;
            }

            string?url = GetCdpUrl(cert);

            if (url == null)
            {
                return;
            }

            string crlFileName = GetCrlFileName(cert, url);

            if (AddCachedCrl(crlFileName, store, verificationTime))
            {
                return;
            }

            // Don't do any work if we're prohibited from fetching new CRLs
            if (revocationMode != X509RevocationMode.Online)
            {
                return;
            }

            DownloadAndAddCrl(url, crlFileName, store, downloadTimeout);
        }
Ejemplo n.º 16
0
 internal static extern bool X509_STORE_add_cert(SafeX509StoreHandle ctx, SafeX509Handle x);
Ejemplo n.º 17
0
 internal static extern bool X509_STORE_set_flags(SafeX509StoreHandle ctx, X509VerifyFlags flags);
Ejemplo n.º 18
0
 internal static extern bool X509_STORE_add_crl(SafeX509StoreHandle ctx, SafeX509CrlHandle x);
Ejemplo n.º 19
0
 internal static extern bool X509StoreSetRevocationFlag(SafeX509StoreHandle ctx, X509RevocationFlag revocationFlag);
Ejemplo n.º 20
0
 internal static extern bool X509StoreAddCert(SafeX509StoreHandle ctx, SafeX509Handle x);
Ejemplo n.º 21
0
 internal static unsafe partial bool X509StoreEnumerateCertificates(
     SafeX509StoreHandle storeHandle,
Ejemplo n.º 22
0
 internal static extern unsafe bool X509StoreEnumerateCertificates(
     SafeX509StoreHandle storeHandle,
Ejemplo n.º 23
0
 internal static extern bool X509StoreAddCrl(SafeX509StoreHandle ctx, SafeX509CrlHandle x);
Ejemplo n.º 24
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,
            });
        }
Ejemplo n.º 25
0
 private static extern bool CryptoNative_X509StoreSetRevocationFlag(SafeX509StoreHandle ctx, X509RevocationFlag revocationFlag);
Ejemplo n.º 26
0
 internal static extern bool X509StoreCtxInit(SafeX509StoreCtxHandle ctx, SafeX509StoreHandle store, SafeX509Handle x509);
Ejemplo n.º 27
0
 internal static extern bool X509StoreCtxInit(
     SafeX509StoreCtxHandle ctx,
     SafeX509StoreHandle store,
     SafeX509Handle x509,
     SafeX509StackHandle extraCerts);
Ejemplo n.º 28
0
 internal static unsafe partial bool X509StoreAddCertificateWithPrivateKey(
     SafeX509StoreHandle store,
     SafeX509Handle cert,
     SafeKeyHandle key,
     PAL_KeyAlgorithm algorithm,
     string hashString);
Ejemplo n.º 29
0
 internal static extern bool X509_STORE_CTX_init(SafeX509StoreCtxHandle ctx, SafeX509StoreHandle store, SafeX509Handle x509, IntPtr zero);
Ejemplo n.º 30
0
 internal static unsafe partial bool X509StoreContainsCertificate(
     SafeX509StoreHandle store,
     SafeX509Handle cert,
     string hashString);