Reset() public method

public Reset ( ) : void
return void
Beispiel #1
0
        /// <summary>
        /// Find the issuer certificate.
        /// First checks if the leaf certificate's Subject and Issuer fields are not the same.
        /// Otherwise, the certificate is the issuer (self-signed certificate)
        /// If different it instatniates a X509Chain object and passes leaf certificate to X509Chain.Build method.Examine ChainElements property (a collection) and element at index 1 is the issuer.
        /// </summary>
        /// <param name="leafCert"></param>
        /// <returns></returns>
        public static X509Certificate2 GetIssuer(X509Certificate2 leafCert)
        {
            if (leafCert.Subject == leafCert.Issuer)
            {
                return(leafCert);
            }
            var chain = new X509Chain();

            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            chain.Build(leafCert);
            X509Certificate2 issuer = null;

            if (chain.ChainElements.Count > 1)
            {
                issuer = chain.ChainElements[1].Certificate;
            }
            chain.Reset();
            return(issuer);
        }
Beispiel #2
0
		public void Reset ()
		{
			X509Chain c = new X509Chain ();
			c.ChainPolicy.ApplicationPolicy.Add (new Oid ("1.2.3"));
			c.ChainPolicy.CertificatePolicy.Add (new Oid ("1.2.4"));
			c.ChainPolicy.ExtraStore.AddRange (collection);
			c.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
			c.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
			c.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (1000);
			c.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreWrongUsage;
			c.ChainPolicy.VerificationTime = DateTime.MinValue;
			c.Reset ();
			// resetting the chain doesn't reset the policy
			Assert.AreEqual (1, c.ChainPolicy.ApplicationPolicy.Count, "ApplicationPolicy");
			Assert.AreEqual (1, c.ChainPolicy.CertificatePolicy.Count, "CertificatePolicy");
			Assert.AreEqual (2, c.ChainPolicy.ExtraStore.Count, "ExtraStore");
			Assert.AreEqual (X509RevocationFlag.EntireChain, c.ChainPolicy.RevocationFlag, "RevocationFlag");
			Assert.AreEqual (X509RevocationMode.Offline, c.ChainPolicy.RevocationMode, "RevocationMode");
			Assert.AreEqual (1000, c.ChainPolicy.UrlRetrievalTimeout.Ticks, "UrlRetrievalTimeout");
			Assert.AreEqual (X509VerificationFlags.IgnoreWrongUsage, c.ChainPolicy.VerificationFlags, "VerificationFlags");
			Assert.AreEqual (DateTime.MinValue, c.ChainPolicy.VerificationTime, "VerificationTime");
		}
Beispiel #3
0
		public void Build_Cert2 ()
		{
			X509Chain c = new X509Chain ();
			foreach (X509VerificationFlags vf in Enum.GetValues (typeof (X509VerificationFlags))) {
				c.ChainPolicy.VerificationFlags = vf;
				CheckCert2 (c);
				c.Reset ();
			}
			// minimal criteria for success
			c.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid | X509VerificationFlags.AllowUnknownCertificateAuthority;
			CheckCert2 (c);
		}
Beispiel #4
0
		public void Build_Cert1_X509RevocationMode_NoCheck ()
		{
			X509Chain c = new X509Chain ();
			c.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
			foreach (X509VerificationFlags vf in Enum.GetValues (typeof (X509VerificationFlags))) {
				c.ChainPolicy.VerificationFlags = vf;
				CheckCert1 (c);
				c.Reset ();
			}
		}
Beispiel #5
0
		public void Build_Twice_WithReset ()
		{
			X509Chain c = new X509Chain ();
			Assert.IsFalse (c.Build (cert1), "Build-1");
			c.Reset ();
			Assert.IsFalse (c.Build (cert2), "Build-2");
			c.Reset ();
			CheckDefaultChain (c);
		}
