2004-03-16 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / System.Security / System.Security.Cryptography.Xml / SignedInfo.cs
1 //
2 // SignedInfo.cs - SignedInfo implementation for XML Signature
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
9 //
10
11 using System.Collections;
12 using System.Xml;
13
14 namespace System.Security.Cryptography.Xml { 
15
16         public class SignedInfo : ICollection, IEnumerable {
17
18                 private ArrayList references;
19                 private string c14nMethod;
20                 private string id;
21                 private string signatureMethod;
22                 private string signatureLength;
23
24                 public SignedInfo() 
25                 {
26                         references = new ArrayList ();
27                         c14nMethod = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
28                 }
29
30                 public string CanonicalizationMethod {
31                         get { return c14nMethod; }
32                         set { c14nMethod = value; }
33                 }
34
35                 // documented as not supported (and throwing exception)
36                 public int Count {
37                         get { throw new NotSupportedException (); }
38                 }
39
40                 public string Id {
41                         get { return id; }
42                         set { id = value; }
43                 }
44
45                 // documented as not supported (and throwing exception)
46                 public bool IsReadOnly {
47                         get { throw new NotSupportedException (); }
48                 }
49
50                 // documented as not supported (and throwing exception)
51                 public bool IsSynchronized {
52                         get { throw new NotSupportedException (); }
53                 }
54
55                 public ArrayList References {
56                         get { return references; }
57                 }
58
59                 public string SignatureLength {
60                         get { return signatureLength; }
61                         set { signatureLength = value; }
62                 }
63
64                 public string SignatureMethod {
65                         get { return signatureMethod; }
66                         set { signatureMethod = value; }
67                 }
68
69                 // documented as not supported (and throwing exception)
70                 public object SyncRoot {
71                         get { throw new NotSupportedException (); }
72                 }
73
74                 public void AddReference (Reference reference) 
75                 {
76                         references.Add (reference);
77                 }
78
79                 // documented as not supported (and throwing exception)
80                 public void CopyTo (Array array, int index) 
81                 {
82                         throw new NotSupportedException ();
83                 }
84
85                 public IEnumerator GetEnumerator () 
86                 {
87                         return references.GetEnumerator ();
88                 }
89
90                 public XmlElement GetXml() 
91                 {
92                         if (signatureMethod == null)
93                                 throw new CryptographicException ("SignatureMethod");
94                         if (references.Count == 0)
95                                 throw new CryptographicException ("References empty");
96
97                         XmlDocument document = new XmlDocument ();
98                         XmlElement xel = document.CreateElement (XmlSignature.ElementNames.SignedInfo, XmlSignature.NamespaceURI);
99                         if (id != null)
100                                 xel.SetAttribute (XmlSignature.AttributeNames.Id, id);
101
102                         if (c14nMethod != null) {
103                                 XmlElement c14n = document.CreateElement (XmlSignature.ElementNames.CanonicalizationMethod, XmlSignature.NamespaceURI);
104                                 c14n.SetAttribute (XmlSignature.AttributeNames.Algorithm, c14nMethod);
105                                 xel.AppendChild (c14n);
106                         }
107                         if (signatureMethod != null) {
108                                 XmlElement sm = document.CreateElement (XmlSignature.ElementNames.SignatureMethod, XmlSignature.NamespaceURI);
109                                 sm.SetAttribute (XmlSignature.AttributeNames.Algorithm, signatureMethod);
110                                 if (signatureLength != null) {
111                                         XmlElement hmac = document.CreateElement (XmlSignature.ElementNames.HMACOutputLength, XmlSignature.NamespaceURI);
112                                         hmac.InnerText = signatureLength;
113                                         sm.AppendChild (hmac);
114                                 }
115                                 xel.AppendChild (sm);
116                         }
117
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
126                         return xel;
127                 }
128
129                 private string GetAttribute (XmlElement xel, string attribute) 
130                 {
131                         XmlAttribute xa = xel.Attributes [attribute];
132                         return ((xa != null) ? xa.InnerText : null);
133                 }
134
135                 public void LoadXml (XmlElement value) 
136                 {
137                         if (value == null)
138                                 throw new ArgumentNullException ("value");
139
140                         if ((value.LocalName != XmlSignature.ElementNames.SignedInfo) || (value.NamespaceURI != XmlSignature.NamespaceURI))
141                                 throw new CryptographicException ();
142
143                         id = GetAttribute (value, XmlSignature.AttributeNames.Id);
144                         c14nMethod = XmlSignature.GetAttributeFromElement (value, XmlSignature.AttributeNames.Algorithm, XmlSignature.ElementNames.CanonicalizationMethod);
145
146                         XmlElement sm = XmlSignature.GetChildElement (value, XmlSignature.ElementNames.SignatureMethod, XmlSignature.NamespaceURI);
147                         if (sm != null) {
148                                 signatureMethod = sm.GetAttribute (XmlSignature.AttributeNames.Algorithm);
149                                 XmlElement length = XmlSignature.GetChildElement (sm, XmlSignature.ElementNames.HMACOutputLength, XmlSignature.NamespaceURI);
150                                 if (length != null) {
151                                         signatureLength = length.InnerText;
152                                 }
153                         }
154
155                         for (int i = 0; i < value.ChildNodes.Count; i++) {
156                                 XmlNode n = value.ChildNodes [i];
157                                 if (n.NodeType == XmlNodeType.Element &&
158                                         n.LocalName == XmlSignature.ElementNames.Reference &&
159                                         n.NamespaceURI == XmlSignature.NamespaceURI) {
160                                         Reference r = new Reference ();
161                                         r.LoadXml ((XmlElement) n);
162                                         AddReference (r);
163                                 }
164                         }
165                 }
166         }
167 }