Inheritance: ICollection, IEnumerable
Beispiel #1
0
 internal static unsafe int BuildChain(IntPtr hChainEngine, System.Security.Cryptography.SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext)
 {
     if (pCertContext == null || pCertContext.IsInvalid)
         throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_InvalidContextHandle"), "pCertContext");
     SafeCertStoreHandle hAdditionalStore = SafeCertStoreHandle.InvalidHandle;
     if (extraStore != null && extraStore.Count > 0)
         hAdditionalStore = X509Utils.ExportToMemoryStore(extraStore);
     CAPI.CERT_CHAIN_PARA pChainPara = new CAPI.CERT_CHAIN_PARA();
     pChainPara.cbSize = (uint)Marshal.SizeOf((object)pChainPara);
     SafeLocalAllocHandle localAllocHandle1 = SafeLocalAllocHandle.InvalidHandle;
     if (applicationPolicy != null && applicationPolicy.Count > 0)
     {
         pChainPara.RequestedUsage.dwType = 0U;
         pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count;
         localAllocHandle1 = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy);
         pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = localAllocHandle1.DangerousGetHandle();
     }
     SafeLocalAllocHandle localAllocHandle2 = SafeLocalAllocHandle.InvalidHandle;
     if (certificatePolicy != null && certificatePolicy.Count > 0)
     {
         pChainPara.RequestedIssuancePolicy.dwType = 0U;
         pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count;
         localAllocHandle2 = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy);
         pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = localAllocHandle2.DangerousGetHandle();
     }
     pChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds;
     System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME();
     *(long*)&pTime = verificationTime.ToFileTime();
     uint dwFlags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag);
     if (!CAPI.CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext))
         return Marshal.GetHRForLastWin32Error();
     localAllocHandle1.Dispose();
     localAllocHandle2.Dispose();
     return 0;
 }
		//BUG [ExpectedException (typeof (ArgumentNullException))]
		public void AddNull () 
		{
			OidCollection oc = new OidCollection ();
			oc.Add (null);
			AssertEquals ("Count", 1, oc.Count);
			// AssertNull ("[0]", oc); throw NullReferenceException
		}
Beispiel #3
0
		//BUG [ExpectedException (typeof (ArgumentNullException))]
		public void AddNull () 
		{
			OidCollection oc = new OidCollection ();
			oc.Add (null);
			Assert.AreEqual (1, oc.Count, "Count");
			// Assert.IsNull (oc, "[0]"); throw NullReferenceException
		}
Beispiel #4
0
		public void CopyToOidNull ()
		{
			OidCollection oc = new OidCollection ();
			oc.Add (new Oid ("1.0"));
			Oid[] array = null;
			oc.CopyTo (array, 0);
		}
Beispiel #5
0
		private OidEnumerator GetEnumerator () 
		{
			OidCollection oc = new OidCollection ();
			oc.Add (new Oid ("1.0"));
			oc.Add (new Oid ("1.1"));
			oc.Add (new Oid ("1.2"));
			return oc.GetEnumerator ();
		}
Beispiel #6
0
		public void Add ()
		{
			OidCollection oc = new OidCollection ();
			oc.Add (new Oid ("1.0"));
			Assert.AreEqual (1, oc.Count, "Count");
			Assert.AreEqual ("1.0", oc [0].Value, "[0]");
			Assert.AreEqual ("1.0", oc ["1.0"].Value, "['1.0']");
		}
		public void Add ()
		{
			OidCollection oc = new OidCollection ();
			oc.Add (new Oid ("1.0"));
			AssertEquals ("Count", 1, oc.Count);
			AssertEquals ("[0]", "1.0", oc [0].Value);
			AssertEquals ("['1.0']", "1.0", oc ["1.0"].Value);
		}
Beispiel #8
0
		public void CopyToOid () 
		{
			OidCollection oc = new OidCollection ();
			oc.Add (new Oid ("1.0"));
			Oid[] array = new Oid [1];
			oc.CopyTo (array, 0);
			Assert.AreEqual ("1.0", array [0].Value, "CopyTo(Oid)");
		}
Beispiel #9
0
		public void Constructor () 
		{
			OidCollection oc = new OidCollection ();
			// default properties
			Assert.AreEqual (0, oc.Count, "Count");
			Assert.IsTrue (!oc.IsSynchronized, "IsSynchronized");
			Assert.IsNotNull (oc.SyncRoot, "SyncRoot");
			Assert.IsNotNull (oc.GetEnumerator (), "GetEnumerator");
		}
		public void Constructor () 
		{
			OidCollection oc = new OidCollection ();
			// default properties
			AssertEquals ("Count", 0, oc.Count);
			Assert ("IsSynchronized", !oc.IsSynchronized);
			AssertNotNull ("SyncRoot", oc.SyncRoot);
			AssertNotNull ("GetEnumerator", oc.GetEnumerator ());
		}
