DataObject.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //
  2. // DataObject.cs - DataObject implementation for XML Signature
  3. // http://www.w3.org/2000/09/xmldsig#Object
  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.Xml;
  13. namespace System.Security.Cryptography.Xml {
  14. // XmlElement part of the signature
  15. // Note: Looks like KeyInfoNode (but the later is XmlElement inside KeyInfo)
  16. // required for "enveloping signatures"
  17. public class DataObject {
  18. private string id;
  19. private string mimeType;
  20. private string encoding;
  21. private XmlElement element;
  22. private bool propertyModified;
  23. public DataObject ()
  24. {
  25. Build (null, null, null, null);
  26. }
  27. public DataObject (string id, string mimeType, string encoding, XmlElement data)
  28. {
  29. if (data == null)
  30. throw new ArgumentNullException ("data");
  31. Build (id, mimeType, encoding, data);
  32. }
  33. // this one accept a null "data" parameter
  34. private void Build (string id, string mimeType, string encoding, XmlElement data)
  35. {
  36. XmlDocument document = new XmlDocument ();
  37. XmlElement xel = document.CreateElement (XmlSignature.ElementNames.Object, XmlSignature.NamespaceURI);
  38. if (id != null) {
  39. this.id = id;
  40. xel.SetAttribute (XmlSignature.AttributeNames.Id, id);
  41. }
  42. if (mimeType != null) {
  43. this.mimeType = mimeType;
  44. xel.SetAttribute (XmlSignature.AttributeNames.MimeType, mimeType);
  45. }
  46. if (encoding != null) {
  47. this.encoding = encoding;
  48. xel.SetAttribute (XmlSignature.AttributeNames.Encoding, encoding);
  49. }
  50. if (data != null) {
  51. XmlNode newNode = document.ImportNode (data, true);
  52. xel.AppendChild (newNode);
  53. }
  54. document.AppendChild (xel); // FIXME: it should not be appended
  55. element = document.DocumentElement;
  56. }
  57. // why is data a XmlNodeList instead of a XmlElement ?
  58. public XmlNodeList Data {
  59. get {
  60. return element.ChildNodes;
  61. }
  62. set {
  63. if (value == null)
  64. throw new ArgumentNullException ("value");
  65. XmlDocument doc = new XmlDocument ();
  66. XmlElement el = (XmlElement) doc.ImportNode (element, true);
  67. doc.AppendChild (el); // FIXME: it should not be appended
  68. el.RemoveAll ();
  69. foreach (XmlNode n in value)
  70. el.AppendChild (doc.ImportNode (n, true));
  71. element = el;
  72. propertyModified = true;
  73. }
  74. }
  75. // default to null - no encoding
  76. public string Encoding {
  77. get { return GetField (XmlSignature.AttributeNames.Encoding); }
  78. set { SetField (XmlSignature.AttributeNames.Encoding, value); }
  79. }
  80. // default to null
  81. public string Id {
  82. get { return GetField (XmlSignature.AttributeNames.Id); }
  83. set { SetField (XmlSignature.AttributeNames.Id, value); }
  84. }
  85. // default to null
  86. public string MimeType {
  87. get { return GetField (XmlSignature.AttributeNames.MimeType); }
  88. set { SetField (XmlSignature.AttributeNames.MimeType, value); }
  89. }
  90. private string GetField (string attribute)
  91. {
  92. XmlNode attr = element.Attributes [attribute];
  93. return attr != null ? attr.Value : null;
  94. }
  95. private void SetField (string attribute, string value)
  96. {
  97. // MS-BUGS: it never cleans attribute value up.
  98. if (value == null)
  99. return;
  100. if (propertyModified)
  101. element.SetAttribute (attribute, value);
  102. else {
  103. XmlDocument document = new XmlDocument ();
  104. XmlElement el = document.ImportNode (element, true) as XmlElement;
  105. el.Attributes.RemoveAll ();
  106. document.AppendChild (el); // FIXME: it should not be appended
  107. el.SetAttribute (attribute, value);
  108. element = el;
  109. propertyModified = true;
  110. }
  111. }
  112. public XmlElement GetXml ()
  113. {
  114. if (propertyModified) {
  115. // It looks MS.NET returns element which comes from new XmlDocument every time
  116. XmlElement oldElement = element;
  117. XmlDocument doc = new XmlDocument ();
  118. element = doc.CreateElement (XmlSignature.ElementNames.Object, XmlSignature.NamespaceURI);
  119. doc.AppendChild (element); // FIXME: it should not be appended
  120. foreach (XmlAttribute attribute in oldElement.Attributes) {
  121. switch (attribute.Name) {
  122. case XmlSignature.AttributeNames.Id:
  123. case XmlSignature.AttributeNames.Encoding:
  124. case XmlSignature.AttributeNames.MimeType:
  125. element.SetAttribute (attribute.Name, attribute.Value);
  126. break;
  127. }
  128. }
  129. foreach (XmlNode n in oldElement.ChildNodes)
  130. element.AppendChild (doc.ImportNode (n, true));
  131. }
  132. return element;
  133. }
  134. public void LoadXml (XmlElement value)
  135. {
  136. if (value == null)
  137. throw new ArgumentNullException ("value");
  138. element = value;
  139. propertyModified = false;
  140. }
  141. }
  142. }