public static SafeCertContextHandle GetCertificateContext(this X509Certificate certificate) { SafeCertContextHandle certContext = X509Native.DuplicateCertContext(certificate.Handle); // Make sure to keep the X509Certificate object alive until after its certificate context is // duplicated, otherwise it could end up being closed out from underneath us before we get a // chance to duplicate the handle. GC.KeepAlive(certificate); return(certContext); }
public static CngKey GetCngPrivateKey(this X509Certificate2 certificate) { if (!certificate.HasPrivateKey || !certificate.HasCngKey()) { return(null); } using (SafeCertContextHandle certContext = certificate.GetCertificateContext()) using (SafeNCryptKeyHandle privateKeyHandle = X509Native.AcquireCngPrivateKey(certContext)) { // We need to assert for full trust when opening the CNG key because // CngKey.Open(SafeNCryptKeyHandle) does a full demand for full trust, and we want to allow // access to a certificate's private key by anyone who has access to the certificate itself. new PermissionSet(PermissionState.Unrestricted).Assert(); return(CngKey.Open(privateKeyHandle, CngKeyHandleOpenOptions.None)); } }
public static bool HasCngKey(this X509Certificate certificate) { using (SafeCertContextHandle certContext = certificate.GetCertificateContext()) { if (X509Native.HasCertificateProperty(certContext, X509Native.CertificateProperty.KeyProviderInfo)) { X509Native.CRYPT_KEY_PROV_INFO keyProvInfo = X509Native.GetCertificateProperty <X509Native.CRYPT_KEY_PROV_INFO>(certContext, X509Native.CertificateProperty.KeyProviderInfo); return(keyProvInfo.dwProvType == 0); } else { return(false); } } }
public static IList <X509AlternateName> GetAlternateNames(this X509Certificate certificate, Oid2 alternateNameExtensionOid) { if (alternateNameExtensionOid == null) { throw new ArgumentNullException("alternateNameExtensionOid"); } List <X509AlternateName> alternateNames = new List <X509AlternateName>(); using (SafeCertContextHandle certContext = certificate.GetCertificateContext()) { // Make sure we have the extension requested if (X509Native.HasExtension(certContext, alternateNameExtensionOid.Value)) { // If so, get it from the certificate, and decode it into a buffer X509Native.CERT_EXTENSION alternateNameExtension = X509Native.FindExtension(certContext, alternateNameExtensionOid.Value); using (SafeLocalAllocHandle decodedBuffer = X509Native.DecodeExtension(alternateNameExtension)) { // This buffer contains CERT_ALT_NAME_INFO which points us at the alternate names we // were looking for X509Native.CERT_ALT_NAME_INFO altNameInfo = decodedBuffer.Read <X509Native.CERT_ALT_NAME_INFO>(0); for (int i = 0; i < altNameInfo.cAltEntry; ++i) { unsafe { X509Native.CERT_ALT_NAME_ENTRY *pAltNameEntry = (X509Native.CERT_ALT_NAME_ENTRY *)altNameInfo.rgAltEntry; alternateNames.Add(X509AlternateName.FromAltNameEntry(pAltNameEntry[i])); } } } } } return(alternateNames); }