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