2 // SignedInfo.cs - SignedInfo implementation for XML Signature
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
11 using System.Collections;
14 namespace System.Security.Cryptography.Xml {
16 public class SignedInfo : ICollection, IEnumerable {
18 private ArrayList references;
19 private string c14nMethod;
21 private string signatureMethod;
22 private string signatureLength;
23 private XmlElement element;
27 references = new ArrayList ();
28 c14nMethod = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
31 public string CanonicalizationMethod {
32 get { return c14nMethod; }
39 // documented as not supported (and throwing exception)
41 get { throw new NotSupportedException (); }
52 // documented as not supported (and throwing exception)
53 public bool IsReadOnly {
54 get { throw new NotSupportedException (); }
57 // documented as not supported (and throwing exception)
58 public bool IsSynchronized {
59 get { throw new NotSupportedException (); }
62 // Manipulating this array never affects GetXml() when
63 // LoadXml() was used.
64 // (Actually, there is no way to detect modification.)
65 public ArrayList References {
66 get { return references; }
69 public string SignatureLength {
70 get { return signatureLength; }
73 signatureLength = value;
77 public string SignatureMethod {
78 get { return signatureMethod; }
81 signatureMethod = value;
85 // documented as not supported (and throwing exception)
86 public object SyncRoot {
87 get { throw new NotSupportedException (); }
90 public void AddReference (Reference reference)
92 references.Add (reference);
95 // documented as not supported (and throwing exception)
96 public void CopyTo (Array array, int index)
98 throw new NotSupportedException ();
101 public IEnumerator GetEnumerator ()
103 return references.GetEnumerator ();
106 public XmlElement GetXml ()
111 if (signatureMethod == null)
112 throw new CryptographicException ("SignatureMethod");
113 if (references.Count == 0)
114 throw new CryptographicException ("References empty");
116 XmlDocument document = new XmlDocument ();
117 XmlElement xel = document.CreateElement (XmlSignature.ElementNames.SignedInfo, XmlSignature.NamespaceURI);
119 xel.SetAttribute (XmlSignature.AttributeNames.Id, id);
121 if (c14nMethod != null) {
122 XmlElement c14n = document.CreateElement (XmlSignature.ElementNames.CanonicalizationMethod, XmlSignature.NamespaceURI);
123 c14n.SetAttribute (XmlSignature.AttributeNames.Algorithm, c14nMethod);
124 xel.AppendChild (c14n);
126 if (signatureMethod != null) {
127 XmlElement sm = document.CreateElement (XmlSignature.ElementNames.SignatureMethod, XmlSignature.NamespaceURI);
128 sm.SetAttribute (XmlSignature.AttributeNames.Algorithm, signatureMethod);
129 if (signatureLength != null) {
130 XmlElement hmac = document.CreateElement (XmlSignature.ElementNames.HMACOutputLength, XmlSignature.NamespaceURI);
131 hmac.InnerText = signatureLength;
132 sm.AppendChild (hmac);
134 xel.AppendChild (sm);
137 // This check is only done when element is created here.
138 if (references.Count == 0)
139 throw new CryptographicException ("At least one Reference element is required in SignedInfo.");
141 // we add References afterward so we don't end up with extraneous
142 // xmlns="..." in each reference elements.
143 foreach (Reference r in references) {
144 XmlNode xn = r.GetXml ();
145 XmlNode newNode = document.ImportNode (xn, true);
146 xel.AppendChild (newNode);
152 private string GetAttribute (XmlElement xel, string attribute)
154 XmlAttribute xa = xel.Attributes [attribute];
155 return ((xa != null) ? xa.InnerText : null);
158 public void LoadXml (XmlElement value)
161 throw new ArgumentNullException ("value");
163 if ((value.LocalName != XmlSignature.ElementNames.SignedInfo) || (value.NamespaceURI != XmlSignature.NamespaceURI))
164 throw new CryptographicException ();
166 id = GetAttribute (value, XmlSignature.AttributeNames.Id);
167 c14nMethod = XmlSignature.GetAttributeFromElement (value, XmlSignature.AttributeNames.Algorithm, XmlSignature.ElementNames.CanonicalizationMethod);
169 XmlElement sm = XmlSignature.GetChildElement (value, XmlSignature.ElementNames.SignatureMethod, XmlSignature.NamespaceURI);
171 signatureMethod = sm.GetAttribute (XmlSignature.AttributeNames.Algorithm);
172 XmlElement length = XmlSignature.GetChildElement (sm, XmlSignature.ElementNames.HMACOutputLength, XmlSignature.NamespaceURI);
173 if (length != null) {
174 signatureLength = length.InnerText;
178 for (int i = 0; i < value.ChildNodes.Count; i++) {
179 XmlNode n = value.ChildNodes [i];
180 if (n.NodeType == XmlNodeType.Element &&
181 n.LocalName == XmlSignature.ElementNames.Reference &&
182 n.NamespaceURI == XmlSignature.NamespaceURI) {
183 Reference r = new Reference ();
184 r.LoadXml ((XmlElement) n);