WsKeyInfoSerializer.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. using System.Collections.Generic;
  5. using System.IdentityModel;
  6. using System.IdentityModel.Selectors;
  7. using System.IdentityModel.Tokens;
  8. using System.ServiceModel.Security.Tokens;
  9. using System.Xml;
  10. namespace System.ServiceModel.Security
  11. {
  12. class WSKeyInfoSerializer : KeyInfoSerializer
  13. {
  14. static Func<KeyInfoSerializer, IEnumerable<SecurityTokenSerializer.SerializerEntries>> CreateAdditionalEntries(SecurityVersion securityVersion, SecureConversationVersion secureConversationVersion)
  15. {
  16. return (KeyInfoSerializer keyInfoSerializer) =>
  17. {
  18. List<SecurityTokenSerializer.SerializerEntries> serializerEntries = new List<SecurityTokenSerializer.SerializerEntries>();
  19. if (securityVersion == SecurityVersion.WSSecurity10)
  20. {
  21. serializerEntries.Add(new System.IdentityModel.Tokens.WSSecurityJan2004(keyInfoSerializer));
  22. }
  23. else if (securityVersion == SecurityVersion.WSSecurity11)
  24. {
  25. serializerEntries.Add(new System.IdentityModel.Tokens.WSSecurityXXX2005(keyInfoSerializer));
  26. }
  27. else
  28. {
  29. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("securityVersion", SR.GetString(SR.MessageSecurityVersionOutOfRange)));
  30. }
  31. if (secureConversationVersion == SecureConversationVersion.WSSecureConversationFeb2005)
  32. {
  33. serializerEntries.Add(new WSSecureConversationFeb2005(keyInfoSerializer));
  34. }
  35. else if (secureConversationVersion == SecureConversationVersion.WSSecureConversation13)
  36. {
  37. serializerEntries.Add(new WSSecureConversationDec2005(keyInfoSerializer));
  38. }
  39. else
  40. {
  41. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
  42. }
  43. return serializerEntries;
  44. };
  45. }
  46. public WSKeyInfoSerializer(bool emitBspRequiredAttributes, DictionaryManager dictionaryManager, System.IdentityModel.TrustDictionary trustDictionary, SecurityTokenSerializer innerSecurityTokenSerializer, SecurityVersion securityVersion, SecureConversationVersion secureConversationVersion)
  47. : base(emitBspRequiredAttributes, dictionaryManager, trustDictionary, innerSecurityTokenSerializer, CreateAdditionalEntries(securityVersion, secureConversationVersion))
  48. {
  49. }
  50. #region WSSecureConversation classes
  51. abstract class WSSecureConversation : SecurityTokenSerializer.SerializerEntries
  52. {
  53. KeyInfoSerializer securityTokenSerializer;
  54. protected WSSecureConversation( KeyInfoSerializer securityTokenSerializer )
  55. {
  56. this.securityTokenSerializer = securityTokenSerializer;
  57. }
  58. public KeyInfoSerializer SecurityTokenSerializer
  59. {
  60. get { return this.securityTokenSerializer; }
  61. }
  62. public abstract System.IdentityModel.SecureConversationDictionary SerializerDictionary
  63. {
  64. get;
  65. }
  66. public virtual string DerivationAlgorithm
  67. {
  68. get { return SecurityAlgorithms.Psha1KeyDerivation; }
  69. }
  70. public override void PopulateTokenEntries( IList<TokenEntry> tokenEntryList )
  71. {
  72. if ( tokenEntryList == null )
  73. {
  74. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "tokenEntryList" );
  75. }
  76. tokenEntryList.Add( new DerivedKeyTokenEntry( this ) );
  77. tokenEntryList.Add( new SecurityContextTokenEntry( this ) );
  78. }
  79. protected abstract class SctStrEntry : StrEntry
  80. {
  81. WSSecureConversation parent;
  82. public SctStrEntry( WSSecureConversation parent )
  83. {
  84. this.parent = parent;
  85. }
  86. protected WSSecureConversation Parent
  87. {
  88. get { return this.parent; }
  89. }
  90. public override Type GetTokenType( SecurityKeyIdentifierClause clause )
  91. {
  92. return null;
  93. }
  94. public override string GetTokenTypeUri()
  95. {
  96. return null;
  97. }
  98. public override bool CanReadClause( XmlDictionaryReader reader, string tokenType )
  99. {
  100. if ( tokenType != null && tokenType != parent.SerializerDictionary.SecurityContextTokenType.Value )
  101. {
  102. return false;
  103. }
  104. if ( reader.IsStartElement(
  105. parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.Reference,
  106. parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.Namespace ) )
  107. {
  108. string valueType = reader.GetAttribute( parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.ValueType, null );
  109. if ( valueType != null && valueType != parent.SerializerDictionary.SecurityContextTokenReferenceValueType.Value )
  110. {
  111. return false;
  112. }
  113. string uri = reader.GetAttribute( parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.URI, null );
  114. if ( uri != null )
  115. {
  116. if ( uri.Length > 0 && uri[0] != '#' )
  117. {
  118. return true;
  119. }
  120. }
  121. }
  122. return false;
  123. }
  124. public override SecurityKeyIdentifierClause ReadClause( XmlDictionaryReader reader, byte[] derivationNonce, int derivationLength, string tokenType )
  125. {
  126. System.Xml.UniqueId uri = XmlHelper.GetAttributeAsUniqueId( reader, XD.SecurityJan2004Dictionary.URI, null );
  127. System.Xml.UniqueId generation = ReadGeneration( reader );
  128. if ( reader.IsEmptyElement )
  129. {
  130. reader.Read();
  131. }
  132. else
  133. {
  134. reader.ReadStartElement();
  135. while ( reader.IsStartElement() )
  136. {
  137. reader.Skip();
  138. }
  139. reader.ReadEndElement();
  140. }
  141. return new SecurityContextKeyIdentifierClause( uri, generation, derivationNonce, derivationLength );
  142. }
  143. protected abstract System.Xml.UniqueId ReadGeneration( XmlDictionaryReader reader );
  144. public override bool SupportsCore( SecurityKeyIdentifierClause clause )
  145. {
  146. return clause is SecurityContextKeyIdentifierClause;
  147. }
  148. public override void WriteContent( XmlDictionaryWriter writer, SecurityKeyIdentifierClause clause )
  149. {
  150. SecurityContextKeyIdentifierClause sctClause = clause as SecurityContextKeyIdentifierClause;
  151. writer.WriteStartElement( XD.SecurityJan2004Dictionary.Prefix.Value, XD.SecurityJan2004Dictionary.Reference, XD.SecurityJan2004Dictionary.Namespace );
  152. XmlHelper.WriteAttributeStringAsUniqueId( writer, null, XD.SecurityJan2004Dictionary.URI, null, sctClause.ContextId );
  153. WriteGeneration( writer, sctClause );
  154. writer.WriteAttributeString( XD.SecurityJan2004Dictionary.ValueType, null, parent.SerializerDictionary.SecurityContextTokenReferenceValueType.Value );
  155. writer.WriteEndElement();
  156. }
  157. protected abstract void WriteGeneration( XmlDictionaryWriter writer, SecurityContextKeyIdentifierClause clause );
  158. }
  159. protected class SecurityContextTokenEntry : SecurityTokenSerializer.TokenEntry
  160. {
  161. WSSecureConversation parent;
  162. Type[] tokenTypes;
  163. public SecurityContextTokenEntry( WSSecureConversation parent )
  164. {
  165. this.parent = parent;
  166. }
  167. protected WSSecureConversation Parent
  168. {
  169. get { return this.parent; }
  170. }
  171. protected override XmlDictionaryString LocalName { get { return parent.SerializerDictionary.SecurityContextToken; } }
  172. protected override XmlDictionaryString NamespaceUri { get { return parent.SerializerDictionary.Namespace; } }
  173. protected override Type[] GetTokenTypesCore()
  174. {
  175. if ( tokenTypes == null )
  176. this.tokenTypes = new Type[] { typeof( SecurityContextSecurityToken ) };
  177. return this.tokenTypes;
  178. }
  179. public override string TokenTypeUri { get { return parent.SerializerDictionary.SecurityContextTokenType.Value; } }
  180. protected override string ValueTypeUri { get { return null; } }
  181. }
  182. protected class DerivedKeyTokenEntry : SecurityTokenSerializer.TokenEntry
  183. {
  184. public const string DefaultLabel = "WS-SecureConversation";
  185. WSSecureConversation parent;
  186. Type[] tokenTypes;
  187. public DerivedKeyTokenEntry( WSSecureConversation parent )
  188. {
  189. if ( parent == null )
  190. {
  191. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "parent" );
  192. }
  193. this.parent = parent;
  194. }
  195. protected override XmlDictionaryString LocalName { get { return parent.SerializerDictionary.DerivedKeyToken; } }
  196. protected override XmlDictionaryString NamespaceUri { get { return parent.SerializerDictionary.Namespace; } }
  197. protected override Type[] GetTokenTypesCore()
  198. {
  199. if ( tokenTypes == null )
  200. this.tokenTypes = new Type[] { typeof( DerivedKeySecurityToken ) };
  201. return this.tokenTypes;
  202. }
  203. public override string TokenTypeUri { get { return parent.SerializerDictionary.DerivedKeyTokenType.Value; } }
  204. protected override string ValueTypeUri { get { return null; } }
  205. }
  206. }
  207. class WSSecureConversationFeb2005 : WSSecureConversation
  208. {
  209. public WSSecureConversationFeb2005( KeyInfoSerializer securityTokenSerializer )
  210. : base( securityTokenSerializer )
  211. {
  212. }
  213. public override System.IdentityModel.SecureConversationDictionary SerializerDictionary
  214. {
  215. get { return this.SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary; }
  216. }
  217. public override void PopulateStrEntries( IList<StrEntry> strEntries )
  218. {
  219. strEntries.Add( new SctStrEntryFeb2005( this ) );
  220. }
  221. class SctStrEntryFeb2005 : SctStrEntry
  222. {
  223. public SctStrEntryFeb2005( WSSecureConversationFeb2005 parent )
  224. : base( parent )
  225. {
  226. }
  227. protected override System.Xml.UniqueId ReadGeneration( XmlDictionaryReader reader )
  228. {
  229. return XmlHelper.GetAttributeAsUniqueId(
  230. reader,
  231. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance,
  232. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary.Namespace );
  233. }
  234. protected override void WriteGeneration( XmlDictionaryWriter writer, SecurityContextKeyIdentifierClause clause )
  235. {
  236. // serialize the generation
  237. if ( clause.Generation != null )
  238. {
  239. XmlHelper.WriteAttributeStringAsUniqueId(
  240. writer,
  241. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary.Prefix.Value,
  242. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance,
  243. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary.Namespace,
  244. clause.Generation );
  245. }
  246. }
  247. }
  248. }
  249. class WSSecureConversationDec2005 : WSSecureConversation
  250. {
  251. public WSSecureConversationDec2005( KeyInfoSerializer securityTokenSerializer )
  252. : base( securityTokenSerializer )
  253. {
  254. }
  255. public override System.IdentityModel.SecureConversationDictionary SerializerDictionary
  256. {
  257. get { return this.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary; }
  258. }
  259. public override void PopulateStrEntries( IList<StrEntry> strEntries )
  260. {
  261. strEntries.Add( new SctStrEntryDec2005( this ) );
  262. }
  263. public override string DerivationAlgorithm
  264. {
  265. get
  266. {
  267. return SecurityAlgorithms.Psha1KeyDerivationDec2005;
  268. }
  269. }
  270. class SctStrEntryDec2005 : SctStrEntry
  271. {
  272. public SctStrEntryDec2005( WSSecureConversationDec2005 parent )
  273. : base( parent )
  274. {
  275. }
  276. protected override System.Xml.UniqueId ReadGeneration( XmlDictionaryReader reader )
  277. {
  278. return XmlHelper.GetAttributeAsUniqueId( reader, this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance,
  279. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Namespace );
  280. }
  281. protected override void WriteGeneration( XmlDictionaryWriter writer, SecurityContextKeyIdentifierClause clause )
  282. {
  283. // serialize the generation
  284. if ( clause.Generation != null )
  285. {
  286. XmlHelper.WriteAttributeStringAsUniqueId(
  287. writer,
  288. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Prefix.Value,
  289. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance,
  290. this.Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Namespace,
  291. clause.Generation );
  292. }
  293. }
  294. }
  295. }
  296. #endregion
  297. }
  298. }