1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System
.ServiceModel
.Channels
6 using System
.Security
.Authentication
;
7 using System
.ComponentModel
;
8 using System
.Collections
.Generic
;
9 using System
.Net
.Security
;
10 using System
.ServiceModel
.Description
;
11 using System
.ServiceModel
;
12 using System
.ServiceModel
.Security
;
13 using System
.ServiceModel
.Security
.Tokens
;
16 public class SslStreamSecurityBindingElement
: StreamUpgradeBindingElement
, ITransportTokenAssertionProvider
, IPolicyExportExtension
18 IdentityVerifier identityVerifier
;
19 bool requireClientCertificate
;
20 SslProtocols sslProtocols
;
22 public SslStreamSecurityBindingElement()
24 this.requireClientCertificate
= TransportDefaults
.RequireClientCertificate
;
25 this.sslProtocols
= TransportDefaults
.SslProtocols
;
28 protected SslStreamSecurityBindingElement(SslStreamSecurityBindingElement elementToBeCloned
)
29 : base(elementToBeCloned
)
31 this.identityVerifier
= elementToBeCloned
.identityVerifier
;
32 this.requireClientCertificate
= elementToBeCloned
.requireClientCertificate
;
33 this.sslProtocols
= elementToBeCloned
.sslProtocols
;
36 public IdentityVerifier IdentityVerifier
40 if (this.identityVerifier
== null)
42 this.identityVerifier
= IdentityVerifier
.CreateDefault();
45 return this.identityVerifier
;
51 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("value");
54 this.identityVerifier
= value;
58 [DefaultValue(TransportDefaults
.RequireClientCertificate
)]
59 public bool RequireClientCertificate
63 return this.requireClientCertificate
;
67 this.requireClientCertificate
= value;
71 [DefaultValue(TransportDefaults
.SslProtocols
)]
72 public SslProtocols SslProtocols
76 return this.sslProtocols
;
80 SslProtocolsHelper
.Validate(value);
81 this.sslProtocols
= value;
85 public override IChannelFactory
<TChannel
> BuildChannelFactory
<TChannel
>(BindingContext context
)
89 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("context");
92 #pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null
93 context
.BindingParameters
.Add(this);
94 return context
.BuildInnerChannelFactory
<TChannel
>();
97 public override bool CanBuildChannelFactory
<TChannel
>(BindingContext context
)
101 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("context");
104 #pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null
105 context
.BindingParameters
.Add(this);
106 return context
.CanBuildInnerChannelFactory
<TChannel
>();
109 public override IChannelListener
<TChannel
> BuildChannelListener
<TChannel
>(BindingContext context
)
113 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("context");
116 #pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null
117 context
.BindingParameters
.Add(this);
118 return context
.BuildInnerChannelListener
<TChannel
>();
121 public override bool CanBuildChannelListener
<TChannel
>(BindingContext context
)
125 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("context");
128 #pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null
129 context
.BindingParameters
.Add(this);
130 return context
.CanBuildInnerChannelListener
<TChannel
>();
133 public override BindingElement
Clone()
135 return new SslStreamSecurityBindingElement(this);
138 public override T GetProperty
<T
>(BindingContext context
)
142 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("context");
144 if (typeof(T
) == typeof(ISecurityCapabilities
))
146 return (T
)(object)new SecurityCapabilities(this.RequireClientCertificate
, true, this.RequireClientCertificate
,
147 ProtectionLevel
.EncryptAndSign
, ProtectionLevel
.EncryptAndSign
);
149 else if (typeof(T
) == typeof(IdentityVerifier
))
151 return (T
)(object)this.IdentityVerifier
;
155 return context
.GetInnerProperty
<T
>();
159 public override StreamUpgradeProvider
BuildClientStreamUpgradeProvider(BindingContext context
)
161 return SslStreamSecurityUpgradeProvider
.CreateClientProvider(this, context
);
164 public override StreamUpgradeProvider
BuildServerStreamUpgradeProvider(BindingContext context
)
166 return SslStreamSecurityUpgradeProvider
.CreateServerProvider(this, context
);
170 internal static void ImportPolicy(MetadataImporter importer
, PolicyConversionContext policyContext
)
172 XmlElement assertion
= PolicyConversionContext
.FindAssertion(policyContext
.GetBindingAssertions(),
173 TransportPolicyConstants
.SslTransportSecurityName
, TransportPolicyConstants
.DotNetFramingNamespace
, true);
175 if (assertion
!= null)
177 SslStreamSecurityBindingElement sslBindingElement
= new SslStreamSecurityBindingElement();
179 XmlReader reader
= new XmlNodeReader(assertion
);
180 reader
.ReadStartElement();
181 sslBindingElement
.RequireClientCertificate
= reader
.IsStartElement(
182 TransportPolicyConstants
.RequireClientCertificateName
,
183 TransportPolicyConstants
.DotNetFramingNamespace
);
184 if (sslBindingElement
.RequireClientCertificate
)
186 reader
.ReadElementString();
189 policyContext
.BindingElements
.Add(sslBindingElement
);
193 #region ITransportTokenAssertionProvider Members
195 public XmlElement
GetTransportTokenAssertion()
197 XmlDocument document
= new XmlDocument();
198 XmlElement assertion
=
199 document
.CreateElement(TransportPolicyConstants
.DotNetFramingPrefix
,
200 TransportPolicyConstants
.SslTransportSecurityName
,
201 TransportPolicyConstants
.DotNetFramingNamespace
);
202 if (this.requireClientCertificate
)
204 assertion
.AppendChild(document
.CreateElement(TransportPolicyConstants
.DotNetFramingPrefix
,
205 TransportPolicyConstants
.RequireClientCertificateName
,
206 TransportPolicyConstants
.DotNetFramingNamespace
));
213 void IPolicyExportExtension
.ExportPolicy(MetadataExporter exporter
, PolicyConversionContext context
)
215 if (exporter
== null)
217 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("exporter");
221 throw DiagnosticUtility
.ExceptionUtility
.ThrowHelperArgumentNull("context");
224 SecurityBindingElement
.ExportPolicyForTransportTokenAssertionProviders(exporter
, context
);
227 internal override bool IsMatch(BindingElement b
)
233 SslStreamSecurityBindingElement ssl
= b
as SslStreamSecurityBindingElement
;
239 return this.requireClientCertificate
== ssl
.requireClientCertificate
&& this.sslProtocols
== ssl
.sslProtocols
;
242 [EditorBrowsable(EditorBrowsableState
.Never
)]
243 public bool ShouldSerializeIdentityVerifier()
245 // IdentifyVerifier.CreateDefault() grabs the static instance of nested DefaultIdentityVerifier.
246 // DefaultIdentityVerifier can't be serialized directly because it's nested.
247 return (!object.ReferenceEquals(this.IdentityVerifier
, IdentityVerifier
.CreateDefault()));