public SafeCertContextHandle Duplicate() { return(WindowsX509Native.CertDuplicateCertificateContext(this.DangerousGetHandle())); }
/// <summary> /// Unlike X509Store.Remove() this function also cleans up private-keys /// </summary> public static void RemoveCertificateFromStore(string thumbprint, StoreLocation storeLocation, string storeName) { var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.ReadWrite); var found = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false); if (found.Count == 0) { return; } var certificate = found[0]; var certificateHandle = new SafeCertContextHandle(found[0].Handle, false); // If the certificate has a private-key, remove it if (certificateHandle.HasPrivateKey()) { var keyProvInfo = certificateHandle.GetCertificateProperty <KeyProviderInfo>(CertificateProperty.KeyProviderInfo); // If it is a CNG key if (keyProvInfo.dwProvType == 0) { try { var key = CertificatePal.GetCngPrivateKey(certificateHandle); CertificatePal.DeleteCngKey(key); } catch (Exception ex) { throw new Exception("Exception while deleting CNG private key", ex); } } else // CAPI key { try { IntPtr providerHandle; var acquireContextFlags = CryptAcquireContextFlags.Delete | CryptAcquireContextFlags.Silent; if (storeLocation == StoreLocation.LocalMachine) { acquireContextFlags = acquireContextFlags | CryptAcquireContextFlags.MachineKeySet; } var success = Native.CryptAcquireContext(out providerHandle, keyProvInfo.pwszContainerName, keyProvInfo.pwszProvName, keyProvInfo.dwProvType, acquireContextFlags); if (!success) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } catch (Exception ex) { // Swallow keyset does not exist if (!(ex is CryptographicException && ex.Message.Contains("Keyset does not exist"))) { throw new Exception("Exception while deleting CAPI private key", ex); } } } } store.Remove(certificate); store.Close(); }
protected override bool ReleaseHandle() { return(WindowsX509Native.CertCloseStore(base.handle, 0)); }