Ejemplo n.º 1
0
        public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal)
        {
            if (oid.Value == Oids.Ecc)
            {
                return DecodeECDsaPublicKey((CertificatePal)certificatePal);
            }

            int algId = OidInfo.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid.Value, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId;
            switch (algId)
            {
                case AlgId.CALG_RSA_KEYX:
                case AlgId.CALG_RSA_SIGN:
                    {
                        byte[] keyBlob = DecodeKeyBlob(CryptDecodeObjectStructType.CNG_RSA_PUBLIC_KEY_BLOB, encodedKeyValue);
                        CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
                        return new RSACng(cngKey);
                    }

#if !NETNATIVE
                case AlgId.CALG_DSS_SIGN:
                    {
                        byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters);
                        DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
                        dsa.ImportCspBlob(keyBlob);
                        return dsa;
                    }
#endif

                default:
                    throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
            }
        }
Ejemplo n.º 2
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;
        }
Ejemplo n.º 3
0
        /// <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);
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal)
        {
            switch (oid.Value)
            {
                case Oids.RsaRsa:
                    return BuildRsaPublicKey(encodedKeyValue);
            }

            // NotSupportedException is what desktop and CoreFx-Windows throw in this situation.
            throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
        }
Ejemplo n.º 5
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();
 }
Ejemplo n.º 6
0
        internal static bool TryReadX509Der(byte[] rawData, out ICertificatePal certPal)
        {
            SafeX509Handle certHandle = Interop.Crypto.DecodeX509(rawData, rawData.Length);

            if (certHandle.IsInvalid)
            {
                certHandle.Dispose();
                certPal = null;
                return false;
            }

            certPal = new OpenSslX509CertificateReader(certHandle);
            return true;
        }
Ejemplo n.º 7
0
        public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal)
        {
            if (oid.Value == Oids.Ecc && certificatePal != null)
            {
                return ((OpenSslX509CertificateReader)certificatePal).GetECDsaPublicKey();
            }

            switch (oid.Value)
            {
                case Oids.RsaRsa:
                    return BuildRsaPublicKey(encodedKeyValue);
            }

            // NotSupportedException is what desktop and CoreFx-Windows throw in this situation.
            throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
        }
Ejemplo n.º 8
0
        public static IExportPal FromCertificate(ICertificatePal cert)
        {
            CertificatePal certificatePal = (CertificatePal)cert;

            SafeCertStoreHandle certStore = Interop.crypt32.CertOpenStore(
                CertStoreProvider.CERT_STORE_PROV_MEMORY,
                CertEncodingType.All,
                IntPtr.Zero,
                CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG | CertStoreFlags.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
                null);
            if (certStore.IsInvalid)
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;
            if (!Interop.crypt32.CertAddCertificateLinkToStore(certStore, certificatePal.CertContext, CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero))
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;
            return new StorePal(certStore);
        }
Ejemplo n.º 9
0
        public void Remove(ICertificatePal certificate)
        {
            unsafe
            {
                SafeCertContextHandle existingCertContext = ((CertificatePal)certificate).CertContext;
                SafeCertContextHandle enumCertContext = null;
                CERT_CONTEXT* pCertContext = existingCertContext.CertContext;
                if (!Interop.crypt32.CertFindCertificateInStore(_certStore, CertFindType.CERT_FIND_EXISTING, pCertContext, ref enumCertContext))
                    return; // The certificate is not present in the store, simply return.

                CERT_CONTEXT* pCertContextToDelete = enumCertContext.Disconnect();  // CertDeleteCertificateFromContext always frees the context (even on error)
                if (!Interop.crypt32.CertDeleteCertificateFromStore(pCertContextToDelete))
                    throw Marshal.GetLastWin32Error().ToCryptographicException();

                GC.KeepAlive(existingCertContext);
            }
        }
