Merge branch 'master' of github.com:tgiphil/mono
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / SecurityBindingElement.cs
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 !NET_2_1
34 using System.ServiceModel.Channels.Security;
35 using System.IdentityModel.Selectors;
36 using System.IdentityModel.Tokens;
37 using System.ServiceModel.Security.Tokens;
38 #endif
39
40 namespace System.ServiceModel.Channels
41 {
42         public abstract class SecurityBindingElement : BindingElement
43         {
44                 internal SecurityBindingElement ()
45                 {
46 #if !NET_2_1
47                         DefaultAlgorithmSuite = SecurityAlgorithmSuite.Default;
48                         MessageSecurityVersion = MessageSecurityVersion.Default;
49                         KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
50                         endpoint = new SupportingTokenParameters ();
51                         operation = new Dictionary<string,SupportingTokenParameters> ();
52                         opt_endpoint = new SupportingTokenParameters ();
53                         opt_operation = new Dictionary<string,SupportingTokenParameters> ();
54                         service_settings = new LocalServiceSecuritySettings ();
55 #endif
56                         IncludeTimestamp = true;
57                         LocalClientSettings = new LocalClientSecuritySettings ();
58                 }
59
60                 internal SecurityBindingElement (SecurityBindingElement other)
61                 {
62 #if !NET_2_1
63                         alg_suite = other.alg_suite;
64                         key_entropy_mode = other.key_entropy_mode;
65                         security_header_layout = other.security_header_layout;
66                         msg_security_version = other.msg_security_version;
67                         endpoint = other.endpoint.Clone ();
68                         opt_endpoint = other.opt_endpoint.Clone ();
69                         operation = new Dictionary<string,SupportingTokenParameters> ();
70                         foreach (KeyValuePair<string,SupportingTokenParameters> p in other.operation)
71                                 operation.Add (p.Key, p.Value.Clone ());
72                         opt_operation = new Dictionary<string,SupportingTokenParameters> ();
73                         foreach (KeyValuePair<string,SupportingTokenParameters> p in other.opt_operation)
74                                 opt_operation.Add (p.Key, p.Value.Clone ());
75                         service_settings = other.service_settings.Clone ();
76 #endif
77                         IncludeTimestamp = other.IncludeTimestamp;
78                         LocalClientSettings = other.LocalClientSettings.Clone ();
79                 }
80
81 #if !NET_2_1
82                 SecurityAlgorithmSuite alg_suite;
83                 SecurityKeyEntropyMode key_entropy_mode;
84                 SecurityHeaderLayout security_header_layout;
85                 MessageSecurityVersion msg_security_version;
86                 SupportingTokenParameters endpoint, opt_endpoint;
87                 IDictionary<string,SupportingTokenParameters> operation, opt_operation;
88                 LocalServiceSecuritySettings service_settings;
89 #endif
90
91                 public bool IncludeTimestamp { get; set; }
92
93                 public LocalClientSecuritySettings LocalClientSettings { get; private set; }
94
95 #if !NET_2_1
96                 public SecurityAlgorithmSuite DefaultAlgorithmSuite {
97                         get { return alg_suite; }
98                         set { alg_suite = value; }
99                 }
100
101                 public SecurityKeyEntropyMode KeyEntropyMode {
102                         get { return key_entropy_mode; }
103                         set { key_entropy_mode = value; }
104                 }
105
106                 public LocalServiceSecuritySettings LocalServiceSettings {
107                         get { return service_settings; }
108                 }
109
110                 public SecurityHeaderLayout SecurityHeaderLayout {
111                         get { return security_header_layout; }
112                         set { security_header_layout = value; }
113                 }
114
115                 public MessageSecurityVersion MessageSecurityVersion {
116                         get { return msg_security_version; }
117                         set { msg_security_version = value; }
118                 }
119
120                 public SupportingTokenParameters EndpointSupportingTokenParameters {
121                         get { return endpoint; }
122                 }
123
124                 public IDictionary<string,SupportingTokenParameters> OperationSupportingTokenParameters {
125                         get { return operation; }
126                 }
127
128                 public SupportingTokenParameters OptionalEndpointSupportingTokenParameters {
129                         get { return opt_endpoint; }
130                 }
131
132                 public IDictionary<string,SupportingTokenParameters> OptionalOperationSupportingTokenParameters {
133                         get { return opt_operation; }
134                 }
135 #endif
136
137                 [MonoTODO ("It supports only IRequestSessionChannel")]
138                 public override bool CanBuildChannelFactory<TChannel> (BindingContext context)
139                 {
140                         return context.CanBuildInnerChannelFactory<TChannel> ();
141                 }
142
143                 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
144                         BindingContext context)
145                 {
146                         return BuildChannelFactoryCore<TChannel> (context);
147                 }
148
149                 protected abstract IChannelFactory<TChannel>
150                         BuildChannelFactoryCore<TChannel> (BindingContext context);
151
152 #if !NET_2_1
153                 [MonoTODO ("It probably supports only IReplySessionChannel")]
154                 public override bool CanBuildChannelListener<TChannel> (BindingContext context)
155                 {
156                         return context.CanBuildInnerChannelListener<TChannel> ();
157                 }
158
159                 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
160                         BindingContext context)
161                 {
162                         return BuildChannelListenerCore<TChannel> (context);
163                 }
164
165                 protected abstract IChannelListener<TChannel> 
166                         BuildChannelListenerCore<TChannel> (BindingContext context)
167                         where TChannel : class, IChannel;
168
169                 public virtual void SetKeyDerivation (bool requireDerivedKeys)
170                 {
171                         endpoint.SetKeyDerivation (requireDerivedKeys);
172                         opt_endpoint.SetKeyDerivation (requireDerivedKeys);
173                         foreach (SupportingTokenParameters p in operation.Values)
174                                 p.SetKeyDerivation (requireDerivedKeys);
175                         foreach (SupportingTokenParameters p in opt_operation.Values)
176                                 p.SetKeyDerivation (requireDerivedKeys);
177                 }
178
179                 [MonoTODO]
180                 public override string ToString ()
181                 {
182                         return base.ToString ();
183                 }
184 #else
185                 [MonoTODO]
186                 public override T GetProperty<T> (BindingContext context)
187                 {
188                         return null;
189                 }
190 #endif
191
192                 #region Factory methods
193 #if !NET_2_1
194                 public static SymmetricSecurityBindingElement 
195                         CreateAnonymousForCertificateBindingElement ()
196                 {
197                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
198                         be.RequireSignatureConfirmation = true;
199                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
200                         return be;
201                 }
202
203                 public static TransportSecurityBindingElement 
204                         CreateCertificateOverTransportBindingElement ()
205                 {
206                         return CreateCertificateOverTransportBindingElement (MessageSecurityVersion.Default);
207                 }
208
209                 public static TransportSecurityBindingElement 
210                         CreateCertificateOverTransportBindingElement (MessageSecurityVersion version)
211                 {
212                         var be = new TransportSecurityBindingElement () { MessageSecurityVersion = version };
213                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new X509SecurityTokenParameters ());
214                         return be;
215                 }
216
217                 [MonoTODO]
218                 public static AsymmetricSecurityBindingElement 
219                         CreateCertificateSignatureBindingElement  ()
220                 {
221                         throw new NotImplementedException ();
222                 }
223
224                 [MonoTODO]
225                 public static SymmetricSecurityBindingElement 
226                         CreateIssuedTokenBindingElement  (
227                         IssuedSecurityTokenParameters issuedTokenParameters)
228                 {
229                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
230                         be.ProtectionTokenParameters = issuedTokenParameters;
231                         return be;
232                 }
233
234                 public static SymmetricSecurityBindingElement
235                         CreateIssuedTokenForCertificateBindingElement (
236                         IssuedSecurityTokenParameters issuedTokenParameters)
237                 {
238                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
239                         be.RequireSignatureConfirmation = true;
240                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
241                         be.EndpointSupportingTokenParameters.Endorsing.Add (
242                                 issuedTokenParameters);
243                         return be;
244                 }
245
246                 [MonoTODO]
247                 public static SymmetricSecurityBindingElement 
248                         CreateIssuedTokenForSslBindingElement (
249                         IssuedSecurityTokenParameters issuedTokenParameters)
250                 {
251                         return CreateIssuedTokenForSslBindingElement (
252                                 issuedTokenParameters, false);
253                 }
254
255                 [MonoTODO]
256                 public static SymmetricSecurityBindingElement 
257                         CreateIssuedTokenForSslBindingElement (
258                         IssuedSecurityTokenParameters issuedTokenParameters,
259                         bool requireCancellation)
260                 {
261                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
262                         be.RequireSignatureConfirmation = true;
263                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
264                         be.EndpointSupportingTokenParameters.Endorsing.Add (
265                                 issuedTokenParameters);
266                         return be;
267                 }
268
269                 [MonoTODO]
270                 public static TransportSecurityBindingElement 
271                         CreateIssuedTokenOverTransportBindingElement (
272                         IssuedSecurityTokenParameters issuedTokenParameters)
273                 {
274                         throw new NotImplementedException ();
275                 }
276
277                 [MonoTODO]
278                 public static SymmetricSecurityBindingElement CreateKerberosBindingElement ()
279                 {
280                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
281                         be.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128;
282                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
283                         be.ProtectionTokenParameters.InclusionMode =
284                                 SecurityTokenInclusionMode.Once;
285                         return be;
286                 }
287
288                 [MonoTODO]
289                 public static TransportSecurityBindingElement 
290                         CreateKerberosOverTransportBindingElement ()
291                 {
292                         throw new NotImplementedException ();
293                 }
294
295                 [MonoTODO]
296                 public static SecurityBindingElement 
297                         CreateMutualCertificateBindingElement ()
298                 {
299                         throw new NotImplementedException ();
300                 }
301
302                 [MonoTODO]
303                 public static SecurityBindingElement 
304                         CreateMutualCertificateBindingElement (MessageSecurityVersion version)
305                 {
306                         throw new NotImplementedException ();
307                 }
308
309                 [MonoTODO]
310                 public static SecurityBindingElement 
311                         CreateMutualCertificateBindingElement (
312                         MessageSecurityVersion version,
313                         bool allowSerializedSigningTokenOnReply)
314                 {
315                         throw new NotImplementedException ();
316                 }
317
318                 [MonoTODO]
319                 public static AsymmetricSecurityBindingElement 
320                         CreateMutualCertificateDuplexBindingElement ()
321                 {
322                         throw new NotImplementedException ();
323                 }
324
325                 [MonoTODO]
326                 public static AsymmetricSecurityBindingElement 
327                         CreateMutualCertificateDuplexBindingElement (
328                         MessageSecurityVersion version)
329                 {
330                         throw new NotImplementedException ();
331                 }
332
333                 public static SecurityBindingElement 
334                         CreateSecureConversationBindingElement (SecurityBindingElement binding)
335                 {
336                         return CreateSecureConversationBindingElement (binding, false);
337                 }
338
339                 public static SecurityBindingElement 
340                         CreateSecureConversationBindingElement (
341                         SecurityBindingElement binding, bool requireCancellation)
342                 {
343                         return CreateSecureConversationBindingElement (binding, requireCancellation, null);
344                 }
345
346                 public static SecurityBindingElement 
347                         CreateSecureConversationBindingElement (
348                         SecurityBindingElement binding, bool requireCancellation,
349                         ChannelProtectionRequirements protectionRequirements)
350                 {
351                         SymmetricSecurityBindingElement be =
352                                 new SymmetricSecurityBindingElement ();
353                         be.ProtectionTokenParameters =
354                                 new SecureConversationSecurityTokenParameters (
355                                         binding, requireCancellation, protectionRequirements);
356                         return be;
357                 }
358
359                 public static SymmetricSecurityBindingElement 
360                         CreateSslNegotiationBindingElement (bool requireClientCertificate)
361                 {
362                         return CreateSslNegotiationBindingElement (
363                                 requireClientCertificate, false);
364                 }
365
366                 public static SymmetricSecurityBindingElement 
367                         CreateSslNegotiationBindingElement (
368                         bool requireClientCertificate,
369                         bool requireCancellation)
370                 {
371                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
372                         be.ProtectionTokenParameters = new SslSecurityTokenParameters (requireClientCertificate, requireCancellation);
373                         return be;
374                 }
375
376                 public static SymmetricSecurityBindingElement 
377                         CreateSspiNegotiationBindingElement ()
378                 {
379                         return CreateSspiNegotiationBindingElement (true);
380                 }
381
382                 public static SymmetricSecurityBindingElement 
383                         CreateSspiNegotiationBindingElement (bool requireCancellation)
384                 {
385                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
386                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
387                         return be;
388                 }
389
390                 public static TransportSecurityBindingElement 
391                         CreateSspiNegotiationOverTransportBindingElement ()
392                 {
393                         return CreateSspiNegotiationOverTransportBindingElement (false);
394                 }
395
396                 [MonoTODO]
397                 public static TransportSecurityBindingElement 
398                         CreateSspiNegotiationOverTransportBindingElement (bool requireCancellation)
399                 {
400                         throw new NotImplementedException ();
401                 }
402
403                 static X509SecurityTokenParameters CreateProtectionTokenParameters (bool cert)
404                 {
405                         X509SecurityTokenParameters p =
406                                 new X509SecurityTokenParameters ();
407                         p.X509ReferenceStyle = X509KeyIdentifierClauseType.Thumbprint;
408                         if (cert)
409                                 p.InclusionMode = SecurityTokenInclusionMode.Never;
410                         return p;
411                 }
412
413                 public static SymmetricSecurityBindingElement 
414                         CreateUserNameForCertificateBindingElement ()
415                 {
416                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
417                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
418                         UserNameSecurityTokenParameters utp =
419                                 new UserNameSecurityTokenParameters ();
420                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (utp);
421                         return be;
422                 }
423
424                 public static SymmetricSecurityBindingElement 
425                         CreateUserNameForSslBindingElement ()
426                 {
427                         return CreateUserNameForSslBindingElement (false);
428                 }
429
430                 public static SymmetricSecurityBindingElement 
431                         CreateUserNameForSslBindingElement (bool requireCancellation)
432                 {
433                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
434                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
435                         UserNameSecurityTokenParameters utp =
436                                 new UserNameSecurityTokenParameters ();
437                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (utp);
438                         return be;
439                 }
440 #endif
441
442                 [MonoTODO]
443                 public static TransportSecurityBindingElement 
444                         CreateUserNameOverTransportBindingElement ()
445                 {
446                         var be = new TransportSecurityBindingElement ();
447 #if !NET_2_1 // FIXME: there should be whatever else to do for 2.1 instead.
448                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new UserNameSecurityTokenParameters ());
449 #endif
450                         return be;
451                 }
452                 #endregion
453
454 #if !NET_2_1
455                 // It seems almost internal, hardcoded like this (I tried
456                 // custom parameters that sets IssuedTokenSecurityTokenParameters
457                 // like below ones, but that didn't trigger this method).
458                 protected static void SetIssuerBindingContextIfRequired (
459                         SecurityTokenParameters parameters,
460                         BindingContext issuerBindingContext)
461                 {
462                         if (parameters is IssuedSecurityTokenParameters ||
463                             parameters is SecureConversationSecurityTokenParameters ||
464                             parameters is SslSecurityTokenParameters ||
465                             parameters is SspiSecurityTokenParameters) {
466                                 parameters.IssuerBindingContext = issuerBindingContext;
467                         }
468                 }
469 #endif
470         }
471 }