XmlDsigEnvelopedSignatureTransform.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //
  2. // XmlDsigEnvelopedSignatureTransform.cs -
  3. // Enveloped Signature Transform implementation for XML Signature
  4. //
  5. // Author:
  6. // Sebastien Pouliot ([email protected])
  7. // Atsushi Enomoto ([email protected])
  8. //
  9. // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
  10. // (C) 2004 Novell Inc.
  11. //
  12. using System.Collections;
  13. using System.IO;
  14. using System.Xml;
  15. namespace System.Security.Cryptography.Xml {
  16. public class XmlDsigEnvelopedSignatureTransform : Transform {
  17. private Type[] input;
  18. private Type[] output;
  19. private bool comments;
  20. private object inputObj;
  21. public XmlDsigEnvelopedSignatureTransform ()
  22. {
  23. Algorithm = "http://www.w3.org/2000/09/xmldsig#enveloped-signature";
  24. comments = false;
  25. }
  26. public XmlDsigEnvelopedSignatureTransform (bool includeComments)
  27. {
  28. comments = includeComments;
  29. }
  30. public override Type[] InputTypes {
  31. get {
  32. if (input == null) {
  33. lock (this) {
  34. // this way the result is cached if called multiple time
  35. input = new Type [3];
  36. input[0] = typeof (System.IO.Stream);
  37. input[1] = typeof (System.Xml.XmlDocument);
  38. input[2] = typeof (System.Xml.XmlNodeList);
  39. }
  40. }
  41. return input;
  42. }
  43. }
  44. public override Type[] OutputTypes {
  45. get {
  46. if (output == null) {
  47. lock (this) {
  48. // this way the result is cached if called multiple time
  49. output = new Type [2];
  50. output [0] = typeof (System.Xml.XmlDocument);
  51. output [1] = typeof (System.Xml.XmlNodeList);
  52. }
  53. }
  54. return output;
  55. }
  56. }
  57. protected override XmlNodeList GetInnerXml ()
  58. {
  59. return null; // THIS IS DOCUMENTED AS SUCH
  60. }
  61. // NOTE: This method never supports the requirements written
  62. // in xmldsig spec that says its input is canonicalized before
  63. // transforming. This method just removes Signature element.
  64. // Canonicalization is done in SignedXml.
  65. public override object GetOutput ()
  66. {
  67. XmlDocument doc = null;
  68. // possible input: Stream, XmlDocument, and XmlNodeList
  69. if (inputObj is Stream) {
  70. doc = new XmlDocument ();
  71. doc.PreserveWhitespace = true;
  72. #if NET_1_1
  73. doc.XmlResolver = GetResolver ();
  74. #endif
  75. doc.Load (inputObj as Stream);
  76. return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
  77. }
  78. else if (inputObj is XmlDocument) {
  79. doc = inputObj as XmlDocument;
  80. return GetOutputFromNode (doc, GetNamespaceManager (doc), true);
  81. }
  82. else if (inputObj is XmlNodeList) {
  83. ArrayList al = new ArrayList ();
  84. XmlNodeList nl = (XmlNodeList) inputObj;
  85. if (nl.Count > 0) {
  86. XmlNamespaceManager m = GetNamespaceManager (nl.Item (0));
  87. ArrayList tmp = new ArrayList ();
  88. foreach (XmlNode n in nl)
  89. tmp.Add (n);
  90. foreach (XmlNode n in tmp)
  91. if (n.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
  92. al.Add (GetOutputFromNode (n, m, false));
  93. }
  94. return new XmlDsigNodeList (al);
  95. }
  96. // Note that it is unexpected behavior with related to InputTypes (MS.NET accepts XmlElement)
  97. else if (inputObj is XmlElement) {
  98. XmlElement el = inputObj as XmlElement;
  99. XmlNamespaceManager m = GetNamespaceManager (el);
  100. if (el.SelectNodes ("ancestor-or-self::dsig:Signature", m).Count == 0)
  101. return GetOutputFromNode (el, m, true);
  102. }
  103. throw new NullReferenceException ();
  104. }
  105. private XmlNamespaceManager GetNamespaceManager (XmlNode n)
  106. {
  107. XmlDocument doc = n is XmlDocument ? n as XmlDocument : n.OwnerDocument;
  108. XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
  109. nsmgr.AddNamespace ("dsig", XmlSignature.NamespaceURI);
  110. return nsmgr;
  111. }
  112. private XmlNode GetOutputFromNode (XmlNode input, XmlNamespaceManager nsmgr, bool remove)
  113. {
  114. XmlDocument doc = input is XmlDocument ? input as XmlDocument : input.OwnerDocument;
  115. if (remove) {
  116. XmlNodeList nl = input.SelectNodes ("descendant-or-self::dsig:Signature", nsmgr);
  117. foreach (XmlNode n in nl)
  118. n.ParentNode.RemoveChild (n);
  119. }
  120. return input;
  121. }
  122. public override object GetOutput (Type type)
  123. {
  124. if (type == Type.GetType ("Stream"))
  125. return GetOutput ();
  126. throw new ArgumentException ("type");
  127. }
  128. public override void LoadInnerXml (XmlNodeList nodeList)
  129. {
  130. // NO CHANGE
  131. }
  132. public override void LoadInput (object obj)
  133. {
  134. inputObj = obj;
  135. }
  136. }
  137. }