Ejemplo n.º 10
0
        private static bool TryReadPkcs7Der(
            byte[] rawData,
            bool single,
            out ICertificatePal certPal,
            out List<ICertificatePal> certPals)
        {
            using (SafePkcs7Handle pkcs7 = Interop.Crypto.DecodePkcs7(rawData, rawData.Length))
            {
                if (pkcs7.IsInvalid)
                {
                    certPal = null;
                    certPals = null;
                    return false;
                }

                return TryReadPkcs7(pkcs7, single, out certPal, out certPals);
            }
        }
Ejemplo n.º 11
0
        private static bool TryReadPkcs7Der(
            SafeBioHandle bio,
            bool single,
            out ICertificatePal certPal,
            out List<ICertificatePal> certPals)
        {
            using (SafePkcs7Handle pkcs7 = Interop.Crypto.D2IPkcs7Bio(bio))
            {
                if (pkcs7.IsInvalid)
                {
                    certPal = null;
                    certPals = null;
                    return false;
                }

                return TryReadPkcs7(pkcs7, single, out certPal, out certPals);
            }
        }
Ejemplo n.º 12
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;
        }
Ejemplo n.º 13
0
        private static bool TryReadPkcs7Der(
            SafeBioHandle bio,
            bool single,
            out ICertificatePal certPal,
            out List<ICertificatePal> certPals)
        {
            SafePkcs7Handle pkcs7 = Interop.libcrypto.d2i_PKCS7_bio(bio, IntPtr.Zero);

            if (pkcs7.IsInvalid)
            {
                certPal = null;
                certPals = null;
                return false;
            }

            using (pkcs7)
            {
                return TryReadPkcs7(pkcs7, single, out certPal, out certPals);
            }
        }
Ejemplo n.º 14
0
        private static unsafe bool TryReadPkcs7Der(
            byte[] rawData,
            bool single,
            out ICertificatePal certPal,
            out List<ICertificatePal> certPals)
        {
            SafePkcs7Handle pkcs7 = Interop.libcrypto.OpenSslD2I(
                (ptr, b, i) => Interop.libcrypto.d2i_PKCS7(ptr, b, i),
                rawData,
                checkHandle: false);

            if (pkcs7.IsInvalid)
            {
                certPal = null;
                certPals = null;
                return false;
            }

            using (pkcs7)
            {
                return TryReadPkcs7(pkcs7, single, out certPal, out certPals);
            }
        }
Ejemplo n.º 15
0
        public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal)
        {
            switch (oid.Value)
            {
            case Oids.RsaRsa:
                return(BuildRsaPublicKey(encodedKeyValue));

            case Oids.Ecc:
                return(((OpenSslX509CertificateReader)certificatePal).GetECDsaPublicKey());
            }

            // NotSupportedException is what desktop and CoreFx-Windows throw in this situation.
            throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
        }
Ejemplo n.º 16
0
 private static IStorePal SingleCertToStorePal(ICertificatePal singleCert)
 {
     return new CollectionBackedStoreProvider(new X509Certificate2(singleCert));
 }
Ejemplo n.º 17
0
        internal static bool TryReadPkcs7Pem(SafeBioHandle bio, out ICertificatePal certPal)
        {
            List<ICertificatePal> ignored;

            return TryReadPkcs7Pem(bio, true, out certPal, out ignored);
        }
