Reference.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. 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. // note: we do NOT return null -on purpose- if attribute isn't found
  94. private string GetAttribute (XmlElement xel, string attribute)
  95. {
  96. XmlAttribute xa = xel.Attributes [attribute];
  97. return ((xa != null) ? xa.InnerText : null);
  98. }
  99. public void LoadXml (XmlElement value)
  100. {
  101. if (value == null)
  102. throw new ArgumentNullException ("value");
  103. if ((value.LocalName != XmlSignature.ElementNames.Reference) || (value.NamespaceURI != XmlSignature.NamespaceURI))
  104. throw new CryptographicException ();
  105. id = GetAttribute (value, XmlSignature.AttributeNames.Id);
  106. uri = GetAttribute (value, XmlSignature.AttributeNames.URI);
  107. type = GetAttribute (value, XmlSignature.AttributeNames.Type);
  108. // Note: order is important for validations
  109. XmlNodeList xnl = value.GetElementsByTagName (XmlSignature.ElementNames.Transform, XmlSignature.NamespaceURI);
  110. if ((xnl != null) && (xnl.Count > 0)) {
  111. Transform t = null;
  112. foreach (XmlNode xn in xnl) {
  113. string a = GetAttribute ((XmlElement)xn, XmlSignature.AttributeNames.Algorithm);
  114. switch (a) {
  115. case "http://www.w3.org/2000/09/xmldsig#base64":
  116. t = new XmlDsigBase64Transform ();
  117. break;
  118. case "http://www.w3.org/TR/2001/REC-xml-c14n-20010315":
  119. t = new XmlDsigC14NTransform ();
  120. break;
  121. case "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments":
  122. t = new XmlDsigC14NWithCommentsTransform ();
  123. break;
  124. case "http://www.w3.org/2000/09/xmldsig#enveloped-signature":
  125. t = new XmlDsigEnvelopedSignatureTransform ();
  126. break;
  127. case "http://www.w3.org/TR/1999/REC-xpath-19991116":
  128. t = new XmlDsigXPathTransform ();
  129. break;
  130. case "http://www.w3.org/TR/1999/REC-xslt-19991116":
  131. t = new XmlDsigXsltTransform ();
  132. break;
  133. default:
  134. throw new NotSupportedException ();
  135. }
  136. if (xn.ChildNodes.Count > 0) {
  137. t.LoadInnerXml (xn.ChildNodes);
  138. }
  139. AddTransform (t);
  140. }
  141. }
  142. // get DigestMethod
  143. DigestMethod = XmlSignature.GetAttributeFromElement (value, XmlSignature.AttributeNames.Algorithm, XmlSignature.ElementNames.DigestMethod);
  144. // get DigestValue
  145. XmlElement dig = XmlSignature.GetChildElement (value, XmlSignature.ElementNames.DigestValue, XmlSignature.NamespaceURI);
  146. if (dig != null)
  147. DigestValue = Convert.FromBase64String (dig.InnerText);
  148. }
  149. }
  150. }