2 // Signature.cs - Signature implementation for XML Signature
5 // Sebastien Pouliot (spouliot@motus.com)
6 // Tim Coleman (tim@timcoleman.com)
8 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) Tim Coleman, 2004
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Collections
;
34 using System
.Security
.Cryptography
;
37 namespace System
.Security
.Cryptography
.Xml
{
39 public class Signature
{
40 static XmlNamespaceManager dsigNsmgr
;
44 dsigNsmgr
= new XmlNamespaceManager (new NameTable ());
45 dsigNsmgr
.AddNamespace ("xd", XmlSignature
.NamespaceURI
);
48 private ArrayList list
;
49 private SignedInfo info
;
52 private byte[] signature
;
53 private XmlElement element
;
57 list
= new ArrayList ();
68 public KeyInfo KeyInfo
{
76 public IList ObjectList
{
78 set { list = ArrayList.Adapter (value); }
81 public byte[] SignatureValue
{
82 get { return signature; }
89 public SignedInfo SignedInfo
{
97 public void AddObject (DataObject dataObject
)
99 list
.Add (dataObject
);
102 public XmlElement
GetXml ()
104 return GetXml (null);
107 internal XmlElement
GetXml (XmlDocument document
)
113 throw new CryptographicException ("SignedInfo");
114 if (signature
== null)
115 throw new CryptographicException ("SignatureValue");
117 if (document
== null)
118 document
= new XmlDocument ();
120 XmlElement xel
= document
.CreateElement (XmlSignature
.ElementNames
.Signature
, XmlSignature
.NamespaceURI
);
122 xel
.SetAttribute (XmlSignature
.AttributeNames
.Id
, id
);
124 XmlNode xn
= info
.GetXml ();
125 XmlNode newNode
= document
.ImportNode (xn
, true);
126 xel
.AppendChild (newNode
);
128 if (signature
!= null) {
129 XmlElement sv
= document
.CreateElement (XmlSignature
.ElementNames
.SignatureValue
, XmlSignature
.NamespaceURI
);
130 sv
.InnerText
= Convert
.ToBase64String (signature
);
131 xel
.AppendChild (sv
);
136 newNode
= document
.ImportNode (xn
, true);
137 xel
.AppendChild (newNode
);
140 if (list
.Count
> 0) {
141 foreach (DataObject obj
in list
) {
143 newNode
= document
.ImportNode (xn
, true);
144 xel
.AppendChild (newNode
);
151 private string GetAttribute (XmlElement xel
, string attribute
)
153 XmlAttribute xa
= xel
.Attributes
[attribute
];
154 return ((xa
!= null) ? xa
.InnerText
: null);
157 public void LoadXml (XmlElement
value)
160 throw new ArgumentNullException ("value");
162 if ((value.LocalName
== XmlSignature
.ElementNames
.Signature
) && (value.NamespaceURI
== XmlSignature
.NamespaceURI
)) {
163 id
= GetAttribute (value, XmlSignature
.AttributeNames
.Id
);
165 // LAMESPEC: This library is totally useless against eXtensibly Marked-up document.
166 int i
= NextElementPos (value.ChildNodes
, 0, XmlSignature
.ElementNames
.SignedInfo
, XmlSignature
.NamespaceURI
, true);
167 XmlElement sinfo
= (XmlElement
) value.ChildNodes
[i
];
168 info
= new SignedInfo ();
169 info
.LoadXml (sinfo
);
171 i
= NextElementPos (value.ChildNodes
, ++i
, XmlSignature
.ElementNames
.SignatureValue
, XmlSignature
.NamespaceURI
, true);
172 XmlElement sigValue
= (XmlElement
) value.ChildNodes
[i
];
173 signature
= Convert
.FromBase64String (sigValue
.InnerText
);
175 // signature isn't required: <element ref="ds:KeyInfo" minOccurs="0"/>
176 i
= NextElementPos (value.ChildNodes
, ++i
, XmlSignature
.ElementNames
.KeyInfo
, XmlSignature
.NamespaceURI
, false);
178 XmlElement kinfo
= (XmlElement
) value.ChildNodes
[i
];
179 key
= new KeyInfo ();
183 XmlNodeList xnl
= value.SelectNodes ("xd:Object", dsigNsmgr
);
184 foreach (XmlElement xn
in xnl
) {
185 DataObject obj
= new DataObject ();
191 throw new CryptographicException ("Malformed element: Signature.");
195 throw new CryptographicException ("SignedInfo");
196 if (signature
== null)
197 throw new CryptographicException ("SignatureValue");
200 private int NextElementPos (XmlNodeList nl
, int pos
, string name
, string ns
, bool required
)
202 while (pos
< nl
.Count
) {
203 if (nl
[pos
].NodeType
== XmlNodeType
.Element
) {
204 if (nl
[pos
].LocalName
!= name
|| nl
[pos
].NamespaceURI
!= ns
) {
206 throw new CryptographicException ("Malformed element " + name
);
217 throw new CryptographicException ("Malformed element " + name
);