Ejemplo n.º 18
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)
        {
            // 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();
            }

            // Until we support the Disallowed store, ensure it's empty (which is done by the ctor)
            using (new X509Store(StoreName.Disallowed, StoreLocation.CurrentUser, OpenFlags.ReadOnly))
            {
            }

            TimeSpan remainingDownloadTime = timeout;

            OpenSslX509ChainProcessor chainPal = OpenSslX509ChainProcessor.InitiateChain(
                ((OpenSslX509CertificateReader)cert).SafeHandle,
                customTrustStore,
                trustMode,
                verificationTime,
                remainingDownloadTime);

            Interop.Crypto.X509VerifyStatusCode status = chainPal.FindFirstChain(extraStore);

            if (!OpenSslX509ChainProcessor.IsCompleteChain(status))
            {
                List <X509Certificate2> tmp = null;
                status = chainPal.FindChainViaAia(ref tmp);

                if (tmp != null)
                {
                    if (status == Interop.Crypto.X509VerifyStatusCode.X509_V_OK)
                    {
                        SaveIntermediateCertificates(tmp);
                    }

                    foreach (X509Certificate2 downloaded in tmp)
                    {
                        downloaded.Dispose();
                    }
                }
            }

            // In NoCheck+OK then we don't need to build the chain any more, we already
            // know it's error-free.  So skip straight to finish.
            if (status != Interop.Crypto.X509VerifyStatusCode.X509_V_OK ||
                revocationMode != X509RevocationMode.NoCheck)
            {
                if (OpenSslX509ChainProcessor.IsCompleteChain(status))
                {
                    chainPal.CommitToChain();
                    chainPal.ProcessRevocation(revocationMode, revocationFlag);
                }
            }

            chainPal.Finish(applicationPolicy, certificatePolicy);

#if DEBUG
            if (chainPal.ChainElements.Length > 0)
            {
                X509Certificate2 reportedLeaf = chainPal.ChainElements[0].Certificate;
                Debug.Assert(reportedLeaf != null, "reportedLeaf != null");
                Debug.Assert(!ReferenceEquals(cert, reportedLeaf.Pal), "!ReferenceEquals(cert, reportedLeaf.Pal)");
            }
#endif
            return(chainPal);
        }
Ejemplo n.º 19
0
        private static bool TryReadPkcs12(
            OpenSslPkcs12Reader pfx,
            string password,
            bool single,
            out ICertificatePal readPal,
            out List<ICertificatePal> readCerts)
        {
            pfx.Decrypt(password);

            ICertificatePal first = null;
            List<ICertificatePal> certs = null;

            if (!single)
            {
                certs = new List<ICertificatePal>();
            }

            foreach (OpenSslX509CertificateReader certPal in pfx.ReadCertificates())
            {
                if (single)
                {
                    // When requesting an X509Certificate2 from a PFX only the first entry is
                    // returned.  Other entries should be disposed.

                    if (first == null)
                    {
                        first = certPal;
                    }
                    else if (certPal.HasPrivateKey && !first.HasPrivateKey)
                    {
                        first.Dispose();
                        first = certPal;
                    }
                    else
                    {
                        certPal.Dispose();
                    }
                }
                else
                {
                    certs.Add(certPal);
                }
            }

            readPal = first;
            readCerts = certs;
            return true;
        }
Ejemplo n.º 20
0
        internal static bool TryReadPkcs12(SafeBioHandle bio, string password, out ICertificatePal certPal)
        {
            List<ICertificatePal> ignored;

            return TryReadPkcs12(bio, password, true, out certPal, out ignored);
        }
Ejemplo n.º 21
0
        private static bool TryReadPkcs7(
            SafePkcs7Handle pkcs7,
            bool single,
            out ICertificatePal certPal,
            out List<ICertificatePal> certPals)
        {
            List<ICertificatePal> readPals = single ? null : new List<ICertificatePal>();

            using (SafeSharedX509StackHandle certs = Interop.Crypto.GetPkcs7Certificates(pkcs7))
            {
                int count = Interop.Crypto.GetX509StackFieldCount(certs);

                if (single)
                {
                    // In single mode for a PKCS#7 signed or signed-and-enveloped file we're supposed to return
                    // the certificate which signed the PKCS#7 file.
                    // 
                    // X509Certificate2Collection::Export(X509ContentType.Pkcs7) claims to be a signed PKCS#7,
                    // but doesn't emit a signature block. So this is hard to test.
                    //
                    // TODO(2910): Figure out how to extract the signing certificate, when it's present.
                    throw new CryptographicException(SR.Cryptography_X509_PKCS7_NoSigner);
                }

                for (int i = 0; i < count; i++)
                {
                    // Use FromHandle to duplicate the handle since it would otherwise be freed when the PKCS7
                    // is Disposed.
                    IntPtr certHandle = Interop.Crypto.GetX509StackField(certs, i);
                    ICertificatePal pal = CertificatePal.FromHandle(certHandle);
                    readPals.Add(pal);
                }
            }

            certPal = null;
            certPals = readPals;
            return true;
        }
