Signature.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. //
  2. // Signature.cs - Signature implementation for XML Signature
  3. //
  4. // Author:
  5. // Sebastien Pouliot ([email protected])
  6. //
  7. // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
  8. //
  9. using System.Collections;
  10. using System.Security.Cryptography;
  11. using System.Xml;
  12. namespace System.Security.Cryptography.Xml {
  13. public class Signature {
  14. static XmlNamespaceManager dsigNsmgr;
  15. static Signature ()
  16. {
  17. dsigNsmgr = new XmlNamespaceManager (new NameTable ());
  18. dsigNsmgr.AddNamespace ("xd", XmlSignature.NamespaceURI);
  19. }
  20. private ArrayList list;
  21. private SignedInfo info;
  22. private KeyInfo key;
  23. private string id;
  24. private byte[] signature;
  25. public Signature()
  26. {
  27. list = new ArrayList ();
  28. }
  29. public string Id {
  30. get { return id; }
  31. set { id = value; }
  32. }
  33. public KeyInfo KeyInfo {
  34. get { return key; }
  35. set { key = value; }
  36. }
  37. public IList ObjectList {
  38. get { return list; }
  39. set { list = ArrayList.Adapter (value); }
  40. }
  41. public byte[] SignatureValue {
  42. get { return signature; }
  43. set { signature = value; }
  44. }
  45. public SignedInfo SignedInfo {
  46. get { return info; }
  47. set { info = value; }
  48. }
  49. public void AddObject (DataObject dataObject)
  50. {
  51. list.Add (dataObject);
  52. }
  53. public XmlElement GetXml ()
  54. {
  55. if (info == null)
  56. throw new CryptographicException ("SignedInfo");
  57. if (signature == null)
  58. throw new CryptographicException ("SignatureValue");
  59. XmlDocument document = new XmlDocument ();
  60. XmlElement xel = document.CreateElement (XmlSignature.ElementNames.Signature, XmlSignature.NamespaceURI);
  61. if (id != null)
  62. xel.SetAttribute (XmlSignature.AttributeNames.Id, id);
  63. XmlNode xn = info.GetXml ();
  64. XmlNode newNode = document.ImportNode (xn, true);
  65. xel.AppendChild (newNode);
  66. if (signature != null) {
  67. XmlElement sv = document.CreateElement (XmlSignature.ElementNames.SignatureValue, XmlSignature.NamespaceURI);
  68. sv.InnerText = Convert.ToBase64String (signature);
  69. xel.AppendChild (sv);
  70. }
  71. if (key != null) {
  72. xn = key.GetXml ();
  73. newNode = document.ImportNode (xn, true);
  74. xel.AppendChild (newNode);
  75. }
  76. if (list.Count > 0) {
  77. foreach (DataObject obj in list) {
  78. xn = obj.GetXml ();
  79. newNode = document.ImportNode (xn, true);
  80. xel.AppendChild (newNode);
  81. }
  82. }
  83. return xel;
  84. }
  85. private string GetAttribute (XmlElement xel, string attribute)
  86. {
  87. XmlAttribute xa = xel.Attributes [attribute];
  88. return ((xa != null) ? xa.InnerText : null);
  89. }
  90. public void LoadXml (XmlElement value)
  91. {
  92. if (value == null)
  93. throw new ArgumentNullException ("value");
  94. if ((value.LocalName == XmlSignature.ElementNames.Signature) && (value.NamespaceURI == XmlSignature.NamespaceURI)) {
  95. id = GetAttribute (value, XmlSignature.AttributeNames.Id);
  96. // LAMESPEC: This library is totally useless against eXtensibly Marked-up document.
  97. int i = NextElementPos (value.ChildNodes, 0, XmlSignature.ElementNames.SignedInfo, XmlSignature.NamespaceURI, true);
  98. XmlElement sinfo = (XmlElement) value.ChildNodes [i];
  99. info = new SignedInfo ();
  100. info.LoadXml (sinfo);
  101. i = NextElementPos (value.ChildNodes, ++i, XmlSignature.ElementNames.SignatureValue, XmlSignature.NamespaceURI, true);
  102. XmlElement sigValue = (XmlElement) value.ChildNodes [i];
  103. signature = Convert.FromBase64String (sigValue.InnerText);
  104. i = NextElementPos (value.ChildNodes, ++i, XmlSignature.ElementNames.KeyInfo, XmlSignature.NamespaceURI, true);
  105. if (i > 0) {
  106. XmlElement kinfo = (XmlElement) value.ChildNodes [i];
  107. key = new KeyInfo ();
  108. key.LoadXml (kinfo);
  109. }
  110. XmlNodeList xnl = value.SelectNodes ("xd:Object", dsigNsmgr);
  111. foreach (XmlElement xn in xnl) {
  112. DataObject obj = new DataObject ();
  113. obj.LoadXml (xn);
  114. AddObject (obj);
  115. }
  116. }
  117. else
  118. throw new CryptographicException ("Malformed element: Signature.");
  119. // if invalid
  120. if (info == null)
  121. throw new CryptographicException ("SignedInfo");
  122. if (signature == null)
  123. throw new CryptographicException ("SignatureValue");
  124. }
  125. private int NextElementPos (XmlNodeList nl, int pos, string name, string ns, bool required)
  126. {
  127. while (pos < nl.Count) {
  128. if (nl [pos].NodeType == XmlNodeType.Element) {
  129. if (nl [pos].LocalName != name && nl [pos].NamespaceURI != ns) {
  130. if (required)
  131. throw new CryptographicException ("Malformed element " + name);
  132. else
  133. return -2;
  134. }
  135. return pos;
  136. }
  137. else
  138. pos++;
  139. }
  140. if (required)
  141. throw new CryptographicException ("Malformed element " + name);
  142. return -1;
  143. }
  144. }
  145. }