private static TAlgorithm DecodeECPublicKey <TAlgorithm>(
            CertificatePal certificatePal,
            Func <CngKey, TAlgorithm> factory,
            CryptImportPublicKeyInfoFlags importFlags = CryptImportPublicKeyInfoFlags.NONE)
            where TAlgorithm : ECAlgorithm, new()
        {
            TAlgorithm key;

            using (SafeCertContextHandle certContext = certificatePal.GetCertContext())
                using (SafeBCryptKeyHandle bCryptKeyHandle = ImportPublicKeyInfo(certContext, importFlags))
                {
                    CngKeyBlobFormat blobFormat;
                    byte[]           keyBlob;
                    string?          curveName = GetCurveName(bCryptKeyHandle);

                    if (curveName == null)
                    {
                        if (HasExplicitParameters(bCryptKeyHandle))
                        {
                            blobFormat = CngKeyBlobFormat.EccFullPublicBlob;
                        }
                        else
                        {
                            blobFormat = CngKeyBlobFormat.EccPublicBlob;
                        }

                        keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat);
                        key     = factory(CngKey.Import(keyBlob, blobFormat));
                    }
                    else
                    {
                        blobFormat = CngKeyBlobFormat.EccPublicBlob;
                        keyBlob    = ExportKeyBlob(bCryptKeyHandle, blobFormat);
                        ECParameters ecparams = default;
                        ExportNamedCurveParameters(ref ecparams, keyBlob, false);
                        ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName);
                        key            = new TAlgorithm();
                        key.ImportParameters(ecparams);
                    }
                }

            return(key);
        }
Пример #2
0
        internal static partial IExportPal FromCertificate(ICertificatePalCore cert)
        {
            CertificatePal certificatePal = (CertificatePal)cert;

            SafeCertStoreHandle certStore = Interop.crypt32.CertOpenStore(
                CertStoreProvider.CERT_STORE_PROV_MEMORY,
                Interop.Crypt32.CertEncodingType.All,
                IntPtr.Zero,
                Interop.Crypt32.CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | Interop.Crypt32.CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG | Interop.Crypt32.CertStoreFlags.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
                null);

            using (SafeCertContextHandle certContext = certificatePal.GetCertContext())
            {
                if (certStore.IsInvalid ||
                    !Interop.Crypt32.CertAddCertificateLinkToStore(certStore, certContext, Interop.Crypt32.CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero))
                {
                    Exception e = Marshal.GetHRForLastWin32Error().ToCryptographicException();
                    certStore.Dispose();
                    throw e;
                }
            }

            return(new StorePal(certStore));
        }
        /// <summary>
        /// Does not throw on error. Returns null ChainPal instead.
        /// </summary>
        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)
        {
            CertificatePal certificatePal = (CertificatePal)cert;

            unsafe
            {
                using (SafeChainEngineHandle storeHandle = GetChainEngine(trustMode, customTrustStore, useMachineContext))
                    using (SafeCertStoreHandle extraStoreHandle = ConvertStoreToSafeHandle(extraStore))
                    {
                        Interop.Crypt32.CERT_CHAIN_PARA chainPara = default;
                        chainPara.cbSize = Marshal.SizeOf <Interop.Crypt32.CERT_CHAIN_PARA>();

                        int applicationPolicyCount;
                        using (SafeHandle applicationPolicyOids = applicationPolicy !.ToLpstrArray(out applicationPolicyCount))
                        {
                            if (!applicationPolicyOids.IsInvalid)
                            {
                                chainPara.RequestedUsage.dwType = Interop.Crypt32.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 = Interop.Crypt32.CertUsageMatchType.USAGE_MATCH_TYPE_AND;
                                    chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier     = certificatePolicyCount;
                                    chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle();
                                }

                                chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds);

                                Interop.Crypt32.FILETIME       ft    = Interop.Crypt32.FILETIME.FromDateTime(verificationTime);
                                Interop.Crypt32.CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag, disableAia);
                                SafeX509ChainHandle            chain;
                                using (SafeCertContextHandle certContext = certificatePal.GetCertContext())
                                {
                                    if (!Interop.Crypt32.CertGetCertificateChain(storeHandle.DangerousGetHandle(), certContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain))
                                    {
                                        chain.Dispose();
                                        return(null);
                                    }
                                }

                                return(new ChainPal(chain));
                            }
                        }
                    }
            }
        }