Ejemplo n.º 22
0
 public static IExportPal FromCertificate(ICertificatePal cert)
 {
     return(new ExportProvider(cert));
 }
Ejemplo n.º 23
0
 private static ILoaderPal SingleCertToLoaderPal(ICertificatePal singleCert)
 {
     return(new SingleCertLoader(singleCert));
 }
Ejemplo n.º 24
0
 public static IExportPal FromCertificate(ICertificatePal cert)
 {
     return(new AppleCertificateExporter(cert));
 }
Ejemplo n.º 25
0
 public static IStorePal FromCertificate(ICertificatePal cert)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 26
0
 internal X509Certificate2(ICertificatePal pal)
     : base(pal)
 {
 }
Ejemplo n.º 27
0
        public void Remove(ICertificatePal certPal)
        {
            OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal;

            using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles()))
            {
                bool hadCandidates;
                string currentFilename = FindExistingFilename(copy, _storePath, out hadCandidates);

                if (currentFilename != null)
                {
                    if (_readOnly)
                    {
                        // Windows compatibility, the readonly check isn't done until after a match is found.
                        throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly);
                    }

                    File.Delete(currentFilename);
                }
            }
        }
Ejemplo n.º 28
0
 private static IStorePal SingleCertToStorePal(ICertificatePal singleCert)
 {
     return(new CollectionBackedStoreProvider(new X509Certificate2(singleCert)));
 }
Ejemplo n.º 29
0
        private static bool TryReadPkcs7Pem(
            byte[] rawData,
            bool single,
            out ICertificatePal certPal,
            out List<ICertificatePal> certPals)
        {
            using (SafeBioHandle bio = Interop.Crypto.CreateMemoryBio())
            {
                Interop.Crypto.CheckValidOpenSslHandle(bio);

                Interop.Crypto.BioWrite(bio, rawData, rawData.Length);

                return TryReadPkcs7Pem(bio, single, out certPal, out certPals);
            }
        }
Ejemplo n.º 30
0
        internal static bool TryReadX509Der(SafeBioHandle bio, out ICertificatePal fromBio)
        {
            SafeX509Handle cert = Interop.Crypto.ReadX509AsDerFromBio(bio);

            if (cert.IsInvalid)
            {
                cert.Dispose();
                fromBio = null;
                return false;
            }

            fromBio = new OpenSslX509CertificateReader(cert);
            return true;
        }
