| File: System\ServiceModel\Security\WSKeyInfoSerializer.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.IdentityModel; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.ServiceModel.Security.Tokens; using System.Xml; namespace System.ServiceModel.Security { internal class WSKeyInfoSerializer : KeyInfoSerializer { private static Func<KeyInfoSerializer, IEnumerable<SerializerEntries>> CreateAdditionalEntries(SecurityVersion securityVersion, SecureConversationVersion secureConversationVersion) { return (KeyInfoSerializer keyInfoSerializer) => { List<SerializerEntries> serializerEntries = new List<SerializerEntries>(); if (securityVersion == SecurityVersion.WSSecurity10) { serializerEntries.Add(new IdentityModel.Tokens.WSSecurityJan2004(keyInfoSerializer)); } else if (securityVersion == SecurityVersion.WSSecurity11) { serializerEntries.Add(new IdentityModel.Tokens.WSSecurityXXX2005(keyInfoSerializer)); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(securityVersion), SRP.MessageSecurityVersionOutOfRange)); } if (secureConversationVersion == SecureConversationVersion.WSSecureConversationFeb2005) { serializerEntries.Add(new WSSecureConversationFeb2005(keyInfoSerializer)); } else if (secureConversationVersion == SecureConversationVersion.WSSecureConversation13) { serializerEntries.Add(new WSSecureConversationDec2005(keyInfoSerializer)); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } return serializerEntries; }; } public WSKeyInfoSerializer(bool emitBspRequiredAttributes, DictionaryManager dictionaryManager, IdentityModel.TrustDictionary trustDictionary, SecurityTokenSerializer innerSecurityTokenSerializer, SecurityVersion securityVersion, SecureConversationVersion secureConversationVersion) : base(emitBspRequiredAttributes, dictionaryManager, trustDictionary, innerSecurityTokenSerializer, CreateAdditionalEntries(securityVersion, secureConversationVersion)) { } #region WSSecureConversation classes private abstract class WSSecureConversation : SerializerEntries { protected WSSecureConversation(KeyInfoSerializer securityTokenSerializer) { SecurityTokenSerializer = securityTokenSerializer; } public KeyInfoSerializer SecurityTokenSerializer { get; } public abstract IdentityModel.SecureConversationDictionary SerializerDictionary { get; } public virtual string DerivationAlgorithm { get { return SecurityAlgorithms.Psha1KeyDerivation; } } public override void PopulateTokenEntries(IList<TokenEntry> tokenEntryList) { if (tokenEntryList == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tokenEntryList)); } tokenEntryList.Add(new DerivedKeyTokenEntry(this)); tokenEntryList.Add(new SecurityContextTokenEntry(this)); } protected abstract class SctStrEntry : StrEntry { public SctStrEntry(WSSecureConversation parent) { Parent = parent; } protected WSSecureConversation Parent { get; } public override Type GetTokenType(SecurityKeyIdentifierClause clause) { return null; } public override string GetTokenTypeUri() { return null; } public override bool CanReadClause(XmlDictionaryReader reader, string tokenType) { if (tokenType != null && tokenType != Parent.SerializerDictionary.SecurityContextTokenType.Value) { return false; } if (reader.IsStartElement( Parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.Reference, Parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.Namespace)) { string valueType = reader.GetAttribute(Parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.ValueType, null); if (valueType != null && valueType != Parent.SerializerDictionary.SecurityContextTokenReferenceValueType.Value) { return false; } string uri = reader.GetAttribute(Parent.SecurityTokenSerializer.DictionaryManager.SecurityJan2004Dictionary.URI, null); if (uri != null) { if (uri.Length > 0 && uri[0] != '#') { return true; } } } return false; } public override SecurityKeyIdentifierClause ReadClause(XmlDictionaryReader reader, byte[] derivationNonce, int derivationLength, string tokenType) { UniqueId uri = XmlHelper.GetAttributeAsUniqueId(reader, XD.SecurityJan2004Dictionary.URI, null); UniqueId generation = ReadGeneration(reader); if (reader.IsEmptyElement) { reader.Read(); } else { reader.ReadStartElement(); while (reader.IsStartElement()) { reader.Skip(); } reader.ReadEndElement(); } return new SecurityContextKeyIdentifierClause(uri, generation, derivationNonce, derivationLength); } protected abstract UniqueId ReadGeneration(XmlDictionaryReader reader); public override bool SupportsCore(SecurityKeyIdentifierClause clause) { return clause is SecurityContextKeyIdentifierClause; } public override void WriteContent(XmlDictionaryWriter writer, SecurityKeyIdentifierClause clause) { SecurityContextKeyIdentifierClause sctClause = clause as SecurityContextKeyIdentifierClause; writer.WriteStartElement(XD.SecurityJan2004Dictionary.Prefix.Value, XD.SecurityJan2004Dictionary.Reference, XD.SecurityJan2004Dictionary.Namespace); XmlHelper.WriteAttributeStringAsUniqueId(writer, null, XD.SecurityJan2004Dictionary.URI, null, sctClause.ContextId); WriteGeneration(writer, sctClause); writer.WriteAttributeString(XD.SecurityJan2004Dictionary.ValueType, null, Parent.SerializerDictionary.SecurityContextTokenReferenceValueType.Value); writer.WriteEndElement(); } protected abstract void WriteGeneration(XmlDictionaryWriter writer, SecurityContextKeyIdentifierClause clause); } protected class SecurityContextTokenEntry : TokenEntry { private Type[] _tokenTypes; public SecurityContextTokenEntry(WSSecureConversation parent) { Parent = parent; } protected WSSecureConversation Parent { get; } protected override XmlDictionaryString LocalName { get { return Parent.SerializerDictionary.SecurityContextToken; } } protected override XmlDictionaryString NamespaceUri { get { return Parent.SerializerDictionary.Namespace; } } protected override Type[] GetTokenTypesCore() { if (_tokenTypes == null) { _tokenTypes = new Type[] { typeof(SecurityContextSecurityToken) }; } return _tokenTypes; } public override string TokenTypeUri { get { return Parent.SerializerDictionary.SecurityContextTokenType.Value; } } protected override string ValueTypeUri { get { return null; } } } protected class DerivedKeyTokenEntry : TokenEntry { public const string DefaultLabel = "WS-SecureConversation"; private WSSecureConversation _parent; private Type[] _tokenTypes; public DerivedKeyTokenEntry(WSSecureConversation parent) { _parent = parent ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(parent)); } protected override XmlDictionaryString LocalName { get { return _parent.SerializerDictionary.DerivedKeyToken; } } protected override XmlDictionaryString NamespaceUri { get { return _parent.SerializerDictionary.Namespace; } } protected override Type[] GetTokenTypesCore() { if (_tokenTypes == null) { _tokenTypes = new Type[] { typeof(DerivedKeySecurityToken) }; } return _tokenTypes; } public override string TokenTypeUri { get { return _parent.SerializerDictionary.DerivedKeyTokenType.Value; } } protected override string ValueTypeUri { get { return null; } } } } private class WSSecureConversationFeb2005 : WSSecureConversation { public WSSecureConversationFeb2005(KeyInfoSerializer securityTokenSerializer) : base(securityTokenSerializer) { } public override IdentityModel.SecureConversationDictionary SerializerDictionary { get { return SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary; } } public override void PopulateStrEntries(IList<StrEntry> strEntries) { strEntries.Add(new SctStrEntryFeb2005(this)); } private class SctStrEntryFeb2005 : SctStrEntry { public SctStrEntryFeb2005(WSSecureConversationFeb2005 parent) : base(parent) { } protected override UniqueId ReadGeneration(XmlDictionaryReader reader) { return XmlHelper.GetAttributeAsUniqueId( reader, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary.Namespace); } protected override void WriteGeneration(XmlDictionaryWriter writer, SecurityContextKeyIdentifierClause clause) { // serialize the generation if (clause.Generation != null) { XmlHelper.WriteAttributeStringAsUniqueId( writer, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary.Prefix.Value, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationFeb2005Dictionary.Namespace, clause.Generation); } } } } private class WSSecureConversationDec2005 : WSSecureConversation { public WSSecureConversationDec2005(KeyInfoSerializer securityTokenSerializer) : base(securityTokenSerializer) { } public override IdentityModel.SecureConversationDictionary SerializerDictionary { get { return SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary; } } public override void PopulateStrEntries(IList<StrEntry> strEntries) { strEntries.Add(new SctStrEntryDec2005(this)); } public override string DerivationAlgorithm { get { return SecurityAlgorithms.Psha1KeyDerivationDec2005; } } private class SctStrEntryDec2005 : SctStrEntry { public SctStrEntryDec2005(WSSecureConversationDec2005 parent) : base(parent) { } protected override UniqueId ReadGeneration(XmlDictionaryReader reader) { return XmlHelper.GetAttributeAsUniqueId(reader, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Namespace); } protected override void WriteGeneration(XmlDictionaryWriter writer, SecurityContextKeyIdentifierClause clause) { // serialize the generation if (clause.Generation != null) { XmlHelper.WriteAttributeStringAsUniqueId( writer, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Prefix.Value, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Instance, Parent.SecurityTokenSerializer.DictionaryManager.SecureConversationDec2005Dictionary.Namespace, clause.Generation); } } } } #endregion } }