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