TryReadX509Der() static private method

static private TryReadX509Der ( SafeBioHandle bio, ICertificatePal &fromBio ) : bool
bio SafeBioHandle
fromBio ICertificatePal
return bool
Ejemplo n.º 1
0
        private static ILoaderPal FromBio(SafeBioHandle bio, SafePasswordHandle password)
        {
            int bioPosition = Interop.Crypto.BioTell(bio);

            Debug.Assert(bioPosition >= 0);

            ICertificatePal singleCert;

            if (CertificatePal.TryReadX509Pem(bio, out singleCert))
            {
                return(SingleCertToLoaderPal(singleCert));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            if (CertificatePal.TryReadX509Der(bio, out singleCert))
            {
                return(SingleCertToLoaderPal(singleCert));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            List <ICertificatePal> certPals;

            if (PkcsFormatReader.TryReadPkcs7Pem(bio, out certPals))
            {
                return(ListToLoaderPal(certPals));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            if (PkcsFormatReader.TryReadPkcs7Der(bio, out certPals))
            {
                return(ListToLoaderPal(certPals));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            if (PkcsFormatReader.TryReadPkcs12(bio, password, out certPals))
            {
                return(ListToLoaderPal(certPals));
            }

            // Since we aren't going to finish reading, leaving the buffer where it was when we got
            // it seems better than leaving it in some arbitrary other position.
            //
            // But, before seeking back to start, save the Exception representing the last reported
            // OpenSSL error in case the last BioSeek would change it.
            Exception openSslException = Interop.Crypto.CreateOpenSslCryptographicException();

            // Use BioSeek directly for the last seek attempt, because any failure here should instead
            // report the already created (but not yet thrown) exception.
            Interop.Crypto.BioSeek(bio, bioPosition);

            throw openSslException;
        }
Ejemplo n.º 2
0
        public X509ContentType GetCertContentType(byte[] rawData)
        {
            {
                ICertificatePal certPal;

                if (CertificatePal.TryReadX509Der(rawData, out certPal) ||
                    CertificatePal.TryReadX509Pem(rawData, out certPal))
                {
                    certPal.Dispose();

                    return(X509ContentType.Cert);
                }
            }

            if (PkcsFormatReader.IsPkcs7(rawData))
            {
                return(X509ContentType.Pkcs7);
            }

            {
                OpenSslPkcs12Reader pfx;

                if (OpenSslPkcs12Reader.TryRead(rawData, out pfx))
                {
                    pfx.Dispose();
                    return(X509ContentType.Pkcs12);
                }
            }

            // Unsupported format.
            // Windows throws new CryptographicException(CRYPT_E_NO_MATCH)
            throw new CryptographicException();
        }
Ejemplo n.º 3
0
        public static ILoaderPal FromBlob(byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            ICertificatePal singleCert;

            if (CertificatePal.TryReadX509Der(rawData, out singleCert) ||
                CertificatePal.TryReadX509Pem(rawData, out singleCert))
            {
                // The single X509 structure methods shouldn't return true and out null, only empty
                // collections have that behavior.
                Debug.Assert(singleCert != null);

                return(SingleCertToLoaderPal(singleCert));
            }

            List <ICertificatePal> certPals;

            if (PkcsFormatReader.TryReadPkcs7Der(rawData, out certPals) ||
                PkcsFormatReader.TryReadPkcs7Pem(rawData, out certPals) ||
                PkcsFormatReader.TryReadPkcs12(rawData, password, out certPals))
            {
                Debug.Assert(certPals != null);

                return(ListToLoaderPal(certPals));
            }

            throw Interop.Crypto.CreateOpenSslCryptographicException();
        }
Ejemplo n.º 4
0
        public static IStorePal FromBlob(byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
        {
            ICertificatePal singleCert;

            if (CertificatePal.TryReadX509Der(rawData, out singleCert) ||
                CertificatePal.TryReadX509Pem(rawData, out singleCert))
            {
                // The single X509 structure methods shouldn't return true and out null, only empty
                // collections have that behavior.
                Debug.Assert(singleCert != null);

                return(SingleCertToStorePal(singleCert));
            }

            List <ICertificatePal> certPals;

            if (PkcsFormatReader.TryReadPkcs7Der(rawData, out certPals) ||
                PkcsFormatReader.TryReadPkcs7Pem(rawData, out certPals) ||
                PkcsFormatReader.TryReadPkcs12(rawData, password, out certPals))
            {
                Debug.Assert(certPals != null);

                return(ListToStorePal(certPals));
            }

            return(null);
        }
Ejemplo n.º 5
0
        private static ILoaderPal FromBio(SafeBioHandle bio, SafePasswordHandle password)
        {
            int bioPosition = Interop.Crypto.BioTell(bio);

            Debug.Assert(bioPosition >= 0);

            ICertificatePal singleCert;

            if (CertificatePal.TryReadX509Pem(bio, out singleCert))
            {
                return(SingleCertToLoaderPal(singleCert));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            if (CertificatePal.TryReadX509Der(bio, out singleCert))
            {
                return(SingleCertToLoaderPal(singleCert));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            List <ICertificatePal> certPals;

            if (PkcsFormatReader.TryReadPkcs7Pem(bio, out certPals))
            {
                return(ListToLoaderPal(certPals));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            if (PkcsFormatReader.TryReadPkcs7Der(bio, out certPals))
            {
                return(ListToLoaderPal(certPals));
            }

            // Rewind, try again.
            CertificatePal.RewindBio(bio, bioPosition);

            // Capture the exception so in case of failure, the call to BioSeek does not override it.
            Exception openSslException;

            if (PkcsFormatReader.TryReadPkcs12(bio, password, out certPals, out openSslException))
            {
                return(ListToLoaderPal(certPals));
            }

            // Since we aren't going to finish reading, leaving the buffer where it was when we got
            // it seems better than leaving it in some arbitrary other position.
            //
            // Use BioSeek directly for the last seek attempt, because any failure here should instead
            // report the already created (but not yet thrown) exception.
            Interop.Crypto.BioSeek(bio, bioPosition);

            Debug.Assert(openSslException != null);
            throw openSslException;
        }
Ejemplo n.º 6
0
        private static void LoadMachineStores()
        {
            Debug.Assert(
                Monitor.IsEntered(s_machineLoadLock),
                "LoadMachineStores assumes a lock(s_machineLoadLock)");

            var rootStore     = new List <X509Certificate2>();
            var intermedStore = new List <X509Certificate2>();

            DirectoryInfo          rootStorePath = null;
            IEnumerable <FileInfo> trustedCertFiles;

            try
            {
                rootStorePath = new DirectoryInfo(Interop.Crypto.GetX509RootStorePath());
            }
            catch (ArgumentException)
            {
                // If SSL_CERT_DIR is set to the empty string, or anything else which gives
                // "The path is not of a legal form", then the GetX509RootStorePath value is ignored.
            }

            if (rootStorePath != null && rootStorePath.Exists)
            {
                trustedCertFiles = rootStorePath.EnumerateFiles();
            }
            else
            {
                trustedCertFiles = Array.Empty <FileInfo>();
            }

            FileInfo rootStoreFile = null;

            try
            {
                rootStoreFile = new FileInfo(Interop.Crypto.GetX509RootStoreFile());
            }
            catch (ArgumentException)
            {
                // If SSL_CERT_FILE is set to the empty string, or anything else which gives
                // "The path is not of a legal form", then the GetX509RootStoreFile value is ignored.
            }

            if (rootStoreFile != null && rootStoreFile.Exists)
            {
                trustedCertFiles = Append(trustedCertFiles, rootStoreFile);
            }

            HashSet <X509Certificate2> uniqueRootCerts         = new HashSet <X509Certificate2>();
            HashSet <X509Certificate2> uniqueIntermediateCerts = new HashSet <X509Certificate2>();

            foreach (FileInfo file in trustedCertFiles)
            {
                using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(file.FullName, "rb"))
                {
                    ICertificatePal pal;

                    while (CertificatePal.TryReadX509Pem(fileBio, out pal) ||
                           CertificatePal.TryReadX509Der(fileBio, out pal))
                    {
                        X509Certificate2 cert = new X509Certificate2(pal);

                        // The HashSets are just used for uniqueness filters, they do not survive this method.
                        if (StringComparer.Ordinal.Equals(cert.Subject, cert.Issuer))
                        {
                            if (uniqueRootCerts.Add(cert))
                            {
                                rootStore.Add(cert);
                                continue;
                            }
                        }
                        else
                        {
                            if (uniqueIntermediateCerts.Add(cert))
                            {
                                intermedStore.Add(cert);
                                continue;
                            }
                        }

                        // There's a good chance we'll encounter duplicates on systems that have both one-cert-per-file
                        // and one-big-file trusted certificate stores. Anything that wasn't unique will end up here.
                        cert.Dispose();
                    }
                }
            }

            var rootStorePal = new CollectionBackedStoreProvider(rootStore);

            s_machineIntermediateStore = new CollectionBackedStoreProvider(intermedStore);

            // s_machineRootStore's nullarity is the loaded-state sentinel, so write it with Volatile.
            Debug.Assert(Monitor.IsEntered(s_machineLoadLock), "LoadMachineStores assumes a lock(s_machineLoadLock)");
            Volatile.Write(ref s_machineRootStore, rootStorePal);
        }
Ejemplo n.º 7
0
        public X509ContentType GetCertContentType(string fileName)
        {
            // If we can't open the file, fail right away.
            using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(fileName, "rb"))
            {
                Interop.Crypto.CheckValidOpenSslHandle(fileBio);

                int bioPosition = Interop.Crypto.BioTell(fileBio);
                Debug.Assert(bioPosition >= 0);

                // X509ContentType.Cert
                {
                    ICertificatePal certPal;

                    if (CertificatePal.TryReadX509Der(fileBio, out certPal))
                    {
                        certPal.Dispose();

                        return(X509ContentType.Cert);
                    }

                    CertificatePal.RewindBio(fileBio, bioPosition);

                    if (CertificatePal.TryReadX509Pem(fileBio, out certPal))
                    {
                        certPal.Dispose();

                        return(X509ContentType.Cert);
                    }

                    CertificatePal.RewindBio(fileBio, bioPosition);
                }

                // X509ContentType.Pkcs7
                {
                    if (PkcsFormatReader.IsPkcs7Der(fileBio))
                    {
                        return(X509ContentType.Pkcs7);
                    }

                    CertificatePal.RewindBio(fileBio, bioPosition);

                    if (PkcsFormatReader.IsPkcs7Pem(fileBio))
                    {
                        return(X509ContentType.Pkcs7);
                    }

                    CertificatePal.RewindBio(fileBio, bioPosition);
                }

                // X509ContentType.Pkcs12 (aka PFX)
                {
                    OpenSslPkcs12Reader pkcs12Reader;

                    if (OpenSslPkcs12Reader.TryRead(fileBio, out pkcs12Reader))
                    {
                        pkcs12Reader.Dispose();

                        return(X509ContentType.Pkcs12);
                    }

                    CertificatePal.RewindBio(fileBio, bioPosition);
                }
            }

            // Unsupported format.
            // Windows throws new CryptographicException(CRYPT_E_NO_MATCH)
            throw new CryptographicException();
        }
Ejemplo n.º 8
0
        private static void LoadMachineStores()
        {
            Debug.Assert(
                Monitor.IsEntered(s_machineIntermediateStore),
                "LoadMachineStores assumes a lock(s_machineIntermediateStore)");

            X509Certificate2Collection rootStore = new X509Certificate2Collection();

            DirectoryInfo          rootStorePath = null;
            IEnumerable <FileInfo> trustedCertFiles;

            try
            {
                rootStorePath = new DirectoryInfo(Interop.Crypto.GetX509RootStorePath());
            }
            catch (ArgumentException)
            {
                // If SSL_CERT_DIR is set to the empty string, or anything else which gives
                // "The path is not of a legal form", then the GetX509RootStorePath value is ignored.
            }

            if (rootStorePath != null && rootStorePath.Exists)
            {
                trustedCertFiles = rootStorePath.EnumerateFiles();
            }
            else
            {
                trustedCertFiles = Array.Empty <FileInfo>();
            }

            FileInfo rootStoreFile = null;

            try
            {
                rootStoreFile = new FileInfo(Interop.Crypto.GetX509RootStoreFile());
            }
            catch (ArgumentException)
            {
                // If SSL_CERT_FILE is set to the empty string, or anything else which gives
                // "The path is not of a legal form", then the GetX509RootStoreFile value is ignored.
            }

            if (rootStoreFile != null && rootStoreFile.Exists)
            {
                trustedCertFiles = Append(trustedCertFiles, rootStoreFile);
            }

            HashSet <X509Certificate2> uniqueRootCerts         = new HashSet <X509Certificate2>();
            HashSet <X509Certificate2> uniqueIntermediateCerts = new HashSet <X509Certificate2>();

            foreach (FileInfo file in trustedCertFiles)
            {
                using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(file.FullName, "rb"))
                {
                    ICertificatePal pal;

                    while (CertificatePal.TryReadX509Pem(fileBio, out pal) ||
                           CertificatePal.TryReadX509Der(fileBio, out pal))
                    {
                        X509Certificate2 cert = new X509Certificate2(pal);

                        // The HashSets are just used for uniqueness filters, they do not survive this method.
                        if (StringComparer.Ordinal.Equals(cert.Subject, cert.Issuer))
                        {
                            if (uniqueRootCerts.Add(cert))
                            {
                                rootStore.Add(cert);
                            }
                        }
                        else
                        {
                            if (uniqueIntermediateCerts.Add(cert))
                            {
                                s_machineIntermediateStore.Add(cert);
                            }
                        }
                    }
                }
            }

            s_machineRootStore = rootStore;
        }