Beispiel #11
0
        public static IChainPal BuildChain(
            bool useMachineContext,
            ICertificatePal cert,
            X509Certificate2Collection extraStore,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            X509RevocationMode revocationMode,
            X509RevocationFlag revocationFlag,
            DateTime verificationTime,
            TimeSpan timeout)
        {
            // An input value of 0 on the timeout is "take all the time you need".
            if (timeout == TimeSpan.Zero)
            {
                timeout = TimeSpan.MaxValue;
            }

            // Let Unspecified mean Local, so only convert if the source was UTC.
            //
            // Converge on Local instead of UTC because OpenSSL is going to assume we gave it
            // local time.
            if (verificationTime.Kind == DateTimeKind.Utc)
            {
                verificationTime = verificationTime.ToLocalTime();
            }

            TimeSpan remainingDownloadTime = timeout;
            var leaf = new X509Certificate2(cert.Handle);
            var downloaded = new HashSet<X509Certificate2>();
            var systemTrusted = new HashSet<X509Certificate2>();

            HashSet<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates(
                leaf,
                extraStore,
                downloaded,
                systemTrusted,
                ref remainingDownloadTime);

            IChainPal chain = OpenSslX509ChainProcessor.BuildChain(
                leaf,
                candidates,
                downloaded,
                systemTrusted,
                applicationPolicy,
                certificatePolicy,
                revocationMode,
                revocationFlag,
                verificationTime,
                ref remainingDownloadTime);

            if (chain.ChainStatus.Length == 0 && downloaded.Count > 0)
            {
                SaveIntermediateCertificates(chain.ChainElements, downloaded);
            }

            return chain;
        }
        /// <summary>
        /// Does not throw on error. Returns null ChainPal instead.
        /// </summary>
        public static ChainPal BuildChain(
            bool useMachineContext,
            ICertificatePal cert,
            X509Certificate2Collection extraStore,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            X509RevocationMode revocationMode,
            X509RevocationFlag revocationFlag,
            DateTime verificationTime,
            TimeSpan timeout)
        {
            CertificatePal certificatePal = (CertificatePal)cert;

            unsafe
            {
                using (SafeCertStoreHandle extraStoreHandle = ConvertExtraStoreToSafeHandle(extraStore))
                {
                    CERT_CHAIN_PARA chainPara = new CERT_CHAIN_PARA();
                    chainPara.cbSize = Marshal.SizeOf<CERT_CHAIN_PARA>();

                    int applicationPolicyCount;
                    using (SafeHandle applicationPolicyOids = applicationPolicy.ToLpstrArray(out applicationPolicyCount))
                    {
                        if (!applicationPolicyOids.IsInvalid)
                        {
                            chainPara.RequestedUsage.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND;
                            chainPara.RequestedUsage.Usage.cUsageIdentifier = applicationPolicyCount;
                            chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyOids.DangerousGetHandle();
                        }

                        int certificatePolicyCount;
                        using (SafeHandle certificatePolicyOids = certificatePolicy.ToLpstrArray(out certificatePolicyCount))
                        {
                            if (!certificatePolicyOids.IsInvalid)
                            {
                                chainPara.RequestedIssuancePolicy.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND;
                                chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = certificatePolicyCount;
                                chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle();
                            }

                            chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds);

                            FILETIME ft = FILETIME.FromDateTime(verificationTime);
                            CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag);
                            ChainEngine chainEngine = useMachineContext ? ChainEngine.HCCE_LOCAL_MACHINE : ChainEngine.HCCE_CURRENT_USER;

                            SafeX509ChainHandle chain;
                            if (!Interop.crypt32.CertGetCertificateChain(chainEngine, certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain))
                                return null;
                            return new ChainPal(chain);
                        }
                    }
                }
            }
        }
 public void Reset()
 {
     this.m_applicationPolicy = new OidCollection();
     this.m_certificatePolicy = new OidCollection();
     this.m_revocationMode = X509RevocationMode.Online;
     this.m_revocationFlag = X509RevocationFlag.ExcludeRoot;
     this.m_verificationFlags = X509VerificationFlags.NoFlag;
     this.m_verificationTime = DateTime.Now;
     this.m_timeout = new TimeSpan(0, 0, 0);
     this.m_extraStore = new X509Certificate2Collection();
 }
Beispiel #14
0
        internal OidCollection ReadOnlyCopy()
        {
            OidCollection copy = new OidCollection();

            foreach (Oid oid in _list)
            {
                copy.Add(oid);
            }
            copy._readOnly = true;
            return(copy);
        }
        internal OidCollection ReadOnlyCopy()
        {
            OidCollection oidCollection = new OidCollection();

            foreach (object obj in this._list)
            {
                Oid oid = (Oid)obj;
                oidCollection.Add(oid);
            }
            oidCollection._readOnly = true;
            return(oidCollection);
        }
Beispiel #16
0
        internal bool MatchesCertificatePolicies(OidCollection policyOids)
        {
            foreach (Oid oid in policyOids)
            {
                if (!MatchesCertificatePolicies(oid))
                {
                    return false;
                }
            }

            return true;
        }
