**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Security / Test / System.Security.Cryptography.Xml / SignedXmlTest.cs
blob900d992eb69214b58396b10430e999d53d8625fa
1 //
2 // SignedXmlTest.cs - NUnit Test Cases for SignedXml
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 //
11 using System;
12 using System.Security.Cryptography;
13 using System.Security.Cryptography.Xml;
14 using System.Text;
15 using System.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 ();
30 [TestFixture]
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>";
35 [Test]
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);
48 [Test]
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);
57 sx.LoadXml (xel);
58 Assert ("CheckSignature", sx.CheckSignature ());
61 [Test]
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 ());
74 [Test]
75 [ExpectedException (typeof (ArgumentNullException))]
76 public void Constructor_XmlDocument_Null ()
78 XmlDocument doc = null;
79 SignedXml sx = new SignedXml (doc);
82 [Test]
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);
91 sx.LoadXml (xel);
92 Assert ("CheckSignature", sx.CheckSignature ());
95 [Test]
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)
109 [Test]
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
138 // message.
139 Reference reference = new Reference ();
140 reference.Uri = "#MyObjectId";
142 // Add it to the message.
143 signedXml.AddReference (reference);
145 return signedXml;
148 [Test]
149 public void AsymmetricRSASignature ()
151 SignedXml signedXml = MSDNSample ();
153 RSA key = RSA.Create ();
154 signedXml.SigningKey = key;
156 // Add a KeyInfo.
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 ());
187 [Test]
188 public void AsymmetricDSASignature ()
190 SignedXml signedXml = MSDNSample ();
192 DSA key = DSA.Create ();
193 signedXml.SigningKey = key;
195 // Add a KeyInfo.
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 ());
226 [Test]
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));
261 [Test]
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
274 [Test]
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 ();
279 doc.LoadXml (value);
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
298 [Test]
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 ();
303 doc.LoadXml (value);
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));
320 [Test]
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 ();
325 doc.LoadXml (value);
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));
336 [Test]
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"));
351 [Test]
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);
367 [Test]
368 public void Add_Null ()
370 SignedXml sx = new SignedXml ();
371 // no ArgumentNull exceptions for those
372 sx.AddObject (null);
373 sx.AddReference (null);
376 [Test]
377 [ExpectedException (typeof (CryptographicException))]
378 public void GetXml_WithoutInfo ()
380 SignedXml sx = new SignedXml ();
381 XmlElement xel = sx.GetXml ();
384 [Test]
385 [ExpectedException (typeof (ArgumentNullException))]
386 public void LoadXml_Null ()
388 SignedXml sx = new SignedXml ();
389 sx.LoadXml (null);
392 [Test]
393 public void SigningKeyName ()
395 SignedXmlEx sxe = new SignedXmlEx ();
396 AssertNull ("SigningKeyName", sxe.SigningKeyName);
397 sxe.SigningKeyName = "mono";
398 AssertEquals ("SigningKeyName", "mono", sxe.SigningKeyName);
401 [Test]
402 public void CheckSignatureEmptySafe ()
404 SignedXml sx;
405 KeyInfoClause kic;
406 KeyInfo ki;
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 ();
415 ki = new KeyInfo ();
416 ki.AddClause (kic);
417 sx.KeyInfo = ki;
418 Assert (!sx.CheckSignature ());
421 [Test]
422 [ExpectedException (typeof (CryptographicException))]
423 public void CheckSignatureEmpty ()
425 SignedXml sx = new SignedXml ();
426 sx.CheckSignature ();