1 //
2 // SecurityBindingElement.cs
3 //
4 // Author:
5 //	Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005-2006 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System.Collections.Generic;
29 using System.Collections.ObjectModel;
30 using System.ServiceModel.Description;
31 using System.ServiceModel.Channels;
32 using System.ServiceModel.Security;
33 #if !MOBILE && !XAMMAC_4_5
34 using System.ServiceModel.Channels.Security;
35 using System.IdentityModel.Selectors;
36 using System.IdentityModel.Tokens;
37 #endif
38 using System.ServiceModel.Security.Tokens;
39 using System.Text;
40 
41 namespace System.ServiceModel.Channels
42 {
43 	public abstract class SecurityBindingElement : BindingElement
44 	{
SecurityBindingElement()45 		internal SecurityBindingElement ()
46 		{
47 #if !XAMMAC_4_5
48 			MessageSecurityVersion = MessageSecurityVersion.Default;
49 #endif
50 			endpoint = new SupportingTokenParameters ();
51 #if !MOBILE && !XAMMAC_4_5
52 			DefaultAlgorithmSuite = SecurityAlgorithmSuite.Default;
53 			KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
54 			operation = new Dictionary<string,SupportingTokenParameters> ();
55 			opt_endpoint = new SupportingTokenParameters ();
56 			opt_operation = new Dictionary<string,SupportingTokenParameters> ();
57 			service_settings = new LocalServiceSecuritySettings ();
58 #endif
59 			IncludeTimestamp = true;
60 			LocalClientSettings = new LocalClientSecuritySettings ();
61 		}
62 
SecurityBindingElement(SecurityBindingElement other)63 		internal SecurityBindingElement (SecurityBindingElement other)
64 		{
65 			security_header_layout = other.security_header_layout;
66 			msg_security_version = other.msg_security_version;
67 			endpoint = other.endpoint.Clone ();
68 #if !MOBILE && !XAMMAC_4_5
69 			alg_suite = other.alg_suite;
70 			key_entropy_mode = other.key_entropy_mode;
71 			opt_endpoint = other.opt_endpoint.Clone ();
72 			operation = new Dictionary<string,SupportingTokenParameters> ();
73 			foreach (KeyValuePair<string,SupportingTokenParameters> p in other.operation)
74 				operation.Add (p.Key, p.Value.Clone ());
75 			opt_operation = new Dictionary<string,SupportingTokenParameters> ();
76 			foreach (KeyValuePair<string,SupportingTokenParameters> p in other.opt_operation)
77 				opt_operation.Add (p.Key, p.Value.Clone ());
78 			service_settings = other.service_settings.Clone ();
79 #endif
80 			IncludeTimestamp = other.IncludeTimestamp;
81 			LocalClientSettings = other.LocalClientSettings.Clone ();
82 		}
83 
84 		SecurityHeaderLayout security_header_layout;
85 		MessageSecurityVersion msg_security_version;
86 		SupportingTokenParameters endpoint;
87 
88 #if !MOBILE && !XAMMAC_4_5
89 		SecurityAlgorithmSuite alg_suite;
90 		SecurityKeyEntropyMode key_entropy_mode;
91 		SupportingTokenParameters opt_endpoint;
92 		IDictionary<string,SupportingTokenParameters> operation, opt_operation;
93 		LocalServiceSecuritySettings service_settings;
94 #endif
95 
96 		public bool IncludeTimestamp { get; set; }
97 
98 		public LocalClientSecuritySettings LocalClientSettings { get; private set; }
99 
100 		public SecurityHeaderLayout SecurityHeaderLayout {
101 			get { return security_header_layout; }
102 			set { security_header_layout = value; }
103 		}
104 
105 		public MessageSecurityVersion MessageSecurityVersion {
106 			get { return msg_security_version; }
107 			set { msg_security_version = value; }
108 		}
109 
110 		public SupportingTokenParameters EndpointSupportingTokenParameters {
111 			get { return endpoint; }
112 		}
113 
114 #if !MOBILE && !XAMMAC_4_5
115 		public SecurityAlgorithmSuite DefaultAlgorithmSuite {
116 			get { return alg_suite; }
117 			set { alg_suite = value; }
118 		}
119 
120 		public SecurityKeyEntropyMode KeyEntropyMode {
121 			get { return key_entropy_mode; }
122 			set { key_entropy_mode = value; }
123 		}
124 
125 		public LocalServiceSecuritySettings LocalServiceSettings {
126 			get { return service_settings; }
127 		}
128 
129 		public IDictionary<string,SupportingTokenParameters> OperationSupportingTokenParameters {
130 			get { return operation; }
131 		}
132 
133 		public SupportingTokenParameters OptionalEndpointSupportingTokenParameters {
134 			get { return opt_endpoint; }
135 		}
136 
137 		public IDictionary<string,SupportingTokenParameters> OptionalOperationSupportingTokenParameters {
138 			get { return opt_operation; }
139 		}
140 #endif
141 
142 		[MonoTODO ("Implement for TransportSecurityBindingElement")]
CanBuildChannelFactory(BindingContext context)143 		public override bool CanBuildChannelFactory<TChannel> (BindingContext context)
144 		{
145 #if MOBILE || XAMMAC_4_5
146 			// not sure this should be like this, but there isn't Symmetric/Asymmetric elements in 2.1 anyways.
147 			return context.CanBuildInnerChannelFactory<TChannel> ();
148 #else
149 			if (this is TransportSecurityBindingElement)
150 				throw new NotImplementedException ();
151 
152 			var symm = this as SymmetricSecurityBindingElement;
153 			var asymm = this as AsymmetricSecurityBindingElement;
154 			var pt = symm != null ? symm.ProtectionTokenParameters : asymm != null ? asymm.InitiatorTokenParameters : null;
155 			if (pt == null)
156 				return false;
157 
158 			var t = typeof (TChannel);
159 			var req = new InitiatorServiceModelSecurityTokenRequirement ();
160 			pt.InitializeSecurityTokenRequirement (req);
161 			object dummy;
162 			if (req.Properties.TryGetValue (ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty, out dummy) && dummy != null) {
163 				if (t == typeof (IRequestSessionChannel))
164 					return context.CanBuildInnerChannelFactory<IRequestChannel> () ||
165 						context.CanBuildInnerChannelFactory<IRequestSessionChannel> ();
166 				else if (t == typeof (IDuplexSessionChannel))
167 					return context.CanBuildInnerChannelFactory<IDuplexChannel> () ||
168 						context.CanBuildInnerChannelFactory<IDuplexSessionChannel> ();
169 			} else {
170 				if (t == typeof (IRequestChannel))
171 					return context.CanBuildInnerChannelFactory<IRequestChannel> () ||
172 						context.CanBuildInnerChannelFactory<IRequestSessionChannel> ();
173 				else if (t == typeof (IDuplexChannel))
174 					return context.CanBuildInnerChannelFactory<IDuplexChannel> () ||
175 						context.CanBuildInnerChannelFactory<IDuplexSessionChannel> ();
176 			}
177 			return false;
178 #endif
179 		}
180 
BuildChannelFactory( BindingContext context)181 		public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
182 			BindingContext context)
183 		{
184 			return BuildChannelFactoryCore<TChannel> (context);
185 		}
186 
187 		protected abstract IChannelFactory<TChannel>
BuildChannelFactoryCore(BindingContext context)188 			BuildChannelFactoryCore<TChannel> (BindingContext context);
189 
190 #if !MOBILE && !XAMMAC_4_5
191 		[MonoTODO ("Implement for TransportSecurityBindingElement")]
CanBuildChannelListener(BindingContext context)192 		public override bool CanBuildChannelListener<TChannel> (BindingContext context)
193 		{
194 			if (this is TransportSecurityBindingElement)
195 				throw new NotImplementedException ();
196 
197 			var symm = this as SymmetricSecurityBindingElement;
198 			var asymm = this as AsymmetricSecurityBindingElement;
199 			var pt = symm != null ? symm.ProtectionTokenParameters : asymm != null ? asymm.RecipientTokenParameters : null;
200 			if (pt == null)
201 				return false;
202 
203 			var t = typeof (TChannel);
204 			var req = new InitiatorServiceModelSecurityTokenRequirement ();
205 			pt.InitializeSecurityTokenRequirement (req);
206 			object dummy;
207 			if (req.Properties.TryGetValue (ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty, out dummy) && dummy != null) {
208 				if (t == typeof (IReplySessionChannel))
209 					return context.CanBuildInnerChannelListener<IReplyChannel> () ||
210 						context.CanBuildInnerChannelListener<IReplySessionChannel> ();
211 				else if (t == typeof (IDuplexSessionChannel))
212 					return context.CanBuildInnerChannelListener<IDuplexChannel> () ||
213 						context.CanBuildInnerChannelListener<IDuplexSessionChannel> ();
214 			} else {
215 				if (t == typeof (IReplyChannel))
216 					return context.CanBuildInnerChannelListener<IReplyChannel> () ||
217 						context.CanBuildInnerChannelListener<IReplySessionChannel> ();
218 				else if (t == typeof (IDuplexChannel))
219 					return context.CanBuildInnerChannelListener<IDuplexChannel> () ||
220 						context.CanBuildInnerChannelListener<IDuplexSessionChannel> ();
221 			}
222 			return false;
223 		}
224 
BuildChannelListener( BindingContext context)225 		public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
226 			BindingContext context)
227 		{
228 			return BuildChannelListenerCore<TChannel> (context);
229 		}
230 
231 		protected abstract IChannelListener<TChannel>
232 			BuildChannelListenerCore<TChannel> (BindingContext context)
233 			where TChannel : class, IChannel;
234 
GetProperty(BindingContext context)235 		public override T GetProperty<T> (BindingContext context)
236 		{
237 			// It is documented that ISecurityCapabilities and IdentityVerifier can be returned.
238 			// Though, this class is not inheritable, and they are returned by the derived types.
239 			// So I don't care about them here.
240 			return context.GetInnerProperty<T> ();
241 		}
242 
SetKeyDerivation(bool requireDerivedKeys)243 		public virtual void SetKeyDerivation (bool requireDerivedKeys)
244 		{
245 			endpoint.SetKeyDerivation (requireDerivedKeys);
246 			opt_endpoint.SetKeyDerivation (requireDerivedKeys);
247 			foreach (SupportingTokenParameters p in operation.Values)
248 				p.SetKeyDerivation (requireDerivedKeys);
249 			foreach (SupportingTokenParameters p in opt_operation.Values)
250 				p.SetKeyDerivation (requireDerivedKeys);
251 		}
252 
ToString()253 		public override string ToString ()
254 		{
255 			var sb = new StringBuilder ();
256 			sb.Append (GetType ().FullName).Append (":\n");
257 			foreach (var pi in GetType ().GetProperties ()) {
258 				var simple = Type.GetTypeCode (pi.PropertyType) != TypeCode.Object;
259 				var val = pi.GetValue (this, null);
260 				sb.Append (pi.Name).Append (':');
261 				if (val != null)
262 					sb.AppendFormat ("{0}{1}{2}", simple ? " " : "\n", simple ? "" : "  ", String.Join ("\n  ", val.ToString ().Split ('\n')));
263 				sb.Append ('\n');
264 			}
265 			sb.Length--; // chop trailing EOL.
266 			return sb.ToString ();
267 		}
268 #else
269 		[MonoTODO]
GetProperty(BindingContext context)270 		public override T GetProperty<T> (BindingContext context)
271 		{
272 			return null;
273 		}
274 #endif
275 
276 		#region Factory methods
277 #if !MOBILE && !XAMMAC_4_5
278 		public static SymmetricSecurityBindingElement
CreateAnonymousForCertificateBindingElement()279 			CreateAnonymousForCertificateBindingElement ()
280 		{
281 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
282 			be.RequireSignatureConfirmation = true;
283 			be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
284 			return be;
285 		}
286 
287 		public static TransportSecurityBindingElement
CreateCertificateOverTransportBindingElement()288 			CreateCertificateOverTransportBindingElement ()
289 		{
290 			return CreateCertificateOverTransportBindingElement (MessageSecurityVersion.Default);
291 		}
292 
293 		public static TransportSecurityBindingElement
CreateCertificateOverTransportBindingElement(MessageSecurityVersion version)294 			CreateCertificateOverTransportBindingElement (MessageSecurityVersion version)
295 		{
296 			var be = new TransportSecurityBindingElement () { MessageSecurityVersion = version };
297 			be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new X509SecurityTokenParameters ());
298 			return be;
299 		}
300 
301 		[MonoTODO]
302 		public static AsymmetricSecurityBindingElement
CreateCertificateSignatureBindingElement()303 			CreateCertificateSignatureBindingElement  ()
304 		{
305 			throw new NotImplementedException ();
306 		}
307 
308 		[MonoTODO]
309 		public static SymmetricSecurityBindingElement
CreateIssuedTokenBindingElement( IssuedSecurityTokenParameters issuedTokenParameters)310 			CreateIssuedTokenBindingElement  (
311 			IssuedSecurityTokenParameters issuedTokenParameters)
312 		{
313 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
314 			be.ProtectionTokenParameters = issuedTokenParameters;
315 			return be;
316 		}
317 
318 		public static SymmetricSecurityBindingElement
CreateIssuedTokenForCertificateBindingElement( IssuedSecurityTokenParameters issuedTokenParameters)319 			CreateIssuedTokenForCertificateBindingElement (
320 			IssuedSecurityTokenParameters issuedTokenParameters)
321 		{
322 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
323 			be.RequireSignatureConfirmation = true;
324 			be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
325 			be.EndpointSupportingTokenParameters.Endorsing.Add (
326 				issuedTokenParameters);
327 			return be;
328 		}
329 
330 		[MonoTODO]
331 		public static SymmetricSecurityBindingElement
CreateIssuedTokenForSslBindingElement( IssuedSecurityTokenParameters issuedTokenParameters)332 			CreateIssuedTokenForSslBindingElement (
333 			IssuedSecurityTokenParameters issuedTokenParameters)
334 		{
335 			return CreateIssuedTokenForSslBindingElement (
336 				issuedTokenParameters, false);
337 		}
338 
339 		[MonoTODO]
340 		public static SymmetricSecurityBindingElement
CreateIssuedTokenForSslBindingElement( IssuedSecurityTokenParameters issuedTokenParameters, bool requireCancellation)341 			CreateIssuedTokenForSslBindingElement (
342 			IssuedSecurityTokenParameters issuedTokenParameters,
343 			bool requireCancellation)
344 		{
345 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
346 			be.RequireSignatureConfirmation = true;
347 			be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
348 			be.EndpointSupportingTokenParameters.Endorsing.Add (
349 				issuedTokenParameters);
350 			return be;
351 		}
352 
353 		[MonoTODO]
354 		public static TransportSecurityBindingElement
CreateIssuedTokenOverTransportBindingElement( IssuedSecurityTokenParameters issuedTokenParameters)355 			CreateIssuedTokenOverTransportBindingElement (
356 			IssuedSecurityTokenParameters issuedTokenParameters)
357 		{
358 			throw new NotImplementedException ();
359 		}
360 
361 		[MonoTODO]
CreateKerberosBindingElement()362 		public static SymmetricSecurityBindingElement CreateKerberosBindingElement ()
363 		{
364 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
365 			be.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128;
366 			be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
367 			be.ProtectionTokenParameters.InclusionMode =
368 				SecurityTokenInclusionMode.Once;
369 			return be;
370 		}
371 
372 		[MonoTODO]
373 		public static TransportSecurityBindingElement
CreateKerberosOverTransportBindingElement()374 			CreateKerberosOverTransportBindingElement ()
375 		{
376 			throw new NotImplementedException ();
377 		}
378 
379 		public static SecurityBindingElement
CreateMutualCertificateBindingElement()380 			CreateMutualCertificateBindingElement ()
381 		{
382 			return CreateMutualCertificateBindingElement (MessageSecurityVersion.Default, false);
383 		}
384 
385 		public static SecurityBindingElement
CreateMutualCertificateBindingElement(MessageSecurityVersion version)386 			CreateMutualCertificateBindingElement (MessageSecurityVersion version)
387 		{
388 			return CreateMutualCertificateBindingElement (version, false);
389 		}
390 
391 		[MonoTODO("Does not support allowSerializedSigningTokenOnReply.")]
392 		public static SecurityBindingElement
CreateMutualCertificateBindingElement( MessageSecurityVersion version, bool allowSerializedSigningTokenOnReply)393 			CreateMutualCertificateBindingElement (
394 			MessageSecurityVersion version,
395 			bool allowSerializedSigningTokenOnReply)
396 		{
397 			if (version == null)
398 				throw new ArgumentNullException ("version");
399 
400 			if (allowSerializedSigningTokenOnReply)
401 				throw new NotSupportedException ("allowSerializedSigningTokenOnReply is not supported");
402 
403 			if (version.SecurityVersion == SecurityVersion.WSSecurity10) {
404 
405 				var recipient = new X509SecurityTokenParameters (
406 					X509KeyIdentifierClauseType.Any,
407 				    SecurityTokenInclusionMode.Never);
408 				recipient.RequireDerivedKeys = false;
409 
410 				var initiator = new X509SecurityTokenParameters (
411 				    X509KeyIdentifierClauseType.Any,
412 				    SecurityTokenInclusionMode.AlwaysToRecipient);
413 				initiator.RequireDerivedKeys = false;
414 
415 				return new AsymmetricSecurityBindingElement (recipient, initiator) {
416 					MessageSecurityVersion = version
417 				};
418 			} else {
419 				X509SecurityTokenParameters p =
420 					new X509SecurityTokenParameters (X509KeyIdentifierClauseType.Thumbprint);
421 				p.RequireDerivedKeys = false;
422 
423 				var sym = new SymmetricSecurityBindingElement () {
424 					MessageSecurityVersion = version,
425 					RequireSignatureConfirmation = true
426 			};
427 
428 				X509SecurityTokenParameters p2 = new X509SecurityTokenParameters (X509KeyIdentifierClauseType.Thumbprint);
429 				p2.ReferenceStyle = SecurityTokenReferenceStyle.External;
430 				sym.ProtectionTokenParameters = p2;
431 				sym.EndpointSupportingTokenParameters.Endorsing.Add (p);
432 				return sym;
433 			}
434 
435 		}
436 
437 		[MonoTODO]
438 		public static AsymmetricSecurityBindingElement
CreateMutualCertificateDuplexBindingElement()439 			CreateMutualCertificateDuplexBindingElement ()
440 		{
441 			throw new NotImplementedException ();
442 		}
443 
444 		[MonoTODO]
445 		public static AsymmetricSecurityBindingElement
CreateMutualCertificateDuplexBindingElement( MessageSecurityVersion version)446 			CreateMutualCertificateDuplexBindingElement (
447 			MessageSecurityVersion version)
448 		{
449 			throw new NotImplementedException ();
450 		}
451 
452 		public static SymmetricSecurityBindingElement
CreateSslNegotiationBindingElement(bool requireClientCertificate)453 			CreateSslNegotiationBindingElement (bool requireClientCertificate)
454 		{
455 			return CreateSslNegotiationBindingElement (
456 				requireClientCertificate, false);
457 		}
458 
459 		public static SymmetricSecurityBindingElement
CreateSslNegotiationBindingElement( bool requireClientCertificate, bool requireCancellation)460 			CreateSslNegotiationBindingElement (
461 			bool requireClientCertificate,
462 			bool requireCancellation)
463 		{
464 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
465 			be.ProtectionTokenParameters = new SslSecurityTokenParameters (requireClientCertificate, requireCancellation);
466 			return be;
467 		}
468 
469 		public static SymmetricSecurityBindingElement
CreateSspiNegotiationBindingElement()470 			CreateSspiNegotiationBindingElement ()
471 		{
472 			return CreateSspiNegotiationBindingElement (true);
473 		}
474 
475 		public static SymmetricSecurityBindingElement
CreateSspiNegotiationBindingElement(bool requireCancellation)476 			CreateSspiNegotiationBindingElement (bool requireCancellation)
477 		{
478 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
479 			be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
480 			return be;
481 		}
482 
483 		public static TransportSecurityBindingElement
CreateSspiNegotiationOverTransportBindingElement()484 			CreateSspiNegotiationOverTransportBindingElement ()
485 		{
486 			return CreateSspiNegotiationOverTransportBindingElement (false);
487 		}
488 
489 		[MonoTODO]
490 		public static TransportSecurityBindingElement
CreateSspiNegotiationOverTransportBindingElement(bool requireCancellation)491 			CreateSspiNegotiationOverTransportBindingElement (bool requireCancellation)
492 		{
493 			throw new NotImplementedException ();
494 		}
495 
CreateProtectionTokenParameters(bool cert)496 		static X509SecurityTokenParameters CreateProtectionTokenParameters (bool cert)
497 		{
498 			X509SecurityTokenParameters p =
499 				new X509SecurityTokenParameters ();
500 			p.X509ReferenceStyle = X509KeyIdentifierClauseType.Thumbprint;
501 			if (cert)
502 				p.InclusionMode = SecurityTokenInclusionMode.Never;
503 			return p;
504 		}
505 
506 		public static SymmetricSecurityBindingElement
CreateUserNameForCertificateBindingElement()507 			CreateUserNameForCertificateBindingElement ()
508 		{
509 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
510 			be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
511 			UserNameSecurityTokenParameters utp =
512 				new UserNameSecurityTokenParameters ();
513 			be.EndpointSupportingTokenParameters.SignedEncrypted.Add (utp);
514 			return be;
515 		}
516 
517 		public static SymmetricSecurityBindingElement
CreateUserNameForSslBindingElement()518 			CreateUserNameForSslBindingElement ()
519 		{
520 			return CreateUserNameForSslBindingElement (false);
521 		}
522 
523 		public static SymmetricSecurityBindingElement
CreateUserNameForSslBindingElement(bool requireCancellation)524 			CreateUserNameForSslBindingElement (bool requireCancellation)
525 		{
526 			SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
527 			be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
528 			UserNameSecurityTokenParameters utp =
529 				new UserNameSecurityTokenParameters ();
530 			be.EndpointSupportingTokenParameters.SignedEncrypted.Add (utp);
531 			return be;
532 		}
533 #endif
534 
535 		public static SecurityBindingElement
CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity)536 			CreateSecureConversationBindingElement (SecurityBindingElement bootstrapSecurity)
537 		{
538 			return CreateSecureConversationBindingElement (bootstrapSecurity, false);
539 		}
540 
541 		public static SecurityBindingElement
CreateSecureConversationBindingElement( SecurityBindingElement bootstrapSecurity, bool requireCancellation)542 			CreateSecureConversationBindingElement (
543 			SecurityBindingElement bootstrapSecurity, bool requireCancellation)
544 		{
545 			return CreateSecureConversationBindingElement (bootstrapSecurity, requireCancellation, null);
546 		}
547 
548 		public static SecurityBindingElement
CreateSecureConversationBindingElement( SecurityBindingElement bootstrapSecurity, bool requireCancellation, ChannelProtectionRequirements bootstrapProtectionRequirements)549 			CreateSecureConversationBindingElement (
550 			SecurityBindingElement bootstrapSecurity, bool requireCancellation,
551 			ChannelProtectionRequirements bootstrapProtectionRequirements)
552 		{
553 #if !MOBILE && !XAMMAC_4_5
554 			SymmetricSecurityBindingElement be =
555 				new SymmetricSecurityBindingElement ();
556 			be.ProtectionTokenParameters =
557 				new SecureConversationSecurityTokenParameters (
558 					bootstrapSecurity, requireCancellation, bootstrapProtectionRequirements);
559 			return be;
560 #else
561 			throw new NotImplementedException ();
562 #endif
563 		}
564 
565 		[MonoTODO]
566 		public static TransportSecurityBindingElement
CreateUserNameOverTransportBindingElement()567 			CreateUserNameOverTransportBindingElement ()
568 		{
569 			var be = new TransportSecurityBindingElement ();
570 #if !MOBILE && !XAMMAC_4_5 // FIXME: there should be whatever else to do for 2.1 instead.
571 			be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new UserNameSecurityTokenParameters ());
572 #endif
573 			return be;
574 		}
575 		#endregion
576 
577 #if !MOBILE && !XAMMAC_4_5
578 		// It seems almost internal, hardcoded like this (I tried
579 		// custom parameters that sets IssuedTokenSecurityTokenParameters
580 		// like below ones, but that didn't trigger this method).
SetIssuerBindingContextIfRequired( SecurityTokenParameters parameters, BindingContext issuerBindingContext)581 		protected static void SetIssuerBindingContextIfRequired (
582 			SecurityTokenParameters parameters,
583 			BindingContext issuerBindingContext)
584 		{
585 			if (parameters is IssuedSecurityTokenParameters ||
586 			    parameters is SecureConversationSecurityTokenParameters ||
587 			    parameters is SslSecurityTokenParameters ||
588 			    parameters is SspiSecurityTokenParameters) {
589 				parameters.IssuerBindingContext = issuerBindingContext;
590 			}
591 		}
592 #endif
593 	}
594 }
595