Beispiel #17
0
 public static IChainPal BuildChain(
     bool useMachineContext,
     ICertificatePal cert,
     X509Certificate2Collection extraStore,
     OidCollection applicationPolicy,
     OidCollection certificatePolicy,
     X509RevocationMode revocationMode,
     X509RevocationFlag revocationFlag,
     DateTime verificationTime,
     TimeSpan timeout)
 {
     return new OpenSslX509ChainProcessor();
 }
 private static unsafe void BuildChain(IntPtr hChainEngine, IntPtr pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, out System.IdentityModel.SafeCertChainHandle ppChainContext)
 {
     System.IdentityModel.SafeCertStoreHandle hAdditionalStore = ExportToMemoryStore(extraStore, pCertContext);
     System.IdentityModel.CAPI.CERT_CHAIN_PARA pChainPara = new System.IdentityModel.CAPI.CERT_CHAIN_PARA {
         cbSize = (uint) Marshal.SizeOf(typeof(System.IdentityModel.CAPI.CERT_CHAIN_PARA))
     };
     SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle;
     SafeHGlobalHandle handle3 = SafeHGlobalHandle.InvalidHandle;
     try
     {
         if ((applicationPolicy != null) && (applicationPolicy.Count > 0))
         {
             pChainPara.RequestedUsage.dwType = 0;
             pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint) applicationPolicy.Count;
             invalidHandle = CopyOidsToUnmanagedMemory(applicationPolicy);
             pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = invalidHandle.DangerousGetHandle();
         }
         if ((certificatePolicy != null) && (certificatePolicy.Count > 0))
         {
             pChainPara.RequestedIssuancePolicy.dwType = 0;
             pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint) certificatePolicy.Count;
             handle3 = CopyOidsToUnmanagedMemory(certificatePolicy);
             pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = handle3.DangerousGetHandle();
         }
         pChainPara.dwUrlRetrievalTimeout = (uint) timeout.Milliseconds;
         System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME();
         *((long*) &pTime) = verificationTime.ToFileTime();
         uint dwFlags = MapRevocationFlags(revocationMode, revocationFlag);
         if (!System.IdentityModel.CAPI.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext))
         {
             int hr = Marshal.GetLastWin32Error();
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(hr));
         }
     }
     finally
     {
         if (invalidHandle != null)
         {
             invalidHandle.Dispose();
         }
         if (handle3 != null)
         {
             handle3.Dispose();
         }
         hAdditionalStore.Close();
     }
 }
Beispiel #19
0
        public static X509Certificate2 CreateRsaCertificate(
            string dnsName, int validityPeriodInYears)
        {
            BasicConstraints basicConstraints = new BasicConstraints
            {
                CertificateAuthority    = false,
                HasPathLengthConstraint = false,
                PathLengthConstraint    = 0,
                Critical = false
            };

            SubjectAlternativeName subjectAlternativeName = new SubjectAlternativeName
            {
                DnsName = new List <string> {
                    dnsName
                }
            };

            X509KeyUsageFlags x509KeyUsageFlags = X509KeyUsageFlags.DigitalSignature;

            OidCollection enhancedKeyUsages = new System.Security.Cryptography.OidCollection
            {
                new Oid("1.3.6.1.5.5.7.3.1"),      // TLS Server auth
                new Oid("1.3.6.1.5.5.7.3.2"),      // TLS Client auth
            };


            X509Certificate2 certificate = _cc.NewRsaSelfSignedCertificate(
                new DistinguishedName {
                CommonName = dnsName
            },
                basicConstraints,
                new ValidityPeriod
            {
                ValidFrom = DateTimeOffset.UtcNow,
                ValidTo   = DateTimeOffset.UtcNow.AddYears(validityPeriodInYears)
            },
                subjectAlternativeName,
                enhancedKeyUsages,
                x509KeyUsageFlags,
                new RsaConfiguration {
                KeySize = 2048
            }
                );

            return(certificate);
        }