Ejemplo n.º 31
0
        internal static bool TryReadPkcs12(byte[] rawData, string password, out ICertificatePal certPal)
        {
            List<ICertificatePal> ignored;

            return TryReadPkcs12(rawData, password, true, out certPal, out ignored);

        }
        public void Add(ICertificatePal certPal)
        {
            if (_readOnly)
            {
                // Windows compatibility: Remove only throws when it needs to do work, add throws always.
                throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly);
            }

            // This may well be the first time that we've added something to this store.
            Directory.CreateDirectory(_storePath);

            uint userId = Interop.Sys.GetEUid();

            EnsureDirectoryPermissions(_storePath, userId);

            OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal;

            using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles()))
            {
                string thumbprint = copy.Thumbprint;
                bool   findOpenSlot;

                // The odds are low that we'd have a thumbprint collision, but check anyways.
                string existingFilename = FindExistingFilename(copy, _storePath, out findOpenSlot);

                if (existingFilename != null)
                {
                    if (!copy.HasPrivateKey)
                    {
                        return;
                    }

                    try
                    {
                        using (X509Certificate2 fromFile = new X509Certificate2(existingFilename))
                        {
                            if (fromFile.HasPrivateKey)
                            {
                                // We have a private key, the file has a private key, we're done here.
                                return;
                            }
                        }
                    }
                    catch (CryptographicException)
                    {
                        // We can't read this file anymore, but a moment ago it was this certificate,
                        // so go ahead and overwrite it.
                    }
                }

                string   destinationFilename;
                FileMode mode = FileMode.CreateNew;

                if (existingFilename != null)
                {
                    destinationFilename = existingFilename;
                    mode = FileMode.Create;
                }
                else if (findOpenSlot)
                {
                    destinationFilename = FindOpenSlot(thumbprint);
                }
                else
                {
                    destinationFilename = Path.Combine(_storePath, thumbprint + PfxExtension);
                }

                using (FileStream stream = new FileStream(destinationFilename, mode))
                {
                    EnsureFilePermissions(stream, userId);
                    byte[] pkcs12 = copy.Export(X509ContentType.Pkcs12);
                    stream.Write(pkcs12, 0, pkcs12.Length);
                }
            }
        }
Ejemplo n.º 33
0
        private static bool TryReadPkcs12(
            SafeBioHandle bio,
            string password,
            bool single,
            out ICertificatePal readPal,
            out List<ICertificatePal> readCerts)
        {
            // DER-PKCS12
            OpenSslPkcs12Reader pfx;

            if (!OpenSslPkcs12Reader.TryRead(bio, out pfx))
            {
                readPal = null;
                readCerts = null;
                return false;
            }

            using (pfx)
            {
                return TryReadPkcs12(pfx, password, single, out readPal, out readCerts);
            }
        }
Ejemplo n.º 34
0
        internal static bool TryReadX509Pem(SafeBioHandle bio, out ICertificatePal certPal)
        {
            SafeX509Handle cert = Interop.Crypto.PemReadX509FromBio(bio);

            if (cert.IsInvalid)
            {
                cert.Dispose();
                certPal = null;
                return false;
            }

            certPal = new OpenSslX509CertificateReader(cert);
            return true;
        }
Ejemplo n.º 35
0
        internal void OpenTrustHandle(
            ICertificatePal leafCert,
            X509Certificate2Collection?extraStore,
            X509RevocationMode revocationMode,
            X509Certificate2Collection customTrustStore,
            X509ChainTrustMode trustMode)
        {
            _revocationMode = revocationMode;
            SafeCreateHandle policiesArray = PreparePoliciesArray(revocationMode != X509RevocationMode.NoCheck);
            SafeCreateHandle certsArray    = PrepareCertsArray(leafCert, extraStore, customTrustStore, trustMode);

            int osStatus;

            SafeX509ChainHandle chain;
            int ret = Interop.AppleCrypto.AppleCryptoNative_X509ChainCreate(
                certsArray,
                policiesArray,
                out chain,
                out osStatus);

            if (ret == 1)
            {
                if (trustMode == X509ChainTrustMode.CustomRootTrust)
                {
                    SafeCreateHandle customCertsArray = s_emptyArray;
                    if (customTrustStore != null && customTrustStore.Count > 0)
                    {
                        customCertsArray = PrepareCustomCertsArray(customTrustStore);
                    }

                    try
                    {
                        int error = Interop.AppleCrypto.X509ChainSetTrustAnchorCertificates(chain, customCertsArray);
                        if (error != 0)
                        {
                            throw Interop.AppleCrypto.CreateExceptionForOSStatus(error);
                        }
                    }
                    finally
                    {
                        if (customCertsArray != s_emptyArray)
                        {
                            customCertsArray.Dispose();
                        }
                    }
                }

                _chainHandle = chain;
                return;
            }

            chain.Dispose();

            if (ret == 0)
            {
                throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus);
            }

            Debug.Fail($"AppleCryptoNative_X509ChainCreate returned unexpected return value {ret}");
            throw new CryptographicException();
        }
 private static string GetCertificateHashString(ICertificatePal certPal)
 {
     return(X509Certificate.GetCertHashString(HashAlgorithmName.SHA256, certPal));
 }
