예제 #1
0
        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);
        }
예제 #2
0
        public static bool HasCngKey(this X509Certificate certificate)
        {
            if (X509Native.HasCertificateProperty(certificate.Handle,
                                                  X509Native.CertificateProperty.KeyProviderInfo))
            {
                X509Native.CERT_KEY_PROV_INFO keyProvInfo =
                    X509Native.GetCertificateProperty <X509Native.CERT_KEY_PROV_INFO>(certificate.Handle, X509Native.CertificateProperty.KeyProviderInfo);

                return(keyProvInfo.dwProvType == 0);
            }
            else
            {
                return(false);
            }
        }
예제 #3
0
        public static CngKey GetCngPrivateKey(this X509Certificate2 certificate)
        {
            if (!certificate.HasPrivateKey || !certificate.HasCngKey())
            {
                return(null);
            }

            using (SafeNCryptKeyHandle privateKeyHandle = X509Native.AcquireCngPrivateKey(certificate.Handle))
            {
                // 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));
            }
        }
예제 #4
0
        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);
                }
            }
        }
예제 #5
0
        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);
        }