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