Ejemplo n.º 37
0
        internal static bool TryReadPkcs7Pem(byte[] rawData, out ICertificatePal certPal)
        {
            List<ICertificatePal> ignored;

            return TryReadPkcs7Pem(rawData, true, out certPal, out ignored);
        }
Ejemplo n.º 38
0
 internal X509Certificate(ICertificatePal pal)
 {
     Debug.Assert(pal != null);
     Pal = pal;
 }
Ejemplo n.º 39
0
        public static IStorePal FromCertificate(ICertificatePal cert)
        {
            ICertificatePal duplicatedHandles = ((OpenSslX509CertificateReader)cert).DuplicateHandles();

            return new CollectionBackedStoreProvider(new X509Certificate2(duplicatedHandles));
        }
Ejemplo n.º 40
0
        public void Add(ICertificatePal certPal)
        {
            if (_readOnly)
            {
                // Windows compatibility: Remove only throws when it needs to do work, add throws always.
                throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly);
            }

            // This may well be the first time that we've added something to this store.
            Directory.CreateDirectory(_storePath);

            uint userId = Interop.Sys.GetEUid();
            EnsureDirectoryPermissions(_storePath, userId);

            OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal;

            using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles()))
            {
                string thumbprint = copy.Thumbprint;
                bool findOpenSlot;

                // The odds are low that we'd have a thumbprint collision, but check anyways.
                string existingFilename = FindExistingFilename(copy, _storePath, out findOpenSlot);

                if (existingFilename != null)
                {
                    if (!copy.HasPrivateKey)
                    {
                        return;
                    }

                    try
                    {
                        using (X509Certificate2 fromFile = new X509Certificate2(existingFilename))
                        {
                            if (fromFile.HasPrivateKey)
                            {
                                // We have a private key, the file has a private key, we're done here.
                                return;
                            }
                        }
                    }
                    catch (CryptographicException)
                    {
                        // We can't read this file anymore, but a moment ago it was this certificate,
                        // so go ahead and overwrite it.
                    }
                }

                string destinationFilename;
                FileMode mode = FileMode.CreateNew;

                if (existingFilename != null)
                {
                    destinationFilename = existingFilename;
                    mode = FileMode.Create;
                }
                else if (findOpenSlot)
                {
                    destinationFilename = FindOpenSlot(thumbprint);
                }
                else
                {
                    destinationFilename = Path.Combine(_storePath, thumbprint + PfxExtension);
                }

                using (FileStream stream = new FileStream(destinationFilename, mode))
                {
                    EnsureFilePermissions(stream, userId);
                    byte[] pkcs12 = copy.Export(X509ContentType.Pkcs12);
                    stream.Write(pkcs12, 0, pkcs12.Length);
                }
            }
        }
Ejemplo n.º 41
0
        public static IStorePal FromCertificate(ICertificatePal cert)
        {
            ICertificatePal duplicatedHandles = ((OpenSslX509CertificateReader)cert).DuplicateHandles();

            return(new CollectionBackedStoreProvider(new X509Certificate2(duplicatedHandles)));
        }
