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 input[0] = typeof (System.Xml.XmlDocument);
60 input[1] = typeof (System.Xml.XmlNodeList);
67 protected override XmlNodeList GetInnerXml ()
69 return null; // THIS IS DOCUMENTED AS SUCH
72 [MonoTODO ("Is it really spec-compliant??")]
73 public override object GetOutput ()
75 XmlDocument doc = null;
77 // possible input: Stream, XmlDocument, and XmlNodeList
78 if (inputObj is Stream) {
79 doc = new XmlDocument ();
80 doc.PreserveWhitespace = true;
81 doc.XmlResolver = GetResolver ();
82 doc.Load (inputObj as Stream);
83 return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
85 else if (inputObj is XmlDocument) {
86 doc = inputObj as XmlDocument;
87 return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
89 else if (inputObj is XmlNodeList) {
90 ArrayList al = new ArrayList ();
91 XmlNodeList nl = (XmlNodeList) inputObj;
93 XmlNamespaceManager m = GetNamespaceManager (nl.Item (0));
94 ArrayList tmp = new ArrayList ();
95 foreach (XmlNode n in nl)
97 foreach (XmlNode n in tmp)
98 if (n.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
99 al.Add (GetOutputFromNode (n, m, false));
101 return new XmlDsigNodeList (al);
103 // Note that it is unexpected behavior with related to InputTypes (MS.NET accepts XmlElement)
104 else if (inputObj is XmlElement) {
105 XmlElement el = inputObj as XmlElement;
106 XmlNamespaceManager m = GetNamespaceManager (el);
107 if (el.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
108 return GetOutputFromNode (el, m, true);
111 throw new NullReferenceException ();
114 private XmlNamespaceManager GetNamespaceManager (XmlNode n)
116 XmlDocument doc = n is XmlDocument ? n as XmlDocument : n.OwnerDocument;
117 XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
118 nsmgr.AddNamespace ("dsig", XmlSignature.NamespaceURI);
122 private XmlNode GetOutputFromNode (XmlNode input, XmlNamespaceManager nsmgr, bool remove)
124 XmlDocument doc = input is XmlDocument ? input as XmlDocument : input.OwnerDocument;
126 XmlNodeList nl = input.SelectNodes ("descendant-or-self::dsig:Signature", nsmgr);
127 foreach (XmlNode n in nl)
128 n.ParentNode.RemoveChild (n);
133 public override object GetOutput (Type type)
135 if (type == Type.GetType ("Stream"))
137 throw new ArgumentException ("type");
140 public override void LoadInnerXml (XmlNodeList nodeList)
146 public override void LoadInput (object obj)