1 //------------------------------------------------------------------------------
2 //     Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------------------------
4 
5 namespace System.IdentityModel.Tokens
6 {
7     using System.Collections.Generic;
8     using System.IdentityModel;
9     using System.IdentityModel.Security;
10     using System.IdentityModel.Selectors;
11     using System.Runtime;
12     using System.Xml;
13 using System.Collections;
14 
15     /// <summary>
16     /// Abstract class for SecurityKeyIdentifierClause Serializer.
17     /// </summary>
18     internal class KeyInfoSerializer : SecurityTokenSerializer
19     {
20         readonly List<SecurityTokenSerializer.KeyIdentifierEntry> keyIdentifierEntries;
21         readonly List<SecurityTokenSerializer.KeyIdentifierClauseEntry> keyIdentifierClauseEntries;
22         readonly List<SecurityTokenSerializer.SerializerEntries> serializerEntries;
23         readonly List<TokenEntry> tokenEntries;
24 
25 
26         DictionaryManager dictionaryManager;
27         bool emitBspRequiredAttributes;
28         SecurityTokenSerializer innerSecurityTokenSerializer;
29 
30         /// <summary>
31         /// Creates an instance of <see cref="SecurityKeyIdentifierClauseSerializer"/>
32         /// </summary>
KeyInfoSerializer(bool emitBspRequiredAttributes)33         public KeyInfoSerializer(bool emitBspRequiredAttributes)
34             : this(emitBspRequiredAttributes, new DictionaryManager(), XD.TrustDec2005Dictionary, null)
35         {
36         }
37 
KeyInfoSerializer( bool emitBspRequiredAttributes, DictionaryManager dictionaryManager, TrustDictionary trustDictionary, SecurityTokenSerializer innerSecurityTokenSerializer )38         public KeyInfoSerializer(
39             bool emitBspRequiredAttributes,
40             DictionaryManager dictionaryManager,
41             TrustDictionary trustDictionary,
42             SecurityTokenSerializer innerSecurityTokenSerializer ) :
43             this( emitBspRequiredAttributes, dictionaryManager, trustDictionary, innerSecurityTokenSerializer, null )
44         {
45         }
46 
KeyInfoSerializer( bool emitBspRequiredAttributes, DictionaryManager dictionaryManager, TrustDictionary trustDictionary, SecurityTokenSerializer innerSecurityTokenSerializer, Func<KeyInfoSerializer, IEnumerable<SerializerEntries>> additionalEntries)47         public KeyInfoSerializer(
48             bool emitBspRequiredAttributes,
49             DictionaryManager dictionaryManager,
50             TrustDictionary trustDictionary,
51             SecurityTokenSerializer innerSecurityTokenSerializer,
52             Func<KeyInfoSerializer, IEnumerable<SerializerEntries>> additionalEntries)
53         {
54             this.dictionaryManager = dictionaryManager;
55             this.emitBspRequiredAttributes = emitBspRequiredAttributes;
56             this.innerSecurityTokenSerializer = innerSecurityTokenSerializer;
57 
58             this.serializerEntries = new List<SecurityTokenSerializer.SerializerEntries>();
59 
60             this.serializerEntries.Add(new XmlDsigSep2000(this));
61             this.serializerEntries.Add(new XmlEncApr2001(this));
62             this.serializerEntries.Add(new System.IdentityModel.Security.WSTrust(this, trustDictionary));
63             if ( additionalEntries != null )
64             {
65                 foreach ( SerializerEntries entries in additionalEntries( this ) )
66                 {
67                     this.serializerEntries.Add(entries);
68                 }
69             }
70 
71             bool wsSecuritySerializerFound = false;
72             foreach ( SerializerEntries entry in this.serializerEntries )
73             {
74                 if ( ( entry is WSSecurityXXX2005 ) || ( entry is WSSecurityJan2004 ) )
75                 {
76                     wsSecuritySerializerFound = true;
77                     break;
78                 }
79             }
80 
81             if ( !wsSecuritySerializerFound )
82             {
83                 this.serializerEntries.Add( new WSSecurityXXX2005( this ) );
84             }
85 
86             this.tokenEntries = new List<TokenEntry>();
87             this.keyIdentifierEntries = new List<SecurityTokenSerializer.KeyIdentifierEntry>();
88             this.keyIdentifierClauseEntries = new List<SecurityTokenSerializer.KeyIdentifierClauseEntry>();
89 
90             for (int i = 0; i < this.serializerEntries.Count; ++i)
91             {
92                 SecurityTokenSerializer.SerializerEntries serializerEntry = this.serializerEntries[i];
93                 serializerEntry.PopulateTokenEntries(this.tokenEntries);
94                 serializerEntry.PopulateKeyIdentifierEntries(this.keyIdentifierEntries);
95                 serializerEntry.PopulateKeyIdentifierClauseEntries(this.keyIdentifierClauseEntries);
96             }
97         }
98 
99         public DictionaryManager DictionaryManager
100         {
101             get { return this.dictionaryManager; }
102         }
103 
104         /// <summary>
105         /// Gets or sets a value indicating if BSP required attributes should be written out.
106         /// </summary>
107         public bool EmitBspRequiredAttributes
108         {
109             get
110             {
111                 return this.emitBspRequiredAttributes;
112             }
113         }
114 
115         public SecurityTokenSerializer InnerSecurityTokenSerializer
116         {
117             get
118             {
119                 return this.innerSecurityTokenSerializer == null ? this : this.innerSecurityTokenSerializer;
120             }
121            set
122             {
123                 this.innerSecurityTokenSerializer = value;
124             }
125         }
126 
CanReadTokenCore(XmlReader reader)127         protected override bool CanReadTokenCore(XmlReader reader)
128         {
129             return false;
130         }
131 
ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)132         protected override SecurityToken ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)
133         {
134             XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader( reader );
135             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException( SR.GetString( SR.CannotReadToken, reader.LocalName, reader.NamespaceURI, localReader.GetAttribute( XD.SecurityJan2004Dictionary.ValueType, null ) ) ) );
136         }
137 
CanWriteTokenCore(SecurityToken token)138         protected override bool CanWriteTokenCore(SecurityToken token)
139         {
140             return false;
141         }
142 
WriteTokenCore(XmlWriter writer, SecurityToken token)143         protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
144         {
145             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StandardsManagerCannotWriteObject, token.GetType())));
146         }
147 
CanReadKeyIdentifierCore(XmlReader reader)148         protected override bool CanReadKeyIdentifierCore(XmlReader reader)
149         {
150             XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader(reader);
151             for (int i = 0; i < this.keyIdentifierEntries.Count; i++)
152             {
153                 KeyIdentifierEntry keyIdentifierEntry = this.keyIdentifierEntries[i];
154                 if (keyIdentifierEntry.CanReadKeyIdentifierCore(localReader))
155                     return true;
156             }
157             return false;
158         }
159 
ReadKeyIdentifierCore(XmlReader reader)160         protected override SecurityKeyIdentifier ReadKeyIdentifierCore(XmlReader reader)
161         {
162             XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader(reader);
163             localReader.ReadStartElement(XD.XmlSignatureDictionary.KeyInfo, XD.XmlSignatureDictionary.Namespace);
164             SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier();
165             while (localReader.IsStartElement())
166             {
167                 SecurityKeyIdentifierClause clause = this.InnerSecurityTokenSerializer.ReadKeyIdentifierClause(localReader);
168                 if (clause == null)
169                 {
170                     localReader.Skip();
171                 }
172                 else
173                 {
174                     keyIdentifier.Add(clause);
175                 }
176             }
177             if (keyIdentifier.Count == 0)
178             {
179                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ErrorDeserializingKeyIdentifierClause)));
180             }
181             localReader.ReadEndElement();
182 
183             return keyIdentifier;
184         }
185 
CanWriteKeyIdentifierCore(SecurityKeyIdentifier keyIdentifier)186         protected override bool CanWriteKeyIdentifierCore(SecurityKeyIdentifier keyIdentifier)
187         {
188             for (int i = 0; i < this.keyIdentifierEntries.Count; ++i)
189             {
190                 KeyIdentifierEntry keyIdentifierEntry = this.keyIdentifierEntries[i];
191                 if (keyIdentifierEntry.SupportsCore(keyIdentifier))
192                     return true;
193             }
194             return false;
195         }
196 
WriteKeyIdentifierCore(XmlWriter writer, SecurityKeyIdentifier keyIdentifier)197         protected override void WriteKeyIdentifierCore(XmlWriter writer, SecurityKeyIdentifier keyIdentifier)
198         {
199             bool wroteKeyIdentifier = false;
200             XmlDictionaryWriter localWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer);
201             for (int i = 0; i < this.keyIdentifierEntries.Count; ++i)
202             {
203                 KeyIdentifierEntry keyIdentifierEntry = this.keyIdentifierEntries[i];
204                 if (keyIdentifierEntry.SupportsCore(keyIdentifier))
205                 {
206                     try
207                     {
208                         keyIdentifierEntry.WriteKeyIdentifierCore(localWriter, keyIdentifier);
209                     }
210 #pragma warning suppress 56500 // covered by FxCOP
211                     catch (Exception e)
212                     {
213                         if (Fx.IsFatal(e))
214                             throw;
215 
216                         if (!ShouldWrapException(e))
217                         {
218                             throw;
219                         }
220 
221                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ErrorSerializingKeyIdentifier), e));
222                     }
223                     wroteKeyIdentifier = true;
224                     break;
225                 }
226             }
227 
228             if (!wroteKeyIdentifier)
229                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StandardsManagerCannotWriteObject, keyIdentifier.GetType())));
230 
231             localWriter.Flush();
232         }
233 
CanReadKeyIdentifierClauseCore(XmlReader reader)234         protected override bool CanReadKeyIdentifierClauseCore(XmlReader reader)
235         {
236             XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader(reader);
237             for (int i = 0; i < this.keyIdentifierClauseEntries.Count; i++)
238             {
239                 KeyIdentifierClauseEntry keyIdentifierClauseEntry = this.keyIdentifierClauseEntries[i];
240                 if (keyIdentifierClauseEntry.CanReadKeyIdentifierClauseCore(localReader))
241                     return true;
242             }
243             return false;
244         }
245 
ReadKeyIdentifierClauseCore(XmlReader reader)246         protected override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlReader reader)
247         {
248             XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader(reader);
249             for (int i = 0; i < this.keyIdentifierClauseEntries.Count; i++)
250             {
251                 KeyIdentifierClauseEntry keyIdentifierClauseEntry = this.keyIdentifierClauseEntries[i];
252                 if (keyIdentifierClauseEntry.CanReadKeyIdentifierClauseCore(localReader))
253                 {
254                     try
255                     {
256                         return keyIdentifierClauseEntry.ReadKeyIdentifierClauseCore(localReader);
257                     }
258 #pragma warning suppress 56500 // covered by FxCOP
259                     catch (Exception e)
260                     {
261                         if (Fx.IsFatal(e))
262                             throw;
263 
264                         if (!ShouldWrapException(e))
265                         {
266                             throw;
267                         }
268                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ErrorDeserializingKeyIdentifierClause), e));
269                     }
270                 }
271             }
272             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.CannotReadKeyIdentifierClause, reader.LocalName, reader.NamespaceURI)));
273         }
274 
CanWriteKeyIdentifierClauseCore(SecurityKeyIdentifierClause keyIdentifierClause)275         protected override bool CanWriteKeyIdentifierClauseCore(SecurityKeyIdentifierClause keyIdentifierClause)
276         {
277             for (int i = 0; i < this.keyIdentifierClauseEntries.Count; ++i)
278             {
279                 KeyIdentifierClauseEntry keyIdentifierClauseEntry = this.keyIdentifierClauseEntries[i];
280                 if (keyIdentifierClauseEntry.SupportsCore(keyIdentifierClause))
281                     return true;
282             }
283             return false;
284         }
285 
WriteKeyIdentifierClauseCore(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)286         protected override void WriteKeyIdentifierClauseCore(XmlWriter writer, SecurityKeyIdentifierClause keyIdentifierClause)
287         {
288             bool wroteKeyIdentifierClause = false;
289             XmlDictionaryWriter localWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer);
290             for (int i = 0; i < this.keyIdentifierClauseEntries.Count; ++i)
291             {
292                 KeyIdentifierClauseEntry keyIdentifierClauseEntry = this.keyIdentifierClauseEntries[i];
293                 if (keyIdentifierClauseEntry.SupportsCore(keyIdentifierClause))
294                 {
295                     try
296                     {
297                         keyIdentifierClauseEntry.WriteKeyIdentifierClauseCore(localWriter, keyIdentifierClause);
298                     }
299 #pragma warning suppress 56500 // covered by FxCOP
300                     catch (Exception e)
301                     {
302                         if (Fx.IsFatal(e))
303                             throw;
304 
305                         if (!ShouldWrapException(e))
306                         {
307                             throw;
308                         }
309 
310                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ErrorSerializingKeyIdentifierClause), e));
311                     }
312                     wroteKeyIdentifierClause = true;
313                     break;
314                 }
315             }
316 
317             if (!wroteKeyIdentifierClause)
318                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.StandardsManagerCannotWriteObject, keyIdentifierClause.GetType())));
319 
320             localWriter.Flush();
321         }
322 
PopulateStrEntries(IList<StrEntry> strEntries)323         internal void PopulateStrEntries(IList<StrEntry> strEntries)
324         {
325             foreach (SerializerEntries serializerEntry in serializerEntries)
326             {
327                 serializerEntry.PopulateStrEntries(strEntries);
328             }
329         }
330 
ShouldWrapException(Exception e)331         bool ShouldWrapException(Exception e)
332         {
333             return ((e is ArgumentException) || (e is FormatException) || (e is InvalidOperationException));
334         }
335 
GetTokenTypes(string tokenTypeUri)336         internal Type[] GetTokenTypes(string tokenTypeUri)
337         {
338             if (tokenTypeUri != null)
339             {
340                 for (int i = 0; i < this.tokenEntries.Count; i++)
341                 {
342                     TokenEntry tokenEntry = this.tokenEntries[i];
343 
344                     if (tokenEntry.SupportsTokenTypeUri(tokenTypeUri))
345                     {
346                         return tokenEntry.GetTokenTypes();
347                     }
348                 }
349             }
350             return null;
351         }
352 
GetTokenTypeUri(Type tokenType)353         protected internal virtual string GetTokenTypeUri(Type tokenType)
354         {
355             if (tokenType != null)
356             {
357                 for (int i = 0; i < this.tokenEntries.Count; i++)
358                 {
359                     TokenEntry tokenEntry = this.tokenEntries[i];
360 
361                     if (tokenEntry.SupportsCore(tokenType))
362                     {
363                         return tokenEntry.TokenTypeUri;
364                     }
365                 }
366             }
367             return null;
368         }
369 
370     }
371 
372 }
373