HttpsChannelFactory.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / HttpsChannelFactory.cs / 2 / HttpsChannelFactory.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Channels
{ 
    using System.Collections;
    using System.ServiceModel; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Diagnostics; 
    using System.Globalization;
    using System.IO;
    using System.Net;
    using System.Runtime.Serialization; 
    using System.IdentityModel.Claims;
    using System.IdentityModel.Policy; 
    using System.IdentityModel.Tokens; 
    using System.IdentityModel.Selectors;
    using System.Security.Cryptography.X509Certificates; 
    using System.Security.Principal;
    using System.ServiceModel.Security.Tokens;
    using System.ServiceModel.Diagnostics;
    using System.ServiceModel.Security; 

    class HttpsChannelFactory : HttpChannelFactory 
    { 
        bool requireClientCertificate;
 
        internal HttpsChannelFactory(HttpsTransportBindingElement httpsBindingElement, BindingContext context)
            : base(httpsBindingElement, context)
        {
            this.requireClientCertificate = httpsBindingElement.RequireClientCertificate; 
        }
 
        public override string Scheme 
        {
            get 
            {
                return Uri.UriSchemeHttps;
            }
        } 

        public bool RequireClientCertificate 
        { 
            get
            { 
                return this.requireClientCertificate;
            }
        }
 
        internal override SecurityMessageProperty CreateReplySecurityProperty(HttpWebRequest request,
            HttpWebResponse response) 
        { 
            SecurityMessageProperty result = null;
            X509Certificate certificate = request.ServicePoint.Certificate; 
            if (certificate != null)
            {
                X509Certificate2 certificateEx = new X509Certificate2(certificate);
                SecurityToken token = new X509SecurityToken(certificateEx, false); 
                ReadOnlyCollection authorizationPolicies = SecurityUtils.NonValidatingX509Authenticator.ValidateToken(token);
                result = new SecurityMessageProperty(); 
                result.TransportToken = new SecurityTokenSpecification(token, authorizationPolicies); 
                result.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies);
            } 
            else
            {
                result = base.CreateReplySecurityProperty(request, response);
            } 
            return result;
        } 
 
        protected override void ValidateCreateChannelParameters(EndpointAddress remoteAddress, Uri via)
        { 
            if (remoteAddress.Identity != null)
            {
                X509CertificateEndpointIdentity certificateIdentity =
                    remoteAddress.Identity as X509CertificateEndpointIdentity; 
                if (certificateIdentity != null)
                { 
                    if (certificateIdentity.Certificates.Count > 1) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("remoteAddress", SR.GetString( 
                            SR.HttpsIdentityMultipleCerts, remoteAddress.Uri));
                    }
                }
 
                EndpointIdentity identity = remoteAddress.Identity;
                bool validIdentity = (certificateIdentity != null) 
                    || ClaimTypes.Spn.Equals(identity.IdentityClaim.ClaimType) 
                    || ClaimTypes.Upn.Equals(identity.IdentityClaim.ClaimType)
                    || ClaimTypes.Dns.Equals(identity.IdentityClaim.ClaimType); 

                if (!AuthenticationSchemesHelper.IsWindowsAuth(this.AuthenticationScheme)
                    && !validIdentity)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("remoteAddress", SR.GetString(
                        SR.HttpsExplicitIdentity)); 
                } 
            }
            base.ValidateCreateChannelParameters(remoteAddress, via); 
        }

        protected override IRequestChannel OnCreateChannel(EndpointAddress address, Uri via)
        { 
            ValidateCreateChannelParameters(address, via);
            return new HttpsRequestChannel(this, address, via, ManualAddressing); 
        } 

        protected override bool IsSecurityTokenManagerRequired() 
        {
            return this.requireClientCertificate || base.IsSecurityTokenManagerRequired();
        }
 
        protected override string OnGetConnectionGroupPrefix(HttpWebRequest httpWebRequest, SecurityTokenContainer clientCertificateToken)
        { 
            System.Text.StringBuilder inputStringBuilder = new System.Text.StringBuilder(); 
            string delimiter = "\0"; // nonprintable characters are invalid for SSPI Domain/UserName/Password
 
            if (this.RequireClientCertificate)
            {
                HttpsChannelFactory.SetCertificate(httpWebRequest, clientCertificateToken);
                X509CertificateCollection certificateCollection = httpWebRequest.ClientCertificates; 
                for (int i = 0; i < certificateCollection.Count; i++)
                { 
                    inputStringBuilder.AppendFormat("{0}{1}", certificateCollection[i].GetCertHashString(), delimiter); 
                }
            } 

            return inputStringBuilder.ToString();
        }
 
        void OnOpenCore()
        { 
            if (this.requireClientCertificate && this.SecurityTokenManager == null) 
            {
                DiagnosticUtility.DebugAssert("HttpsChannelFactory: SecurityTokenManager is null on open."); 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
            }
        }
 
        protected override void OnEndOpen(IAsyncResult result)
        { 
            base.OnEndOpen(result); 
            OnOpenCore();
        } 

        protected override void OnOpen(TimeSpan timeout)
        {
            base.OnOpen(timeout); 
            OnOpenCore();
        } 
 
        SecurityTokenProvider CreateAndOpenCertificateTokenProvider(EndpointAddress target, Uri via, ChannelParameterCollection channelParameters, TimeSpan timeout)
        { 
            if (!this.RequireClientCertificate)
            {
                return null;
            } 
            SecurityTokenProvider certificateProvider = TransportSecurityHelpers.GetCertificateTokenProvider(
                this.SecurityTokenManager, target, via, this.Scheme, channelParameters); 
            SecurityUtils.OpenTokenProviderIfRequired(certificateProvider, timeout); 
            return certificateProvider;
        } 

        static void SetCertificate(HttpWebRequest request, SecurityTokenContainer clientCertificateToken)
        {
            if (clientCertificateToken != null) 
            {
                X509SecurityToken x509Token = (X509SecurityToken)clientCertificateToken.Token; 
                request.ClientCertificates.Add(x509Token.Certificate); 
            }
        } 

        SecurityTokenContainer GetCertificateSecurityToken(SecurityTokenProvider certificateProvider,
            EndpointAddress to, Uri via, ChannelParameterCollection channelParameters, ref TimeoutHelper timeoutHelper)
        { 
            SecurityToken token = null;
            SecurityTokenContainer tokenContainer = null; 
            SecurityTokenProvider webRequestCertificateProvider; 
            if (ManualAddressing && this.RequireClientCertificate)
            { 
                webRequestCertificateProvider = CreateAndOpenCertificateTokenProvider(to, via, channelParameters, timeoutHelper.RemainingTime());
            }
            else
            { 
                webRequestCertificateProvider = certificateProvider;
            } 
 
            if (webRequestCertificateProvider != null)
            { 
                token = webRequestCertificateProvider.GetToken(timeoutHelper.RemainingTime());
            }

            if (ManualAddressing && this.RequireClientCertificate) 
            {
                SecurityUtils.AbortTokenProviderIfRequired(webRequestCertificateProvider); 
            } 

            if (token != null) 
            {
                tokenContainer = new SecurityTokenContainer(token);
            }
 
            return tokenContainer;
        } 
 
        class HttpsRequestChannel : HttpRequestChannel
        { 
            SecurityTokenProvider certificateProvider;
            HttpsChannelFactory factory;

            public HttpsRequestChannel(HttpsChannelFactory factory, EndpointAddress to, Uri via, bool manualAddressing) 
                : base(factory, to, via, manualAddressing)
            { 
                this.factory = factory; 
            }
 
            public new HttpsChannelFactory Factory
            {
                get { return this.factory; }
            } 

            void CreateAndOpenTokenProvider(TimeSpan timeout) 
            { 
                if (!ManualAddressing && this.Factory.RequireClientCertificate)
                { 
                    this.certificateProvider = Factory.CreateAndOpenCertificateTokenProvider(this.RemoteAddress, this.Via, this.ChannelParameters, timeout);
                }
            }
 
            void CloseTokenProvider(TimeSpan timeout)
            { 
                if (this.certificateProvider != null) 
                {
                    SecurityUtils.CloseTokenProviderIfRequired(this.certificateProvider, timeout); 
                }
            }

            void AbortTokenProvider() 
            {
                if (this.certificateProvider != null) 
                { 
                    SecurityUtils.AbortTokenProviderIfRequired(this.certificateProvider);
                } 
            }

            protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
            { 
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
                CreateAndOpenTokenProvider(timeoutHelper.RemainingTime()); 
                return base.OnBeginOpen(timeoutHelper.RemainingTime(), callback, state); 
            }
 
            protected override void OnOpen(TimeSpan timeout)
            {
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
                CreateAndOpenTokenProvider(timeoutHelper.RemainingTime()); 
                base.OnOpen(timeoutHelper.RemainingTime());
            } 
 
            protected override void OnAbort()
            { 
                AbortTokenProvider();
                base.OnAbort();
            }
 
            protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
            { 
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); 
                CloseTokenProvider(timeoutHelper.RemainingTime());
                return base.OnBeginClose(timeoutHelper.RemainingTime(), callback, state); 
            }

            protected override void OnClose(TimeSpan timeout)
            { 
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
                CloseTokenProvider(timeoutHelper.RemainingTime()); 
                base.OnClose(timeoutHelper.RemainingTime()); 
            }
 
            public IAsyncResult BeginBaseGetWebRequest(EndpointAddress to, Uri via, SecurityTokenContainer clientCertificateToken, ref TimeoutHelper timeoutHelper, AsyncCallback callback, object state)
            {
                return base.BeginGetWebRequest(to, via, clientCertificateToken, ref timeoutHelper, callback, state);
            } 

            public HttpWebRequest EndBaseGetWebRequest(IAsyncResult result) 
            { 
                return base.EndGetWebRequest(result);
            } 

            public override HttpWebRequest GetWebRequest(EndpointAddress to, Uri via,  ref TimeoutHelper timeoutHelper)
            {
                SecurityTokenContainer clientCertificateToken = Factory.GetCertificateSecurityToken(this.certificateProvider, to, via, this.ChannelParameters, ref timeoutHelper); 
                HttpWebRequest request = base.GetWebRequest(to, via, clientCertificateToken, ref timeoutHelper);
                HttpTransportSecurityHelpers.AddServerCertMapping(request, to); 
                return request; 
            }
 
            public override IAsyncResult BeginGetWebRequest(EndpointAddress to, Uri via, ref TimeoutHelper timeoutHelper, AsyncCallback callback, object state)
            {
                return new GetWebRequestAsyncResult(this, to, via, ref timeoutHelper, callback, state);
            } 

            public override HttpWebRequest EndGetWebRequest(IAsyncResult result) 
            { 
                return GetWebRequestAsyncResult.End(result);
            } 

            public override bool WillGetWebRequestCompleteSynchronously()
            {
                if (!base.WillGetWebRequestCompleteSynchronously()) 
                {
                    return false; 
                } 

                return (this.certificateProvider == null && !Factory.ManualAddressing); 
            }

            internal override void OnWebRequestCompleted(HttpWebRequest request)
            { 
                HttpTransportSecurityHelpers.RemoveServerCertMapping(request);
            } 
 
            class GetWebRequestAsyncResult : AsyncResult
            { 
                SecurityTokenProvider certificateProvider;
                HttpsChannelFactory factory;
                HttpsRequestChannel httpsChannel;
                HttpWebRequest request; 
                EndpointAddress to;
                Uri via; 
                TimeoutHelper timeoutHelper; 
                SecurityTokenContainer tokenContainer;
                static AsyncCallback onGetBaseWebRequestCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnGetBaseWebRequestCallback)); 
                static AsyncCallback onGetTokenCallback;

                public GetWebRequestAsyncResult(HttpsRequestChannel httpsChannel, EndpointAddress to, Uri via,
                    ref TimeoutHelper timeoutHelper, 
                    AsyncCallback callback, object state)
                    : base(callback, state) 
                { 
                    this.httpsChannel = httpsChannel;
                    this.to = to; 
                    this.via = via;
                    this.timeoutHelper = timeoutHelper;
                    this.factory = httpsChannel.Factory;
                    this.certificateProvider = httpsChannel.certificateProvider; 
                    if (this.factory.ManualAddressing && this.factory.RequireClientCertificate)
                    { 
                        this.certificateProvider = 
                            this.factory.CreateAndOpenCertificateTokenProvider(to, via, httpsChannel.ChannelParameters, timeoutHelper.RemainingTime());
                    } 

                    if (!GetToken())
                    {
                        return; 
                    }
 
                    if (!GetWebRequest()) 
                    {
                        return; 
                    }

                    base.Complete(true);
                } 

                bool GetWebRequest() 
                { 
                    IAsyncResult result = this.httpsChannel.BeginBaseGetWebRequest(to, via, tokenContainer, ref timeoutHelper, onGetBaseWebRequestCallback, this);
 
                    if (!result.CompletedSynchronously)
                    {
                        return false;
                    } 

                    this.request = this.httpsChannel.EndBaseGetWebRequest(result); 
                    HttpTransportSecurityHelpers.AddServerCertMapping(this.request, this.to); 

                    return true; 
                }

                bool GetToken()
                { 
                    if (this.certificateProvider != null)
                    { 
                        if (onGetTokenCallback == null) 
                        {
                            onGetTokenCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnGetTokenCallback)); 
                        }

                        IAsyncResult result = this.certificateProvider.BeginGetToken(
                            timeoutHelper.RemainingTime(), onGetTokenCallback, this); 

                        if (!result.CompletedSynchronously) 
                        { 
                            return false;
                        } 
                        OnGetToken(result);
                    }

                    return true; 
                }
 
                static void OnGetBaseWebRequestCallback(IAsyncResult result) 
                {
                    if (result.CompletedSynchronously) 
                        return;

                    GetWebRequestAsyncResult thisPtr = (GetWebRequestAsyncResult)result.AsyncState;
 
                    Exception completionException = null;
                    try 
                    { 
                        thisPtr.request = thisPtr.httpsChannel.EndBaseGetWebRequest(result);
                        HttpTransportSecurityHelpers.AddServerCertMapping(thisPtr.request, thisPtr.to); 
                    }
#pragma warning suppress 56500 // [....], transferring exception to another thread
                    catch (Exception e)
                    { 
                        if (DiagnosticUtility.IsFatal(e))
                        { 
                            throw; 
                        }
                        completionException = e; 
                    }
                    thisPtr.Complete(false, completionException);
                }
 
                static void OnGetTokenCallback(IAsyncResult result)
                { 
                    if (result.CompletedSynchronously) 
                        return;
 
                    GetWebRequestAsyncResult thisPtr = (GetWebRequestAsyncResult)result.AsyncState;

                    Exception completionException = null;
                    bool completeSelf; 
                    try
                    { 
                        thisPtr.OnGetToken(result); 
                        completeSelf = thisPtr.GetWebRequest();
                    } 
#pragma warning suppress 56500 // [....], transferring exception to another thread
                    catch (Exception e)
                    {
                        if (DiagnosticUtility.IsFatal(e)) 
                        {
                            throw; 
                        } 
                        completeSelf = true;
                        completionException = e; 
                    }
                    if (completeSelf)
                    {
                        thisPtr.Complete(false, completionException); 
                    }
                } 
 
                void OnGetToken(IAsyncResult result)
                { 
                    SecurityToken token = this.certificateProvider.EndGetToken(result);
                    if (token != null)
                    {
                        this.tokenContainer = new SecurityTokenContainer(token); 
                    }
                    CloseCertificateProviderIfRequired(); 
                } 

                void CloseCertificateProviderIfRequired() 
                {
                    if (this.factory.ManualAddressing && this.certificateProvider != null)
                    {
                        SecurityUtils.AbortTokenProviderIfRequired(this.certificateProvider); 
                    }
                } 
 
                public static HttpWebRequest End(IAsyncResult result)
                { 
                    GetWebRequestAsyncResult thisPtr = AsyncResult.End(result);
                    return thisPtr.request;
                }
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK