internal static SafeSecCertificateHandle X509ImportCertificate( ReadOnlySpan <byte> bytes, X509ContentType contentType, SafePasswordHandle importPassword, SafeKeychainHandle keychain, bool exportable, out SafeSecIdentityHandle identityHandle) { SafeCreateHandle?cfPassphrase = null; bool releasePassword = false; try { if (!importPassword.IsInvalid) { importPassword.DangerousAddRef(ref releasePassword); cfPassphrase = CoreFoundation.CFStringCreateFromSpan(importPassword.DangerousGetSpan()); } return(X509ImportCertificate( bytes, contentType, cfPassphrase, keychain, exportable, out identityHandle)); } finally { if (releasePassword) { importPassword.DangerousRelease(); } cfPassphrase?.Dispose(); } }
public override byte[] Export(X509ContentType contentType, SafePasswordHandle password) { if (_cert == null) { throw new CryptographicException(empty_error); } switch (contentType) { case X509ContentType.Cert: return(_cert.RawData); case X509ContentType.Pfx: // this includes Pkcs12 return(ExportPkcs12(password)); case X509ContentType.SerializedCert: // TODO throw new NotSupportedException(); default: string msg = Locale.GetText("This certificate format '{0}' cannot be exported.", contentType); throw new CryptographicException(msg); } }
public static ICertificatePal FromBlob(byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); ICertificatePal cert; if (TryReadX509Der(rawData, out cert) || TryReadX509Pem(rawData, out cert) || PkcsFormatReader.TryReadPkcs7Der(rawData, out cert) || PkcsFormatReader.TryReadPkcs7Pem(rawData, out cert) || PkcsFormatReader.TryReadPkcs12(rawData, password, out cert)) { if (cert == null) { // Empty collection, most likely. throw new CryptographicException(); } return(cert); } // Unsupported throw Interop.Crypto.CreateOpenSslCryptographicException(); }
private static bool TryReadPkcs12( ReadOnlySpan <byte> rawData, SafePasswordHandle password, bool single, bool ephemeralSpecified, out ICertificatePal?readPal, out List <ICertificatePal>?readCerts, out Exception?openSslException) { // DER-PKCS12 OpenSslPkcs12Reader?pfx; if (!OpenSslPkcs12Reader.TryRead(rawData, out pfx, out openSslException)) { readPal = null; readCerts = null; return(false); } using (pfx) { return(TryReadPkcs12(pfx, password, single, ephemeralSpecified, out readPal, out readCerts)); } }
public static ICertificatePal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); ICertificatePal?cert; Exception? exception; if (TryReadX509(rawData, out cert) || PkcsFormatReader.TryReadPkcs7Der(rawData, out cert) || PkcsFormatReader.TryReadPkcs7Pem(rawData, out cert) || PkcsFormatReader.TryReadPkcs12(rawData, password, out cert, out exception)) { if (cert == null) { // Empty collection, most likely. throw new CryptographicException(); } return(cert); } // Unsupported Debug.Assert(exception != null); throw exception; }
public sealed override byte[] Export(X509ContentType contentType, SafePasswordHandle password) { ThrowIfContextInvalid(); Debug.Assert(password != null); switch (contentType) { case X509ContentType.Cert: return(RawData); case X509ContentType.Pkcs12: return(ExportPkcs12(password)); case X509ContentType.Pkcs7: return(ExportPkcs12((string)null)); case X509ContentType.SerializedCert: case X509ContentType.SerializedStore: throw new PlatformNotSupportedException(SR.Cryptography_Unix_X509_SerializedExport); default: throw new CryptographicException(SR.Cryptography_X509_InvalidContentType); } }
public static ICertificatePal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return(OpenSslX509CertificateReader.FromBlob(rawData, password, keyStorageFlags)); }
public static ICertificatePal FromBlob( byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); X509ContentType contentType = X509Certificate2.GetCertContentType(rawData); if (contentType == X509ContentType.Pkcs7) { // 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); } bool exportable = true; SafeKeychainHandle keychain; if (contentType == X509ContentType.Pkcs12) { if ((keyStorageFlags & X509KeyStorageFlags.EphemeralKeySet) == X509KeyStorageFlags.EphemeralKeySet) { throw new PlatformNotSupportedException(SR.Cryptography_X509_NoEphemeralPfx); } exportable = (keyStorageFlags & X509KeyStorageFlags.Exportable) == X509KeyStorageFlags.Exportable; bool persist = (keyStorageFlags & X509KeyStorageFlags.PersistKeySet) == X509KeyStorageFlags.PersistKeySet; keychain = persist ? Interop.AppleCrypto.SecKeychainCopyDefault() : Interop.AppleCrypto.CreateTemporaryKeychain(); } else { keychain = SafeTemporaryKeychainHandle.InvalidHandle; password = SafePasswordHandle.InvalidHandle; } using (keychain) { SafeSecIdentityHandle identityHandle; SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate( rawData, contentType, password, keychain, exportable, out identityHandle); if (identityHandle.IsInvalid) { identityHandle.Dispose(); return(new AppleCertificatePal(certHandle)); } if (contentType != X509ContentType.Pkcs12) { Debug.Fail("Non-PKCS12 import produced an identity handle"); identityHandle.Dispose(); certHandle.Dispose(); throw new CryptographicException(); } Debug.Assert(certHandle.IsInvalid); certHandle.Dispose(); return(new AppleCertificatePal(identityHandle)); } }
public static partial bool PFXExportCertStore(SafeCertStoreHandle hStore, ref CRYPTOAPI_BLOB pPFX, SafePasswordHandle szPassword, PFXExportFlags dwFlags);
public static partial SafeCertStoreHandle PFXImportCertStore(ref CRYPTOAPI_BLOB pPFX, SafePasswordHandle password, PfxCertStoreFlags dwFlags);
public static extern SafeCertStoreHandle PFXImportCertStore([In] ref CRYPTOAPI_BLOB pPFX, SafePasswordHandle password, PfxCertStoreFlags dwFlags);
public static ICertificatePal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return(FromBlobOrFile(rawData, null, password, keyStorageFlags)); }
public virtual void Import(string fileName, SecureString password, X509KeyStorageFlags keyStorageFlags) { byte[] rawData = File.ReadAllBytes(fileName); using (var safePasswordHandle = new SafePasswordHandle(password)) impl = X509Helper.Import(rawData, safePasswordHandle, keyStorageFlags); }
public static X509Certificate2 CreateCertificate2(byte[] data, string password, bool disallowFallback = false) { using (var handle = new SafePasswordHandle(password)) using (var impl = new X509CertificateImplBtls(data, handle, X509KeyStorageFlags.DefaultKeySet)) return(new X509Certificate2(impl)); }
private static ILoaderPal FromBio(SafeBioHandle bio, SafePasswordHandle password) { int bioPosition = Interop.Crypto.BioTell(bio); Debug.Assert(bioPosition >= 0); ICertificatePal singleCert; if (OpenSslX509CertificateReader.TryReadX509Pem(bio, out singleCert)) { return(SingleCertToLoaderPal(singleCert)); } // Rewind, try again. OpenSslX509CertificateReader.RewindBio(bio, bioPosition); if (OpenSslX509CertificateReader.TryReadX509Der(bio, out singleCert)) { return(SingleCertToLoaderPal(singleCert)); } // Rewind, try again. OpenSslX509CertificateReader.RewindBio(bio, bioPosition); List <ICertificatePal> certPals; if (PkcsFormatReader.TryReadPkcs7Pem(bio, out certPals)) { return(ListToLoaderPal(certPals)); } // Rewind, try again. OpenSslX509CertificateReader.RewindBio(bio, bioPosition); if (PkcsFormatReader.TryReadPkcs7Der(bio, out certPals)) { return(ListToLoaderPal(certPals)); } // Rewind, try again. OpenSslX509CertificateReader.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. if (Interop.Crypto.BioSeek(bio, bioPosition) < 0) { Interop.Crypto.ErrClearError(); } Debug.Assert(openSslException != null); throw openSslException; }
internal X509Certificate2Impl GetNativeCertificate( byte[] data, SafePasswordHandle password, X509KeyStorageFlags flags) { return(new X509CertificateImplBtls(data, password, flags)); }
internal override X509Certificate2Impl GetNativeCertificate( byte[] data, string password, X509KeyStorageFlags flags) { using (var handle = new SafePasswordHandle(password)) return(GetNativeCertificate(data, handle, flags)); }
public static extern bool PFXExportCertStore(SafeCertStoreHandle hStore, [In, Out] ref CRYPTOAPI_BLOB pPFX, SafePasswordHandle szPassword, PFXExportFlags dwFlags);
public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return(OpenSslX509CertificateReader.FromFile(fileName, password, keyStorageFlags)); }
private static ICertificatePal FromBlobOrFile(ReadOnlySpan <byte> rawData, string?fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(!rawData.IsEmpty || fileName != null); Debug.Assert(password != null); bool loadFromFile = (fileName != null); Interop.Crypt32.PfxCertStoreFlags pfxCertStoreFlags = MapKeyStorageFlags(keyStorageFlags); bool deleteKeyContainer = false; Interop.Crypt32.CertEncodingType msgAndCertEncodingType; Interop.Crypt32.ContentType contentType; Interop.Crypt32.FormatType formatType; SafeCertStoreHandle? hCertStore = null; SafeCryptMsgHandle? hCryptMsg = null; SafeCertContextHandle?pCertContext = null; try { unsafe { fixed(byte *pRawData = rawData) { fixed(char *pFileName = fileName) { Interop.Crypt32.DATA_BLOB certBlob = new Interop.Crypt32.DATA_BLOB(new IntPtr(pRawData), (uint)(loadFromFile ? 0 : rawData.Length)); Interop.Crypt32.CertQueryObjectType objectType = loadFromFile ? Interop.Crypt32.CertQueryObjectType.CERT_QUERY_OBJECT_FILE : Interop.Crypt32.CertQueryObjectType.CERT_QUERY_OBJECT_BLOB; void *pvObject = loadFromFile ? (void *)pFileName : (void *)&certBlob; bool success = Interop.Crypt32.CryptQueryObject( objectType, pvObject, X509ExpectedContentTypeFlags, X509ExpectedFormatTypeFlags, 0, out msgAndCertEncodingType, out contentType, out formatType, out hCertStore, out hCryptMsg, out pCertContext ); if (!success) { int hr = Marshal.GetHRForLastWin32Error(); throw hr.ToCryptographicException(); } } } if (contentType == Interop.Crypt32.ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED || contentType == Interop.Crypt32.ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED) { pCertContext = GetSignerInPKCS7Store(hCertStore, hCryptMsg); } else if (contentType == Interop.Crypt32.ContentType.CERT_QUERY_CONTENT_PFX) { if (loadFromFile) { rawData = File.ReadAllBytes(fileName !); } pCertContext = FilterPFXStore(rawData, password, pfxCertStoreFlags); // If PersistKeySet is set we don't delete the key, so that it persists. // If EphemeralKeySet is set we don't delete the key, because there's no file, so it's a wasteful call. const X509KeyStorageFlags DeleteUnless = X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.EphemeralKeySet; deleteKeyContainer = ((keyStorageFlags & DeleteUnless) == 0); } CertificatePal pal = new CertificatePal(pCertContext, deleteKeyContainer); pCertContext = null; return(pal); } } finally { if (hCertStore != null) { hCertStore.Dispose(); } if (hCryptMsg != null) { hCryptMsg.Dispose(); } if (pCertContext != null) { pCertContext.Dispose(); } } }
public virtual void Import(byte[] rawData, SecureString password, X509KeyStorageFlags keyStorageFlags) { using (var safePasswordHandle = new SafePasswordHandle(password)) impl = X509Helper.Import(rawData, safePasswordHandle, keyStorageFlags); }
public static X509CertificateImpl Import(byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return(CertificateProvider.Import(rawData, password, keyStorageFlags)); }
private static SafeCertContextHandle FilterPFXStore( ReadOnlySpan <byte> rawData, SafePasswordHandle password, Interop.Crypt32.PfxCertStoreFlags pfxCertStoreFlags) { SafeCertStoreHandle hStore; unsafe { fixed(byte *pbRawData = rawData) { Interop.Crypt32.DATA_BLOB certBlob = new Interop.Crypt32.DATA_BLOB(new IntPtr(pbRawData), (uint)rawData.Length); hStore = Interop.Crypt32.PFXImportCertStore(ref certBlob, password, pfxCertStoreFlags); if (hStore.IsInvalid) { throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); } } } try { // Find the first cert with private key. If none, then simply take the very first cert. Along the way, delete the keycontainers // of any cert we don't accept. SafeCertContextHandle pCertContext = SafeCertContextHandle.InvalidHandle; SafeCertContextHandle?pEnumContext = null; while (Interop.crypt32.CertEnumCertificatesInStore(hStore, ref pEnumContext)) { if (pEnumContext.ContainsPrivateKey) { if ((!pCertContext.IsInvalid) && pCertContext.ContainsPrivateKey) { // We already found our chosen one. Free up this one's key and move on. // If this one has a persisted private key, clean up the key file. // If it was an ephemeral private key no action is required. if (pEnumContext.HasPersistedPrivateKey) { SafeCertContextHandleWithKeyContainerDeletion.DeleteKeyContainer(pEnumContext); } } else { // Found our first cert that has a private key. Set it up as our chosen one but keep iterating // as we need to free up the keys of any remaining certs. pCertContext.Dispose(); pCertContext = pEnumContext.Duplicate(); } } else { if (pCertContext.IsInvalid) { // Doesn't have a private key but hang on to it anyway in case we don't find any certs with a private key. pCertContext = pEnumContext.Duplicate(); } } } if (pCertContext.IsInvalid) { throw new CryptographicException(SR.Cryptography_Pfx_NoCertificates); } return(pCertContext); } finally { hStore.Dispose(); } }
internal static partial ICertificatePal FromFile( string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags);
public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return(FromBlobOrFile(ReadOnlySpan <byte> .Empty, fileName, password, keyStorageFlags)); }
public static ILoaderPal FromBlob(byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return(FromBlobOrFile(rawData, null, password, keyStorageFlags)); }
public static ICertificatePal FromBlob( ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); X509ContentType contentType = X509Certificate2.GetCertContentType(rawData); if (contentType == X509ContentType.Pkcs7) { // 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); } if (contentType == X509ContentType.Pkcs12) { if ((keyStorageFlags & X509KeyStorageFlags.EphemeralKeySet) == X509KeyStorageFlags.EphemeralKeySet) { throw new PlatformNotSupportedException(SR.Cryptography_X509_NoEphemeralPfx); } bool exportable = (keyStorageFlags & X509KeyStorageFlags.Exportable) == X509KeyStorageFlags.Exportable; bool persist = (keyStorageFlags & X509KeyStorageFlags.PersistKeySet) == X509KeyStorageFlags.PersistKeySet; SafeKeychainHandle keychain = persist ? Interop.AppleCrypto.SecKeychainCopyDefault() : Interop.AppleCrypto.CreateTemporaryKeychain(); using (keychain) { AppleCertificatePal ret = ImportPkcs12(rawData, password, exportable, keychain); if (!persist) { // If we used temporary keychain we need to prevent deletion. // on 10.15+ if keychain is unlinked, certain certificate operations may fail. bool success = false; keychain.DangerousAddRef(ref success); if (success) { ret._tempKeychain = keychain; } } return(ret); } } SafeSecIdentityHandle identityHandle; SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate( rawData, contentType, SafePasswordHandle.InvalidHandle, SafeTemporaryKeychainHandle.InvalidHandle, exportable: true, out identityHandle); if (identityHandle.IsInvalid) { identityHandle.Dispose(); return(new AppleCertificatePal(certHandle)); } Debug.Fail("Non-PKCS12 import produced an identity handle"); identityHandle.Dispose(); certHandle.Dispose(); throw new CryptographicException(); }
public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return(FromBlobOrFile(null, fileName, password, keyStorageFlags)); }
public static byte[] Export(X509CertificateImpl impl, X509ContentType contentType, SafePasswordHandle password) { ThrowIfContextInvalid(impl); return(impl.Export(contentType, password)); }
private static StorePal FromBlobOrFile(byte[] rawData, string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); bool fromFile = fileName != null; unsafe { fixed(byte *pRawData = rawData) { fixed(char *pFileName = fileName) { CRYPTOAPI_BLOB blob = new CRYPTOAPI_BLOB(fromFile ? 0 : rawData.Length, pRawData); bool persistKeySet = (0 != (keyStorageFlags & X509KeyStorageFlags.PersistKeySet)); PfxCertStoreFlags certStoreFlags = MapKeyStorageFlags(keyStorageFlags); void *pvObject = fromFile ? (void *)pFileName : (void *)&blob; ContentType contentType; SafeCertStoreHandle certStore; if (!Interop.crypt32.CryptQueryObject( fromFile ? CertQueryObjectType.CERT_QUERY_OBJECT_FILE : CertQueryObjectType.CERT_QUERY_OBJECT_BLOB, pvObject, StoreExpectedContentFlags, ExpectedFormatTypeFlags.CERT_QUERY_FORMAT_FLAG_ALL, 0, IntPtr.Zero, out contentType, IntPtr.Zero, out certStore, IntPtr.Zero, IntPtr.Zero )) { throw Marshal.GetLastWin32Error().ToCryptographicException(); } if (contentType == ContentType.CERT_QUERY_CONTENT_PFX) { certStore.Dispose(); if (fromFile) { rawData = File.ReadAllBytes(fileName); } fixed(byte *pRawData2 = rawData) { CRYPTOAPI_BLOB blob2 = new CRYPTOAPI_BLOB(rawData.Length, pRawData2); certStore = Interop.crypt32.PFXImportCertStore(ref blob2, password, certStoreFlags); if (certStore == null || certStore.IsInvalid) { throw Marshal.GetLastWin32Error().ToCryptographicException(); } } if (!persistKeySet) { // // If the user did not want us to persist private keys, then we should loop through all // the certificates in the collection and set our custom CERT_CLR_DELETE_KEY_PROP_ID property // so the key container will be deleted when the cert contexts will go away. // SafeCertContextHandle pCertContext = null; while (Interop.crypt32.CertEnumCertificatesInStore(certStore, ref pCertContext)) { CRYPTOAPI_BLOB nullBlob = new CRYPTOAPI_BLOB(0, null); if (!Interop.crypt32.CertSetCertificateContextProperty(pCertContext, CertContextPropId.CERT_CLR_DELETE_KEY_PROP_ID, CertSetPropertyFlags.CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, &nullBlob)) { throw Marshal.GetLastWin32Error().ToCryptographicException(); } } } } return(new StorePal(certStore)); } } } }