public byte[] Export(X509ContentType contentType, SafePasswordHandle password) { using (IExportPal storePal = StorePal.FromCertificate(this)) { byte[]? exported = storePal.Export(contentType, password); Debug.Assert(exported != null); return(exported); } }
public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { // If we can't open the file, fail right away. using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(fileName, "rb")) { Interop.Crypto.CheckValidOpenSslHandle(fileBio); return FromBio(fileBio, password); } }
public X509Certificate(byte[] data) { if (data != null && data.Length != 0) { // For compat reasons, this constructor treats passing a null or empty data set as the same as calling the nullary constructor. using (var safePasswordHandle = new SafePasswordHandle((string)null)) { Pal = CertificatePal.FromBlob(data, safePasswordHandle, X509KeyStorageFlags.DefaultKeySet); } } }
public X509Certificate(byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags) { if (rawData == null || rawData.Length == 0) throw new ArgumentException(SR.Arg_EmptyOrNullArray, nameof(rawData)); ValidateKeyStorageFlags(keyStorageFlags); using (var safePasswordHandle = new SafePasswordHandle(password)) { Pal = CertificatePal.FromBlob(rawData, safePasswordHandle, keyStorageFlags); } }
public void Decrypt(SafePasswordHandle password) { bool parsed = Interop.Crypto.Pkcs12Parse( _pkcs12Handle, password, out _evpPkeyHandle, out _x509Handle, out _caStackHandle); if (!parsed) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } }
public byte[] Export(X509ContentType contentType, SafePasswordHandle password) { Debug.Assert(password != null); switch (contentType) { case X509ContentType.Cert: return ExportX509Der(); case X509ContentType.Pfx: return ExportPfx(password); case X509ContentType.Pkcs7: return ExportPkcs7(); 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(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(); }
internal static extern SafePkcs12Handle Pkcs12Create( SafePasswordHandle pass, SafeEvpPKeyHandle pkey, SafeX509Handle cert, SafeX509StackHandle ca);
internal static bool TryReadPkcs12(SafeBioHandle bio, SafePasswordHandle password, out List<ICertificatePal> certPals) { ICertificatePal ignored; return TryReadPkcs12(bio, password, false, out ignored, out certPals); }
internal static bool TryReadPkcs12(byte[] rawData, SafePasswordHandle password, out List<ICertificatePal> certPals) { ICertificatePal ignored; return TryReadPkcs12(rawData, password, false, out ignored, out certPals); }
internal static bool TryReadPkcs12(SafeBioHandle bio, SafePasswordHandle password, out ICertificatePal certPal) { List<ICertificatePal> ignored; return TryReadPkcs12(bio, password, true, out certPal, out ignored); }
internal static bool TryReadPkcs12(byte[] rawData, SafePasswordHandle password, out ICertificatePal certPal) { List<ICertificatePal> ignored; return TryReadPkcs12(rawData, password, true, out certPal, out ignored); }
private static bool TryReadPkcs12( OpenSslPkcs12Reader pfx, SafePasswordHandle 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; }
public X509Certificate(string fileName, SecureString password, X509KeyStorageFlags keyStorageFlags) : this() { if (fileName == null) throw new ArgumentNullException(nameof(fileName)); ValidateKeyStorageFlags(keyStorageFlags); using (var safePasswordHandle = new SafePasswordHandle(password)) { Pal = CertificatePal.FromFile(fileName, safePasswordHandle, keyStorageFlags); } }
public X509Certificate(SerializationInfo info, StreamingContext context) : this() { byte[] rawData = (byte[])info.GetValue("RawData", typeof(byte[])); if (rawData != null) { using (var safePasswordHandle = new SafePasswordHandle((string)null)) { Pal = CertificatePal.FromBlob(rawData, safePasswordHandle, X509KeyStorageFlags.DefaultKeySet); } } }
public static extern bool PFXExportCertStore(SafeCertStoreHandle hStore, [In, Out] ref CRYPTOAPI_BLOB pPFX, SafePasswordHandle szPassword, PFXExportFlags dwFlags);
public static ILoaderPal FromBlob(byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return FromBlobOrFile(rawData, null, password, keyStorageFlags); }
private byte[] ExportPfx(SafePasswordHandle password) { using (SafeX509StackHandle publicCerts = Interop.Crypto.NewX509Stack()) { SafeX509Handle privateCertHandle = SafeX509Handle.InvalidHandle; SafeEvpPKeyHandle privateCertKeyHandle = InvalidPKeyHandle; if (_singleCertPal != null) { var certPal = (OpenSslX509CertificateReader)_singleCertPal; if (_singleCertPal.HasPrivateKey) { privateCertHandle = certPal.SafeHandle; privateCertKeyHandle = certPal.PrivateKeyHandle; } else { PushHandle(certPal.Handle, publicCerts); } } else { X509Certificate2 privateCert = null; // Walk the collection backwards, because we're pushing onto a stack. // This will cause the read order later to be the same as it was now. for (int i = _certs.Count - 1; i >= 0; --i) { X509Certificate2 cert = _certs[i]; if (cert.HasPrivateKey) { if (privateCert != null) { // OpenSSL's PKCS12 accelerator (PKCS12_create) only supports one // private key. The data structure supports more than one, but // being able to use that functionality requires a lot more code for // a low-usage scenario. throw new PlatformNotSupportedException(SR.NotSupported_Export_MultiplePrivateCerts); } privateCert = cert; } else { PushHandle(cert.Handle, publicCerts); } } } using (SafePkcs12Handle pkcs12 = Interop.Crypto.Pkcs12Create( password, privateCertKeyHandle, privateCertHandle, publicCerts)) { if (pkcs12.IsInvalid) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } return Interop.Crypto.OpenSslEncode( Interop.Crypto.GetPkcs12DerSize, Interop.Crypto.EncodePkcs12, pkcs12); } } }
private static SafeCertContextHandle FilterPFXStore(byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags) { SafeCertStoreHandle hStore; unsafe { fixed (byte* pbRawData = rawData) { CRYPTOAPI_BLOB certBlob = new CRYPTOAPI_BLOB(rawData.Length, pbRawData); 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 him 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) pCertContext = pEnumContext.Duplicate(); // Doesn't have a private key but hang on to it anyway in case we don't find any certs with a private key. } } if (pCertContext.IsInvalid) { // For compat, setting "hr" to ERROR_INVALID_PARAMETER even though ERROR_INVALID_PARAMETER is not actually an HRESULT. throw ErrorCode.ERROR_INVALID_PARAMETER.ToCryptographicException(); } return pCertContext; } finally { hStore.Dispose(); } }
private static ICertificatePal FromBlobOrFile(byte[] rawData, string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(rawData != null || fileName != null); Debug.Assert(password != null); bool loadFromFile = (fileName != null); PfxCertStoreFlags pfxCertStoreFlags = MapKeyStorageFlags(keyStorageFlags); bool persistKeySet = (0 != (keyStorageFlags & X509KeyStorageFlags.PersistKeySet)); CertEncodingType msgAndCertEncodingType; ContentType contentType; FormatType formatType; SafeCertStoreHandle hCertStore = null; SafeCryptMsgHandle hCryptMsg = null; SafeCertContextHandle pCertContext = null; try { unsafe { fixed (byte* pRawData = rawData) { fixed (char* pFileName = fileName) { CRYPTOAPI_BLOB certBlob = new CRYPTOAPI_BLOB(loadFromFile ? 0 : rawData.Length, pRawData); CertQueryObjectType objectType = loadFromFile ? CertQueryObjectType.CERT_QUERY_OBJECT_FILE : 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 == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED || contentType == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED) { pCertContext = GetSignerInPKCS7Store(hCertStore, hCryptMsg); } else if (contentType == ContentType.CERT_QUERY_CONTENT_PFX) { if (loadFromFile) rawData = File.ReadAllBytes(fileName); pCertContext = FilterPFXStore(rawData, password, pfxCertStoreFlags); } CertificatePal pal = new CertificatePal(pCertContext, deleteKeyContainer: !persistKeySet); pCertContext = null; return pal; } } finally { if (hCertStore != null) hCertStore.Dispose(); if (hCryptMsg != null) hCryptMsg.Dispose(); if (pCertContext != null) pCertContext.Dispose(); } }
public virtual byte[] Export(X509ContentType contentType, SecureString password) { VerifyContentType(contentType); if (Pal == null) throw new CryptographicException(ErrorCode.E_POINTER); // Not the greatest error, but needed for backward compat. using (var safePasswordHandle = new SafePasswordHandle(password)) using (IExportPal storePal = StorePal.FromCertificate(Pal)) { return storePal.Export(contentType, safePasswordHandle); } }
private static ICertificatePal FromBio(SafeBioHandle bio, SafePasswordHandle password) { int bioPosition = Interop.Crypto.BioTell(bio); Debug.Assert(bioPosition >= 0); ICertificatePal certPal; if (TryReadX509Pem(bio, out certPal)) { return certPal; } // Rewind, try again. RewindBio(bio, bioPosition); if (TryReadX509Der(bio, out certPal)) { return certPal; } // Rewind, try again. RewindBio(bio, bioPosition); if (PkcsFormatReader.TryReadPkcs7Pem(bio, out certPal)) { return certPal; } // Rewind, try again. RewindBio(bio, bioPosition); if (PkcsFormatReader.TryReadPkcs7Der(bio, out certPal)) { return certPal; } // Rewind, try again. RewindBio(bio, bioPosition); if (PkcsFormatReader.TryReadPkcs12(bio, password, out certPal)) { return certPal; } // 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 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_DELETE_KEYSET_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_DELETE_KEYSET_PROP_ID, CertSetPropertyFlags.CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, &nullBlob)) throw Marshal.GetLastWin32Error().ToCryptographicException(); } } } return new StorePal(certStore); } } } }
internal static extern bool Pkcs12Parse( SafePkcs12Handle p12, SafePasswordHandle pass, out SafeEvpPKeyHandle pkey, out SafeX509Handle cert, out SafeX509StackHandle ca);
public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return FromBlobOrFile(null, fileName, password, keyStorageFlags); }
public byte[] Export(X509ContentType contentType, string password) { using (var safePasswordHandle = new SafePasswordHandle(password)) using (IExportPal storePal = StorePal.LinkFromCertificateCollection(this)) { return storePal.Export(contentType, safePasswordHandle); } }
public static extern SafeCertStoreHandle PFXImportCertStore([In] ref CRYPTOAPI_BLOB pPFX, SafePasswordHandle password, PfxCertStoreFlags dwFlags);
public void Import(string fileName, string password, X509KeyStorageFlags keyStorageFlags) { if (fileName == null) throw new ArgumentNullException(nameof(fileName)); X509Certificate.ValidateKeyStorageFlags(keyStorageFlags); using (var safePasswordHandle = new SafePasswordHandle(password)) using (ILoaderPal storePal = StorePal.FromFile(fileName, safePasswordHandle, keyStorageFlags)) { storePal.MoveTo(this); } }
private static bool TryReadPkcs12( SafeBioHandle bio, SafePasswordHandle 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); } }
public byte[] Export(X509ContentType contentType, SafePasswordHandle password) { Debug.Assert(password != null); switch (contentType) { case X509ContentType.Cert: { SafeCertContextHandle pCertContext = null; if (!Interop.crypt32.CertEnumCertificatesInStore(_certStore, ref pCertContext)) return null; try { unsafe { byte[] rawData = new byte[pCertContext.CertContext->cbCertEncoded]; Marshal.Copy((IntPtr)(pCertContext.CertContext->pbCertEncoded), rawData, 0, rawData.Length); GC.KeepAlive(pCertContext); return rawData; } } finally { pCertContext.Dispose(); } } case X509ContentType.SerializedCert: { SafeCertContextHandle pCertContext = null; if (!Interop.crypt32.CertEnumCertificatesInStore(_certStore, ref pCertContext)) return null; try { int cbEncoded = 0; if (!Interop.crypt32.CertSerializeCertificateStoreElement(pCertContext, 0, null, ref cbEncoded)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException();; byte[] pbEncoded = new byte[cbEncoded]; if (!Interop.crypt32.CertSerializeCertificateStoreElement(pCertContext, 0, pbEncoded, ref cbEncoded)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException();; return pbEncoded; } finally { pCertContext.Dispose(); } } case X509ContentType.Pkcs12: { unsafe { CRYPTOAPI_BLOB dataBlob = new CRYPTOAPI_BLOB(0, (byte*)null); if (!Interop.crypt32.PFXExportCertStore(_certStore, ref dataBlob, password, PFXExportFlags.EXPORT_PRIVATE_KEYS | PFXExportFlags.REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException();; byte[] pbEncoded = new byte[dataBlob.cbData]; fixed (byte* ppbEncoded = pbEncoded) { dataBlob.pbData = ppbEncoded; if (!Interop.crypt32.PFXExportCertStore(_certStore, ref dataBlob, password, PFXExportFlags.EXPORT_PRIVATE_KEYS | PFXExportFlags.REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException();; } return pbEncoded; } } case X509ContentType.SerializedStore: return SaveToMemoryStore(CertStoreSaveAs.CERT_STORE_SAVE_AS_STORE); case X509ContentType.Pkcs7: return SaveToMemoryStore(CertStoreSaveAs.CERT_STORE_SAVE_AS_PKCS7); default: throw new CryptographicException(SR.Cryptography_X509_InvalidContentType); } }