| File: System\IdentityModel\Tokens\XmlDsigSep2000.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.Selectors; using System.Security.Cryptography.X509Certificates; using System.ServiceModel; using System.Xml; using KeyIdentifierEntry = System.IdentityModel.Selectors.SecurityTokenSerializer.KeyIdentifierEntry; namespace System.IdentityModel.Tokens { internal class XmlDsigSep2000 : SecurityTokenSerializer.SerializerEntries { private KeyInfoSerializer _securityTokenSerializer; public XmlDsigSep2000(KeyInfoSerializer securityTokenSerializer) { _securityTokenSerializer = securityTokenSerializer; } public override void PopulateKeyIdentifierEntries(IList<KeyIdentifierEntry> keyIdentifierEntries) { keyIdentifierEntries.Add(new KeyInfoEntry(_securityTokenSerializer)); } public override void PopulateKeyIdentifierClauseEntries(IList<SecurityTokenSerializer.KeyIdentifierClauseEntry> keyIdentifierClauseEntries) { keyIdentifierClauseEntries.Add(new X509CertificateClauseEntry()); } internal class KeyInfoEntry : KeyIdentifierEntry { private KeyInfoSerializer _securityTokenSerializer; public KeyInfoEntry(KeyInfoSerializer securityTokenSerializer) { _securityTokenSerializer = securityTokenSerializer; } protected override XmlDictionaryString LocalName { get { return XD.XmlSignatureDictionary.KeyInfo; } } protected override XmlDictionaryString NamespaceUri { get { return XD.XmlSignatureDictionary.Namespace; } } public override SecurityKeyIdentifier ReadKeyIdentifierCore(XmlDictionaryReader reader) { reader.ReadStartElement(LocalName, NamespaceUri); SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier(); while (reader.IsStartElement()) { SecurityKeyIdentifierClause clause = _securityTokenSerializer.ReadKeyIdentifierClause(reader); if (clause == null) { reader.Skip(); } else { keyIdentifier.Add(clause); } } if (keyIdentifier.Count == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SRP.ErrorDeserializingKeyIdentifierClause)); } reader.ReadEndElement(); return keyIdentifier; } public override bool SupportsCore(SecurityKeyIdentifier keyIdentifier) { return true; } public override void WriteKeyIdentifierCore(XmlDictionaryWriter writer, SecurityKeyIdentifier keyIdentifier) { writer.WriteStartElement(XD.XmlSignatureDictionary.Prefix.Value, LocalName, NamespaceUri); bool clauseWritten = false; foreach (SecurityKeyIdentifierClause clause in keyIdentifier) { _securityTokenSerializer.InnerSecurityTokenSerializer.WriteKeyIdentifierClause(writer, clause); clauseWritten = true; } writer.WriteEndElement(); // KeyInfo if (!clauseWritten) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityMessageSerializationException(SRP.NoKeyInfoClausesToWrite)); } } } // so far, we only support two types of X509Data directly under KeyInfo - X509Certificate and X509SKI // <ds:X509Data> // <ds:X509Certificate>...</ds:X509Certificate> // or // <X509SKI>... </X509SKI> // </ds:X509Data> // only support 1 certificate right now internal class X509CertificateClauseEntry : SecurityTokenSerializer.KeyIdentifierClauseEntry { protected override XmlDictionaryString LocalName { get { return XD.XmlSignatureDictionary.X509Data; } } protected override XmlDictionaryString NamespaceUri { get { return XD.XmlSignatureDictionary.Namespace; } } public override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlDictionaryReader reader) { SecurityKeyIdentifierClause ski = null; reader.ReadStartElement(XD.XmlSignatureDictionary.X509Data, NamespaceUri); while (reader.IsStartElement()) { if (ski == null && reader.IsStartElement(XD.XmlSignatureDictionary.X509Certificate, NamespaceUri)) { X509Certificate2 certificate = null; if (!SecurityUtils.TryCreateX509CertificateFromRawData(reader.ReadElementContentAsBase64(), out certificate)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityMessageSerializationException(SRP.InvalidX509RawData)); } ski = new X509RawDataKeyIdentifierClause(certificate); } else if (ski == null && reader.IsStartElement(XmlSignatureStrings.X509Ski, NamespaceUri.ToString())) { ski = new X509SubjectKeyIdentifierClause(reader.ReadElementContentAsBase64()); } else if ((ski == null) && reader.IsStartElement(XD.XmlSignatureDictionary.X509IssuerSerial, XD.XmlSignatureDictionary.Namespace)) { reader.ReadStartElement(XD.XmlSignatureDictionary.X509IssuerSerial, XD.XmlSignatureDictionary.Namespace); reader.ReadStartElement(XD.XmlSignatureDictionary.X509IssuerName, XD.XmlSignatureDictionary.Namespace); string issuerName = reader.ReadContentAsString(); reader.ReadEndElement(); reader.ReadStartElement(XD.XmlSignatureDictionary.X509SerialNumber, XD.XmlSignatureDictionary.Namespace); string serialNumber = reader.ReadContentAsString(); reader.ReadEndElement(); reader.ReadEndElement(); ski = new X509IssuerSerialKeyIdentifierClause(issuerName, serialNumber); } else { reader.Skip(); } } reader.ReadEndElement(); return ski; } public override bool SupportsCore(SecurityKeyIdentifierClause keyIdentifierClause) { return (keyIdentifierClause is X509RawDataKeyIdentifierClause); // This method should not write X509IssuerSerialKeyIdentifierClause or X509SubjectKeyIdentifierClause as that should be written by the WSSecurityXXX classes with SecurityTokenReference tag. // The XmlDsig entries are written by the X509SecurityTokenHandler. } public override void WriteKeyIdentifierClauseCore(XmlDictionaryWriter writer, SecurityKeyIdentifierClause keyIdentifierClause) { X509RawDataKeyIdentifierClause x509Clause = keyIdentifierClause as X509RawDataKeyIdentifierClause; if (x509Clause != null) { writer.WriteStartElement(XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509Data, NamespaceUri); writer.WriteStartElement(XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509Certificate, NamespaceUri); byte[] certBytes = x509Clause.GetX509RawData(); writer.WriteBase64(certBytes, 0, certBytes.Length); writer.WriteEndElement(); writer.WriteEndElement(); } X509IssuerSerialKeyIdentifierClause issuerSerialClause = keyIdentifierClause as X509IssuerSerialKeyIdentifierClause; if (issuerSerialClause != null) { writer.WriteStartElement(XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509Data, XD.XmlSignatureDictionary.Namespace); writer.WriteStartElement(XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509IssuerSerial, XD.XmlSignatureDictionary.Namespace); writer.WriteElementString(XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509IssuerName, XD.XmlSignatureDictionary.Namespace, issuerSerialClause.IssuerName); writer.WriteElementString(XD.XmlSignatureDictionary.Prefix.Value, XD.XmlSignatureDictionary.X509SerialNumber, XD.XmlSignatureDictionary.Namespace, issuerSerialClause.IssuerSerialNumber); writer.WriteEndElement(); writer.WriteEndElement(); return; } X509SubjectKeyIdentifierClause skiClause = keyIdentifierClause as X509SubjectKeyIdentifierClause; if (skiClause != null) { writer.WriteStartElement(XmlSignatureConstants.Prefix, XmlSignatureConstants.Elements.X509Data, XmlSignatureConstants.Namespace); writer.WriteStartElement(XmlSignatureConstants.Prefix, XmlSignatureConstants.Elements.X509SKI, XmlSignatureConstants.Namespace); byte[] ski = skiClause.GetX509SubjectKeyIdentifier(); writer.WriteBase64(ski, 0, ski.Length); writer.WriteEndElement(); writer.WriteEndElement(); return; } } } } }