Example #1
0
        /// <summary>
        /// Gets the validated stream on client.
        /// </summary>
        /// <param name="serverName">Name of the server.</param>
        /// <param name="client">TCP client</param>
        /// <param name="timeout">Time to wait for the validation</param>
        /// <param name="cancellationToken">Token to be observed for cancellation signal</param>
        /// <returns>A Task that resolves to the validated stream</returns>
        public virtual async Task <Stream> AuthenticateAsClient(string serverName, TcpClient client, TimeSpan timeout, CancellationToken cancellationToken)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            Stream    clientStream = null;
            SslStream sslStream    = null;

            try
            {
                clientStream = client.GetStream();

                sslStream = new SslStream(
                    clientStream,
                    false,
                    this.configuration.RemoteCertificateValidationCallback ?? this.certificateValidator.ValidateServerCertificate,
                    this.configuration.LocalCertificateSelectionCallback);

                X509CertificateCollection coll = new X509CertificateCollection(this.identities.ClientIdentities);

                SecureTransportEventSource.Log.AuthenticateAsClient(this.transportId, (int)timeout.TotalMilliseconds, this.configuration.MustCheckCertificateRevocation, this.configuration.MustCheckCertificateTrustChain);
                Task task = sslStream.AuthenticateAsClientAsync(
                    serverName,
                    coll,
                    this.configuration.SupportedProtocols,
                    this.configuration.MustCheckCertificateRevocation);

                await Task.WhenAny(task, Task.Delay(timeout, cancellationToken));

                if (!task.IsCompleted)
                {
                    throw SecureTransportException.SslValidationTimedOut();
                }

                // Task is already completed, await it to ensure that it successfully
                // completed.
                await task;

                return(sslStream);
            }
            catch (Exception ex)
            {
                SecureTransportEventSource.Log.AuthenticateAsClientFailed(this.transportId, ex.ToString());

                if (sslStream != null)
                {
                    sslStream.Dispose();
                }
                else
                {
                    if (clientStream != null)
                    {
                        clientStream.Dispose();
                    }
                }

                throw;
            }
        }
Example #2
0
        /// <summary>
        /// Gets the validated stream on server.
        /// </summary>
        /// <param name="client">TCP client</param>
        /// <param name="timeout">Time to wait for the validation</param>
        /// <param name="cancellationToken">Token to be observed for cancellation signal</param>
        /// <returns>A Task that resolves to the validated stream</returns>
        public virtual async Task <Stream> AuthenticateAsServer(TcpClient client, TimeSpan timeout, CancellationToken cancellationToken)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            SslStream sslStream    = null;
            Stream    clientStream = client.GetStream();

            try
            {
                // We want to use ONLY the first cert in the given list
                X509Certificate serverCertificate = this.identities.ServerIdentity;
                if (serverCertificate == null)
                {
                    throw SecureTransportException.NoServerCertificate();
                }

                SecureTransportEventSource.Log.AuthenticateAsServer(this.transportId, (int)timeout.TotalMilliseconds, this.configuration.MustCheckCertificateRevocation, this.configuration.MustCheckCertificateTrustChain);
                sslStream = new SslStream(
                    clientStream,
                    false,
                    this.configuration.RemoteCertificateValidationCallback ?? this.certificateValidator.ValidateClientCertificate,
                    this.configuration.LocalCertificateSelectionCallback);

                Task task = sslStream.AuthenticateAsServerAsync(
                    serverCertificate,
                    clientCertificateRequired: this.configuration.IsClientCertificateRequired,
                    enabledSslProtocols: this.configuration.SupportedProtocols,
                    checkCertificateRevocation: this.configuration.MustCheckCertificateRevocation);

                await Task.WhenAny(task, Task.Delay(timeout, cancellationToken));

                if (!task.IsCompleted)
                {
                    throw SecureTransportException.SslValidationTimedOut();
                }

                // Task is already completed, await it to ensure that it successfully
                // completed.
                await task;

                return(sslStream);
            }
            catch (Exception ex)
            {
                SecureTransportEventSource.Log.AuthenticateAsServerFailed(this.transportId, ex.ToString());

                if (sslStream != null)
                {
                    sslStream.Dispose();
                }
                else
                {
                    clientStream.Dispose();
                    client.Close();
                }

                throw;
            }
        }