Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / SignedXml.cs / 1 / SignedXml.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.IdentityModel { using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IdentityModel.Tokens; using System.IdentityModel.Selectors; using System.Security.Cryptography; using System.Text; using System.Xml; sealed class SignedXml : ISignatureValueSecurityElement { internal const string DefaultPrefix = XmlSignatureStrings.Prefix; SecurityTokenSerializer tokenSerializer; readonly Signature signature; TransformFactory transformFactory; DictionaryManager dictionaryManager; public SignedXml(DictionaryManager dictionaryManager, SecurityTokenSerializer tokenSerializer) : this(new StandardSignedInfo(dictionaryManager), dictionaryManager, tokenSerializer) { } internal SignedXml(SignedInfo signedInfo, DictionaryManager dictionaryManager, SecurityTokenSerializer tokenSerializer) { if (signedInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("signedInfo")); } if (dictionaryManager == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dictionaryManager"); } if (tokenSerializer == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenSerializer"); } this.transformFactory = StandardTransformFactory.Instance; this.tokenSerializer = tokenSerializer; this.signature = new Signature(this, signedInfo); this.dictionaryManager = dictionaryManager; } public bool HasId { get { return true; } } public string Id { get { return this.signature.Id; } set { this.signature.Id = value; } } public SecurityTokenSerializer SecurityTokenSerializer { get { return this.tokenSerializer; } } public Signature Signature { get { return this.signature; } } public TransformFactory TransformFactory { get { return this.transformFactory; } set { this.transformFactory = value; } } void ComputeSignature(HashAlgorithm hash, AsymmetricSignatureFormatter formatter) { this.Signature.SignedInfo.ComputeReferenceDigests(); this.Signature.SignedInfo.ComputeHash(hash); byte[] signature = formatter.CreateSignature(hash); this.Signature.SetSignatureValue(signature); } void ComputeSignature(KeyedHashAlgorithm hash) { this.Signature.SignedInfo.ComputeReferenceDigests(); this.Signature.SignedInfo.ComputeHash(hash); byte[] signature = hash.Hash; this.Signature.SetSignatureValue(signature); } public void ComputeSignature(SecurityKey signingKey) { string signatureMethod = this.Signature.SignedInfo.SignatureMethod; SymmetricSecurityKey symmetricKey = signingKey as SymmetricSecurityKey; if (symmetricKey != null) { using (KeyedHashAlgorithm algorithm = symmetricKey.GetKeyedHashAlgorithm(signatureMethod)) { if (algorithm == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.UnableToCreateKeyedHashAlgorithm, symmetricKey, signatureMethod))); } ComputeSignature(algorithm); } } else { AsymmetricSecurityKey asymmetricKey = signingKey as AsymmetricSecurityKey; if (asymmetricKey == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.UnknownICryptoType, signingKey))); } using (HashAlgorithm hash = asymmetricKey.GetHashAlgorithmForSignature(signatureMethod)) { if (hash == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.UnableToCreateHashAlgorithmFromAsymmetricCrypto, signatureMethod, asymmetricKey))); } AsymmetricSignatureFormatter formatter = asymmetricKey.GetSignatureFormatter(signatureMethod); if (formatter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.UnableToCreateSignatureFormatterFromAsymmetricCrypto, signatureMethod, asymmetricKey))); } ComputeSignature(hash, formatter); } } } public void CompleteSignatureVerification() { this.Signature.SignedInfo.EnsureAllReferencesVerified(); } public void EnsureDigestValidity(string id, object resolvedXmlSource) { this.Signature.SignedInfo.EnsureDigestValidity(id, resolvedXmlSource); } public byte[] GetSignatureValue() { return this.Signature.GetSignatureBytes(); } public void ReadFrom(XmlReader reader) { ReadFrom(XmlDictionaryReader.CreateDictionaryReader(reader)); } public void ReadFrom(XmlDictionaryReader reader) { this.signature.ReadFrom(reader, this.dictionaryManager); } void VerifySignature(KeyedHashAlgorithm hash) { this.Signature.SignedInfo.ComputeHash(hash); if (!CryptoHelper.IsEqual(hash.Hash, GetSignatureValue())) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.SignatureVerificationFailed))); } } void VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter) { this.Signature.SignedInfo.ComputeHash(hash); if (!deformatter.VerifySignature(hash, GetSignatureValue())) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.SignatureVerificationFailed))); } } public void StartSignatureVerification(SecurityKey verificationKey) { string signatureMethod = this.Signature.SignedInfo.SignatureMethod; SymmetricSecurityKey symmetricKey = verificationKey as SymmetricSecurityKey; if (symmetricKey != null) { using (KeyedHashAlgorithm hash = symmetricKey.GetKeyedHashAlgorithm(signatureMethod)) { if (hash == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.UnableToCreateKeyedHashAlgorithmFromSymmetricCrypto, signatureMethod, symmetricKey))); } VerifySignature(hash); } } else { AsymmetricSecurityKey asymmetricKey = verificationKey as AsymmetricSecurityKey; if (asymmetricKey == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnknownICryptoType, verificationKey))); } using (HashAlgorithm hash = asymmetricKey.GetHashAlgorithmForSignature(signatureMethod)) { if (hash == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.UnableToCreateHashAlgorithmFromAsymmetricCrypto, signatureMethod, asymmetricKey))); } AsymmetricSignatureDeformatter deformatter = asymmetricKey.GetSignatureDeformatter(signatureMethod); if (deformatter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.UnableToCreateSignatureDeformatterFromAsymmetricCrypto, signatureMethod, asymmetricKey))); } VerifySignature(hash, deformatter); } } } public void WriteTo(XmlDictionaryWriter writer) { this.WriteTo(writer, this.dictionaryManager); } public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { this.signature.WriteTo(writer, dictionaryManager); } } sealed class Signature { SignedXml signedXml; string id; SecurityKeyIdentifier keyIdentifier; string prefix = SignedXml.DefaultPrefix; readonly SignatureValueElement signatureValueElement = new SignatureValueElement(); readonly SignedInfo signedInfo; public Signature(SignedXml signedXml, SignedInfo signedInfo) { this.signedXml = signedXml; this.signedInfo = signedInfo; } public string Id { get { return this.id; } set { this.id = value; } } public SecurityKeyIdentifier KeyIdentifier { get { return this.keyIdentifier; } set { this.keyIdentifier = value; } } public SignedInfo SignedInfo { get { return this.signedInfo; } } public ISignatureValueSecurityElement SignatureValue { get { return this.signatureValueElement; } } public byte[] GetSignatureBytes() { return this.signatureValueElement.Value; } public void ReadFrom(XmlDictionaryReader reader, DictionaryManager dictionaryManager) { reader.MoveToStartElement(dictionaryManager.XmlSignatureDictionary.Signature, dictionaryManager.XmlSignatureDictionary.Namespace); this.prefix = reader.Prefix; this.Id = reader.GetAttribute(dictionaryManager.UtilityDictionary.IdAttribute, null); reader.Read(); this.signedInfo.ReadFrom(reader, signedXml.TransformFactory, dictionaryManager); this.signatureValueElement.ReadFrom(reader, dictionaryManager); if (signedXml.SecurityTokenSerializer.CanReadKeyIdentifier(reader)) { this.keyIdentifier = signedXml.SecurityTokenSerializer.ReadKeyIdentifier(reader); } reader.ReadEndElement(); // Signature } public void SetSignatureValue(byte[] signatureValue) { this.signatureValueElement.Value = signatureValue; } public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { writer.WriteStartElement(this.prefix, dictionaryManager.XmlSignatureDictionary.Signature, dictionaryManager.XmlSignatureDictionary.Namespace); if (this.id != null) { writer.WriteAttributeString(dictionaryManager.UtilityDictionary.IdAttribute, null, this.id); } this.signedInfo.WriteTo(writer, dictionaryManager); this.signatureValueElement.WriteTo(writer, dictionaryManager); if (this.keyIdentifier != null) { this.signedXml.SecurityTokenSerializer.WriteKeyIdentifier(writer, this.keyIdentifier); } writer.WriteEndElement(); // Signature } sealed class SignatureValueElement : ISignatureValueSecurityElement { string id; string prefix = SignedXml.DefaultPrefix; byte[] signatureValue; string signatureText; public bool HasId { get { return true; } } public string Id { get { return this.id; } set { this.id = value; } } internal byte[] Value { get { return this.signatureValue; } set { this.signatureValue = value; this.signatureText = null; } } public void ReadFrom(XmlDictionaryReader reader, DictionaryManager dictionaryManager) { reader.MoveToStartElement(dictionaryManager.XmlSignatureDictionary.SignatureValue, dictionaryManager.XmlSignatureDictionary.Namespace); this.prefix = reader.Prefix; this.Id = reader.GetAttribute(UtilityStrings.IdAttribute, null); reader.Read(); this.signatureText = reader.ReadString(); this.signatureValue = System.Convert.FromBase64String(signatureText.Trim()); reader.ReadEndElement(); // SignatureValue } public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { writer.WriteStartElement(this.prefix, dictionaryManager.XmlSignatureDictionary.SignatureValue, dictionaryManager.XmlSignatureDictionary.Namespace); if (this.id != null) { writer.WriteAttributeString(dictionaryManager.UtilityDictionary.IdAttribute, null, this.id); } if (this.signatureText != null) { writer.WriteString(this.signatureText); } else { writer.WriteBase64(this.signatureValue, 0, this.signatureValue.Length); } writer.WriteEndElement(); // SignatureValue } byte[] ISignatureValueSecurityElement.GetSignatureValue() { return this.Value; } } } internal interface ISignatureReaderProvider { XmlDictionaryReader GetReader(object callbackContext); } abstract class SignedInfo : ISecurityElement { readonly ExclusiveCanonicalizationTransform canonicalizationMethodElement = new ExclusiveCanonicalizationTransform(true); string id; ElementWithAlgorithmAttribute signatureMethodElement; SignatureResourcePool resourcePool; DictionaryManager dictionaryManager; MemoryStream canonicalStream; ISignatureReaderProvider readerProvider; object signatureReaderProviderCallbackContext; bool sendSide = true; protected SignedInfo(DictionaryManager dictionaryManager) { if (dictionaryManager == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dictionaryManager"); this.signatureMethodElement = new ElementWithAlgorithmAttribute(dictionaryManager.XmlSignatureDictionary.SignatureMethod); this.dictionaryManager = dictionaryManager; } protected DictionaryManager DictionaryManager { get { return this.dictionaryManager; } } protected MemoryStream CanonicalStream { get { return this.canonicalStream; } set { this.canonicalStream = value; } } protected bool SendSide { get { return this.sendSide; } set { this.sendSide = value; } } public ISignatureReaderProvider ReaderProvider { get { return this.readerProvider; } set { this.readerProvider = value; } } public object SignatureReaderProviderCallbackContext { get { return this.signatureReaderProviderCallbackContext; } set { this.signatureReaderProviderCallbackContext = value; } } public string CanonicalizationMethod { get { return this.canonicalizationMethodElement.Algorithm; } set { if (value != this.canonicalizationMethodElement.Algorithm) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedTransformAlgorithm))); } } } public XmlDictionaryString CanonicalizationMethodDictionaryString { set { if (value != null && value.Value != this.canonicalizationMethodElement.Algorithm) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedTransformAlgorithm))); } } } public bool HasId { get { return true; } } public string Id { get { return this.id; } set { this.id = value; } } public abstract int ReferenceCount { get; } public string SignatureMethod { get { return this.signatureMethodElement.Algorithm; } set { this.signatureMethodElement.Algorithm = value; } } public XmlDictionaryString SignatureMethodDictionaryString { get { return this.signatureMethodElement.AlgorithmDictionaryString; } set { this.signatureMethodElement.AlgorithmDictionaryString = value; } } public SignatureResourcePool ResourcePool { get { if (this.resourcePool == null) { this.resourcePool = new SignatureResourcePool(); } return this.resourcePool; } set { this.resourcePool = value; } } public void ComputeHash(HashAlgorithm algorithm) { if (this.CanonicalizationMethod != SecurityAlgorithms.ExclusiveC14n) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.UnsupportedTransformAlgorithm))); } HashStream hashStream = this.ResourcePool.TakeHashStream(algorithm); ComputeHash(hashStream); hashStream.FlushHash(); } protected virtual void ComputeHash(HashStream hashStream) { if (this.sendSide) { XmlDictionaryWriter utf8Writer = this.ResourcePool.TakeUtf8Writer(); utf8Writer.StartCanonicalization(hashStream, false, null); WriteTo(utf8Writer, this.dictionaryManager); utf8Writer.EndCanonicalization(); } else if (this.canonicalStream != null) { this.canonicalStream.WriteTo(hashStream); } else { if (this.readerProvider == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.InclusiveNamespacePrefixRequiresSignatureReader))); XmlDictionaryReader signatureReader = this.readerProvider.GetReader(this.signatureReaderProviderCallbackContext); DiagnosticUtility.DebugAssert(signatureReader != null, "Require a Signature reader to validate signature."); if (!signatureReader.CanCanonicalize) { MemoryStream stream = new MemoryStream(); XmlDictionaryWriter bufferingWriter = XmlDictionaryWriter.CreateBinaryWriter(stream, this.DictionaryManager.ParentDictionary); string[] inclusivePrefix = GetInclusivePrefixes(); if (inclusivePrefix != null) { bufferingWriter.WriteStartElement("a"); for (int i = 0; i < inclusivePrefix.Length; ++i) { string ns = GetNamespaceForInclusivePrefix(inclusivePrefix[i]); if (ns != null) { bufferingWriter.WriteXmlnsAttribute(inclusivePrefix[i], ns); } } } signatureReader.MoveToContent(); bufferingWriter.WriteNode(signatureReader, false); if (inclusivePrefix != null) bufferingWriter.WriteEndElement(); bufferingWriter.Flush(); byte[] buffer = stream.ToArray(); int bufferLength = (int)stream.Length; bufferingWriter.Close(); signatureReader.Close(); // Create a reader around the buffering Stream. signatureReader = XmlDictionaryReader.CreateBinaryReader(buffer, 0, bufferLength, this.DictionaryManager.ParentDictionary, XmlDictionaryReaderQuotas.Max); if (inclusivePrefix != null) signatureReader.ReadStartElement("a"); } signatureReader.ReadStartElement(dictionaryManager.XmlSignatureDictionary.Signature, dictionaryManager.XmlSignatureDictionary.Namespace); signatureReader.MoveToStartElement(dictionaryManager.XmlSignatureDictionary.SignedInfo, dictionaryManager.XmlSignatureDictionary.Namespace); signatureReader.StartCanonicalization(hashStream, false, GetInclusivePrefixes()); signatureReader.Skip(); signatureReader.EndCanonicalization(); signatureReader.Close(); } } public abstract void ComputeReferenceDigests(); protected string[] GetInclusivePrefixes() { return this.canonicalizationMethodElement.GetInclusivePrefixes(); } protected virtual string GetNamespaceForInclusivePrefix(string prefix) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } public abstract void EnsureAllReferencesVerified(); public void EnsureDigestValidity(string id, object resolvedXmlSource) { if (!EnsureDigestValidityIfIdMatches(id, resolvedXmlSource)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.RequiredTargetNotSigned, id))); } } public abstract bool EnsureDigestValidityIfIdMatches(string id, object resolvedXmlSource); public virtual bool HasUnverifiedReference(string id) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } protected void ReadCanonicalizationMethod(XmlDictionaryReader reader, DictionaryManager dictionaryManager) { this.canonicalizationMethodElement.ReadFrom(reader, dictionaryManager); } public abstract void ReadFrom(XmlDictionaryReader reader, TransformFactory transformFactory, DictionaryManager dictionaryManager); protected void ReadSignatureMethod(XmlDictionaryReader reader, DictionaryManager dictionaryManager) { this.signatureMethodElement.ReadFrom(reader, dictionaryManager); } protected void WriteCanonicalizationMethod(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { this.canonicalizationMethodElement.WriteTo(writer, dictionaryManager); } protected void WriteSignatureMethod(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { this.signatureMethodElement.WriteTo(writer, dictionaryManager); } public abstract void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager); } // whitespace preservation convention: ws1 immediately inside open tag; ws2 immediately after end tag. sealed class StandardSignedInfo : SignedInfo { string prefix = SignedXml.DefaultPrefix; Listreferences; Dictionary context; public StandardSignedInfo(DictionaryManager dictionaryManager) : base(dictionaryManager) { this.references = new List (); } public override int ReferenceCount { get { return this.references.Count; } } public Reference this[int index] { get { return this.references[index]; } } public void AddReference(Reference reference) { reference.ResourcePool = this.ResourcePool; this.references.Add(reference); } public override void EnsureAllReferencesVerified() { for (int i = 0; i < this.references.Count; i++) { if (!this.references[i].Verified) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new CryptographicException(SR.GetString(SR.UnableToResolveReferenceUriForSignature, this.references[i].Uri))); } } } public override bool EnsureDigestValidityIfIdMatches(string id, object resolvedXmlSource) { for (int i = 0; i < this.references.Count; i++) { if (this.references[i].EnsureDigestValidityIfIdMatches(id, resolvedXmlSource)) { return true; } } return false; } public override bool HasUnverifiedReference(string id) { for (int i = 0; i < this.references.Count; i++) { if (!this.references[i].Verified && this.references[i].ExtractReferredId() == id) { return true; } } return false; } public override void ComputeReferenceDigests() { if (this.references.Count == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.AtLeastOneReferenceRequired))); } for (int i = 0; i < this.references.Count; i++) { this.references[i].ComputeAndSetDigest(); } } public override void ReadFrom(XmlDictionaryReader reader, TransformFactory transformFactory, DictionaryManager dictionaryManager) { this.SendSide = false; if (reader.CanCanonicalize) { this.CanonicalStream = new MemoryStream(); reader.StartCanonicalization(this.CanonicalStream, false, null); } reader.MoveToStartElement(dictionaryManager.XmlSignatureDictionary.SignedInfo, dictionaryManager.XmlSignatureDictionary.Namespace); this.prefix = reader.Prefix; this.Id = reader.GetAttribute(dictionaryManager.UtilityDictionary.IdAttribute, null); reader.Read(); ReadCanonicalizationMethod(reader, dictionaryManager); ReadSignatureMethod(reader, dictionaryManager); while (reader.IsStartElement(dictionaryManager.XmlSignatureDictionary.Reference, dictionaryManager.XmlSignatureDictionary.Namespace)) { Reference reference = new Reference(dictionaryManager); reference.ReadFrom(reader, transformFactory, dictionaryManager); AddReference(reference); } reader.ReadEndElement(); // SignedInfo if (reader.CanCanonicalize) reader.EndCanonicalization(); string[] inclusivePrefixes = GetInclusivePrefixes(); if (inclusivePrefixes != null) { // Clear the canonicalized stream. We cannot use this while inclusive prefixes are // specified. this.CanonicalStream = null; this.context = new Dictionary (inclusivePrefixes.Length); for (int i = 0; i < inclusivePrefixes.Length; i++) { this.context.Add(inclusivePrefixes[i], reader.LookupNamespace(inclusivePrefixes[i])); } } } public override void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { writer.WriteStartElement(this.prefix, dictionaryManager.XmlSignatureDictionary.SignedInfo, dictionaryManager.XmlSignatureDictionary.Namespace); if (this.Id != null) { writer.WriteAttributeString(dictionaryManager.UtilityDictionary.IdAttribute, null, this.Id); } WriteCanonicalizationMethod(writer, dictionaryManager); WriteSignatureMethod(writer, dictionaryManager); for (int i = 0; i < this.references.Count; i++) { this.references[i].WriteTo(writer, dictionaryManager); } writer.WriteEndElement(); // SignedInfo } protected override string GetNamespaceForInclusivePrefix(string prefix) { if (this.context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException()); if (prefix == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("prefix"); return context[prefix]; } } sealed class Reference { ElementWithAlgorithmAttribute digestMethodElement; DigestValueElement digestValueElement = new DigestValueElement(); string id; string prefix = SignedXml.DefaultPrefix; object resolvedXmlSource; readonly TransformChain transformChain = new TransformChain(); string type; string uri; SignatureResourcePool resourcePool; bool verified; string referredId; DictionaryManager dictionaryManager; public Reference(DictionaryManager dictionaryManager) : this(dictionaryManager, null) { } public Reference(DictionaryManager dictionaryManager, string uri) : this(dictionaryManager, uri, null) { } public Reference(DictionaryManager dictionaryManager, string uri, object resolvedXmlSource) { if (dictionaryManager == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dictionaryManager"); this.dictionaryManager = dictionaryManager; this.digestMethodElement = new ElementWithAlgorithmAttribute(dictionaryManager.XmlSignatureDictionary.DigestMethod); this.uri = uri; this.resolvedXmlSource = resolvedXmlSource; } public string DigestMethod { get { return this.digestMethodElement.Algorithm; } set { this.digestMethodElement.Algorithm = value; } } public XmlDictionaryString DigestMethodDictionaryString { get { return this.digestMethodElement.AlgorithmDictionaryString; } set { this.digestMethodElement.AlgorithmDictionaryString = value; } } public string Id { get { return this.id; } set { this.id = value; } } public SignatureResourcePool ResourcePool { get { return this.resourcePool; } set { this.resourcePool = value; } } public TransformChain TransformChain { get { return this.transformChain; } } public int TransformCount { get { return this.transformChain.TransformCount; } } public string Type { get { return this.type; } set { this.type = value; } } public string Uri { get { return this.uri; } set { this.uri = value; } } public bool Verified { get { return this.verified; } } public void AddTransform(Transform transform) { this.transformChain.Add(transform); } public void EnsureDigestValidity(string id, byte[] computedDigest) { if (!EnsureDigestValidityIfIdMatches(id, computedDigest)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.RequiredTargetNotSigned, id))); } } public void EnsureDigestValidity(string id, object resolvedXmlSource) { if (!EnsureDigestValidityIfIdMatches(id, resolvedXmlSource)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.RequiredTargetNotSigned, id))); } } public bool EnsureDigestValidityIfIdMatches(string id, byte[] computedDigest) { if (this.verified || id != ExtractReferredId()) { return false; } if (!CryptoHelper.IsEqual(computedDigest, GetDigestValue())) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new CryptographicException(SR.GetString(SR.DigestVerificationFailedForReference, this.uri))); } this.verified = true; return true; } public bool EnsureDigestValidityIfIdMatches(string id, object resolvedXmlSource) { if (this.verified || id != ExtractReferredId()) { return false; } this.resolvedXmlSource = resolvedXmlSource; if (!CheckDigest()) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new CryptographicException(SR.GetString(SR.DigestVerificationFailedForReference, this.uri))); } this.verified = true; return true; } public string ExtractReferredId() { if (this.referredId == null) { if (this.uri == null || this.uri.Length < 2 || this.uri[0] != '#') { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new CryptographicException(SR.GetString(SR.UnableToResolveReferenceUriForSignature, this.uri))); } this.referredId = this.uri.Substring(1); } return this.referredId; } public bool CheckDigest() { byte[] computedDigest = ComputeDigest(); bool result = CryptoHelper.IsEqual(computedDigest, GetDigestValue()); #if LOG_DIGESTS Console.WriteLine(">>> Checking digest for reference '{0}', result {1}", uri, result); Console.WriteLine(" Computed digest {0}", Convert.ToBase64String(computedDigest)); Console.WriteLine(" Received digest {0}", Convert.ToBase64String(GetDigestValue())); #endif return result; } public void ComputeAndSetDigest() { this.digestValueElement.Value = ComputeDigest(); } public byte[] ComputeDigest() { if (this.transformChain.TransformCount == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.EmptyTransformChainNotSupported))); } if (this.resolvedXmlSource == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.UnableToResolveReferenceUriForSignature, this.uri))); } return this.transformChain.TransformToDigest(this.resolvedXmlSource, this.ResourcePool, this.DigestMethod, this.dictionaryManager); } public byte[] GetDigestValue() { return this.digestValueElement.Value; } public void ReadFrom(XmlDictionaryReader reader, TransformFactory transformFactory, DictionaryManager dictionaryManager) { reader.MoveToStartElement(dictionaryManager.XmlSignatureDictionary.Reference, dictionaryManager.XmlSignatureDictionary.Namespace); this.prefix = reader.Prefix; this.Id = reader.GetAttribute(UtilityStrings.IdAttribute, null); this.Uri = reader.GetAttribute(dictionaryManager.XmlSignatureDictionary.URI, null); this.Type = reader.GetAttribute(dictionaryManager.XmlSignatureDictionary.Type, null); reader.Read(); if (reader.IsStartElement(dictionaryManager.XmlSignatureDictionary.Transforms, dictionaryManager.XmlSignatureDictionary.Namespace)) { this.transformChain.ReadFrom(reader, transformFactory, dictionaryManager); } this.digestMethodElement.ReadFrom(reader, dictionaryManager); this.digestValueElement.ReadFrom(reader, dictionaryManager); reader.MoveToContent(); reader.ReadEndElement(); // Reference } public void SetResolvedXmlSource(object resolvedXmlSource) { this.resolvedXmlSource = resolvedXmlSource; } public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { writer.WriteStartElement(this.prefix, dictionaryManager.XmlSignatureDictionary.Reference, dictionaryManager.XmlSignatureDictionary.Namespace); if (this.id != null) { writer.WriteAttributeString(dictionaryManager.UtilityDictionary.IdAttribute, null, this.id); } if (this.uri != null) { writer.WriteAttributeString(dictionaryManager.XmlSignatureDictionary.URI, null, this.uri); } if (this.type != null) { writer.WriteAttributeString(dictionaryManager.XmlSignatureDictionary.Type, null, this.type); } if (this.transformChain.TransformCount > 0) { this.transformChain.WriteTo(writer, dictionaryManager); } this.digestMethodElement.WriteTo(writer, dictionaryManager); this.digestValueElement.WriteTo(writer, dictionaryManager); writer.WriteEndElement(); // Reference } struct DigestValueElement { byte[] digestValue; string digestText; string prefix; internal byte[] Value { get { return this.digestValue; } set { this.digestValue = value; this.digestText = null; } } public void ReadFrom(XmlDictionaryReader reader, DictionaryManager dictionaryManager) { reader.MoveToStartElement(dictionaryManager.XmlSignatureDictionary.DigestValue, dictionaryManager.XmlSignatureDictionary.Namespace); this.prefix = reader.Prefix; reader.Read(); reader.MoveToContent(); this.digestText = reader.ReadString(); this.digestValue = System.Convert.FromBase64String(digestText.Trim()); reader.MoveToContent(); reader.ReadEndElement(); // DigestValue } public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { writer.WriteStartElement(this.prefix ?? XmlSignatureStrings.Prefix, dictionaryManager.XmlSignatureDictionary.DigestValue, dictionaryManager.XmlSignatureDictionary.Namespace); if (this.digestText != null) { writer.WriteString(this.digestText); } else { writer.WriteBase64(this.digestValue, 0, this.digestValue.Length); } writer.WriteEndElement(); // DigestValue } } } sealed class TransformChain { string prefix = SignedXml.DefaultPrefix; MostlySingletonList transforms; public TransformChain() { } public int TransformCount { get { return this.transforms.Count; } } public Transform this[int index] { get { return this.transforms[index]; } } public bool NeedsInclusiveContext { get { for (int i = 0; i < this.TransformCount; i++) { if (this[i].NeedsInclusiveContext) { return true; } } return false; } } public void Add(Transform transform) { this.transforms.Add(transform); } public void ReadFrom(XmlDictionaryReader reader, TransformFactory transformFactory, DictionaryManager dictionaryManager) { reader.MoveToStartElement(dictionaryManager.XmlSignatureDictionary.Transforms, dictionaryManager.XmlSignatureDictionary.Namespace); this.prefix = reader.Prefix; reader.Read(); while (reader.IsStartElement(dictionaryManager.XmlSignatureDictionary.Transform, dictionaryManager.XmlSignatureDictionary.Namespace)) { string transformAlgorithmUri = reader.GetAttribute(dictionaryManager.XmlSignatureDictionary.Algorithm, null); Transform transform = transformFactory.CreateTransform(transformAlgorithmUri); transform.ReadFrom(reader, dictionaryManager); Add(transform); } reader.MoveToContent(); reader.ReadEndElement(); // Transforms if (this.TransformCount == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.AtLeastOneTransformRequired))); } } public byte[] TransformToDigest(object data, SignatureResourcePool resourcePool, string digestMethod, DictionaryManager dictionaryManager) { DiagnosticUtility.DebugAssert(TransformCount > 0, ""); for (int i = 0; i < this.TransformCount - 1; i++) { data = this[i].Process(data, resourcePool, dictionaryManager); } return this[this.TransformCount - 1].ProcessAndDigest(data, resourcePool, digestMethod, dictionaryManager); } public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { writer.WriteStartElement(this.prefix, dictionaryManager.XmlSignatureDictionary.Transforms, dictionaryManager.XmlSignatureDictionary.Namespace); for (int i = 0; i < this.TransformCount; i++) { this[i].WriteTo(writer, dictionaryManager); } writer.WriteEndElement(); // Transforms } } struct ElementWithAlgorithmAttribute { readonly XmlDictionaryString elementName; string algorithm; XmlDictionaryString algorithmDictionaryString; string prefix; public ElementWithAlgorithmAttribute(XmlDictionaryString elementName) { if (elementName == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("elementName")); } this.elementName = elementName; this.algorithm = null; this.algorithmDictionaryString = null; this.prefix = SignedXml.DefaultPrefix; } public string Algorithm { get { return this.algorithm; } set { this.algorithm = value; } } public XmlDictionaryString AlgorithmDictionaryString { get { return this.algorithmDictionaryString; } set { this.algorithmDictionaryString = value; } } public void ReadFrom(XmlDictionaryReader reader, DictionaryManager dictionaryManager) { reader.MoveToStartElement(this.elementName, dictionaryManager.XmlSignatureDictionary.Namespace); this.prefix = reader.Prefix; bool isEmptyElement = reader.IsEmptyElement; this.algorithm = reader.GetAttribute(dictionaryManager.XmlSignatureDictionary.Algorithm, null); if (this.algorithm == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException( SR.GetString(SR.RequiredAttributeMissing, dictionaryManager.XmlSignatureDictionary.Algorithm, this.elementName))); } reader.Read(); reader.MoveToContent(); if (!isEmptyElement) { reader.MoveToContent(); reader.ReadEndElement(); } } public void WriteTo(XmlDictionaryWriter writer, DictionaryManager dictionaryManager) { writer.WriteStartElement(this.prefix, this.elementName, dictionaryManager.XmlSignatureDictionary.Namespace); writer.WriteStartAttribute(dictionaryManager.XmlSignatureDictionary.Algorithm, null); if (this.algorithmDictionaryString != null) { writer.WriteString(this.algorithmDictionaryString); } else { writer.WriteString(this.algorithm); } writer.WriteEndAttribute(); writer.WriteEndElement(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TextReader.cs
- DropShadowBitmapEffect.cs
- DataBinding.cs
- DeflateStream.cs
- Rect3DValueSerializer.cs
- FixedElement.cs
- ProfilePropertySettings.cs
- HtmlPageAdapter.cs
- FontFaceLayoutInfo.cs
- XmlValueConverter.cs
- CompoundFileStorageReference.cs
- ConnectionStringSettings.cs
- ForEach.cs
- QualifierSet.cs
- Sequence.cs
- OutputCacheProviderCollection.cs
- DirectoryInfo.cs
- XPathScanner.cs
- Timeline.cs
- MemberAccessException.cs
- DataObjectEventArgs.cs
- ScriptManagerProxy.cs
- DisplayNameAttribute.cs
- XmlWriterTraceListener.cs
- InProcStateClientManager.cs
- Oid.cs
- PageTheme.cs
- WebUtil.cs
- EventProviderWriter.cs
- DisplayInformation.cs
- XmlSerializer.cs
- HwndSourceKeyboardInputSite.cs
- DesignerDataConnection.cs
- recordstatescratchpad.cs
- ToolBarDesigner.cs
- DeflateStream.cs
- NetMsmqBindingCollectionElement.cs
- XmlWrappingReader.cs
- CodeCommentStatementCollection.cs
- CustomAttributeFormatException.cs
- NullableConverter.cs
- BindingContext.cs
- ObjectNotFoundException.cs
- ProcessHost.cs
- ELinqQueryState.cs
- Literal.cs
- FaultDescriptionCollection.cs
- ClientUtils.cs
- ResourceDisplayNameAttribute.cs
- RemoteCryptoDecryptRequest.cs
- TimeSpanStorage.cs
- CodeLabeledStatement.cs
- TreeIterator.cs
- EmptyTextWriter.cs
- errorpatternmatcher.cs
- ProcessModuleDesigner.cs
- Int64KeyFrameCollection.cs
- CustomAttributeFormatException.cs
- JsonObjectDataContract.cs
- SafeLocalMemHandle.cs
- Privilege.cs
- SurrogateChar.cs
- ComponentDispatcherThread.cs
- DependentList.cs
- WebPartTransformerCollection.cs
- NameTable.cs
- UDPClient.cs
- HtmlInputRadioButton.cs
- OdbcDataAdapter.cs
- XmlExpressionDumper.cs
- HandledMouseEvent.cs
- HttpStreamXmlDictionaryReader.cs
- StateMachineTimers.cs
- ConvertEvent.cs
- HttpDebugHandler.cs
- CultureSpecificStringDictionary.cs
- StoreContentChangedEventArgs.cs
- ResourcesChangeInfo.cs
- SingleTagSectionHandler.cs
- GridViewDeleteEventArgs.cs
- SignedXml.cs
- HtmlLink.cs
- _Rfc2616CacheValidators.cs
- ScriptResourceAttribute.cs
- BinaryKeyIdentifierClause.cs
- SymbolPair.cs
- SystemWebSectionGroup.cs
- DataGridViewColumnHeaderCell.cs
- TableRowCollection.cs
- SequenceNumber.cs
- Int32RectValueSerializer.cs
- IconEditor.cs
- translator.cs
- AxisAngleRotation3D.cs
- RangeValueProviderWrapper.cs
- SerializationInfoEnumerator.cs
- SessionPageStateSection.cs
- SafeViewOfFileHandle.cs
- HostExecutionContextManager.cs
- ParameterCollection.cs