Reference.cs 5.3 KB

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