Beispiel #6
0
        private bool AcquireClientCredentials(ref byte[] thumbPrint)
        {
            GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials");

            //
            // Acquire possible Client Certificate information and set it on the handle
            //

            X509Certificate clientCertificate = null;   // This is a candidate that can come from the user callback or be guessed when targeting a session restart
            ArrayList filteredCerts = new ArrayList();  // This is an intermediate client certs collection that try to use if no selectedCert is available yet.
            string[] issuers = null;                    // This is a list of issuers sent by the server, only valid is we do know what the server cert is.

            bool sessionRestartAttempt = false; // if true and no cached creds we will use anonymous creds.

            if (m_CertSelectionDelegate!=null)
            {
                if (issuers == null)
                    issuers = GetIssuers();

                GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials() calling CertificateSelectionCallback");
                
                X509Certificate2 remoteCert = null;
                try {
                    X509Certificate2Collection dummyCollection;
                    remoteCert = GetRemoteCertificate(out dummyCollection);
                    clientCertificate = m_CertSelectionDelegate(m_HostName, ClientCertificates, remoteCert, issuers);
                }
                finally {
                    if (remoteCert != null)
                        remoteCert.Reset();
                }


                if (clientCertificate != null)
                {
                    if (m_CredentialsHandle == null)
                        sessionRestartAttempt = true;
                    filteredCerts.Add(clientCertificate);
                    if (Logging.On) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_got_certificate_from_delegate));
                }
                else 
                {
                    // If ClientCertificates.Count != 0, how come we don't try to go through them and add them to the filtered certs, just like when there is no delegate????
                    if (ClientCertificates.Count == 0)
                    {
                        if (Logging.On) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_no_delegate_and_have_no_client_cert));
                        sessionRestartAttempt = true;
                    }
                    else
                    {
                        if (Logging.On) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_no_delegate_but_have_client_cert));
                    }
                }

            }
            else if (m_CredentialsHandle == null && m_ClientCertificates != null && m_ClientCertificates.Count > 0)
            {
                // This is where we attempt to restart a session by picking the FIRST cert from the collection.
                // Otheriwse (next elses) it is either server sending a client cert request or the session is renegotiated.
                clientCertificate = ClientCertificates[0];
                sessionRestartAttempt = true;
                if (clientCertificate!=null)
                    filteredCerts.Add(clientCertificate);
                if (Logging.On) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_attempting_restart_using_cert, (clientCertificate == null ? "null" : clientCertificate.ToString(true))));
            }
            else if (m_ClientCertificates!=null && m_ClientCertificates.Count > 0)
            {
                //
                // This should be a server request for the client cert sent over currently anonyumous sessions.
                //
                if (issuers == null)
                    issuers = GetIssuers();


                if (Logging.On) 
                {
                    if (issuers == null || issuers.Length == 0)
                        Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_no_issuers_try_all_certs));
                    else
                        Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_server_issuers_look_for_matching_certs, issuers.Length));
                }

                for (int i = 0; i < m_ClientCertificates.Count; ++i)
                {
                    //
                    // make sure we add only if the cert matches one of the issuers
                    // If no issuers were sent and then try all client certs starting with the first one.
                    //
                    if (issuers != null && issuers.Length != 0)
                    {
                        X509Certificate2 certificateEx = null;
                        X509Chain chain = null;
                        try {
                            certificateEx = MakeEx(m_ClientCertificates[i]);
                            if (certificateEx == null)
                                continue;

                            GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials() root cert:" + certificateEx.Issuer);
                            chain = new X509Chain();

                            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreInvalidName;
                            chain.Build(certificateEx);
                            bool found = false;

                            //
                            // We ignore any errors happened with chain.
                            // Consider: try to locate the "best" client cert that has no errors and the lognest validity internal
                            //
                            if (chain.ChainElements.Count > 0)
                            {
                                for (int ii=0; ii< chain.ChainElements.Count; ++ii)
                                {
                                    string issuer = chain.ChainElements[ii].Certificate.Issuer;
                                    found = Array.IndexOf(issuers, issuer)!=-1;
                                    if (found) {
                                        GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials() matched:" + issuer);
                                        break;
                                    }
                                    GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials() no match:" + issuer);
                                }
                            }
                            if (!found) {
                                continue;
                            }
                        }
                        finally {
                            if (chain != null)
                                chain.Reset();

                            if (certificateEx != null && (object)certificateEx != (object)m_ClientCertificates[i])
                                certificateEx.Reset();
                        }
                    }
                    if (Logging.On) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_selected_cert, m_ClientCertificates[i].ToString(true)));
                    filteredCerts.Add(m_ClientCertificates[i]);
                }
            }

            bool cachedCred = false;                    // This is a return result from this method
            X509Certificate2 selectedCert = null;      // This is a final selected cert (ensured that it does have private key with it)

            clientCertificate = null;

            if (Logging.On) {
                Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_n_certs_after_filtering, filteredCerts.Count));
                if (filteredCerts.Count != 0) 
                    Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_finding_matching_certs));
            }

            //
            // ATTN: When the client cert was returned by the user callback OR it was guessed AND it has no private key.
            //       THEN anonymous (no client cert) credential will be used
            //
            // SECURITY: Accessing X509 cert Credential is disabled for semitrust
            // We no longer need to demand for unmanaged code permissions.
            // EnsurePrivateKey should do the right demand for us.
            for (int i=0; i < filteredCerts.Count; ++i)
            {
                clientCertificate = filteredCerts[i] as X509Certificate;
                if ((selectedCert = EnsurePrivateKey(clientCertificate)) != null)
                    break;
                clientCertificate = null;
                selectedCert = null;
            }

            GlobalLog.Assert(((object) clientCertificate == (object) selectedCert) || clientCertificate.Equals(selectedCert), "AcquireClientCredentials()|'selectedCert' does not match 'clientCertificate'.");

            GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials() Selected Cert = " + (selectedCert == null? "null": selectedCert.Subject));
            try {
                // Try to locate cached creds first.
                //
                // SECURITY: selectedCert ref if not null is a safe object that does not depend on possible **user** inherited X509Certificate type.
                //
                byte[] guessedThumbPrint = selectedCert == null? null: selectedCert.GetCertHash();
                SafeFreeCredentials cachedCredentialHandle = SslSessionsCache.TryCachedCredential(guessedThumbPrint, m_ProtocolFlags, m_EncryptionPolicy);

                // We can probably do some optimization here. If the selectedCert is returned by the delegate
                // we can always go ahead and use the certificate to create our credential
                // (Instead of going anonymous as we do here)
                if (sessionRestartAttempt && cachedCredentialHandle == null && selectedCert != null)
                {
                    GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials() Reset to anonymous session.");

                    // (see VsWhidbey#363953) For some (probably good) reason IIS does not renegotiate a restarted session if client cert is needed.
                    // So we don't want to reuse **anonymous** cached credential for a new SSL connection if the client has passed some certificate.
                    // The following block happens if client did specify a certificate but no cached creds were found in the cache
                    // Since we don't restart a session the server side can still challenge for a client cert.
                    if ((object)clientCertificate != (object)selectedCert)
                        selectedCert.Reset();
                    guessedThumbPrint = null;
                    selectedCert = null;
                    clientCertificate = null;
                }

                if (cachedCredentialHandle != null)
                {
                    if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_using_cached_credential));
                    m_CredentialsHandle = cachedCredentialHandle;
                    m_SelectedClientCertificate = clientCertificate;
                    cachedCred = true;
                }
                else
                {
                    SecureCredential.Flags flags = SecureCredential.Flags.ValidateManual | SecureCredential.Flags.NoDefaultCred;

                    if (!ServicePointManager.DisableSendAuxRecord)
                    {
                        flags |= SecureCredential.Flags.SendAuxRecord;
                    }

                    if (!ServicePointManager.DisableStrongCrypto 
                        && ((m_ProtocolFlags & (SchProtocols.Tls10 | SchProtocols.Tls11 | SchProtocols.Tls12)) != 0)
                        && (m_EncryptionPolicy != EncryptionPolicy.AllowNoEncryption) && (m_EncryptionPolicy != EncryptionPolicy.NoEncryption))
                    {
                        flags |= SecureCredential.Flags.UseStrongCrypto;
                    }

                    SecureCredential secureCredential = new SecureCredential(SecureCredential.CurrentVersion, selectedCert, flags, m_ProtocolFlags, m_EncryptionPolicy);
                    m_CredentialsHandle = AcquireCredentialsHandle(CredentialUse.Outbound, ref secureCredential);
                    thumbPrint = guessedThumbPrint; //delay it until here in case something above threw
                    m_SelectedClientCertificate = clientCertificate;
                }

            }
            finally {
                // an extra cert could have been created, dispose it now
                if (selectedCert != null && (object)clientCertificate != (object)selectedCert)
                    selectedCert.Reset();
            }

            GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireClientCredentials, cachedCreds = " + cachedCred.ToString(), ValidationHelper.ToString(m_CredentialsHandle));
            return cachedCred;
        }
            internal static X509CertificateCollection FindClientCertificates()
            {
                if (!ComNetOS.IsWin7orLater)
                {
                    throw new PlatformNotSupportedException();
                }

                X509CertificateCollection certificates = new X509CertificateCollection();

                X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.MaxAllowed);

                int chainCount = 0;
                SafeFreeCertChainList chainList = null;
                SafeCertSelectCritera criteria = new SafeCertSelectCritera();
                try
                {
                    bool success = CertSelectCertificateChains(
                        IntPtr.Zero,
                        CertificateSelect.HasPrivateKey, 
                        IntPtr.Zero,
                        criteria.Count,  // DWORD
                        criteria, // PCCERT_SELECT_CRITERIA
                        store.StoreHandle, 
                        out chainCount, 
                        out chainList);

                    if (!success)
                    {
                        throw new Win32Exception(); // Calls GetLastError.
                    }

                    Debug.Assert(chainCount == 0 || !chainList.IsInvalid);

                    for (int i = 0; i < chainCount; i++)
                    {
                        // Resolve IntPtr in array.
                        using (SafeFreeCertChain chainRef = new SafeFreeCertChain(
                            Marshal.ReadIntPtr(chainList.DangerousGetHandle() 
                            + i * Marshal.SizeOf(typeof(IntPtr))), true))
                        {
                            Debug.Assert(!chainRef.IsInvalid);

                            // X509Chain will duplicate the chain by increasing its ref-count.
                            X509Chain chain = new X509Chain(chainRef.DangerousGetHandle());
                            
                            // Copy base cert from chain.
                            if (chain.ChainElements.Count > 0)
                            {
                                X509Certificate2 cert = chain.ChainElements[0].Certificate;
                                certificates.Add(cert);
                            }

                            // Remove the X509Chain's reference prior to releasing the Chain List.
                            chain.Reset();
                        }
                    }
                }
                finally
                {
                    // Close store.
                    store.Close();
                    chainList.Dispose();
                    criteria.Dispose();
                }

                return certificates;
            }
 private bool AcquireClientCredentials(ref byte[] thumbPrint)
 {
     X509Certificate certificate = null;
     ArrayList list = new ArrayList();
     string[] acceptableIssuers = null;
     bool flag = false;
     if (this.m_CertSelectionDelegate != null)
     {
         if (acceptableIssuers == null)
         {
             acceptableIssuers = this.GetIssuers();
         }
         X509Certificate2 remoteCertificate = null;
         try
         {
             X509Certificate2Collection certificates;
             remoteCertificate = this.GetRemoteCertificate(out certificates);
             certificate = this.m_CertSelectionDelegate(this.m_HostName, this.ClientCertificates, remoteCertificate, acceptableIssuers);
         }
         finally
         {
             if (remoteCertificate != null)
             {
                 remoteCertificate.Reset();
             }
         }
         if (certificate != null)
         {
             if (this.m_CredentialsHandle == null)
             {
                 flag = true;
             }
             list.Add(certificate);
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_got_certificate_from_delegate"));
             }
         }
         else if (this.ClientCertificates.Count == 0)
         {
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_no_delegate_and_have_no_client_cert"));
             }
             flag = true;
         }
         else if (Logging.On)
         {
             Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_no_delegate_but_have_client_cert"));
         }
     }
     else if (((this.m_CredentialsHandle == null) && (this.m_ClientCertificates != null)) && (this.m_ClientCertificates.Count > 0))
     {
         certificate = this.ClientCertificates[0];
         flag = true;
         if (certificate != null)
         {
             list.Add(certificate);
         }
         if (Logging.On)
         {
             Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_attempting_restart_using_cert", new object[] { (certificate == null) ? "null" : certificate.ToString(true) }));
         }
     }
     else if ((this.m_ClientCertificates != null) && (this.m_ClientCertificates.Count > 0))
     {
         if (acceptableIssuers == null)
         {
             acceptableIssuers = this.GetIssuers();
         }
         if (Logging.On)
         {
             if ((acceptableIssuers == null) || (acceptableIssuers.Length == 0))
             {
                 Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_no_issuers_try_all_certs"));
             }
             else
             {
                 Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_server_issuers_look_for_matching_certs", new object[] { acceptableIssuers.Length }));
             }
         }
         for (int j = 0; j < this.m_ClientCertificates.Count; j++)
         {
             if ((acceptableIssuers != null) && (acceptableIssuers.Length != 0))
             {
                 X509Certificate2 certificate3 = null;
                 X509Chain chain = null;
                 try
                 {
                     certificate3 = MakeEx(this.m_ClientCertificates[j]);
                     if (certificate3 == null)
                     {
                         continue;
                     }
                     chain = new X509Chain {
                         ChainPolicy = { RevocationMode = X509RevocationMode.NoCheck, VerificationFlags = X509VerificationFlags.IgnoreInvalidName }
                     };
                     chain.Build(certificate3);
                     bool flag2 = false;
                     if (chain.ChainElements.Count > 0)
                     {
                         for (int k = 0; k < chain.ChainElements.Count; k++)
                         {
                             string issuer = chain.ChainElements[k].Certificate.Issuer;
                             flag2 = Array.IndexOf<string>(acceptableIssuers, issuer) != -1;
                             if (flag2)
                             {
                                 break;
                             }
                         }
                     }
                     if (!flag2)
                     {
                         continue;
                     }
                 }
                 finally
                 {
                     if (chain != null)
                     {
                         chain.Reset();
                     }
                     if ((certificate3 != null) && (certificate3 != this.m_ClientCertificates[j]))
                     {
                         certificate3.Reset();
                     }
                 }
             }
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_selected_cert", new object[] { this.m_ClientCertificates[j].ToString(true) }));
             }
             list.Add(this.m_ClientCertificates[j]);
         }
     }
     X509Certificate2 certificate4 = null;
     certificate = null;
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_n_certs_after_filtering", new object[] { list.Count }));
         if (list.Count != 0)
         {
             Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_finding_matching_certs"));
         }
     }
     for (int i = 0; i < list.Count; i++)
     {
         certificate = list[i] as X509Certificate;
         certificate4 = this.EnsurePrivateKey(certificate);
         if (certificate4 != null)
         {
             break;
         }
         certificate = null;
         certificate4 = null;
     }
     try
     {
         byte[] buffer = (certificate4 == null) ? null : certificate4.GetCertHash();
         SafeFreeCredentials credentials = SslSessionsCache.TryCachedCredential(buffer, this.m_ProtocolFlags, this.m_EncryptionPolicy);
         if ((flag && (credentials == null)) && (certificate4 != null))
         {
             if (certificate != certificate4)
             {
                 certificate4.Reset();
             }
             buffer = null;
             certificate4 = null;
             certificate = null;
         }
         if (credentials != null)
         {
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.Web, SR.GetString("net_log_using_cached_credential"));
             }
             this.m_CredentialsHandle = credentials;
             this.m_SelectedClientCertificate = certificate;
             return true;
         }
         SecureCredential secureCredential = new SecureCredential(4, certificate4, SecureCredential.Flags.NoDefaultCred | SecureCredential.Flags.ValidateManual, this.m_ProtocolFlags, this.m_EncryptionPolicy);
         this.m_CredentialsHandle = this.AcquireCredentialsHandle(CredentialUse.Outbound, ref secureCredential);
         thumbPrint = buffer;
         this.m_SelectedClientCertificate = certificate;
     }
     finally
     {
         if ((certificate4 != null) && (certificate != certificate4))
         {
             certificate4.Reset();
         }
     }
     return false;
 }