Beispiel #20
0
        public static IChainPal BuildChain(
            bool useMachineContext,
            ICertificatePal cert,
            X509Certificate2Collection extraStore,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            X509RevocationMode revocationMode,
            X509RevocationFlag revocationFlag,
            DateTime verificationTime,
            TimeSpan timeout)
        {
            CheckRevocationMode(revocationMode);

            // An input value of 0 on the timeout is "take all the time you need".
            if (timeout == TimeSpan.Zero)
            {
                timeout = TimeSpan.MaxValue;
            }

            TimeSpan remainingDownloadTime = timeout;
            X509Certificate2 leaf = new X509Certificate2(cert.Handle);
            List<X509Certificate2> downloaded = new List<X509Certificate2>();

            List<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates(
                leaf,
                extraStore,
                downloaded,
                ref remainingDownloadTime);

            IChainPal chain = OpenSslX509ChainProcessor.BuildChain(
                leaf,
                candidates,
                downloaded,
                applicationPolicy,
                certificatePolicy,
                verificationTime);

            if (chain.ChainStatus.Length == 0 && downloaded.Count > 0)
            {
                SaveIntermediateCertificates(chain.ChainElements, downloaded);
            }

            return chain;
        }
        /// <summary>
        /// Creates a new self-signed X509 certificate
        /// </summary>
        /// <param name="issuer">The certificate issuer</param>
        /// <param name="friendlyName">Human readable name</param>
        /// <param name="password">The certificate's password</param>
        /// <param name="startTime">Certificate creation date & time</param>
        /// <param name="endTime">Certificate expiry date & time</param>
        /// <returns>An X509Certificate2</returns>
        public static X509Certificate2 CreateSelfSignedCert(string issuer, string friendlyName, string password, DateTime startTime, DateTime endTime)
        {
            string distinguishedNameString = issuer;
            var key = Create2048RsaKey();

            var creationParams = new X509CertificateCreationParameters(new X500DistinguishedName(distinguishedNameString))
            {
                TakeOwnershipOfKey = true,
                StartTime = startTime,
                EndTime = endTime
            };

            // adding client authentication, -eku = 1.3.6.1.5.5.7.3.2, 
            // This is mandatory for the upload to be successful
            OidCollection oidCollection = new OidCollection();
            oidCollection.Add(new Oid(OIDClientAuthValue, OIDClientAuthFriendlyName));
            creationParams.Extensions.Add(new X509EnhancedKeyUsageExtension(oidCollection, false));

            // Documentation of CreateSelfSignedCertificate states:
            // If creationParameters have TakeOwnershipOfKey set to true, the certificate
            // generated will own the key and the input CngKey will be disposed to ensure
            // that the caller doesn't accidentally use it beyond its lifetime (which is
            // now controlled by the certificate object).
            // We don't dispose it ourselves in this case.
            var cert = key.CreateSelfSignedCertificate(creationParams);
            key = null;
            cert.FriendlyName = friendlyName;

            // X509 certificate needs PersistKeySet flag set.  
            // Reload a new X509Certificate2 instance from exported bytes in order to set the PersistKeySet flag.
            var bytes = cert.Export(X509ContentType.Pfx, password);

            // NOTE: PfxValidation is not done here because these are newly created certs and assumed valid.

            ICommonEventSource evtSource = null;
            return X509Certificate2Helper.NewX509Certificate2(bytes, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable, evtSource, doPfxValidation: false);
        }
Beispiel #22
0
        internal static unsafe int BuildChain (IntPtr hChainEngine,
                                               SafeCertContextHandle pCertContext,
                                               X509Certificate2Collection extraStore,
                                               OidCollection applicationPolicy,
                                               OidCollection certificatePolicy,
                                               X509RevocationMode revocationMode,
                                               X509RevocationFlag revocationFlag,
                                               DateTime verificationTime,
                                               TimeSpan timeout,
                                               ref SafeCertChainHandle ppChainContext) {
            if (pCertContext == null || pCertContext.IsInvalid)
                throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_InvalidContextHandle"), "pCertContext");

            SafeCertStoreHandle hCertStore = SafeCertStoreHandle.InvalidHandle;
            if (extraStore != null && extraStore.Count > 0)
                hCertStore = X509Utils.ExportToMemoryStore(extraStore);

            CAPI.CERT_CHAIN_PARA ChainPara = new CAPI.CERT_CHAIN_PARA();

            // Initialize the structure size.
            ChainPara.cbSize = (uint) Marshal.SizeOf(ChainPara);

            // Application policy
            SafeLocalAllocHandle applicationPolicyHandle = SafeLocalAllocHandle.InvalidHandle;
            if (applicationPolicy != null && applicationPolicy.Count > 0) {
                ChainPara.RequestedUsage.dwType = CAPI.USAGE_MATCH_TYPE_AND;
                ChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint) applicationPolicy.Count;
                applicationPolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy);
                ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyHandle.DangerousGetHandle();
            }

            // Certificate policy
            SafeLocalAllocHandle certificatePolicyHandle = SafeLocalAllocHandle.InvalidHandle;
            if (certificatePolicy != null && certificatePolicy.Count > 0) {
                ChainPara.RequestedIssuancePolicy.dwType = CAPI.USAGE_MATCH_TYPE_AND;
                ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint) certificatePolicy.Count;
                certificatePolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy);
                ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyHandle.DangerousGetHandle();
            }

            ChainPara.dwUrlRetrievalTimeout = (uint) timeout.Milliseconds;

            _FILETIME ft = new _FILETIME();
            *((long*) &ft) = verificationTime.ToFileTime();

            uint flags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag);

            // Build the chain.
            if (!CAPI.CAPISafe.CertGetCertificateChain(hChainEngine,
                                                       pCertContext,
                                                       ref ft,
                                                       hCertStore,
                                                       ref ChainPara,
                                                       flags,
                                                       IntPtr.Zero,
                                                       ref ppChainContext))
                return Marshal.GetHRForLastWin32Error();

            applicationPolicyHandle.Dispose();
            certificatePolicyHandle.Dispose();

            return CAPI.S_OK;
        }
 internal OidEnumerator(OidCollection collection)
 {
     this._collection = collection;
     this._position   = -1;
 }
