2 // XmlDsigEnvelopedSignatureTransform.cs -
3 // Enveloped Signature Transform implementation for XML Signature
6 // Sebastien Pouliot (spouliot@motus.com)
7 // Atsushi Enomoto (atsushi@ximian.com)
9 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
10 // (C) 2004 Novell Inc.
13 using System.Collections;
17 namespace System.Security.Cryptography.Xml {
20 public class XmlDsigEnvelopedSignatureTransform : Transform {
23 private Type[] output;
24 private bool comments;
25 private object inputObj;
27 public XmlDsigEnvelopedSignatureTransform ()
29 Algorithm = "http://www.w3.org/2000/09/xmldsig#enveloped-signature";
33 public XmlDsigEnvelopedSignatureTransform (bool includeComments)
35 comments = includeComments;
38 public override Type[] InputTypes {
42 // this way the result is cached if called multiple time
44 input[0] = typeof (System.IO.Stream);
45 input[1] = typeof (System.Xml.XmlDocument);
46 input[2] = typeof (System.Xml.XmlNodeList);
53 public override Type[] OutputTypes {
57 // this way the result is cached if called multiple time
58 output = new Type [2];
59 output [0] = typeof (System.Xml.XmlDocument);
60 output [1] = typeof (System.Xml.XmlNodeList);
67 protected override XmlNodeList GetInnerXml ()
69 return null; // THIS IS DOCUMENTED AS SUCH
72 // NOTE: This method never supports the requirements written
73 // in xmldsig spec that says its input is canonicalized before
74 // transforming. This method just removes Signature element.
75 // Canonicalization is done in SignedXml.
76 public override object GetOutput ()
78 XmlDocument doc = null;
80 // possible input: Stream, XmlDocument, and XmlNodeList
81 if (inputObj is Stream) {
82 doc = new XmlDocument ();
83 doc.PreserveWhitespace = true;
85 doc.XmlResolver = GetResolver ();
87 doc.Load (inputObj as Stream);
88 return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
90 else if (inputObj is XmlDocument) {
91 doc = inputObj as XmlDocument;
92 return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
94 else if (inputObj is XmlNodeList) {
95 ArrayList al = new ArrayList ();
96 XmlNodeList nl = (XmlNodeList) inputObj;
98 XmlNamespaceManager m = GetNamespaceManager (nl.Item (0));
99 ArrayList tmp = new ArrayList ();
100 foreach (XmlNode n in nl)
102 foreach (XmlNode n in tmp)
103 if (n.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
104 al.Add (GetOutputFromNode (n, m, false));
106 return new XmlDsigNodeList (al);
108 // Note that it is unexpected behavior with related to InputTypes (MS.NET accepts XmlElement)
109 else if (inputObj is XmlElement) {
110 XmlElement el = inputObj as XmlElement;
111 XmlNamespaceManager m = GetNamespaceManager (el);
112 if (el.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
113 return GetOutputFromNode (el, m, true);
116 throw new NullReferenceException ();
119 private XmlNamespaceManager GetNamespaceManager (XmlNode n)
121 XmlDocument doc = n is XmlDocument ? n as XmlDocument : n.OwnerDocument;
122 XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
123 nsmgr.AddNamespace ("dsig", XmlSignature.NamespaceURI);
127 private XmlNode GetOutputFromNode (XmlNode input, XmlNamespaceManager nsmgr, bool remove)
129 XmlDocument doc = input is XmlDocument ? input as XmlDocument : input.OwnerDocument;
131 XmlNodeList nl = input.SelectNodes ("descendant-or-self::dsig:Signature", nsmgr);
132 foreach (XmlNode n in nl)
133 n.ParentNode.RemoveChild (n);
138 public override object GetOutput (Type type)
140 if (type == Type.GetType ("Stream"))
142 throw new ArgumentException ("type");
145 public override void LoadInnerXml (XmlNodeList nodeList)
151 public override void LoadInput (object obj)