Ejemplo n.º 42
0
            public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters,
                                                       ICertificatePal certificatePal)
            {
                const int           errSecInvalidKeyRef      = -67712;
                const int           errSecUnsupportedKeySize = -67735;
                AppleCertificatePal applePal = certificatePal as AppleCertificatePal;

                if (applePal != null)
                {
                    SafeSecKeyRefHandle key = Interop.AppleCrypto.X509GetPublicKey(applePal.CertificateHandle);

                    switch (oid.Value)
                    {
                    case Oids.RsaRsa:
                        Debug.Assert(!key.IsInvalid);
                        return(new RSAImplementation.RSASecurityTransforms(key));

                    case Oids.DsaDsa:
                        if (key.IsInvalid)
                        {
                            // SecCertificateCopyKey returns null for DSA, so fall back to manually building it.
                            return(DecodeDsaPublicKey(encodedKeyValue, encodedParameters));
                        }
                        return(new DSAImplementation.DSASecurityTransforms(key));

                    case Oids.Ecc:
                        // If X509GetPublicKey uses the new SecCertificateCopyKey API it can return an invalid
                        // key reference for unsupported algorithms. This currently happens for the BrainpoolP160r1
                        // algorithm in the test suite (as of macOS Mojave Developer Preview 4).
                        if (key.IsInvalid)
                        {
                            throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecInvalidKeyRef);
                        }
                        // EccGetKeySizeInBits can fail for two reasons. First, the Apple implementation has changed
                        // and we receive values from API that were not previously handled. In that case the CoreFX
                        // implementation will need to be adjusted to handle these values. Second, we deliberately
                        // return 0 from the native code to prevent hitting buggy API implementations in Apple code
                        // later.
                        if (Interop.AppleCrypto.EccGetKeySizeInBits(key) == 0)
                        {
                            key.Dispose();
                            throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecUnsupportedKeySize);
                        }
                        return(new ECDsaImplementation.ECDsaSecurityTransforms(key));
                    }

                    key.Dispose();
                }
                else
                {
                    switch (oid.Value)
                    {
                    case Oids.RsaRsa:
                        return(DecodeRsaPublicKey(encodedKeyValue));

                    case Oids.DsaDsa:
                        return(DecodeDsaPublicKey(encodedKeyValue, encodedParameters));
                    }
                }

                throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
            }
Ejemplo n.º 43
0
        internal static bool TryReadX509Pem(byte[] rawData, out ICertificatePal certPal)
        {
            using (SafeBioHandle bio = Interop.Crypto.CreateMemoryBio())
            {
                Interop.Crypto.CheckValidOpenSslHandle(bio);

                Interop.Crypto.BioWrite(bio, rawData, rawData.Length);
                return TryReadX509Pem(bio, out certPal);
            }
        }
Ejemplo n.º 44
0
        public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal)
        {
            if (oid.Value == Oids.Ecc && certificatePal != null)
            {
                return(DecodeECDsaPublicKey((CertificatePal)certificatePal));
            }

            int algId = Interop.Crypt32.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid.Value, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId;

            switch (algId)
            {
            case AlgId.CALG_RSA_KEYX:
            case AlgId.CALG_RSA_SIGN:
            {
                byte[] keyBlob = DecodeKeyBlob(CryptDecodeObjectStructType.CNG_RSA_PUBLIC_KEY_BLOB, encodedKeyValue);
                CngKey cngKey  = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
                return(new RSACng(cngKey));
            }

#if !NETNATIVE
            case AlgId.CALG_DSS_SIGN:
            {
                byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters);
                DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
                dsa.ImportCspBlob(keyBlob);
                return(dsa);
            }
#endif

            default:
                throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
            }
        }
 public void Remove(ICertificatePal cert)
 {
     throw new InvalidOperationException();
 }
Ejemplo n.º 46
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();
            }

            // Until we support the Disallowed store, ensure it's empty (which is done by the ctor)
            using (new X509Store(StoreName.Disallowed, StoreLocation.CurrentUser, OpenFlags.ReadOnly))
            {
            }

            TimeSpan remainingDownloadTime = timeout;

            using (var leaf = new X509Certificate2(cert.Handle))
            {
                GC.KeepAlive(cert); // ensure cert's safe handle isn't finalized while raw handle is in use

                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,
                    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);
            }
        }