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;
84 doc.XmlResolver = GetResolver ();
85 doc.Load (inputObj as Stream);
86 return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
88 else if (inputObj is XmlDocument) {
89 doc = inputObj as XmlDocument;
90 return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
92 else if (inputObj is XmlNodeList) {
93 ArrayList al = new ArrayList ();
94 XmlNodeList nl = (XmlNodeList) inputObj;
96 XmlNamespaceManager m = GetNamespaceManager (nl.Item (0));
97 ArrayList tmp = new ArrayList ();
98 foreach (XmlNode n in nl)
100 foreach (XmlNode n in tmp)
101 if (n.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
102 al.Add (GetOutputFromNode (n, m, false));
104 return new XmlDsigNodeList (al);
106 // Note that it is unexpected behavior with related to InputTypes (MS.NET accepts XmlElement)
107 else if (inputObj is XmlElement) {
108 XmlElement el = inputObj as XmlElement;
109 XmlNamespaceManager m = GetNamespaceManager (el);
110 if (el.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
111 return GetOutputFromNode (el, m, true);
114 throw new NullReferenceException ();
117 private XmlNamespaceManager GetNamespaceManager (XmlNode n)
119 XmlDocument doc = n is XmlDocument ? n as XmlDocument : n.OwnerDocument;
120 XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
121 nsmgr.AddNamespace ("dsig", XmlSignature.NamespaceURI);
125 private XmlNode GetOutputFromNode (XmlNode input, XmlNamespaceManager nsmgr, bool remove)
127 XmlDocument doc = input is XmlDocument ? input as XmlDocument : input.OwnerDocument;
129 XmlNodeList nl = input.SelectNodes ("descendant-or-self::dsig:Signature", nsmgr);
130 foreach (XmlNode n in nl)
131 n.ParentNode.RemoveChild (n);
136 public override object GetOutput (Type type)
138 if (type == Type.GetType ("Stream"))
140 throw new ArgumentException ("type");
143 public override void LoadInnerXml (XmlNodeList nodeList)
149 public override void LoadInput (object obj)