Beispiel #24
0
 // note: couldn't reuse the IEnumerator from ArrayList because
 // it doesn't throw the same exceptions
 internal OidEnumerator(OidCollection collection)
 {
     _collection = collection;
     _position   = -1;
 }
        public void DecodeX509EnhancedKeyUsageExtension(byte[] encoded, out OidCollection usages)
        {
            OidCollection localUsages = new OidCollection();

            unsafe
            {
                encoded.DecodeObject(
                    CryptDecodeObjectStructType.X509_ENHANCED_KEY_USAGE,
                    delegate (void* pvDecoded)
                    {
                        CERT_ENHKEY_USAGE* pEnhKeyUsage = (CERT_ENHKEY_USAGE*)pvDecoded;
                        int count = pEnhKeyUsage->cUsageIdentifier;
                        for (int i = 0; i < count; i++)
                        {
                            IntPtr oidValuePointer = pEnhKeyUsage->rgpszUsageIdentifier[i];
                            string oidValue = Marshal.PtrToStringAnsi(oidValuePointer);
                            Oid oid = new Oid(oidValue);
                            localUsages.Add(oid);
                        }
                    }
                );
            }

            usages = localUsages;
        }
        public byte[] EncodeX509EnhancedKeyUsageExtension(OidCollection usages)
        {
            int numUsages;
            using (SafeHandle usagesSafeHandle = usages.ToLpstrArray(out numUsages))
            {
                unsafe
                {
                    CERT_ENHKEY_USAGE enhKeyUsage = new CERT_ENHKEY_USAGE()
                    {
                        cUsageIdentifier = numUsages,
                        rgpszUsageIdentifier = (IntPtr*)(usagesSafeHandle.DangerousGetHandle()),
                    };

                    return Interop.crypt32.EncodeObject(Oids.EnhancedKeyUsage, &enhKeyUsage);
                }
            }
        }
