SignedInfo.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //
  2. // SignedInfo.cs - SignedInfo 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. // (C) 2004 Novell (http://www.novell.com)
  9. //
  10. using System.Collections;
  11. using System.Xml;
  12. namespace System.Security.Cryptography.Xml {
  13. public class SignedInfo : ICollection, IEnumerable {
  14. private ArrayList references;
  15. private string c14nMethod;
  16. private string id;
  17. private string signatureMethod;
  18. private string signatureLength;
  19. private XmlElement element;
  20. public SignedInfo()
  21. {
  22. references = new ArrayList ();
  23. c14nMethod = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
  24. }
  25. public string CanonicalizationMethod {
  26. get { return c14nMethod; }
  27. set {
  28. c14nMethod = value;
  29. element = null;
  30. }
  31. }
  32. // documented as not supported (and throwing exception)
  33. public int Count {
  34. get { throw new NotSupportedException (); }
  35. }
  36. public string Id {
  37. get { return id; }
  38. set {
  39. element = null;
  40. id = value;
  41. }
  42. }
  43. // documented as not supported (and throwing exception)
  44. public bool IsReadOnly {
  45. get { throw new NotSupportedException (); }
  46. }
  47. // documented as not supported (and throwing exception)
  48. public bool IsSynchronized {
  49. get { throw new NotSupportedException (); }
  50. }
  51. // Manipulating this array never affects GetXml() when
  52. // LoadXml() was used.
  53. // (Actually, there is no way to detect modification.)
  54. public ArrayList References {
  55. get { return references; }
  56. }
  57. public string SignatureLength {
  58. get { return signatureLength; }
  59. set {
  60. element = null;
  61. signatureLength = value;
  62. }
  63. }
  64. public string SignatureMethod {
  65. get { return signatureMethod; }
  66. set {
  67. element = null;
  68. signatureMethod = value;
  69. }
  70. }
  71. // documented as not supported (and throwing exception)
  72. public object SyncRoot {
  73. get { throw new NotSupportedException (); }
  74. }
  75. public void AddReference (Reference reference)
  76. {
  77. references.Add (reference);
  78. }
  79. // documented as not supported (and throwing exception)
  80. public void CopyTo (Array array, int index)
  81. {
  82. throw new NotSupportedException ();
  83. }
  84. public IEnumerator GetEnumerator ()
  85. {
  86. return references.GetEnumerator ();
  87. }
  88. public XmlElement GetXml ()
  89. {
  90. if (element != null)
  91. return element;
  92. if (signatureMethod == null)
  93. throw new CryptographicException ("SignatureMethod");
  94. if (references.Count == 0)
  95. throw new CryptographicException ("References empty");
  96. XmlDocument document = new XmlDocument ();
  97. XmlElement xel = document.CreateElement (XmlSignature.ElementNames.SignedInfo, XmlSignature.NamespaceURI);
  98. if (id != null)
  99. xel.SetAttribute (XmlSignature.AttributeNames.Id, id);
  100. if (c14nMethod != null) {
  101. XmlElement c14n = document.CreateElement (XmlSignature.ElementNames.CanonicalizationMethod, XmlSignature.NamespaceURI);
  102. c14n.SetAttribute (XmlSignature.AttributeNames.Algorithm, c14nMethod);
  103. xel.AppendChild (c14n);
  104. }
  105. if (signatureMethod != null) {
  106. XmlElement sm = document.CreateElement (XmlSignature.ElementNames.SignatureMethod, XmlSignature.NamespaceURI);
  107. sm.SetAttribute (XmlSignature.AttributeNames.Algorithm, signatureMethod);
  108. if (signatureLength != null) {
  109. XmlElement hmac = document.CreateElement (XmlSignature.ElementNames.HMACOutputLength, XmlSignature.NamespaceURI);
  110. hmac.InnerText = signatureLength;
  111. sm.AppendChild (hmac);
  112. }
  113. xel.AppendChild (sm);
  114. }
  115. // This check is only done when element is created here.
  116. if (references.Count == 0)
  117. throw new CryptographicException ("At least one Reference element is required in SignedInfo.");
  118. // we add References afterward so we don't end up with extraneous
  119. // xmlns="..." in each reference elements.
  120. foreach (Reference r in references) {
  121. XmlNode xn = r.GetXml ();
  122. XmlNode newNode = document.ImportNode (xn, true);
  123. xel.AppendChild (newNode);
  124. }
  125. return xel;
  126. }
  127. private string GetAttribute (XmlElement xel, string attribute)
  128. {
  129. XmlAttribute xa = xel.Attributes [attribute];
  130. return ((xa != null) ? xa.InnerText : null);
  131. }
  132. public void LoadXml (XmlElement value)
  133. {
  134. if (value == null)
  135. throw new ArgumentNullException ("value");
  136. if ((value.LocalName != XmlSignature.ElementNames.SignedInfo) || (value.NamespaceURI != XmlSignature.NamespaceURI))
  137. throw new CryptographicException ();
  138. id = GetAttribute (value, XmlSignature.AttributeNames.Id);
  139. c14nMethod = XmlSignature.GetAttributeFromElement (value, XmlSignature.AttributeNames.Algorithm, XmlSignature.ElementNames.CanonicalizationMethod);
  140. XmlElement sm = XmlSignature.GetChildElement (value, XmlSignature.ElementNames.SignatureMethod, XmlSignature.NamespaceURI);
  141. if (sm != null) {
  142. signatureMethod = sm.GetAttribute (XmlSignature.AttributeNames.Algorithm);
  143. XmlElement length = XmlSignature.GetChildElement (sm, XmlSignature.ElementNames.HMACOutputLength, XmlSignature.NamespaceURI);
  144. if (length != null) {
  145. signatureLength = length.InnerText;
  146. }
  147. }
  148. for (int i = 0; i < value.ChildNodes.Count; i++) {
  149. XmlNode n = value.ChildNodes [i];
  150. if (n.NodeType == XmlNodeType.Element &&
  151. n.LocalName == XmlSignature.ElementNames.Reference &&
  152. n.NamespaceURI == XmlSignature.NamespaceURI) {
  153. Reference r = new Reference ();
  154. r.LoadXml ((XmlElement) n);
  155. AddReference (r);
  156. }
  157. }
  158. element = value;
  159. }
  160. }
  161. }