Merge pull request #3442 from lateralusX/jlorenss/win-atexit-commands
[mono.git] / mcs / class / System.IdentityModel / System.ServiceModel.Security.Tokens / WrappedKeySecurityToken.cs
1 //
2 // WrappedKeySecurityToken.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 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;
29 using System.Collections.ObjectModel;
30 using System.Security.Cryptography;
31 using System.Security.Cryptography.Xml;
32 using System.Xml;
33 using System.IdentityModel.Policy;
34 using System.IdentityModel.Tokens;
35
36 namespace System.ServiceModel.Security.Tokens
37 {
38         public class WrappedKeySecurityToken : SecurityToken
39         {
40                 string id;
41                 byte [] raw_key;
42                 byte [] wrapped_key;
43                 string wrap_alg;
44                 SecurityToken wrap_token;
45                 SecurityKeyIdentifier wrap_token_ref;
46                 DateTime valid_from = DateTime.Now.ToUniversalTime ();
47                 ReadOnlyCollection<SecurityKey> keys;
48                 ReferenceList reference_list;
49                 byte [] keyhash;
50
51                 public WrappedKeySecurityToken (
52                         string id,
53                         byte [] keyToWrap,
54                         string wrappingAlgorithm,
55                         SecurityToken wrappingToken,
56                         SecurityKeyIdentifier wrappingTokenReference)
57                 {
58                         if (id == null)
59                                 throw new ArgumentNullException ("id");
60                         if (keyToWrap == null)
61                                 throw new ArgumentNullException ("keyToWrap");
62                         if (wrappingAlgorithm == null)
63                                 throw new ArgumentNullException ("wrappingAlgorithm");
64                         if (wrappingToken == null)
65                                 throw new ArgumentNullException ("wrappingToken");
66
67                         raw_key = keyToWrap;
68                         this.id = id;
69                         wrap_alg = wrappingAlgorithm;
70                         wrap_token = wrappingToken;
71                         wrap_token_ref = wrappingTokenReference;
72                         Collection<SecurityKey> l = new Collection<SecurityKey> ();
73                         foreach (SecurityKey sk in wrappingToken.SecurityKeys) {
74                                 if (sk.IsSupportedAlgorithm (wrappingAlgorithm)) {
75                                         wrapped_key = sk.EncryptKey (wrappingAlgorithm, keyToWrap);
76                                         l.Add (new InMemorySymmetricSecurityKey (keyToWrap));
77                                         break;
78                                 }
79                         }
80                         keys = new ReadOnlyCollection<SecurityKey> (l);
81                         if (wrapped_key == null)
82                                 throw new ArgumentException (String.Format ("None of the security keys in the argument token supports specified wrapping algorithm '{0}'", wrappingAlgorithm));
83                 }
84
85                 internal byte [] RawKey {
86                         get { return raw_key; }
87                 }
88
89                 // It is kind of compromised solution to output
90                 // ReferenceList inside e:EncryptedKey and might disappear
91                 // when non-wrapped key is represented by another token type.
92                 internal ReferenceList ReferenceList {
93                         get { return reference_list; }
94                         set { reference_list = value; }
95                 }
96
97                 public override DateTime ValidFrom {
98                         get { return valid_from; }
99                 }
100
101                 public override DateTime ValidTo {
102                         get { return DateTime.MaxValue.AddDays (-1); }
103                 }
104
105                 public override string Id {
106                         get { return id; }
107                 }
108
109                 public override ReadOnlyCollection<SecurityKey> SecurityKeys {
110                         get { return keys; }
111                 }
112
113                 public string WrappingAlgorithm {
114                         get { return wrap_alg; }
115                 }
116
117                 public SecurityToken WrappingToken {
118                         get { return wrap_token; }
119                 }
120
121                 public SecurityKeyIdentifier WrappingTokenReference {
122                         get { return wrap_token_ref; }
123                 }
124
125                 public byte [] GetWrappedKey ()
126                 {
127                         return (byte []) wrapped_key.Clone ();
128                 }
129
130                 internal void SetWrappedKey (byte [] value)
131                 {
132                         wrapped_key = (byte []) value.Clone ();
133                 }
134
135                 [MonoTODO]
136                 public override bool CanCreateKeyIdentifierClause<T> ()
137                 {
138                         /*
139                         foreach (SecurityKeyIdentifierClause k in WrappingTokenReference) {
140                                 Type t = k.GetType ();
141                                 if (t == typeof (T) || t.IsSubclassOf (typeof (T)))
142                                         return true;
143                         }
144                         */
145                         return false;
146                 }
147
148                 [MonoTODO]
149                 public override T CreateKeyIdentifierClause<T> ()
150                 {
151                         /*
152                         foreach (SecurityKeyIdentifierClause k in WrappingTokenReference) {
153                                 Type t = k.GetType ();
154                                 if (t == typeof (T) || t.IsSubclassOf (typeof (T)))
155                                         return (T) k;
156                         }
157                         */
158                         throw new NotSupportedException (String.Format ("WrappedKeySecurityToken cannot create '{0}'", typeof (T)));
159                 }
160
161                 public override bool MatchesKeyIdentifierClause (SecurityKeyIdentifierClause keyIdentifierClause)
162                 {
163                         LocalIdKeyIdentifierClause lkic = keyIdentifierClause as LocalIdKeyIdentifierClause;
164                         if (lkic != null && lkic.LocalId == Id)
165                                 return true;
166
167                         InternalEncryptedKeyIdentifierClause khic = keyIdentifierClause as InternalEncryptedKeyIdentifierClause;
168                         if (keyhash == null)
169                                 keyhash = SHA1.Create ().ComputeHash (wrapped_key);
170                         if (khic != null && khic.Matches (keyhash))
171                                 return true;
172
173                         return false;
174                 }
175         }
176 }