Beispiel #27
0
 internal OidEnumerator(OidCollection oids)
 {
     _oids    = oids;
     _current = -1;
 }
        public static IChainPal BuildChain(
            X509Certificate2 leaf,
            HashSet<X509Certificate2> candidates,
            HashSet<X509Certificate2> downloaded,
            HashSet<X509Certificate2> systemTrusted,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            X509RevocationMode revocationMode,
            X509RevocationFlag revocationFlag,
            DateTime verificationTime,
            ref TimeSpan remainingDownloadTime)
        {
            X509ChainElement[] elements;
            List<X509ChainStatus> overallStatus = new List<X509ChainStatus>();
            WorkingChain workingChain = new WorkingChain();
            Interop.Crypto.X509StoreVerifyCallback workingCallback = workingChain.VerifyCallback;

            // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to
            // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes.
            //
            // (If you need to think of it as an X509Store, it's a volatile memory store)
            using (SafeX509StoreHandle store = Interop.Crypto.X509StoreCreate())
            using (SafeX509StoreCtxHandle storeCtx = Interop.Crypto.X509StoreCtxCreate())
            {
                Interop.Crypto.CheckValidOpenSslHandle(store);
                Interop.Crypto.CheckValidOpenSslHandle(storeCtx);

                bool lookupCrl = revocationMode != X509RevocationMode.NoCheck;

                foreach (X509Certificate2 cert in candidates)
                {
                    OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal;

                    if (!Interop.Crypto.X509StoreAddCert(store, pal.SafeHandle))
                    {
                        throw Interop.Crypto.CreateOpenSslCryptographicException();
                    }

                    if (lookupCrl)
                    {
                        CrlCache.AddCrlForCertificate(
                            cert,
                            store,
                            revocationMode,
                            verificationTime,
                            ref remainingDownloadTime);

                        // If we only wanted the end-entity certificate CRL then don't look up
                        // any more of them.
                        lookupCrl = revocationFlag != X509RevocationFlag.EndCertificateOnly;
                    }
                }

                if (revocationMode != X509RevocationMode.NoCheck)
                {
                    if (!Interop.Crypto.X509StoreSetRevocationFlag(store, revocationFlag))
                    {
                        throw Interop.Crypto.CreateOpenSslCryptographicException();
                    }
                }

                SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle;

                if (!Interop.Crypto.X509StoreCtxInit(storeCtx, store, leafHandle))
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                Interop.Crypto.X509StoreCtxSetVerifyCallback(storeCtx, workingCallback);
                Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime);

                int verify = Interop.Crypto.X509VerifyCert(storeCtx);

                if (verify < 0)
                {
                    throw Interop.Crypto.CreateOpenSslCryptographicException();
                }

                // Because our callback tells OpenSSL that every problem is ignorable, it should tell us that the
                // chain is just fine (unless it returned a negative code for an exception)
                Debug.Assert(verify == 1, "verify == 1");

                using (SafeX509StackHandle chainStack = Interop.Crypto.X509StoreCtxGetChain(storeCtx))
                {
                    int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack);
                    elements = new X509ChainElement[chainSize];
                    int maybeRootDepth = chainSize - 1;

                    // The leaf cert is 0, up to (maybe) the root at chainSize - 1
                    for (int i = 0; i < chainSize; i++)
                    {
                        List<X509ChainStatus> status = new List<X509ChainStatus>();

                        List<Interop.Crypto.X509VerifyStatusCode> elementErrors =
                            i < workingChain.Errors.Count ? workingChain.Errors[i] : null;

                        if (elementErrors != null)
                        {
                            AddElementStatus(elementErrors, status, overallStatus);
                        }

                        IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i);

                        if (elementCertPtr == IntPtr.Zero)
                        {
                            throw Interop.Crypto.CreateOpenSslCryptographicException();
                        }

                        // Duplicate the certificate handle
                        X509Certificate2 elementCert = new X509Certificate2(elementCertPtr);

                        // If the last cert is self signed then it's the root cert, do any extra checks.
                        if (i == maybeRootDepth && IsSelfSigned(elementCert))
                        {
                            // If the root certificate was downloaded or the system
                            // doesn't trust it, it's untrusted.
                            if (downloaded.Contains(elementCert) ||
                                !systemTrusted.Contains(elementCert))
                            {
                                AddElementStatus(
                                    Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED,
                                    status,
                                    overallStatus);
                            }
                        }

                        elements[i] = new X509ChainElement(elementCert, status.ToArray(), "");
                    }
                }
            }

            GC.KeepAlive(workingCallback);

            if ((certificatePolicy != null && certificatePolicy.Count > 0) ||
                (applicationPolicy != null && applicationPolicy.Count > 0))
            {
                List<X509Certificate2> certsToRead = new List<X509Certificate2>();

                foreach (X509ChainElement element in elements)
                {
                    certsToRead.Add(element.Certificate);
                }

                CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead);

                bool failsPolicyChecks = false;

                if (certificatePolicy != null)
                {
                    if (!policyChain.MatchesCertificatePolicies(certificatePolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (applicationPolicy != null)
                {
                    if (!policyChain.MatchesApplicationPolicies(applicationPolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (failsPolicyChecks)
                {
                    X509ChainElement leafElement = elements[0];

                    X509ChainStatus chainStatus = new X509ChainStatus
                    {
                        Status = X509ChainStatusFlags.NotValidForUsage,
                        StatusInformation = SR.Chain_NoPolicyMatch,
                    };

                    var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1);
                    elementStatus.AddRange(leafElement.ChainElementStatus);

                    AddUniqueStatus(elementStatus, ref chainStatus);
                    AddUniqueStatus(overallStatus, ref chainStatus);

                    elements[0] = new X509ChainElement(
                        leafElement.Certificate,
                        elementStatus.ToArray(),
                        leafElement.Information);
                }
            }

            return new OpenSslX509ChainProcessor
            {
                ChainStatus = overallStatus.ToArray(),
                ChainElements = elements,
            };
        }
Beispiel #29
0
        internal static SafeLocalAllocHandle CopyOidsToUnmanagedMemory (OidCollection oids) {
            SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.InvalidHandle;
            if (oids == null || oids.Count == 0)
                return safeLocalAllocHandle;

            int ptrSize = oids.Count * Marshal.SizeOf(typeof(IntPtr));
            int oidSize = 0;
            foreach (Oid oid in oids) {
                oidSize += (oid.Value.Length + 1);
            }
            safeLocalAllocHandle = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr((uint) ptrSize + (uint) oidSize));
            IntPtr pOid = new IntPtr((long)safeLocalAllocHandle.DangerousGetHandle() + ptrSize);
            for (int index=0; index < oids.Count; index++) {
                Marshal.WriteIntPtr(new IntPtr((long) safeLocalAllocHandle.DangerousGetHandle() + index * Marshal.SizeOf(typeof(IntPtr))), pOid); 
                byte[] ansiOid = Encoding.ASCII.GetBytes(oids[index].Value);
                Marshal.Copy(ansiOid, 0, pOid, ansiOid.Length);
                pOid = new IntPtr((long) pOid + oids[index].Value.Length + 1);
            }
            return safeLocalAllocHandle;
        }
        private static unsafe byte[] EncodeExtension (OidCollection enhancedKeyUsages) {
            if (enhancedKeyUsages == null)
                throw new ArgumentNullException("enhancedKeyUsages");

            SafeLocalAllocHandle safeLocalAllocHandle = X509Utils.CopyOidsToUnmanagedMemory(enhancedKeyUsages);
            byte[] encodedEnhancedKeyUsages = null;
            using (safeLocalAllocHandle) {
                CAPI.CERT_ENHKEY_USAGE pEnhKeyUsage = new CAPI.CERT_ENHKEY_USAGE();
                pEnhKeyUsage.cUsageIdentifier = (uint) enhancedKeyUsages.Count;
                pEnhKeyUsage.rgpszUsageIdentifier = safeLocalAllocHandle.DangerousGetHandle();
                if (!CAPI.EncodeObject(CAPI.szOID_ENHANCED_KEY_USAGE, new IntPtr(&pEnhKeyUsage), out encodedEnhancedKeyUsages))
                    throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            return encodedEnhancedKeyUsages;
        }
        private void DecodeExtension () {
            uint cbDecoded = 0;
            SafeLocalAllocHandle decoded = null;

            bool result = CAPI.DecodeObject(new IntPtr(CAPI.X509_ENHANCED_KEY_USAGE),
                                            m_rawData,
                                            out decoded,
                                            out cbDecoded);
            if (result == false) 
                throw new CryptographicException(Marshal.GetLastWin32Error());

            CAPI.CERT_ENHKEY_USAGE pEnhKeyUsage = (CAPI.CERT_ENHKEY_USAGE) Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CERT_ENHKEY_USAGE));

            m_enhancedKeyUsages = new OidCollection();
            for (int index = 0; index < pEnhKeyUsage.cUsageIdentifier; index++) {
                IntPtr pszOid = Marshal.ReadIntPtr(new IntPtr((long) pEnhKeyUsage.rgpszUsageIdentifier + index * Marshal.SizeOf(typeof(IntPtr))));
                string oidValue = Marshal.PtrToStringAnsi(pszOid);
                Oid oid = new Oid(oidValue, OidGroup.ExtensionOrAttribute, false);
                m_enhancedKeyUsages.Add(oid);
            }

            m_decoded = true;
            decoded.Dispose();
        }
 public X509EnhancedKeyUsageExtension(OidCollection enhancedKeyUsages, bool critical) :
     base (CAPI.szOID_ENHANCED_KEY_USAGE, EncodeExtension(enhancedKeyUsages), critical) {}
        internal static SafeLocalAllocHandle CopyOidsToUnmanagedMemory (OidCollection oids) {
            SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.InvalidHandle;
            if (oids == null || oids.Count == 0)
                return safeLocalAllocHandle;

            // Copy the oid strings to a local list to prevent a security race condition where
            // the OidCollection or individual oids can be modified by another thread and
            // potentially cause a buffer overflow
            List<string> oidStrs = new List<string>();
            foreach (Oid oid in oids) {
                oidStrs.Add(oid.Value);
            }

            IntPtr pOid = IntPtr.Zero;
            // Needs to be checked to avoid having large sets of oids overflow the sizes and allow
            // a potential buffer overflow
            checked {
                int ptrSize = oidStrs.Count * Marshal.SizeOf(typeof(IntPtr));
                int oidSize = 0;
                foreach (string oidStr in oidStrs) {
                    oidSize += (oidStr.Length + 1);
                }
                safeLocalAllocHandle = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr((uint)ptrSize + (uint)oidSize));
                pOid = new IntPtr((long)safeLocalAllocHandle.DangerousGetHandle() + ptrSize);
            }
            for (int index = 0; index < oidStrs.Count; index++) {
                Marshal.WriteIntPtr(new IntPtr((long) safeLocalAllocHandle.DangerousGetHandle() + index * Marshal.SizeOf(typeof(IntPtr))), pOid);
                byte[] ansiOid = Encoding.ASCII.GetBytes(oidStrs[index]);
                Marshal.Copy(ansiOid, 0, pOid, ansiOid.Length);
                pOid = new IntPtr((long)pOid + oidStrs[index].Length + 1);
            }
            return safeLocalAllocHandle;
        }
        internal static unsafe int VerifyCertificate (Cryptography.SafeCertContextHandle pCertContext,
                                                      OidCollection applicationPolicy,
                                                      OidCollection certificatePolicy,
                                                      X509RevocationMode revocationMode,
                                                      X509RevocationFlag revocationFlag,
                                                      DateTime verificationTime,
                                                      TimeSpan timeout,
                                                      X509Certificate2Collection extraStore,
                                                      IntPtr pszPolicy,
                                                      IntPtr pdwErrorStatus) {
            if (pCertContext == null || pCertContext.IsInvalid)
                throw new ArgumentException("pCertContext");

            CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA)));
            CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS)));

            // Build the chain.
            SafeX509ChainHandle pChainContext = SafeX509ChainHandle.InvalidHandle;
            int hr = X509Chain.BuildChain(new IntPtr(CAPI.HCCE_CURRENT_USER),
                                          pCertContext, 
                                          extraStore,
                                          applicationPolicy, 
                                          certificatePolicy,
                                          revocationMode,
                                          revocationFlag,
                                          verificationTime,
                                          timeout,
                                          ref pChainContext);
            if (hr != CAPI.S_OK)
                return hr;

            // Verify the chain using the specified policy.
            if (CAPI.CertVerifyCertificateChainPolicy(pszPolicy, pChainContext, ref PolicyPara, ref PolicyStatus)) {
                if (pdwErrorStatus != IntPtr.Zero)
                    *(uint*) pdwErrorStatus = PolicyStatus.dwError;

                if (PolicyStatus.dwError != 0)
                    return CAPI.S_FALSE;
            } else {
                // The API failed.
                return Marshal.GetHRForLastWin32Error();
            }

            return CAPI.S_OK;
        }
 public X509EnhancedKeyUsageExtension() : base (CAPI.szOID_ENHANCED_KEY_USAGE) {
     m_enhancedKeyUsages = new OidCollection();
     m_decoded = true;
 }
        public static IChainPal BuildChain(
            X509Certificate2 leaf,
            X509Certificate2Collection candidates,
            OidCollection applicationPolicy,
            OidCollection certificatePolicy,
            DateTime verificationTime)
        {
            X509ChainElement[] elements;
            List<X509ChainStatus> overallStatus = new List<X509ChainStatus>();

            // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to
            // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes.
            //
            // (If you need to think of it as an X509Store, it's a volatile memory store)
            using (SafeX509StoreHandle store = Interop.libcrypto.X509_STORE_new())
            using (SafeX509StoreCtxHandle storeCtx = Interop.libcrypto.X509_STORE_CTX_new())
            {
                Interop.libcrypto.CheckValidOpenSslHandle(store);
                Interop.libcrypto.CheckValidOpenSslHandle(storeCtx);

                foreach (X509Certificate2 cert in candidates)
                {
                    OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal;

                    if (!Interop.libcrypto.X509_STORE_add_cert(store, pal.SafeHandle))
                    {
                        throw Interop.libcrypto.CreateOpenSslCryptographicException();
                    }
                }

                // When CRL checking support is added, it should be done before the call to
                // X509_STORE_CTX_init (aka here) by calling X509_STORE_set_flags(store, flags);

                SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle;

                if (!Interop.libcrypto.X509_STORE_CTX_init(storeCtx, store, leafHandle, IntPtr.Zero))
                {
                    throw Interop.libcrypto.CreateOpenSslCryptographicException();
                }

                Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime);

                int verify = Interop.libcrypto.X509_verify_cert(storeCtx);

                if (verify < 0)
                {
                    throw Interop.libcrypto.CreateOpenSslCryptographicException();
                }

                using (SafeX509StackHandle chainStack = Interop.libcrypto.X509_STORE_CTX_get1_chain(storeCtx))
                {
                    int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack);
                    int errorDepth = -1;
                    Interop.libcrypto.X509VerifyStatusCode errorCode = 0;
                    string errorMsg = null;

                    if (verify == 0)
                    {
                        errorCode = Interop.libcrypto.X509_STORE_CTX_get_error(storeCtx);
                        errorDepth = Interop.libcrypto.X509_STORE_CTX_get_error_depth(storeCtx);
                        errorMsg = Interop.libcrypto.X509_verify_cert_error_string(errorCode);
                    }

                    elements = new X509ChainElement[chainSize];

                    for (int i = 0; i < chainSize; i++)
                    {
                        List<X509ChainStatus> status = new List<X509ChainStatus>();

                        if (i == errorDepth)
                        {
                            X509ChainStatus chainStatus = new X509ChainStatus
                            {
                                Status = MapVerifyErrorToChainStatus(errorCode),
                                StatusInformation = errorMsg,
                            };

                            status.Add(chainStatus);
                            AddUniqueStatus(overallStatus, ref chainStatus);
                        }

                        IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i);

                        if (elementCertPtr == IntPtr.Zero)
                        {
                            throw Interop.libcrypto.CreateOpenSslCryptographicException();
                        }

                        // Duplicate the certificate handle
                        X509Certificate2 elementCert = new X509Certificate2(elementCertPtr);

                        elements[i] = new X509ChainElement(elementCert, status.ToArray(), "");
                    }
                }
            }

            if ((certificatePolicy != null && certificatePolicy.Count > 0) ||
                (applicationPolicy != null && applicationPolicy.Count > 0))
            {
                X509Certificate2Collection certsToRead = new X509Certificate2Collection();

                foreach (X509ChainElement element in elements)
                {
                    certsToRead.Add(element.Certificate);
                }

                CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead);

                bool failsPolicyChecks = false;

                if (certificatePolicy != null)
                {
                    if (!policyChain.MatchesCertificatePolicies(certificatePolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (applicationPolicy != null)
                {
                    if (!policyChain.MatchesApplicationPolicies(applicationPolicy))
                    {
                        failsPolicyChecks = true;
                    }
                }

                if (failsPolicyChecks)
                {
                    X509ChainElement leafElement = elements[0];

                    X509ChainStatus chainStatus = new X509ChainStatus
                    {
                        Status = X509ChainStatusFlags.InvalidPolicyConstraints,
                        StatusInformation = SR.Chain_NoPolicyMatch,
                    };

                    var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1);
                    elementStatus.AddRange(leafElement.ChainElementStatus);

                    AddUniqueStatus(elementStatus, ref chainStatus);
                    AddUniqueStatus(overallStatus, ref chainStatus);

                    elements[0] = new X509ChainElement(
                        leafElement.Certificate,
                        elementStatus.ToArray(),
                        leafElement.Information);
                }
            }

            return new OpenSslX509ChainProcessor
            {
                ChainStatus = overallStatus.ToArray(),
                ChainElements = elements,
            };
        }
Beispiel #37
0
 internal OidEnumerator(OidCollection oids)
 {
     this.m_oids    = oids;
     this.m_current = -1;
 }