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