2009-04-28 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / AsymmetricSecurityBindingElement.cs
1 //
2 // AsymmetricSecurityBindingElement.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 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.Net.Security;
31 using System.IdentityModel.Selectors;
32 using System.ServiceModel.Channels;
33 using System.ServiceModel.Description;
34 using System.ServiceModel.Dispatcher;
35 using System.ServiceModel.Security;
36 using System.ServiceModel.Security.Tokens;
37
38 namespace System.ServiceModel.Channels
39 {
40         public sealed class AsymmetricSecurityBindingElement
41                 : SecurityBindingElement, IPolicyExportExtension
42         {
43                 public AsymmetricSecurityBindingElement ()
44                         : this (null, null)
45                 {
46                 }
47
48                 public AsymmetricSecurityBindingElement (
49                         SecurityTokenParameters recipientTokenParameters)
50                         : this (recipientTokenParameters, null)
51                 {
52                 }
53
54                 public AsymmetricSecurityBindingElement (
55                         SecurityTokenParameters recipientTokenParameters,
56                         SecurityTokenParameters initiatorTokenParameters)
57                 {
58                         this.initiator_token_params = initiatorTokenParameters;
59                         this.recipient_token_params = recipientTokenParameters;
60                         msg_protection_order = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature;
61                 }
62
63                 private AsymmetricSecurityBindingElement (
64                         AsymmetricSecurityBindingElement other)
65                         : base (other)
66                 {
67                         msg_protection_order = other.msg_protection_order;
68                         require_sig_confirm = other.require_sig_confirm;
69                         if (other.initiator_token_params != null)
70                                 initiator_token_params = other.initiator_token_params.Clone ();
71                         if (other.recipient_token_params != null)
72                                 recipient_token_params = other.recipient_token_params.Clone ();
73                         allow_serialized_sign = other.allow_serialized_sign;
74                 }
75
76                 MessageProtectionOrder msg_protection_order;
77                 SecurityTokenParameters initiator_token_params,
78                         recipient_token_params;
79                 bool allow_serialized_sign, require_sig_confirm;
80
81                 public bool AllowSerializedSigningTokenOnReply {
82                         get { return allow_serialized_sign; }
83                         set { allow_serialized_sign = value; }
84                 }
85
86                 public MessageProtectionOrder MessageProtectionOrder {
87                         get { return msg_protection_order; }
88                         set { msg_protection_order = value; }
89                 }
90
91                 public SecurityTokenParameters InitiatorTokenParameters {
92                         get { return initiator_token_params; }
93                         set { initiator_token_params = value; }
94                 }
95
96                 public SecurityTokenParameters RecipientTokenParameters {
97                         get { return recipient_token_params; }
98                         set { recipient_token_params = value; }
99                 }
100
101                 public bool RequireSignatureConfirmation {
102                         get { return require_sig_confirm; }
103                         set { require_sig_confirm = value; }
104                 }
105
106                 public override void SetKeyDerivation (bool requireDerivedKeys)
107                 {
108                         base.SetKeyDerivation (requireDerivedKeys);
109                         if (InitiatorTokenParameters != null)
110                                 InitiatorTokenParameters.RequireDerivedKeys = requireDerivedKeys;
111                         if (RecipientTokenParameters != null)
112                                 RecipientTokenParameters.RequireDerivedKeys = requireDerivedKeys;
113                 }
114
115                 [MonoTODO]
116                 public override string ToString ()
117                 {
118                         return base.ToString ();
119                 }
120
121                 [MonoTODO]
122                 protected override IChannelFactory<TChannel>
123                         BuildChannelFactoryCore<TChannel> (
124                         BindingContext context)
125                 {
126                         if (InitiatorTokenParameters == null)
127                                 throw new InvalidOperationException ("InitiatorTokenParameters must be set before building channel factory.");
128                         if (RecipientTokenParameters == null)
129                                 throw new InvalidOperationException ("RecipientTokenParameters must be set before building channel factory.");
130
131                         SetIssuerBindingContextIfRequired (InitiatorTokenParameters, context);
132                         SetIssuerBindingContextIfRequired (RecipientTokenParameters, context);
133
134                         ClientCredentials cred = context.BindingParameters.Find<ClientCredentials> ();
135                         if (cred == null)
136                                 // it happens when there is no ChannelFactory<T>.
137                                 cred = new ClientCredentials ();
138                         SecurityTokenManager manager = cred.CreateSecurityTokenManager ();
139                         ChannelProtectionRequirements requirements =
140                                 context.BindingParameters.Find<ChannelProtectionRequirements> ();
141
142                         return new SecurityChannelFactory<TChannel> (
143                                 context.BuildInnerChannelFactory<TChannel> (), new InitiatorMessageSecurityBindingSupport (GetCapabilities (), manager, requirements));
144                 }
145
146                 [MonoTODO]
147                 protected override IChannelListener<TChannel>
148                         BuildChannelListenerCore<TChannel> (
149                         BindingContext context)
150                 {
151                         if (InitiatorTokenParameters == null)
152                                 throw new InvalidOperationException ("InitiatorTokenParameters must be set before building channel factory.");
153                         if (RecipientTokenParameters == null)
154                                 throw new InvalidOperationException ("RecipientTokenParameters must be set before building channel factory.");
155
156                         SetIssuerBindingContextIfRequired (InitiatorTokenParameters, context);
157                         SetIssuerBindingContextIfRequired (RecipientTokenParameters, context);
158
159                         ServiceCredentials cred = context.BindingParameters.Find<ServiceCredentials> ();
160                         if (cred == null)
161                                 // it happens when there is no ChannelFactory<T>.
162                                 cred = new ServiceCredentials ();
163                         ServiceCredentialsSecurityTokenManager manager = (ServiceCredentialsSecurityTokenManager) cred.CreateSecurityTokenManager ();
164                         ChannelProtectionRequirements requirements =
165                                 context.BindingParameters.Find<ChannelProtectionRequirements> ();
166
167                         return new SecurityChannelListener<TChannel> (
168                                 context.BuildInnerChannelListener<TChannel> (), new RecipientMessageSecurityBindingSupport (GetCapabilities (), manager, requirements));
169                 }
170
171                 public override BindingElement Clone ()
172                 {
173                         return new AsymmetricSecurityBindingElement (this);
174                 }
175
176                 [MonoTODO]
177                 public override T GetProperty<T> (BindingContext context)
178                 {
179                         if (context == null)
180                                 throw new ArgumentNullException ("context");
181                         if (typeof (T) == typeof (ISecurityCapabilities))
182                                 return (T) (object) GetCapabilities ();
183                         if (typeof (T) == typeof (IdentityVerifier))
184                                 throw new NotImplementedException ();
185                         return context.GetInnerProperty<T> ();
186                 }
187
188                 AsymmetricSecurityCapabilities GetCapabilities ()
189                 {
190                         return new AsymmetricSecurityCapabilities (this);
191                 }
192
193                 #region explicit interface implementations
194
195                 [MonoTODO]
196                 void IPolicyExportExtension.ExportPolicy (
197                         MetadataExporter exporter,
198                         PolicyConversionContext policyContext)
199                 {
200                         throw new NotImplementedException ();
201                 }
202                 #endregion
203         }
204 }