Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / SslStreamSecurityUpgradeProvider.cs / 1 / SslStreamSecurityUpgradeProvider.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Description; using System.Diagnostics; using System.IO; using System.IdentityModel.Policy; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.ServiceModel.Diagnostics; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; class SslStreamSecurityUpgradeProvider : StreamSecurityUpgradeProvider { SecurityTokenAuthenticator clientCertificateAuthenticator; SecurityTokenManager clientSecurityTokenManager; SecurityTokenProvider serverTokenProvider; EndpointIdentity identity; IdentityVerifier identityVerifier; X509Certificate2 serverCertificate; bool requireClientCertificate; string scheme; SslStreamSecurityUpgradeProvider(IDefaultCommunicationTimeouts timeouts, SecurityTokenManager clientSecurityTokenManager, bool requireClientCertificate, string scheme, IdentityVerifier identityVerifier) : base(timeouts) { this.identityVerifier = identityVerifier; this.scheme = scheme; this.clientSecurityTokenManager = clientSecurityTokenManager; this.requireClientCertificate = requireClientCertificate; } SslStreamSecurityUpgradeProvider(IDefaultCommunicationTimeouts timeouts, SecurityTokenProvider serverTokenProvider, bool requireClientCertificate, SecurityTokenAuthenticator clientCertificateAuthenticator, string scheme, IdentityVerifier identityVerifier) : base(timeouts) { this.serverTokenProvider = serverTokenProvider; this.requireClientCertificate = requireClientCertificate; this.clientCertificateAuthenticator = clientCertificateAuthenticator; this.identityVerifier = identityVerifier; this.scheme = scheme; } public static SslStreamSecurityUpgradeProvider CreateClientProvider( SslStreamSecurityBindingElement bindingElement, BindingContext context) { SecurityCredentialsManager credentialProvider = context.BindingParameters.Find(); if (credentialProvider == null) { credentialProvider = ClientCredentials.CreateDefaultCredentials(); } SecurityTokenManager tokenManager = credentialProvider.CreateSecurityTokenManager(); return new SslStreamSecurityUpgradeProvider(context.Binding, tokenManager, bindingElement.RequireClientCertificate, context.Binding.Scheme, bindingElement.IdentityVerifier); } public static SslStreamSecurityUpgradeProvider CreateServerProvider( SslStreamSecurityBindingElement bindingElement, BindingContext context) { SecurityCredentialsManager credentialProvider = context.BindingParameters.Find (); if (credentialProvider == null) { credentialProvider = ServiceCredentials.CreateDefaultCredentials(); } SecurityTokenManager tokenManager = credentialProvider.CreateSecurityTokenManager(); RecipientServiceModelSecurityTokenRequirement serverCertRequirement = new RecipientServiceModelSecurityTokenRequirement(); serverCertRequirement.TokenType = SecurityTokenTypes.X509Certificate; serverCertRequirement.RequireCryptographicToken = true; serverCertRequirement.KeyUsage = SecurityKeyUsage.Exchange; serverCertRequirement.TransportScheme = context.Binding.Scheme; SecurityTokenProvider tokenProvider = tokenManager.CreateSecurityTokenProvider(serverCertRequirement); if (tokenProvider == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCredentialsUnableToCreateLocalTokenProvider, serverCertRequirement))); } SecurityTokenAuthenticator certificateAuthenticator = TransportSecurityHelpers.GetCertificateTokenAuthenticator(tokenManager, context.Binding.Scheme); return new SslStreamSecurityUpgradeProvider(context.Binding, tokenProvider, bindingElement.RequireClientCertificate, certificateAuthenticator, context.Binding.Scheme, bindingElement.IdentityVerifier); } public override EndpointIdentity Identity { get { if ((this.identity == null) && (this.serverCertificate != null)) { this.identity = SecurityUtils.GetServiceCertificateIdentity(this.serverCertificate); } return this.identity; } } public IdentityVerifier IdentityVerifier { get { return this.identityVerifier; } } public bool RequireClientCertificate { get { return this.requireClientCertificate; } } public X509Certificate2 ServerCertificate { get { return this.serverCertificate; } } public SecurityTokenAuthenticator ClientCertificateAuthenticator { get { if (this.clientCertificateAuthenticator == null) { this.clientCertificateAuthenticator = new X509SecurityTokenAuthenticator(X509ClientCertificateAuthentication.DefaultCertificateValidator); } return this.clientCertificateAuthenticator; } } public SecurityTokenManager ClientSecurityTokenManager { get { return this.clientSecurityTokenManager; } } public string Scheme { get { return this.scheme; } } public override StreamUpgradeAcceptor CreateUpgradeAcceptor() { ThrowIfDisposedOrNotOpen(); return new SslStreamSecurityUpgradeAcceptor(this); } public override StreamUpgradeInitiator CreateUpgradeInitiator(EndpointAddress remoteAddress, Uri via) { ThrowIfDisposedOrNotOpen(); return new SslStreamSecurityUpgradeInitiator(this, remoteAddress, via); } protected override void OnAbort() { if (this.clientCertificateAuthenticator != null) { SecurityUtils.AbortTokenAuthenticatorIfRequired(this.clientCertificateAuthenticator); } CleanupServerCertificate(); } protected override void OnClose(TimeSpan timeout) { if (this.clientCertificateAuthenticator != null) { SecurityUtils.CloseTokenAuthenticatorIfRequired(this.clientCertificateAuthenticator, timeout); } CleanupServerCertificate(); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return SecurityUtils.BeginCloseTokenAuthenticatorIfRequired(this.clientCertificateAuthenticator, timeout, callback, state); } protected override void OnEndClose(IAsyncResult result) { SecurityUtils.EndCloseTokenAuthenticatorIfRequired(result); CleanupServerCertificate(); } void SetupServerCertificate(SecurityToken token) { X509SecurityToken x509Token = token as X509SecurityToken; if (x509Token == null) { SecurityUtils.AbortTokenProviderIfRequired(this.serverTokenProvider); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString( SR.InvalidTokenProvided, this.serverTokenProvider.GetType(), typeof(X509SecurityToken)))); } this.serverCertificate = new X509Certificate2(x509Token.Certificate); } void CleanupServerCertificate() { if (this.serverCertificate != null) { this.serverCertificate.Reset(); this.serverCertificate = null; } } protected override void OnOpen(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); SecurityUtils.OpenTokenAuthenticatorIfRequired(this.ClientCertificateAuthenticator, timeoutHelper.RemainingTime()); if (this.serverTokenProvider != null) { SecurityUtils.OpenTokenProviderIfRequired(this.serverTokenProvider, timeoutHelper.RemainingTime()); SecurityToken token = this.serverTokenProvider.GetToken(timeout); SetupServerCertificate(token); SecurityUtils.CloseTokenProviderIfRequired(this.serverTokenProvider, timeoutHelper.RemainingTime()); this.serverTokenProvider = null; } } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return new OpenAsyncResult(this, timeout, callback, state); } protected override void OnEndOpen(IAsyncResult result) { OpenAsyncResult.End(result); } class OpenAsyncResult : AsyncResult { SslStreamSecurityUpgradeProvider parent; TimeoutHelper timeoutHelper; AsyncCallback onOpenTokenAuthenticator; AsyncCallback onOpenTokenProvider; AsyncCallback onGetToken; AsyncCallback onCloseTokenProvider; public OpenAsyncResult(SslStreamSecurityUpgradeProvider parent, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.parent = parent; this.timeoutHelper = new TimeoutHelper(timeout); // since we're at channel.Open and not per-message, minimize our statics overhead and leverage GC for our callbacks this.onOpenTokenAuthenticator = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnOpenTokenAuthenticator)); IAsyncResult result = SecurityUtils.BeginOpenTokenAuthenticatorIfRequired(parent.ClientCertificateAuthenticator, timeoutHelper.RemainingTime(), onOpenTokenAuthenticator, this); if (!result.CompletedSynchronously) { return; } if (HandleOpenAuthenticatorComplete(result)) { base.Complete(true); } } public static void End(IAsyncResult result) { AsyncResult.End (result); } bool HandleOpenAuthenticatorComplete(IAsyncResult result) { SecurityUtils.EndOpenTokenAuthenticatorIfRequired(result); if (parent.serverTokenProvider == null) { return true; } this.onOpenTokenProvider = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnOpenTokenProvider)); IAsyncResult openTokenProviderResult = SecurityUtils.BeginOpenTokenProviderIfRequired( parent.serverTokenProvider, timeoutHelper.RemainingTime(), onOpenTokenProvider, this); if (!openTokenProviderResult.CompletedSynchronously) { return false; } return HandleOpenTokenProviderComplete(openTokenProviderResult); } bool HandleOpenTokenProviderComplete(IAsyncResult result) { SecurityUtils.EndOpenTokenProviderIfRequired(result); this.onGetToken = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnGetToken)); IAsyncResult getTokenResult = parent.serverTokenProvider.BeginGetToken(timeoutHelper.RemainingTime(), onGetToken, this); if (!getTokenResult.CompletedSynchronously) { return false; } return HandleGetTokenComplete(getTokenResult); } bool HandleGetTokenComplete(IAsyncResult result) { SecurityToken token = parent.serverTokenProvider.EndGetToken(result); parent.SetupServerCertificate(token); this.onCloseTokenProvider = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnCloseTokenProvider)); IAsyncResult closeTokenProviderResult = SecurityUtils.BeginCloseTokenProviderIfRequired(parent.serverTokenProvider, timeoutHelper.RemainingTime(), onCloseTokenProvider, this); if (!closeTokenProviderResult.CompletedSynchronously) { return false; } return HandleCloseTokenProviderComplete(closeTokenProviderResult); } bool HandleCloseTokenProviderComplete(IAsyncResult result) { SecurityUtils.EndCloseTokenProviderIfRequired(result); parent.serverTokenProvider = null; return true; } void OnOpenTokenAuthenticator(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleOpenAuthenticatorComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } void OnOpenTokenProvider(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleOpenTokenProviderComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } void OnGetToken(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleGetTokenComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } void OnCloseTokenProvider(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleCloseTokenProviderComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } } } class SslStreamSecurityUpgradeAcceptor : StreamSecurityUpgradeAcceptorBase { SslStreamSecurityUpgradeProvider parent; SecurityMessageProperty clientSecurity; // for audit X509Certificate2 clientCertificate = null; public SslStreamSecurityUpgradeAcceptor(SslStreamSecurityUpgradeProvider parent) : base(FramingUpgradeString.SslOrTls) { this.parent = parent; this.clientSecurity = new SecurityMessageProperty(); } protected override Stream OnAcceptUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity) { SslStream sslStream = new SslStream(stream, false, this.ValidateRemoteCertificate); try { sslStream.AuthenticateAsServer(this.parent.ServerCertificate, this.parent.RequireClientCertificate, SslProtocols.Default, false); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( SR.GetString(SR.NegotiationFailedIO, ioException.Message), ioException)); } if (SecurityUtils.ShouldValidateSslCipherStrength()) { SecurityUtils.ValidateSslCipherStrength(sslStream.CipherStrength); } remoteSecurity = this.clientSecurity; return sslStream; } protected override IAsyncResult OnBeginAcceptUpgrade(Stream stream, AsyncCallback callback, object state) { AcceptUpgradeAsyncResult result = new AcceptUpgradeAsyncResult(this, callback, state); result.Begin(stream); return result; } protected override Stream OnEndAcceptUpgrade(IAsyncResult result, out SecurityMessageProperty remoteSecurity) { return AcceptUpgradeAsyncResult.End(result, out remoteSecurity); } bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (this.parent.RequireClientCertificate) { if (certificate == null) { if (DiagnosticUtility.ShouldTraceError) { TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.SslClientCertMissing, this); } return false; } // Note: add ref to handle since the caller will reset the cert after the callback return. X509Certificate2 certificate2 = new X509Certificate2(certificate); this.clientCertificate = certificate2; try { SecurityToken token = new X509SecurityToken(certificate2, false); ReadOnlyCollection authorizationPolicies = this.parent.ClientCertificateAuthenticator.ValidateToken(token); this.clientSecurity = new SecurityMessageProperty(); this.clientSecurity.TransportToken = new SecurityTokenSpecification(token, authorizationPolicies); this.clientSecurity.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies); } catch (SecurityTokenException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } return false; } } return true; } public override SecurityMessageProperty GetRemoteSecurity() { if (this.clientSecurity.TransportToken != null) { return this.clientSecurity; } if (this.clientCertificate != null) { SecurityToken token = new X509SecurityToken(this.clientCertificate); ReadOnlyCollection authorizationPolicies = SecurityUtils.NonValidatingX509Authenticator.ValidateToken(token); this.clientSecurity = new SecurityMessageProperty(); this.clientSecurity.TransportToken = new SecurityTokenSpecification(token, authorizationPolicies); this.clientSecurity.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies); return this.clientSecurity; } return base.GetRemoteSecurity(); } class AcceptUpgradeAsyncResult : StreamSecurityUpgradeAcceptorAsyncResult { SslStreamSecurityUpgradeAcceptor acceptor; SslStream sslStream; public AcceptUpgradeAsyncResult(SslStreamSecurityUpgradeAcceptor acceptor, AsyncCallback callback, object state) : base(callback, state) { this.acceptor = acceptor; } protected override IAsyncResult OnBegin(Stream stream, AsyncCallback callback) { this.sslStream = new SslStream(stream, false, this.acceptor.ValidateRemoteCertificate); return this.sslStream.BeginAuthenticateAsServer(this.acceptor.parent.ServerCertificate, this.acceptor.parent.RequireClientCertificate, SslProtocols.Default, false, callback, this); } protected override Stream OnCompleteAuthenticateAsServer(IAsyncResult result) { this.sslStream.EndAuthenticateAsServer(result); if (SecurityUtils.ShouldValidateSslCipherStrength()) { SecurityUtils.ValidateSslCipherStrength(sslStream.CipherStrength); } return this.sslStream; } protected override SecurityMessageProperty ValidateCreateSecurity() { return this.acceptor.clientSecurity; } } } class SslStreamSecurityUpgradeInitiator : StreamSecurityUpgradeInitiatorBase { SslStreamSecurityUpgradeProvider parent; SecurityMessageProperty serverSecurity; SecurityTokenProvider clientCertificateProvider; X509SecurityToken clientToken; SecurityTokenAuthenticator serverCertificateAuthenticator; static LocalCertificateSelectionCallback clientCertificateSelectionCallback; public SslStreamSecurityUpgradeInitiator(SslStreamSecurityUpgradeProvider parent, EndpointAddress remoteAddress, Uri via) : base(FramingUpgradeString.SslOrTls, remoteAddress, via) { this.parent = parent; InitiatorServiceModelSecurityTokenRequirement serverCertRequirement = new InitiatorServiceModelSecurityTokenRequirement(); serverCertRequirement.TokenType = SecurityTokenTypes.X509Certificate; serverCertRequirement.RequireCryptographicToken = true; serverCertRequirement.KeyUsage = SecurityKeyUsage.Exchange; serverCertRequirement.TargetAddress = remoteAddress; serverCertRequirement.Via = via; serverCertRequirement.TransportScheme = this.parent.Scheme; SecurityTokenResolver dummy; this.serverCertificateAuthenticator = (parent.ClientSecurityTokenManager.CreateSecurityTokenAuthenticator(serverCertRequirement, out dummy)); if (parent.RequireClientCertificate) { InitiatorServiceModelSecurityTokenRequirement clientCertRequirement = new InitiatorServiceModelSecurityTokenRequirement(); clientCertRequirement.TokenType = SecurityTokenTypes.X509Certificate; clientCertRequirement.RequireCryptographicToken = true; clientCertRequirement.KeyUsage = SecurityKeyUsage.Signature; clientCertRequirement.TargetAddress = remoteAddress; clientCertRequirement.Via = via; clientCertRequirement.TransportScheme = this.parent.Scheme; this.clientCertificateProvider = parent.ClientSecurityTokenManager.CreateSecurityTokenProvider(clientCertRequirement); if (clientCertificateProvider == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCredentialsUnableToCreateLocalTokenProvider, clientCertRequirement))); } } } static LocalCertificateSelectionCallback ClientCertificateSelectionCallback { get { if (clientCertificateSelectionCallback == null) { clientCertificateSelectionCallback = new LocalCertificateSelectionCallback(SelectClientCertificate); } return clientCertificateSelectionCallback; } } IAsyncResult BaseBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return base.BeginOpen(timeout, callback, state); } void BaseEndOpen(IAsyncResult result) { base.EndOpen(result); } internal override IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return new OpenAsyncResult(this, timeout, callback, state); } internal override void EndOpen(IAsyncResult result) { OpenAsyncResult.End(result); } internal override void Open(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); base.Open(timeoutHelper.RemainingTime()); if (this.clientCertificateProvider != null) { SecurityUtils.OpenTokenProviderIfRequired(this.clientCertificateProvider, timeoutHelper.RemainingTime()); this.clientToken = (X509SecurityToken)this.clientCertificateProvider.GetToken(timeoutHelper.RemainingTime()); } } IAsyncResult BaseBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return base.BeginClose(timeout, callback, state); } void BaseEndClose(IAsyncResult result) { base.EndClose(result); } internal override IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new CloseAsyncResult(this, timeout, callback, state); } internal override void EndClose(IAsyncResult result) { CloseAsyncResult.End(result); } internal override void Close(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); base.Close(timeoutHelper.RemainingTime()); if (this.clientCertificateProvider != null) { SecurityUtils.CloseTokenProviderIfRequired(this.clientCertificateProvider, timeoutHelper.RemainingTime()); } } protected override IAsyncResult OnBeginInitiateUpgrade(Stream stream, AsyncCallback callback, object state) { InitiateUpgradeAsyncResult result = new InitiateUpgradeAsyncResult(this, callback, state); result.Begin(stream); return result; } protected override Stream OnEndInitiateUpgrade(IAsyncResult result, out SecurityMessageProperty remoteSecurity) { return InitiateUpgradeAsyncResult.End(result, out remoteSecurity); } protected override Stream OnInitiateUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity) { X509CertificateCollection clientCertificates = null; LocalCertificateSelectionCallback selectionCallback = null; if (this.clientToken != null) { clientCertificates = new X509CertificateCollection(); clientCertificates.Add(clientToken.Certificate); selectionCallback = ClientCertificateSelectionCallback; } SslStream sslStream = new SslStream(stream, false, this.ValidateRemoteCertificate, selectionCallback); try { sslStream.AuthenticateAsClient(string.Empty, clientCertificates, SslProtocols.Default, false); } catch (SecurityTokenValidationException tokenValidationException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(tokenValidationException.Message, tokenValidationException)); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( SR.GetString(SR.NegotiationFailedIO, ioException.Message), ioException)); } if (SecurityUtils.ShouldValidateSslCipherStrength()) { SecurityUtils.ValidateSslCipherStrength(sslStream.CipherStrength); } remoteSecurity = this.serverSecurity; return sslStream; } static X509Certificate SelectClientCertificate(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers) { return localCertificates[0]; } bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { // Note: add ref to handle since the caller will reset the cert after the callback return. X509Certificate2 certificate2 = new X509Certificate2(certificate); SecurityToken token = new X509SecurityToken(certificate2, false); ReadOnlyCollection authorizationPolicies = this.serverCertificateAuthenticator.ValidateToken(token); this.serverSecurity = new SecurityMessageProperty(); this.serverSecurity.TransportToken = new SecurityTokenSpecification(token, authorizationPolicies); this.serverSecurity.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies); AuthorizationContext authzContext = this.serverSecurity.ServiceSecurityContext.AuthorizationContext; this.parent.IdentityVerifier.EnsureOutgoingIdentity(this.RemoteAddress, this.Via, authzContext); return true; } class InitiateUpgradeAsyncResult : StreamSecurityUpgradeInitiatorAsyncResult { X509CertificateCollection clientCertificates; SslStreamSecurityUpgradeInitiator initiator; LocalCertificateSelectionCallback selectionCallback; SslStream sslStream; public InitiateUpgradeAsyncResult(SslStreamSecurityUpgradeInitiator initiator, AsyncCallback callback, object state) : base(callback, state) { this.initiator = initiator; if (initiator.clientToken != null) { this.clientCertificates = new X509CertificateCollection(); this.clientCertificates.Add(initiator.clientToken.Certificate); this.selectionCallback = ClientCertificateSelectionCallback; } } protected override IAsyncResult OnBeginAuthenticateAsClient(Stream stream, AsyncCallback callback) { this.sslStream = new SslStream(stream, false, this.initiator.ValidateRemoteCertificate, this.selectionCallback); try { return this.sslStream.BeginAuthenticateAsClient(string.Empty, this.clientCertificates, SslProtocols.Default, false, callback, this); } catch (SecurityTokenValidationException tokenValidationException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(tokenValidationException.Message, tokenValidationException)); } } protected override Stream OnCompleteAuthenticateAsClient(IAsyncResult result) { try { this.sslStream.EndAuthenticateAsClient(result); } catch (SecurityTokenValidationException tokenValidationException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(tokenValidationException.Message, tokenValidationException)); } if (SecurityUtils.ShouldValidateSslCipherStrength()) { SecurityUtils.ValidateSslCipherStrength(sslStream.CipherStrength); } return this.sslStream; } protected override SecurityMessageProperty ValidateCreateSecurity() { return this.initiator.serverSecurity; } } class OpenAsyncResult : AsyncResult { SslStreamSecurityUpgradeInitiator parent; TimeoutHelper timeoutHelper; AsyncCallback onBaseOpen; AsyncCallback onOpenTokenProvider; AsyncCallback onGetClientToken; public OpenAsyncResult(SslStreamSecurityUpgradeInitiator parent, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.parent = parent; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // since we're at channel.Open and not per-message, minimize our statics overhead and leverage GC for our callback this.onBaseOpen = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnBaseOpen)); if (parent.clientCertificateProvider != null) { this.onOpenTokenProvider = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnOpenTokenProvider)); this.onGetClientToken = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnGetClientToken)); } IAsyncResult result = parent.BaseBeginOpen(timeoutHelper.RemainingTime(), onBaseOpen, this); if (!result.CompletedSynchronously) { return; } if (HandleBaseOpenComplete(result)) { base.Complete(true); } } public static void End(IAsyncResult result) { AsyncResult.End (result); } bool HandleBaseOpenComplete(IAsyncResult result) { parent.BaseEndOpen(result); if (parent.clientCertificateProvider == null) { return true; } IAsyncResult openTokenProviderResult = SecurityUtils.BeginOpenTokenProviderIfRequired( parent.clientCertificateProvider, timeoutHelper.RemainingTime(), onOpenTokenProvider, this); if (!openTokenProviderResult.CompletedSynchronously) { return false; } return HandleOpenTokenProviderComplete(openTokenProviderResult); } bool HandleOpenTokenProviderComplete(IAsyncResult result) { SecurityUtils.EndOpenTokenProviderIfRequired(result); IAsyncResult getTokenResult = parent.clientCertificateProvider.BeginGetToken(timeoutHelper.RemainingTime(), onGetClientToken, this); if (!getTokenResult.CompletedSynchronously) { return false; } return HandleGetTokenComplete(getTokenResult); } bool HandleGetTokenComplete(IAsyncResult result) { parent.clientToken = (X509SecurityToken)parent.clientCertificateProvider.EndGetToken(result); return true; } void OnBaseOpen(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleBaseOpenComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } void OnOpenTokenProvider(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleOpenTokenProviderComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } void OnGetClientToken(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleGetTokenComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } } class CloseAsyncResult : AsyncResult { SslStreamSecurityUpgradeInitiator parent; TimeoutHelper timeoutHelper; AsyncCallback onBaseClose; AsyncCallback onCloseTokenProvider; public CloseAsyncResult(SslStreamSecurityUpgradeInitiator parent, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.parent = parent; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // since we're at channel.Open and not per-message, minimize our statics overhead and leverage GC for our callback this.onBaseClose = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnBaseClose)); if (parent.clientCertificateProvider != null) { this.onCloseTokenProvider = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnCloseTokenProvider)); } IAsyncResult result = parent.BaseBeginClose(timeoutHelper.RemainingTime(), onBaseClose, this); if (!result.CompletedSynchronously) { return; } if (HandleBaseCloseComplete(result)) { base.Complete(true); } } public static void End(IAsyncResult result) { AsyncResult.End (result); } bool HandleBaseCloseComplete(IAsyncResult result) { parent.BaseEndClose(result); if (parent.clientCertificateProvider == null) { return true; } IAsyncResult closeTokenProviderResult = SecurityUtils.BeginCloseTokenProviderIfRequired( parent.clientCertificateProvider, timeoutHelper.RemainingTime(), onCloseTokenProvider, this); if (!closeTokenProviderResult.CompletedSynchronously) { return false; } SecurityUtils.EndCloseTokenProviderIfRequired(closeTokenProviderResult); return true; } void OnBaseClose(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; bool completeSelf = false; try { completeSelf = this.HandleBaseCloseComplete(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { base.Complete(false, completionException); } } void OnCloseTokenProvider(IAsyncResult result) { if (result.CompletedSynchronously) { return; } Exception completionException = null; try { SecurityUtils.EndCloseTokenProviderIfRequired(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completionException = e; } base.Complete(false, completionException); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Baml6Assembly.cs
- ComplexType.cs
- AssertSection.cs
- SetStoryboardSpeedRatio.cs
- OdbcConnectionString.cs
- Triangle.cs
- EnterpriseServicesHelper.cs
- LinkedResourceCollection.cs
- CodeIdentifiers.cs
- RepeaterItemCollection.cs
- BrushProxy.cs
- PeerCollaboration.cs
- OdbcEnvironment.cs
- SpecialFolderEnumConverter.cs
- NamespaceQuery.cs
- HwndMouseInputProvider.cs
- baseaxisquery.cs
- ControlCodeDomSerializer.cs
- SchemaTableOptionalColumn.cs
- ZipIOCentralDirectoryBlock.cs
- ClientSettingsStore.cs
- RectangleHotSpot.cs
- StorageComplexTypeMapping.cs
- MissingMemberException.cs
- WindowsBrush.cs
- TargetConverter.cs
- OdbcHandle.cs
- BackStopAuthenticationModule.cs
- DrawingGroup.cs
- RuntimeConfigLKG.cs
- _ContextAwareResult.cs
- SignalGate.cs
- DataBindingHandlerAttribute.cs
- WebPartPersonalization.cs
- Variable.cs
- ConstructorBuilder.cs
- DependencyPropertyAttribute.cs
- HtmlPhoneCallAdapter.cs
- SqlConnectionHelper.cs
- StyleCollection.cs
- CompiledELinqQueryState.cs
- TdsParserSessionPool.cs
- ToolStripDropDown.cs
- HitTestParameters.cs
- RuntimeHelpers.cs
- ListManagerBindingsCollection.cs
- NavigationCommands.cs
- OSEnvironmentHelper.cs
- ClientBuildManagerCallback.cs
- ManipulationInertiaStartingEventArgs.cs
- RoutedEventHandlerInfo.cs
- TimeStampChecker.cs
- DragStartedEventArgs.cs
- GroupBox.cs
- BrowserCapabilitiesFactory.cs
- ReadOnlyKeyedCollection.cs
- BindingExpressionBase.cs
- EmptyStringExpandableObjectConverter.cs
- CodeIterationStatement.cs
- DrawingContext.cs
- xmlformatgeneratorstatics.cs
- WorkflowTraceTransfer.cs
- GregorianCalendarHelper.cs
- DetailsViewUpdatedEventArgs.cs
- CompositionTarget.cs
- FacetValueContainer.cs
- KnownTypes.cs
- OleDbTransaction.cs
- Timeline.cs
- GPPOINTF.cs
- XmlDictionaryReader.cs
- COMException.cs
- ListBoxChrome.cs
- HtmlTableRow.cs
- ChannelBuilder.cs
- DataGridColumnEventArgs.cs
- COM2ExtendedUITypeEditor.cs
- ResourceManager.cs
- __Filters.cs
- XmlValueConverter.cs
- EntityCodeGenerator.cs
- Header.cs
- SeparatorAutomationPeer.cs
- SplitterCancelEvent.cs
- CellRelation.cs
- ChtmlImageAdapter.cs
- Attributes.cs
- PropertyChangingEventArgs.cs
- MessageVersion.cs
- ToolboxItemAttribute.cs
- CollectionViewGroup.cs
- ListViewTableCell.cs
- OracleSqlParser.cs
- WorkflowOperationErrorHandler.cs
- UInt16.cs
- SafeRightsManagementQueryHandle.cs
- DataGridViewRowHeaderCell.cs
- CacheAxisQuery.cs
- Console.cs
- X509UI.cs