2004-02-19 Tim Coleman <tim@timcoleman.com>
[mono.git] / mcs / class / System.Security / System.Security.Cryptography.Xml / Signature.cs
1 //
2 // Signature.cs - Signature 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.Security.Cryptography;
12 using System.Xml;
13
14 namespace System.Security.Cryptography.Xml {
15
16         public class Signature {
17
18                 private ArrayList list;
19                 private SignedInfo info;
20                 private KeyInfo key;
21                 private string id;
22                 private byte[] signature;
23
24                 public Signature() 
25                 {
26                         list = new ArrayList ();
27                 }
28
29                 public string Id {
30                         get { return id; }
31                         set { id = value; }
32                 }
33
34                 public KeyInfo KeyInfo {
35                         get { return key; }
36                         set { key = value; }
37                 }
38
39                 public IList ObjectList {
40                         get { return list; }
41                         set { list = ArrayList.Adapter (value); }
42                 }
43
44                 public byte[] SignatureValue {
45                         get { return signature; }
46                         set { signature = value; }
47                 }
48
49                 public SignedInfo SignedInfo {
50                         get { return info; }
51                         set { info = value; }
52                 }
53
54                 public void AddObject (DataObject dataObject) 
55                 {
56                         list.Add (dataObject);
57                 }
58
59                 public XmlElement GetXml () 
60                 {
61                         if (info == null)
62                                 throw new CryptographicException ("SignedInfo");
63                         if (signature == null)
64                                 throw new CryptographicException ("SignatureValue");
65
66                         XmlDocument document = new XmlDocument ();
67                         XmlElement xel = document.CreateElement (XmlSignature.ElementNames.Signature, XmlSignature.NamespaceURI);
68                         if (id != null)
69                                 xel.SetAttribute (XmlSignature.AttributeNames.Id, id);
70
71                         XmlNode xn = info.GetXml ();
72                         XmlNode newNode = document.ImportNode (xn, true);
73                         xel.AppendChild (newNode);
74
75                         if (signature != null) {
76                                 XmlElement sv = document.CreateElement (XmlSignature.ElementNames.SignatureValue, XmlSignature.NamespaceURI);
77                                 sv.InnerText = Convert.ToBase64String (signature);
78                                 xel.AppendChild (sv);
79                         }
80
81                         if (key != null) {
82                                 xn = key.GetXml ();
83                                 newNode = document.ImportNode (xn, true);
84                                 xel.AppendChild (newNode);
85                         }
86
87                         if (list.Count > 0) {
88                                 foreach (DataObject obj in list) {
89                                         xn = obj.GetXml ();
90                                         newNode = document.ImportNode (xn, true);
91                                         xel.AppendChild (newNode);
92                                 }
93                         }
94
95                         return xel;
96                 }
97
98                 private string GetAttribute (XmlElement xel, string attribute) 
99                 {
100                         XmlAttribute xa = xel.Attributes [attribute];
101                         return ((xa != null) ? xa.InnerText : null);
102                 }
103
104                 public void LoadXml (XmlElement value) 
105                 {
106                         if (value == null)
107                                 throw new ArgumentNullException ("value");
108
109                         if ((value.LocalName == XmlSignature.ElementNames.Signature) && (value.NamespaceURI == XmlSignature.NamespaceURI)) {
110                                 id = GetAttribute (value, XmlSignature.AttributeNames.Id);
111
112                                 XmlNodeList xnl = value.GetElementsByTagName (XmlSignature.ElementNames.SignedInfo);
113                                 if ((xnl != null) && (xnl.Count == 1)) {
114                                         info = new SignedInfo ();
115                                         info.LoadXml ((XmlElement) xnl[0]);
116                                 }
117
118                                 xnl = value.GetElementsByTagName (XmlSignature.ElementNames.SignatureValue);
119                                 if ((xnl != null) && (xnl.Count == 1)) {
120                                         signature = Convert.FromBase64String (xnl[0].InnerText);
121                                 }
122
123                                 xnl = value.GetElementsByTagName (XmlSignature.ElementNames.KeyInfo);
124                                 if ((xnl != null) && (xnl.Count == 1)) {
125                                         key = new KeyInfo ();
126                                         key.LoadXml ((XmlElement) xnl[0]);
127                                 }
128
129                                 xnl = value.GetElementsByTagName (XmlSignature.ElementNames.Object);
130                                 if ((xnl != null) && (xnl.Count > 0)) {
131                                         foreach (XmlNode xn in xnl) {
132                                                 DataObject obj = new DataObject ();
133                                                 obj.LoadXml ((XmlElement) xn);
134                                                 AddObject (obj);
135                                         }
136                                 }
137                         }
138
139                         // if invalid
140                         if (info == null)
141                                 throw new CryptographicException ("SignedInfo");
142                         if (signature == null)
143                                 throw new CryptographicException ("SignatureValue");
144                 }
145         }
146 }