[System.Security.SecurityCritical] // auto-generated private byte[] ExportHelper(X509ContentType contentType, object password) { switch (contentType) { case X509ContentType.Cert: break; #if FEATURE_CORECLR case (X509ContentType)0x02 /* X509ContentType.SerializedCert */: case (X509ContentType)0x03 /* X509ContentType.Pkcs12 */: throw new CryptographicException(Environment.GetResourceString("Cryptography_X509_InvalidContentType"), new NotSupportedException()); #else // FEATURE_CORECLR case X509ContentType.SerializedCert: break; #if !FEATURE_PAL case X509ContentType.Pkcs12: KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Export); kp.Demand(); break; #endif // !FEATURE_PAL #endif // FEATURE_CORECLR else default: throw new CryptographicException(Environment.GetResourceString("Cryptography_X509_InvalidContentType")); } #if !FEATURE_CORECLR IntPtr szPassword = IntPtr.Zero; byte[] encodedRawData = null; SafeCertStoreHandle safeCertStoreHandle = X509Utils.ExportCertToMemoryStore(this); RuntimeHelpers.PrepareConstrainedRegions(); try { szPassword = X509Utils.PasswordToHGlobalUni(password); encodedRawData = X509Utils._ExportCertificatesToBlob(safeCertStoreHandle, contentType, szPassword); } finally { if (szPassword != IntPtr.Zero) { Marshal.ZeroFreeGlobalAllocUnicode(szPassword); } safeCertStoreHandle.Dispose(); } if (encodedRawData == null) { throw new CryptographicException(Environment.GetResourceString("Cryptography_X509_ExportFailed")); } return(encodedRawData); #else // !FEATURE_CORECLR return(RawData); #endif // !FEATURE_CORECLR }
public void Open(OpenFlags flags) { if (m_location != StoreLocation.CurrentUser && m_location != StoreLocation.LocalMachine) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Arg_EnumIllegalVal), "m_location")); } uint storeFlags = X509Utils.MapX509StoreFlags(m_location, flags); if (!m_safeCertStoreHandle.IsInvalid) { // Free the current store handle m_safeCertStoreHandle.Dispose(); } m_safeCertStoreHandle = CAPI.CertOpenStore(new IntPtr(CAPI.CERT_STORE_PROV_SYSTEM), CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, IntPtr.Zero, storeFlags, m_storeName); if (m_safeCertStoreHandle == null || m_safeCertStoreHandle.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } // // We want the store to auto-resync when requesting a snapshot so that // updates to the store will be taken into account. // CAPI.CertControlStore(m_safeCertStoreHandle, 0, CAPI.CERT_STORE_CTRL_AUTO_RESYNC, IntPtr.Zero); }
/// <summary> /// Note: this factory method creates the store using links to the original certificates rather than copies. This means that any changes to certificate properties /// in the store changes the original. /// </summary> internal static partial IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) { // we always want to use CERT_STORE_ENUM_ARCHIVED_FLAG since we want to preserve the collection in this operation. // By default, Archived certificates will not be included. SafeCertStoreHandle certStore = Interop.crypt32.CertOpenStore( CertStoreProvider.CERT_STORE_PROV_MEMORY, Interop.Crypt32.CertEncodingType.All, IntPtr.Zero, Interop.Crypt32.CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | Interop.Crypt32.CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG, null); try { if (certStore.IsInvalid) { throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); } // // We use CertAddCertificateLinkToStore to keep a link to the original store, so any property changes get // applied to the original store. This has a limit of 99 links per cert context however. // for (int i = 0; i < certificates.Count; i++) { using (SafeCertContextHandle certContext = ((CertificatePal)certificates[i].Pal !).GetCertContext()) { if (!Interop.Crypt32.CertAddCertificateLinkToStore(certStore, certContext, Interop.Crypt32.CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero)) { throw Marshal.GetLastPInvokeError().ToCryptographicException(); } } } return(new StorePal(certStore)); } catch { certStore.Dispose(); throw; } }
internal static partial IStorePal FromHandle(IntPtr storeHandle) { if (storeHandle == IntPtr.Zero) { throw new ArgumentNullException(nameof(storeHandle)); } SafeCertStoreHandle certStoreHandle = Interop.Crypt32.CertDuplicateStore(storeHandle); if (certStoreHandle == null || certStoreHandle.IsInvalid) { certStoreHandle?.Dispose(); throw new CryptographicException(SR.Cryptography_InvalidStoreHandle, nameof(storeHandle)); } var pal = new StorePal(certStoreHandle); return(pal); }
private byte[] ExportHelper(X509ContentType contentType, object password) { switch (contentType) { case X509ContentType.Cert: case X509ContentType.SerializedCert: break; case X509ContentType.Pfx: new KeyContainerPermission(KeyContainerPermissionFlags.Export | KeyContainerPermissionFlags.Open).Demand(); break; default: throw new CryptographicException(Environment.GetResourceString("Cryptography_X509_InvalidContentType")); } IntPtr zero = IntPtr.Zero; byte[] buffer = null; SafeCertStoreHandle safeCertStoreHandle = X509Utils.ExportCertToMemoryStore(this); RuntimeHelpers.PrepareConstrainedRegions(); try { zero = X509Utils.PasswordToHGlobalUni(password); buffer = X509Utils._ExportCertificatesToBlob(safeCertStoreHandle, contentType, zero); } finally { if (zero != IntPtr.Zero) { Marshal.ZeroFreeGlobalAllocUnicode(zero); } safeCertStoreHandle.Dispose(); } if (buffer == null) { throw new CryptographicException(Environment.GetResourceString("Cryptography_X509_ExportFailed")); } return(buffer); }
internal static partial IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) { Interop.Crypt32.CertStoreFlags certStoreFlags = MapX509StoreFlags(storeLocation, openFlags); SafeCertStoreHandle certStore = Interop.crypt32.CertOpenStore(CertStoreProvider.CERT_STORE_PROV_SYSTEM_W, Interop.Crypt32.CertEncodingType.All, IntPtr.Zero, certStoreFlags, storeName); if (certStore.IsInvalid) { Exception e = Marshal.GetLastWin32Error().ToCryptographicException(); certStore.Dispose(); throw e; } // // We want the store to auto-resync when requesting a snapshot so that // updates to the store will be taken into account. // // For compat with desktop, ignoring any failures from this call. (It is pretty unlikely to fail, in any case.) // _ = Interop.Crypt32.CertControlStore(certStore, Interop.Crypt32.CertControlStoreFlags.None, Interop.Crypt32.CertControlStoreType.CERT_STORE_CTRL_AUTO_RESYNC, IntPtr.Zero); return new StorePal(certStore); }
private byte[] ExportHelper(X509ContentType contentType, object password) { switch (contentType) { case X509ContentType.Cert: case X509ContentType.SerializedCert: IntPtr num = IntPtr.Zero; byte[] numArray = (byte[])null; SafeCertStoreHandle memoryStore = X509Utils.ExportCertToMemoryStore(this); RuntimeHelpers.PrepareConstrainedRegions(); try { num = X509Utils.PasswordToHGlobalUni(password); numArray = X509Utils._ExportCertificatesToBlob(memoryStore, contentType, num); } finally { if (num != IntPtr.Zero) { Marshal.ZeroFreeGlobalAllocUnicode(num); } memoryStore.Dispose(); } if (numArray == null) { throw new CryptographicException(Environment.GetResourceString("Cryptography_X509_ExportFailed")); } return(numArray); case X509ContentType.Pfx: new KeyContainerPermission(KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Export).Demand(); goto case X509ContentType.Cert; default: throw new CryptographicException(Environment.GetResourceString("Cryptography_X509_InvalidContentType")); } }
internal static partial IExportPal FromCertificate(ICertificatePalCore cert) { CertificatePal certificatePal = (CertificatePal)cert; SafeCertStoreHandle certStore = Interop.crypt32.CertOpenStore( CertStoreProvider.CERT_STORE_PROV_MEMORY, Interop.Crypt32.CertEncodingType.All, IntPtr.Zero, Interop.Crypt32.CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | Interop.Crypt32.CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG | Interop.Crypt32.CertStoreFlags.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, null); using (SafeCertContextHandle certContext = certificatePal.GetCertContext()) { if (certStore.IsInvalid || !Interop.Crypt32.CertAddCertificateLinkToStore(certStore, certContext, Interop.Crypt32.CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero)) { Exception e = Marshal.GetHRForLastWin32Error().ToCryptographicException(); certStore.Dispose(); throw e; } } return(new StorePal(certStore)); }
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?.Dispose(); pCertContext = GetSignerInPKCS7Store(hCertStore, hCryptMsg); } else if (contentType == Interop.Crypt32.ContentType.CERT_QUERY_CONTENT_PFX) { if (loadFromFile) { rawData = File.ReadAllBytes(fileName !); } pCertContext?.Dispose(); 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 { hCertStore?.Dispose(); hCryptMsg?.Dispose(); pCertContext?.Dispose(); } }
private static unsafe SafeCertStoreHandle SelectFromStore(SafeCertStoreHandle safeSourceStoreHandle, string?title, string?message, X509SelectionFlag selectionFlags, IntPtr hwndParent) { int dwErrorCode = ERROR_SUCCESS; SafeCertStoreHandle safeCertStoreHandle = Interop.Crypt32.CertOpenStore( (IntPtr)Interop.Crypt32.CERT_STORE_PROV_MEMORY, Interop.Crypt32.X509_ASN_ENCODING | Interop.Crypt32.PKCS_7_ASN_ENCODING, IntPtr.Zero, 0, IntPtr.Zero); if (safeCertStoreHandle == null || safeCertStoreHandle.IsInvalid) { Exception e = new CryptographicException(Marshal.GetLastWin32Error()); safeCertStoreHandle?.Dispose(); throw e; } Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW csc = default; // Older versions of CRYPTUI do not check the size correctly, // so always force it to the oldest version of the structure. #if NET7_0_OR_GREATER // Declare a local for Native to enable us to get the managed byte offset // without having a null check cause a failure. Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW.Marshaller.Native native; Unsafe.SkipInit(out native); csc.dwSize = (uint)Unsafe.ByteOffset(ref Unsafe.As <Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW.Marshaller.Native, byte>(ref native), ref Unsafe.As <IntPtr, byte>(ref native.hSelectedCertStore)); #else csc.dwSize = (uint)Marshal.OffsetOf(typeof(Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW), "hSelectedCertStore"); #endif csc.hwndParent = hwndParent; csc.dwFlags = (uint)selectionFlags; csc.szTitle = title; csc.dwDontUseColumn = 0; csc.szDisplayString = message; csc.pFilterCallback = IntPtr.Zero; csc.pDisplayCallback = IntPtr.Zero; csc.pvCallbackData = IntPtr.Zero; csc.cDisplayStores = 1; IntPtr hSourceCertStore = safeSourceStoreHandle.DangerousGetHandle(); csc.rghDisplayStores = new IntPtr(&hSourceCertStore); csc.cStores = 0; csc.rghStores = IntPtr.Zero; csc.cPropSheetPages = 0; csc.rgPropSheetPages = IntPtr.Zero; csc.hSelectedCertStore = safeCertStoreHandle.DangerousGetHandle(); SafeCertContextHandle safeCertContextHandle = Interop.CryptUI.CryptUIDlgSelectCertificateW(ref csc); if (safeCertContextHandle != null && !safeCertContextHandle.IsInvalid) { // Single select, so add it to our hCertStore SafeCertContextHandle ppStoreContext = SafeCertContextHandle.InvalidHandle; if (!Interop.Crypt32.CertAddCertificateLinkToStore(safeCertStoreHandle, safeCertContextHandle, Interop.Crypt32.CERT_STORE_ADD_ALWAYS, ppStoreContext)) { dwErrorCode = Marshal.GetLastWin32Error(); } } if (dwErrorCode != ERROR_SUCCESS) { safeCertContextHandle?.Dispose(); throw new CryptographicException(dwErrorCode); } return(safeCertStoreHandle); }