2 // SignedXmlTest.cs - NUnit Test Cases for SignedXml
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)
12 using System
.Security
.Cryptography
;
13 using System
.Security
.Cryptography
.Xml
;
17 using NUnit
.Framework
;
19 namespace MonoTests
.System
.Security
.Cryptography
.Xml
{
21 public class SignedXmlEx
: SignedXml
{
23 // required to test protected GetPublicKey in SignedXml
24 public AsymmetricAlgorithm
PublicGetPublicKey ()
26 return base.GetPublicKey ();
31 public class SignedXmlTest
: Assertion
{
33 private const string signature
= "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" /><Reference URI=\"#MyObjectId\"><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>CTnnhjxUQHJmD+t1MjVXrOW+MCA=</DigestValue></Reference></SignedInfo><SignatureValue>dbFt6Zw3vR+Xh7LbM/vuifyFA7gPh/NlDM2Glz/SJBsveISieuTBpZlk/zavAeuXR/Nu0Ztt4OP4tCOg09a2RNlrTP0dhkeEfL1jTzpnVaLHuQbCiwOWCgbRif7Xt7N12FuiHYb3BltP/YyXS4E12NxlGlqnDiFA1v/mkK5+C1o=</SignatureValue><KeyInfo><KeyValue xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><RSAKeyValue><Modulus>hEfTJNa2idz2u+fSYDDG4Lx/xuk4aBbvOPVNqgc1l9Y8t7Pt+ZyF+kkF3uUl8Y0700BFGAsprnhwrWENK+PGdtvM5796ZKxCCa0ooKkofiT4355HqK26hpV8dvj38vq/rkJe1jHZgkTKa+c/0vjcYZOI/RT/IZv9JfXxVWLuLxk=</Modulus><Exponent>EQ==</Exponent></RSAKeyValue></KeyValue></KeyInfo><Object Id=\"MyObjectId\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><ObjectListTag xmlns=\"\" /></Object></Signature>";
36 public void StaticValues ()
38 AssertEquals ("XmlDsigCanonicalizationUrl", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", SignedXml
.XmlDsigCanonicalizationUrl
);
39 AssertEquals ("XmlDsigCanonicalizationWithCommentsUrl", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments", SignedXml
.XmlDsigCanonicalizationWithCommentsUrl
);
40 AssertEquals ("XmlDsigDSAUrl", "http://www.w3.org/2000/09/xmldsig#dsa-sha1", SignedXml
.XmlDsigDSAUrl
);
41 AssertEquals ("XmlDsigHMACSHA1Url", "http://www.w3.org/2000/09/xmldsig#hmac-sha1", SignedXml
.XmlDsigHMACSHA1Url
);
42 AssertEquals ("XmlDsigMinimalCanonicalizationUrl", "http://www.w3.org/2000/09/xmldsig#minimal", SignedXml
.XmlDsigMinimalCanonicalizationUrl
);
43 AssertEquals ("XmlDsigNamespaceUrl", "http://www.w3.org/2000/09/xmldsig#", SignedXml
.XmlDsigNamespaceUrl
);
44 AssertEquals ("XmlDsigRSASHA1Url", "http://www.w3.org/2000/09/xmldsig#rsa-sha1", SignedXml
.XmlDsigRSASHA1Url
);
45 AssertEquals ("XmlDsigSHA1Url", "http://www.w3.org/2000/09/xmldsig#sha1", SignedXml
.XmlDsigSHA1Url
);
49 public void Constructor_Empty ()
51 XmlDocument doc
= new XmlDocument ();
52 doc
.LoadXml (signature
);
53 XmlNodeList xnl
= doc
.GetElementsByTagName ("Signature", SignedXml
.XmlDsigNamespaceUrl
);
54 XmlElement xel
= (XmlElement
) xnl
[0];
56 SignedXml sx
= new SignedXml (doc
);
58 Assert ("CheckSignature", sx
.CheckSignature ());
62 public void Constructor_XmlDocument ()
64 XmlDocument doc
= new XmlDocument ();
65 doc
.LoadXml (signature
);
66 XmlNodeList xnl
= doc
.GetElementsByTagName ("Signature", SignedXml
.XmlDsigNamespaceUrl
);
67 XmlElement xel
= (XmlElement
) xnl
[0];
69 SignedXml sx
= new SignedXml (doc
);
70 sx
.LoadXml (doc
.DocumentElement
);
71 Assert ("CheckSignature", sx
.CheckSignature ());
75 [ExpectedException (typeof (ArgumentNullException
))]
76 public void Constructor_XmlDocument_Null ()
78 XmlDocument doc
= null;
79 SignedXml sx
= new SignedXml (doc
);
83 public void Constructor_XmlElement ()
85 XmlDocument doc
= new XmlDocument ();
86 doc
.LoadXml (signature
);
87 XmlNodeList xnl
= doc
.GetElementsByTagName ("Signature", SignedXml
.XmlDsigNamespaceUrl
);
88 XmlElement xel
= (XmlElement
) xnl
[0];
90 SignedXml sx
= new SignedXml (doc
.DocumentElement
);
92 Assert ("CheckSignature", sx
.CheckSignature ());
96 [ExpectedException (typeof (CryptographicException
))]
97 public void Constructor_XmlElement_WithoutLoadXml ()
99 XmlDocument doc
= new XmlDocument ();
100 doc
.LoadXml (signature
);
101 XmlNodeList xnl
= doc
.GetElementsByTagName ("Signature", SignedXml
.XmlDsigNamespaceUrl
);
102 XmlElement xel
= (XmlElement
) xnl
[0];
104 SignedXml sx
= new SignedXml (doc
.DocumentElement
);
105 Assert ("!CheckSignature", sx
.CheckSignature ());
106 // SignedXml (XmlElement) != SignedXml () + LoadXml (XmlElement)
110 [ExpectedException (typeof (ArgumentNullException
))]
111 public void Constructor_XmlElement_Null ()
113 XmlElement xel
= null;
114 SignedXml sx
= new SignedXml (xel
);
117 // sample from MSDN (url)
118 public SignedXml
MSDNSample ()
120 // Create example data to sign.
121 XmlDocument document
= new XmlDocument ();
122 XmlNode node
= document
.CreateNode (XmlNodeType
.Element
, "", "MyElement", "samples");
123 node
.InnerText
= "This is some text";
124 document
.AppendChild (node
);
126 // Create the SignedXml message.
127 SignedXml signedXml
= new SignedXml ();
129 // Create a data object to hold the data to sign.
130 DataObject dataObject
= new DataObject ();
131 dataObject
.Data
= document
.ChildNodes
;
132 dataObject
.Id
= "MyObjectId";
134 // Add the data object to the signature.
135 signedXml
.AddObject (dataObject
);
137 // Create a reference to be able to package everything into the
139 Reference reference
= new Reference ();
140 reference
.Uri
= "#MyObjectId";
142 // Add it to the message.
143 signedXml
.AddReference (reference
);
149 public void AsymmetricRSASignature ()
151 SignedXml signedXml
= MSDNSample ();
153 RSA key
= RSA
.Create ();
154 signedXml
.SigningKey
= key
;
157 KeyInfo keyInfo
= new KeyInfo ();
158 keyInfo
.AddClause (new RSAKeyValue (key
));
159 signedXml
.KeyInfo
= keyInfo
;
161 AssertEquals ("KeyInfo", 1, signedXml
.KeyInfo
.Count
);
162 AssertNull ("SignatureLength", signedXml
.SignatureLength
);
163 AssertNull ("SignatureMethod", signedXml
.SignatureMethod
);
164 AssertNull ("SignatureValue", signedXml
.SignatureValue
);
165 AssertNull ("SigningKeyName", signedXml
.SigningKeyName
);
167 // Compute the signature.
168 signedXml
.ComputeSignature ();
170 AssertNull ("SigningKeyName", signedXml
.SigningKeyName
);
171 AssertEquals ("SignatureMethod", SignedXml
.XmlDsigRSASHA1Url
, signedXml
.SignatureMethod
);
172 AssertEquals ("SignatureValue", 128, signedXml
.SignatureValue
.Length
);
173 AssertNull ("SigningKeyName", signedXml
.SigningKeyName
);
175 // Get the XML representation of the signature.
176 XmlElement xmlSignature
= signedXml
.GetXml ();
178 // LAMESPEC: we must reload the signature or it won't work
179 // MS framework throw a "malformed element"
180 SignedXml vrfy
= new SignedXml ();
181 vrfy
.LoadXml (xmlSignature
);
183 // assert that we can verify our own signature
184 Assert ("RSA-Compute/Verify", vrfy
.CheckSignature ());
188 public void AsymmetricDSASignature ()
190 SignedXml signedXml
= MSDNSample ();
192 DSA key
= DSA
.Create ();
193 signedXml
.SigningKey
= key
;
196 KeyInfo keyInfo
= new KeyInfo ();
197 keyInfo
.AddClause (new DSAKeyValue (key
));
198 signedXml
.KeyInfo
= keyInfo
;
200 AssertEquals ("KeyInfo", 1, signedXml
.KeyInfo
.Count
);
201 AssertNull ("SignatureLength", signedXml
.SignatureLength
);
202 AssertNull ("SignatureMethod", signedXml
.SignatureMethod
);
203 AssertNull ("SignatureValue", signedXml
.SignatureValue
);
204 AssertNull ("SigningKeyName", signedXml
.SigningKeyName
);
206 // Compute the signature.
207 signedXml
.ComputeSignature ();
209 AssertNull ("SignatureLength", signedXml
.SignatureLength
);
210 AssertEquals ("SignatureMethod", SignedXml
.XmlDsigDSAUrl
, signedXml
.SignatureMethod
);
211 AssertEquals ("SignatureValue", 40, signedXml
.SignatureValue
.Length
);
212 AssertNull ("SigningKeyName", signedXml
.SigningKeyName
);
214 // Get the XML representation of the signature.
215 XmlElement xmlSignature
= signedXml
.GetXml ();
217 // LAMESPEC: we must reload the signature or it won't work
218 // MS framework throw a "malformed element"
219 SignedXml vrfy
= new SignedXml ();
220 vrfy
.LoadXml (xmlSignature
);
222 // assert that we can verify our own signature
223 Assert ("DSA-Compute/Verify", vrfy
.CheckSignature ());
227 public void SymmetricHMACSHA1Signature ()
229 SignedXml signedXml
= MSDNSample ();
231 // Compute the signature.
232 byte[] secretkey
= Encoding
.Default
.GetBytes ("password");
233 HMACSHA1 hmac
= new HMACSHA1 (secretkey
);
235 AssertNull ("KeyInfo", signedXml
.KeyInfo
);
236 AssertNull ("SignatureLength", signedXml
.SignatureLength
);
237 AssertNull ("SignatureMethod", signedXml
.SignatureMethod
);
238 AssertNull ("SignatureValue", signedXml
.SignatureValue
);
239 AssertNull ("SigningKeyName", signedXml
.SigningKeyName
);
241 signedXml
.ComputeSignature (hmac
);
243 AssertNull ("KeyInfo", signedXml
.KeyInfo
);
244 AssertNull ("SignatureLength", signedXml
.SignatureLength
);
245 AssertEquals ("SignatureMethod", SignedXml
.XmlDsigHMACSHA1Url
, signedXml
.SignatureMethod
);
246 AssertEquals ("SignatureValue", 20, signedXml
.SignatureValue
.Length
);
247 AssertNull ("SigningKeyName", signedXml
.SigningKeyName
);
249 // Get the XML representation of the signature.
250 XmlElement xmlSignature
= signedXml
.GetXml ();
252 // LAMESPEC: we must reload the signature or it won't work
253 // MS framework throw a "malformed element"
254 SignedXml vrfy
= new SignedXml ();
255 vrfy
.LoadXml (xmlSignature
);
257 // assert that we can verify our own signature
258 Assert ("HMACSHA1-Compute/Verify", vrfy
.CheckSignature (hmac
));
262 [ExpectedException (typeof (CryptographicException
))]
263 public void SymmetricMACTripleDESSignature ()
265 SignedXml signedXml
= MSDNSample ();
266 // Compute the signature.
267 byte[] secretkey
= Encoding
.Default
.GetBytes ("password");
268 MACTripleDES hmac
= new MACTripleDES (secretkey
);
269 signedXml
.ComputeSignature (hmac
);
272 // Using empty constructor
273 // LAMESPEC: The two other constructors don't seems to apply in verifying signatures
275 public void AsymmetricRSAVerify ()
277 string value = "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" /><Reference URI=\"#MyObjectId\"><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>/Vvq6sXEVbtZC8GwNtLQnGOy/VI=</DigestValue></Reference></SignedInfo><SignatureValue>A6XuE8Cy9iOffRXaW9b0+dUcMUJQnlmwLsiqtQnADbCtZXnXAaeJ6nGnQ4Mm0IGi0AJc7/2CoJReXl7iW4hltmFguG1e3nl0VxCyCTHKGOCo1u8R3K+B1rTaenFbSxs42EM7/D9KETsPlzfYfis36yM3PqatiCUOsoMsAiMGzlc=</SignatureValue><KeyInfo><KeyValue xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><RSAKeyValue><Modulus>tI8QYIpbG/m6JLyvP+S3X8mzcaAIayxomyTimSh9UCpEucRnGvLw0P73uStNpiF7wltTZA1HEsv+Ha39dY/0j/Wiy3RAodGDRNuKQao1wu34aNybZ673brbsbHFUfw/o7nlKD2xO84fbajBZmKtBBDy63NHt+QL+grSrREPfCTM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo><Object Id=\"MyObjectId\"><MyElement xmlns=\"samples\">This is some text</MyElement></Object></Signature>";
278 XmlDocument doc
= new XmlDocument ();
281 SignedXml v1
= new SignedXml ();
282 v1
.LoadXml (doc
.DocumentElement
);
283 Assert ("RSA-CheckSignature()", v1
.CheckSignature ());
285 SignedXml v2
= new SignedXml ();
286 v2
.LoadXml (doc
.DocumentElement
);
287 AsymmetricAlgorithm key
= null;
288 bool vrfy
= v2
.CheckSignatureReturningKey (out key
);
289 Assert ("RSA-CheckSignatureReturningKey()", vrfy
);
291 SignedXml v3
= new SignedXml ();
292 v3
.LoadXml (doc
.DocumentElement
);
293 Assert ("RSA-CheckSignature(key)", v3
.CheckSignature (key
));
296 // Using empty constructor
297 // LAMESPEC: The two other constructors don't seems to apply in verifying signatures
299 public void AsymmetricDSAVerify ()
301 string value = "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#dsa-sha1\" /><Reference URI=\"#MyObjectId\"><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>/Vvq6sXEVbtZC8GwNtLQnGOy/VI=</DigestValue></Reference></SignedInfo><SignatureValue>BYz/qRGjGsN1yMFPxWa3awUZm1y4I/IxOQroMxkOteRGgk1HIwhRYw==</SignatureValue><KeyInfo><KeyValue xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><DSAKeyValue><P>iglVaZ+LsSL8Y0aDXmFMBwva3xHqIypr3l/LtqBH9ziV2Sh1M4JVasAiKqytWIWt/s/Uk8Ckf2tO2Ww1vsNi1NL+Kg9T7FE52sn380/rF0miwGkZeidzm74OWhykb3J+wCTXaIwOzAWI1yN7FoeoN7wzF12jjlSXAXeqPMlViqk=</P><Q>u4sowiJMHilNRojtdmIuQY2YnB8=</Q><G>SdnN7d+wn1n+HH4Hr8MIryIRYgcXdbZ5TH7jAnuWc1koqRc1AZfcYAZ6RDf+orx6Lzn055FTFiN+1NHQfGUtXJCWW0zz0FVV1NJux7WRj8vGTldjJ5ef0oCenkpwDjcIxWsZgVobve4GPoyN1sAc1scnkJB59oupibklmF4y72A=</G><Y>XejzS8Z51yfl0zbYnxSYYbHqreSLjNCoGPB/KjM1TOyV5sMjz0StKtGrFWryTWc7EgvFY7kUth4e04VKf9HbK8z/FifHTXj8+Tszbjzw8GfInnBwLN+vJgbpnjtypmiI5Bm2nLiRbfkdAHP+OrKtr/EauM9GQfYuaxm3/Vj8B84=</Y><J>vGwGg9wqwwWP9xsoPoXu6kHArJtadiNKe9azBiUx5Ob883gd5wlKfEcGuKkBmBySGbgwxyOsIBovd9Kk48hF01ymfQzAAuHR0EdJECSsTsTTKVTLQNBU32O+PRbLYpv4E8kt6rNL83JLJCBY</J><Seed>sqzn8J6fd2gtEyq6YOqiUSHgPE8=</Seed><PgenCounter>sQ==</PgenCounter></DSAKeyValue></KeyValue></KeyInfo><Object Id=\"MyObjectId\"><MyElement xmlns=\"samples\">This is some text</MyElement></Object></Signature>";
302 XmlDocument doc
= new XmlDocument ();
305 SignedXml v1
= new SignedXml ();
306 v1
.LoadXml (doc
.DocumentElement
);
307 Assert ("DSA-CheckSignature()", v1
.CheckSignature ());
309 SignedXml v2
= new SignedXml ();
310 v2
.LoadXml (doc
.DocumentElement
);
311 AsymmetricAlgorithm key
= null;
312 bool vrfy
= v2
.CheckSignatureReturningKey (out key
);
313 Assert ("DSA-CheckSignatureReturningKey()", vrfy
);
315 SignedXml v3
= new SignedXml ();
316 v3
.LoadXml (doc
.DocumentElement
);
317 Assert ("DSA-CheckSignature(key)", v3
.CheckSignature (key
));
321 public void SymmetricHMACSHA1Verify ()
323 string value = "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#hmac-sha1\" /><Reference URI=\"#MyObjectId\"><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>/Vvq6sXEVbtZC8GwNtLQnGOy/VI=</DigestValue></Reference></SignedInfo><SignatureValue>e2RxYr5yGbvTqZLCFcgA2RAC0yE=</SignatureValue><Object Id=\"MyObjectId\"><MyElement xmlns=\"samples\">This is some text</MyElement></Object></Signature>";
324 XmlDocument doc
= new XmlDocument ();
327 SignedXml v1
= new SignedXml ();
328 v1
.LoadXml (doc
.DocumentElement
);
330 byte[] secretkey
= Encoding
.Default
.GetBytes ("password");
331 HMACSHA1 hmac
= new HMACSHA1 (secretkey
);
333 Assert ("HMACSHA1-CheckSignature(key)", v1
.CheckSignature (hmac
));
337 // adapted from http://bugzilla.ximian.com/show_bug.cgi?id=52084
338 public void GetIdElement ()
340 XmlDocument doc
= new XmlDocument ();
341 doc
.LoadXml (signature
);
343 SignedXml v1
= new SignedXml ();
344 v1
.LoadXml (doc
.DocumentElement
);
345 Assert ("CheckSignature", v1
.CheckSignature ());
347 XmlElement xel
= v1
.GetIdElement (doc
, "MyObjectId");
348 Assert ("GetIdElement", xel
.InnerXml
.StartsWith ("<ObjectListTag"));
352 public void GetPublicKey ()
354 XmlDocument doc
= new XmlDocument ();
355 doc
.LoadXml (signature
);
357 SignedXmlEx sxe
= new SignedXmlEx ();
358 sxe
.LoadXml (doc
.DocumentElement
);
360 AsymmetricAlgorithm aa1
= sxe
.PublicGetPublicKey ();
361 Assert ("First Public Key is RSA", (aa1
is RSA
));
363 AsymmetricAlgorithm aa2
= sxe
.PublicGetPublicKey ();
364 AssertNull ("Second Public Key is null", aa2
);
368 public void Add_Null ()
370 SignedXml sx
= new SignedXml ();
371 // no ArgumentNull exceptions for those
373 sx
.AddReference (null);
377 [ExpectedException (typeof (CryptographicException
))]
378 public void GetXml_WithoutInfo ()
380 SignedXml sx
= new SignedXml ();
381 XmlElement xel
= sx
.GetXml ();
385 [ExpectedException (typeof (ArgumentNullException
))]
386 public void LoadXml_Null ()
388 SignedXml sx
= new SignedXml ();
393 public void SigningKeyName ()
395 SignedXmlEx sxe
= new SignedXmlEx ();
396 AssertNull ("SigningKeyName", sxe
.SigningKeyName
);
397 sxe
.SigningKeyName
= "mono";
398 AssertEquals ("SigningKeyName", "mono", sxe
.SigningKeyName
);
402 public void CheckSignatureEmptySafe ()
408 // empty keyinfo passes...
409 sx
= new SignedXml ();
410 sx
.KeyInfo
= new KeyInfo ();
411 Assert (!sx
.CheckSignature ());
413 // with empty KeyInfoName
414 kic
= new KeyInfoName ();
418 Assert (!sx
.CheckSignature ());
422 [ExpectedException (typeof (CryptographicException
))]
423 public void CheckSignatureEmpty ()
425 SignedXml sx
= new SignedXml ();
426 sx
.CheckSignature ();