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 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections; 7 using System.IO; 8 using System.Runtime.InteropServices; 9 using System.Security; 10 using System.Text; 11 using System.Xml; 12 using System.Xml.XPath; 13 using System.Xml.Xsl; 14 15 namespace System.Security.Cryptography.Xml 16 { 17 public class XmlDsigExcC14NTransform : Transform 18 { 19 private Type[] _inputTypes = { typeof(Stream), typeof(XmlDocument), typeof(XmlNodeList) }; 20 private Type[] _outputTypes = { typeof(Stream) }; 21 private bool _includeComments = false; 22 private string _inclusiveNamespacesPrefixList; 23 private ExcCanonicalXml _excCanonicalXml; 24 XmlDsigExcC14NTransform()25 public XmlDsigExcC14NTransform() : this(false, null) { } 26 XmlDsigExcC14NTransform(bool includeComments)27 public XmlDsigExcC14NTransform(bool includeComments) : this(includeComments, null) { } 28 XmlDsigExcC14NTransform(string inclusiveNamespacesPrefixList)29 public XmlDsigExcC14NTransform(string inclusiveNamespacesPrefixList) : this(false, inclusiveNamespacesPrefixList) { } 30 XmlDsigExcC14NTransform(bool includeComments, string inclusiveNamespacesPrefixList)31 public XmlDsigExcC14NTransform(bool includeComments, string inclusiveNamespacesPrefixList) 32 { 33 _includeComments = includeComments; 34 _inclusiveNamespacesPrefixList = inclusiveNamespacesPrefixList; 35 Algorithm = (includeComments ? SignedXml.XmlDsigExcC14NWithCommentsTransformUrl : SignedXml.XmlDsigExcC14NTransformUrl); 36 } 37 38 public string InclusiveNamespacesPrefixList 39 { 40 get { return _inclusiveNamespacesPrefixList; } 41 set { _inclusiveNamespacesPrefixList = value; } 42 } 43 44 public override Type[] InputTypes 45 { 46 get { return _inputTypes; } 47 } 48 49 public override Type[] OutputTypes 50 { 51 get { return _outputTypes; } 52 } 53 LoadInnerXml(XmlNodeList nodeList)54 public override void LoadInnerXml(XmlNodeList nodeList) 55 { 56 if (nodeList != null) 57 { 58 foreach (XmlNode n in nodeList) 59 { 60 XmlElement e = n as XmlElement; 61 if (e != null && e.LocalName.Equals("InclusiveNamespaces") && 62 e.NamespaceURI.Equals(SignedXml.XmlDsigExcC14NTransformUrl) && 63 Utils.HasAttribute(e, "PrefixList", SignedXml.XmlDsigNamespaceUrl)) 64 { 65 InclusiveNamespacesPrefixList = Utils.GetAttribute(e, "PrefixList", SignedXml.XmlDsigNamespaceUrl); 66 return; 67 } 68 } 69 } 70 } 71 LoadInput(object obj)72 public override void LoadInput(object obj) 73 { 74 XmlResolver resolver = (ResolverSet ? _xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), BaseURI)); 75 if (obj is Stream) 76 { 77 _excCanonicalXml = new ExcCanonicalXml((Stream)obj, _includeComments, _inclusiveNamespacesPrefixList, resolver, BaseURI); 78 } 79 else if (obj is XmlDocument) 80 { 81 _excCanonicalXml = new ExcCanonicalXml((XmlDocument)obj, _includeComments, _inclusiveNamespacesPrefixList, resolver); 82 } 83 else if (obj is XmlNodeList) 84 { 85 _excCanonicalXml = new ExcCanonicalXml((XmlNodeList)obj, _includeComments, _inclusiveNamespacesPrefixList, resolver); 86 } 87 else 88 throw new ArgumentException(SR.Cryptography_Xml_IncorrectObjectType, nameof(obj)); 89 } 90 GetInnerXml()91 protected override XmlNodeList GetInnerXml() 92 { 93 if (InclusiveNamespacesPrefixList == null) 94 return null; 95 XmlDocument document = new XmlDocument(); 96 XmlElement element = document.CreateElement("Transform", SignedXml.XmlDsigNamespaceUrl); 97 if (!string.IsNullOrEmpty(Algorithm)) 98 element.SetAttribute("Algorithm", Algorithm); 99 XmlElement prefixListElement = document.CreateElement("InclusiveNamespaces", SignedXml.XmlDsigExcC14NTransformUrl); 100 prefixListElement.SetAttribute("PrefixList", InclusiveNamespacesPrefixList); 101 element.AppendChild(prefixListElement); 102 return element.ChildNodes; 103 } 104 GetOutput()105 public override object GetOutput() 106 { 107 return new MemoryStream(_excCanonicalXml.GetBytes()); 108 } 109 GetOutput(Type type)110 public override object GetOutput(Type type) 111 { 112 if (type != typeof(Stream) && !type.IsSubclassOf(typeof(Stream))) 113 throw new ArgumentException(SR.Cryptography_Xml_TransformIncorrectInputType, nameof(type)); 114 return new MemoryStream(_excCanonicalXml.GetBytes()); 115 } 116 GetDigestedOutput(HashAlgorithm hash)117 public override byte[] GetDigestedOutput(HashAlgorithm hash) 118 { 119 return _excCanonicalXml.GetDigestedBytes(hash); 120 } 121 } 122 } 123