Reference.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //
  2. // Reference.cs - Reference 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.IO;
  11. using System.Xml;
  12. namespace System.Security.Cryptography.Xml {
  13. // http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/Overview.html#sec-Reference
  14. public class Reference {
  15. private TransformChain chain;
  16. private string digestMethod;
  17. private byte[] digestValue;
  18. private string id;
  19. private string uri;
  20. private string type;
  21. private Stream stream;
  22. private XmlElement element;
  23. public Reference ()
  24. {
  25. chain = new TransformChain ();
  26. digestMethod = XmlSignature.NamespaceURI + "sha1";
  27. }
  28. [MonoTODO ("There is no description about how it is used.")]
  29. public Reference (Stream stream) : this ()
  30. {
  31. this.stream = stream;
  32. }
  33. public Reference (string uri) : this ()
  34. {
  35. this.uri = uri;
  36. }
  37. // default to SHA1
  38. public string DigestMethod {
  39. get { return digestMethod; }
  40. set {
  41. element = null;
  42. digestMethod = value;
  43. }
  44. }
  45. public byte[] DigestValue {
  46. get { return digestValue; }
  47. set {
  48. element = null;
  49. digestValue = value;
  50. }
  51. }
  52. public string Id {
  53. get { return id; }
  54. set {
  55. element = null;
  56. id = value;
  57. }
  58. }
  59. public TransformChain TransformChain {
  60. get { return chain; }
  61. }
  62. public string Type {
  63. get { return type; }
  64. set {
  65. element = null;
  66. type = value;
  67. }
  68. }
  69. public string Uri {
  70. get { return uri; }
  71. set {
  72. element = null;
  73. uri = value;
  74. }
  75. }
  76. public void AddTransform (Transform transform)
  77. {
  78. chain.Add (transform);
  79. }
  80. public XmlElement GetXml ()
  81. {
  82. if (element != null)
  83. return element;
  84. if (digestMethod == null)
  85. throw new CryptographicException ("DigestMethod");
  86. if (digestValue == null)
  87. throw new NullReferenceException ("DigestValue");
  88. XmlDocument document = new XmlDocument ();
  89. XmlElement xel = document.CreateElement (XmlSignature.ElementNames.Reference, XmlSignature.NamespaceURI);
  90. if (id != null)
  91. xel.SetAttribute (XmlSignature.AttributeNames.Id, id);
  92. if (uri != null)
  93. xel.SetAttribute (XmlSignature.AttributeNames.URI, uri);
  94. if (type != null)
  95. xel.SetAttribute (XmlSignature.AttributeNames.Type, type);
  96. if (chain.Count > 0) {
  97. XmlElement ts = document.CreateElement (XmlSignature.ElementNames.Transforms, XmlSignature.NamespaceURI);
  98. foreach (Transform t in chain) {
  99. XmlNode xn = t.GetXml ();
  100. XmlNode newNode = document.ImportNode (xn, true);
  101. ts.AppendChild (newNode);
  102. }
  103. xel.AppendChild (ts);
  104. }
  105. XmlElement dm = document.CreateElement (XmlSignature.ElementNames.DigestMethod, XmlSignature.NamespaceURI);
  106. dm.SetAttribute (XmlSignature.AttributeNames.Algorithm, digestMethod);
  107. xel.AppendChild (dm);
  108. XmlElement dv = document.CreateElement (XmlSignature.ElementNames.DigestValue, XmlSignature.NamespaceURI);
  109. dv.InnerText = Convert.ToBase64String (digestValue);
  110. xel.AppendChild (dv);
  111. return xel;
  112. }
  113. // note: we do NOT return null -on purpose- if attribute isn't found
  114. private string GetAttribute (XmlElement xel, string attribute)
  115. {
  116. XmlAttribute xa = xel.Attributes [attribute];
  117. return ((xa != null) ? xa.InnerText : null);
  118. }
  119. public void LoadXml (XmlElement value)
  120. {
  121. if (value == null)
  122. throw new ArgumentNullException ("value");
  123. if ((value.LocalName != XmlSignature.ElementNames.Reference) || (value.NamespaceURI != XmlSignature.NamespaceURI))
  124. throw new CryptographicException ();
  125. id = GetAttribute (value, XmlSignature.AttributeNames.Id);
  126. uri = GetAttribute (value, XmlSignature.AttributeNames.URI);
  127. type = GetAttribute (value, XmlSignature.AttributeNames.Type);
  128. // Note: order is important for validations
  129. XmlNodeList xnl = value.GetElementsByTagName (XmlSignature.ElementNames.Transform, XmlSignature.NamespaceURI);
  130. if ((xnl != null) && (xnl.Count > 0)) {
  131. Transform t = null;
  132. foreach (XmlNode xn in xnl) {
  133. string a = GetAttribute ((XmlElement)xn, XmlSignature.AttributeNames.Algorithm);
  134. switch (a) {
  135. case "http://www.w3.org/2000/09/xmldsig#base64":
  136. t = new XmlDsigBase64Transform ();
  137. break;
  138. case "http://www.w3.org/TR/2001/REC-xml-c14n-20010315":
  139. t = new XmlDsigC14NTransform ();
  140. break;
  141. case "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments":
  142. t = new XmlDsigC14NWithCommentsTransform ();
  143. break;
  144. case "http://www.w3.org/2000/09/xmldsig#enveloped-signature":
  145. t = new XmlDsigEnvelopedSignatureTransform ();
  146. break;
  147. case "http://www.w3.org/TR/1999/REC-xpath-19991116":
  148. t = new XmlDsigXPathTransform ();
  149. break;
  150. case "http://www.w3.org/TR/1999/REC-xslt-19991116":
  151. t = new XmlDsigXsltTransform ();
  152. break;
  153. default:
  154. throw new NotSupportedException ();
  155. }
  156. if (xn.ChildNodes.Count > 0) {
  157. t.LoadInnerXml (xn.ChildNodes);
  158. }
  159. AddTransform (t);
  160. }
  161. }
  162. // get DigestMethod
  163. DigestMethod = XmlSignature.GetAttributeFromElement (value, XmlSignature.AttributeNames.Algorithm, XmlSignature.ElementNames.DigestMethod);
  164. // get DigestValue
  165. XmlElement dig = XmlSignature.GetChildElement (value, XmlSignature.ElementNames.DigestValue, XmlSignature.NamespaceURI);
  166. if (dig != null)
  167. DigestValue = Convert.FromBase64String (dig.InnerText);
  168. element = value;
  169. }
  170. }
  171. }