Example #1
0
        public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
        {
            if (IsAuthenticated)
            {
                throw new InvalidOperationException("This SslStream is already authenticated");
            }

            SslClientStream s = new SslClientStream(InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol(enabledSslProtocols), clientCertificates);

            s.CheckCertRevocationStatus = checkCertificateRevocation;

            // Due to the Mono.Security internal, it cannot reuse
            // the delegated argument, as Mono.Security creates
            // another instance of X509Certificate which lacks
            // private key but is filled the private key via this
            // delegate.
            s.PrivateKeyCertSelectionDelegate = delegate(X509Certificate cert, string host) {
                string hash = cert.GetCertHashString();
                // ... so, we cannot use the delegate argument.
                foreach (X509Certificate cc in clientCertificates)
                {
                    if (cc.GetCertHashString() != hash)
                    {
                        continue;
                    }
                    X509Certificate2 cert2 = cc as X509Certificate2;
                    cert2 = cert2 ?? new X509Certificate2(cc);
                    return(cert2.PrivateKey);
                }
                return(null);
            };

            // Even if validation_callback is null this allows us to verify requests where the user
            // does not provide a verification callback but attempts to authenticate with the website
            // as a client (see https://bugzilla.xamarin.com/show_bug.cgi?id=18962 for an example)
            s.ServerCertValidation2 += (mcerts) => {
                X509CertificateCollection certs = null;
                if (mcerts != null)
                {
                    certs = new X509CertificateCollection();
                    for (int i = 0; i < mcerts.Count; i++)
                    {
                        certs.Add(new X509Certificate2(mcerts [i].RawData));
                    }
                }
                return(((ChainValidationHelper)certificateValidator).ValidateCertificate(targetHost, false, certs));
            };
            s.ClientCertSelectionDelegate = OnCertificateSelection;

            ssl_stream = s;

            return(BeginWrite(new byte [0], 0, 0, asyncCallback, asyncState));
        }
        internal bool ValidateClientCertificate(X509Certificate certificate, MonoSslPolicyErrors errors)
        {
            var certs = new XX509CertificateCollection();

            certs.Add(new X509Certificate2(certificate.GetRawCertData()));

            var result = ValidateChain(string.Empty, true, certs, (SslPolicyErrors)errors);

            if (result == null)
            {
                return(false);
            }

            return(result.Trusted && !result.UserDenied);
        }
Example #3
0
		public virtual IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState)
		{
			if (IsAuthenticated)
				throw new InvalidOperationException ("This SslStream is already authenticated");

			SslClientStream s = new SslClientStream (InnerStream, targetHost, !LeaveInnerStreamOpen, GetMonoSslProtocol (enabledSslProtocols), clientCertificates);
			s.CheckCertRevocationStatus = checkCertificateRevocation;

			// Due to the Mono.Security internal, it cannot reuse
			// the delegated argument, as Mono.Security creates 
			// another instance of X509Certificate which lacks 
			// private key but is filled the private key via this
			// delegate.
			s.PrivateKeyCertSelectionDelegate = delegate (X509Certificate cert, string host) {
				string hash = cert.GetCertHashString ();
				// ... so, we cannot use the delegate argument.
				foreach (X509Certificate cc in clientCertificates) {
					if (cc.GetCertHashString () != hash)
						continue;
					X509Certificate2 cert2 = cc as X509Certificate2;
					cert2 = cert2 ?? new X509Certificate2 (cc);
					return cert2.PrivateKey;
				}
				return null;
			};

			// Even if validation_callback is null this allows us to verify requests where the user
			// does not provide a verification callback but attempts to authenticate with the website
			// as a client (see https://bugzilla.xamarin.com/show_bug.cgi?id=18962 for an example)
			s.ServerCertValidation2 += (mcerts) => {
				X509CertificateCollection certs = null;
				if (mcerts != null) {
					certs = new X509CertificateCollection ();
					for (int i = 0; i < mcerts.Count; i++)
						certs.Add (new X509Certificate2 (mcerts [i].RawData));
				}
				return ((ChainValidationHelper)certificateValidator).ValidateChain (targetHost, certs);
			};
			s.ClientCertSelectionDelegate = OnCertificateSelection;

			ssl_stream = s;

			return BeginWrite (new byte [0], 0, 0, asyncCallback, asyncState);
		}
		internal bool ValidateClientCertificate (X509Certificate certificate, MonoSslPolicyErrors errors)
		{
			var certs = new XX509CertificateCollection ();
			certs.Add (new X509Certificate2 (certificate.GetRawCertData ()));

			var result = ValidateChain (string.Empty, false, certs, (SslPolicyErrors)errors);
			if (result == null)
				return false;

			return result.Trusted && !result.UserDenied;
		}
        private bool AcquireServerCredentials(ref byte[] thumbPrint)
        {
            GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireServerCredentials");

            X509Certificate localCertificate = null;
            bool cachedCred = false;

            if (m_CertSelectionDelegate != null)
            {
                X509CertificateCollection tempCollection = new X509CertificateCollection();
                tempCollection.Add(m_ServerCertificate);
                localCertificate = m_CertSelectionDelegate(string.Empty, tempCollection, null, new string[0]);
                GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireServerCredentials() Use delegate selected Cert");
            }
            else
            {
                localCertificate = m_ServerCertificate;
            }

            if (localCertificate == null)
                throw new NotSupportedException(SR.GetString(SR.net_ssl_io_no_server_cert));

            // 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.
            X509Certificate2 selectedCert = EnsurePrivateKey(localCertificate);

            if (selectedCert == null)
                throw new NotSupportedException(SR.GetString(SR.net_ssl_io_no_server_cert));

            GlobalLog.Assert(localCertificate.Equals(selectedCert), "AcquireServerCredentials()|'selectedCert' does not match 'localCertificate'.");

            //
            // Note selectedCert is a safe ref possibly cloned from the user passed Cert object
            //
            byte [] guessedThumbPrint = selectedCert.GetCertHash();
            try {
                SafeFreeCredentials cachedCredentialHandle = SslSessionsCache.TryCachedCredential(guessedThumbPrint, m_ProtocolFlags, m_EncryptionPolicy);

                if (cachedCredentialHandle != null)
                {
                    m_CredentialsHandle = cachedCredentialHandle;
                    m_ServerCertificate = localCertificate;
                    cachedCred = true;
                }
                else
                {
                    SecureCredential secureCredential = new SecureCredential(SecureCredential.CurrentVersion, selectedCert, SecureCredential.Flags.Zero, m_ProtocolFlags, m_EncryptionPolicy);
                    m_CredentialsHandle = AcquireCredentialsHandle(CredentialUse.Inbound, ref secureCredential);
                    thumbPrint = guessedThumbPrint;
                    m_ServerCertificate = localCertificate;
                }

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

            GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::AcquireServerCredentials, cachedCreds = " + cachedCred.ToString(), ValidationHelper.ToString(m_CredentialsHandle));
            return cachedCred;
        }