merge r67228-r67235, r67237, r67251 and r67256-67259 to trunk (they are
[mono.git] / mcs / class / System.Security / Test / System.Security.Cryptography.Xml / ReferenceTest.cs
1 //
2 // ReferenceTest.cs - NUnit Test Cases for Reference
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 //
10
11 using System;
12 using System.Security.Cryptography;
13 using System.Security.Cryptography.Xml;
14 using System.Xml;
15
16 using NUnit.Framework;
17
18 namespace MonoTests.System.Security.Cryptography.Xml {
19
20         [TestFixture]
21         public class ReferenceTest : Assertion {
22
23                 protected Reference reference;
24
25                 [SetUp]
26                 public void SetUp () 
27                 {
28                         reference = new Reference ();
29                 }
30
31                 [Test]
32                 public void Properties () 
33                 {
34                         AssertNull ("Uri (null)", reference.Uri);
35                         AssertNotNull ("TransformChain", reference.TransformChain);
36                         AssertEquals ("ToString()", "System.Security.Cryptography.Xml.Reference", reference.ToString ());
37                         // test uri constructor
38                         string uri = "uri";
39                         reference = new Reference (uri);
40                         AssertEquals ("DigestMethod", "http://www.w3.org/2000/09/xmldsig#sha1", reference.DigestMethod);
41                         AssertNull ("DigestValue", reference.DigestValue);
42                         AssertNull ("Id", reference.Id);
43                         AssertNull ("Type", reference.Type);
44                         AssertEquals ("Uri", uri, reference.Uri);
45                 }
46
47                 [Test]
48                 public void LoadNoTransform () 
49                 {
50                         string test = "<Reference URI=\"#MyObjectId\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>/Vvq6sXEVbtZC8GwNtLQnGOy/VI=</DigestValue></Reference>";
51                         XmlDocument doc = new XmlDocument ();
52                         doc.LoadXml (test);
53                         reference.LoadXml (doc.DocumentElement);
54                         AssertEquals ("Load-Xml", test, (reference.GetXml().OuterXml));
55                         AssertEquals ("Load-URI", "#MyObjectId", reference.Uri);
56                         byte[] hash = { 0xFD, 0x5B, 0xEA, 0xEA, 0xC5, 0xC4, 0x55, 0xBB, 0x59, 0x0B, 0xC1, 0xB0, 0x36, 0xD2, 0xD0, 0x9C, 0x63, 0xB2, 0xFD, 0x52 };
57                         AssertCrypto.AssertEquals("Load-Digest", hash, reference.DigestValue);
58                         AssertEquals ("Load-#Transform", 0, reference.TransformChain.Count);
59                 }
60
61                 [Test]
62                 public void LoadBase64Transform () 
63                 {
64                         string test = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#base64\" /></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
65                         XmlDocument doc = new XmlDocument ();
66                         doc.LoadXml (test);
67                         reference.LoadXml (doc.DocumentElement);
68                         AssertEquals ("Load-Base64", test, (reference.GetXml().OuterXml));
69                         AssertEquals ("Load-#Transform", 1, reference.TransformChain.Count);
70                 }
71
72                 [Test]
73                 public void LoadC14NTransform () 
74                 {
75                         string test = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
76                         XmlDocument doc = new XmlDocument ();
77                         doc.LoadXml (test);
78                         reference.LoadXml (doc.DocumentElement);
79                         AssertEquals ("Load-C14N", test, (reference.GetXml().OuterXml));
80                         AssertEquals ("Load-#Transform", 1, reference.TransformChain.Count);
81                 }
82
83                 [Test]
84                 public void LoadC14NWithCommentsTransforms () 
85                 {
86                         string test = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments\" /></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
87                         XmlDocument doc = new XmlDocument ();
88                         doc.LoadXml (test);
89                         reference.LoadXml (doc.DocumentElement);
90                         AssertEquals ("Load-C14NWithComments", test, (reference.GetXml().OuterXml));
91                         AssertEquals ("Load-#Transform", 1, reference.TransformChain.Count);
92                 }
93
94                 [Test]
95                 public void LoadEnvelopedSignatureTransforms () 
96                 {
97                         string test = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\" /></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
98                         XmlDocument doc = new XmlDocument ();
99                         doc.LoadXml (test);
100                         reference.LoadXml (doc.DocumentElement);
101                         AssertEquals ("Load-Enveloped", test, (reference.GetXml().OuterXml));
102                         AssertEquals ("Load-#Transform", 1, reference.TransformChain.Count);
103                 }
104
105                 [Test]
106                 public void LoadXPathTransforms () 
107                 {
108                         // test1 (MS) is an XML equivalent to test2 (Mono)
109                         string test1 = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xpath-19991116\"><XPath></XPath></Transform></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
110                         string test2 = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xpath-19991116\"><XPath /></Transform></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
111                         XmlDocument doc = new XmlDocument ();
112                         doc.LoadXml (test1);
113                         reference.LoadXml (doc.DocumentElement);
114                         string result = (reference.GetXml().OuterXml);
115                         Assert (result, ((test1 == result) || (test2 == result)));
116                         AssertEquals ("Load-#Transform", 1, reference.TransformChain.Count);
117                 }
118
119                 [Test]
120                 public void LoadXsltTransforms () 
121                 {
122                         string test = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms>";
123                         test += "<Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xslt-19991116\">";
124                         test += "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns=\"http://www.w3.org/TR/xhtml1/strict\" exclude-result-prefixes=\"foo\" version=\"1.0\">";
125                         test += "<xsl:output encoding=\"UTF-8\" indent=\"no\" method=\"xml\" />";
126                         test += "<xsl:template match=\"/\"><html><head><title>Notaries</title>";
127                         test += "</head><body><table><xsl:for-each select=\"Notaries/Notary\">";
128                         test += "<tr><th><xsl:value-of select=\"@name\" /></th></tr></xsl:for-each>";
129                         test += "</table></body></html></xsl:template></xsl:stylesheet></Transform>";
130                         test += "</Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
131                         XmlDocument doc = new XmlDocument ();
132                         doc.LoadXml (test);
133                         reference.LoadXml (doc.DocumentElement);
134                         string result = reference.GetXml().OuterXml;
135                         AssertEquals (result, test, result);
136                         AssertEquals ("Load-#Transform", 1, reference.TransformChain.Count);
137                 }
138
139                 [Test]
140                 public void LoadAllTransforms () 
141                 {
142                         string test1 = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#base64\" /><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments\" /><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\" /><Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xpath-19991116\"><XPath></XPath></Transform>";
143                         test1 += "<Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xslt-19991116\">";
144                         test1 += "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns=\"http://www.w3.org/TR/xhtml1/strict\" exclude-result-prefixes=\"foo\" version=\"1.0\">";
145                         test1 += "<xsl:output encoding=\"UTF-8\" indent=\"no\" method=\"xml\" />";
146                         test1 += "<xsl:template match=\"/\"><html><head><title>Notaries</title>";
147                         test1 += "</head><body><table><xsl:for-each select=\"Notaries/Notary\">";
148                         test1 += "<tr><th><xsl:value-of select=\"@name\" /></th></tr></xsl:for-each>";
149                         test1 += "</table></body></html></xsl:template></xsl:stylesheet></Transform>";
150                         test1 += "</Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
151                         string test2 = test1.Replace ("<XPath></XPath>", "<XPath />"); // Mono
152                         XmlDocument doc = new XmlDocument ();
153                         doc.LoadXml (test1);
154                         reference.LoadXml (doc.DocumentElement);
155                         string result = reference.GetXml().OuterXml;
156                         Assert (result, ((result == test1) || (result == test2)));
157                         AssertEquals ("Load-#Transform", 6, reference.TransformChain.Count);
158                 }
159
160                 [Test]
161 #if NET_2_0
162                 [Category ("NotDotNet")]
163                 // MS throws a NullReferenceException (reported as FDBK25886) but only when executed in NUnit\r
164                 // http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=3596d1e3-362b-40bd-bca9-2e8be75261ff
165 #endif
166                 public void AddAllTransforms () 
167                 {
168                         // adding an empty hash value
169                         byte[] hash = new byte [20];
170                         reference.DigestValue = hash;
171                         XmlElement xel = reference.GetXml ();
172                         // this is the minimal Reference (DigestValue)!
173                         AssertNotNull ("GetXml", xel);
174
175                         reference.AddTransform (new XmlDsigBase64Transform ());
176                         reference.AddTransform (new XmlDsigC14NTransform ());
177                         reference.AddTransform (new XmlDsigC14NWithCommentsTransform ());
178                         reference.AddTransform (new XmlDsigEnvelopedSignatureTransform ());
179                         reference.AddTransform (new XmlDsigXPathTransform ());
180                         reference.AddTransform (new XmlDsigXsltTransform ());
181
182                         // MS's results
183                         string test1 = "<Reference xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Transforms><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#base64\" /><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments\" /><Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\" /><Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xpath-19991116\"><XPath></XPath></Transform><Transform Algorithm=\"http://www.w3.org/TR/1999/REC-xslt-19991116\" /></Transforms><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</DigestValue></Reference>";
184                         // Mono's result (xml is equivalent but not identical)
185                         string test2 = test1.Replace ("<XPath></XPath>", "<XPath xmlns=\"http://www.w3.org/2000/09/xmldsig#\" />");
186                         string result = reference.GetXml().OuterXml;
187                         Assert (result, ((result == test1) || (result == test2)));
188                         // however this value cannot be loaded as it's missing some transform (xslt) parameters
189
190                         // can we add them again ?
191                         reference.AddTransform (new XmlDsigBase64Transform ());
192                         reference.AddTransform (new XmlDsigC14NTransform ());
193                         reference.AddTransform (new XmlDsigC14NWithCommentsTransform ());
194                         reference.AddTransform (new XmlDsigEnvelopedSignatureTransform ());
195                         reference.AddTransform (new XmlDsigXPathTransform ());
196                         reference.AddTransform (new XmlDsigXsltTransform ());
197
198                         // seems so ;-)
199                         AssertEquals ("# Transforms", 12, reference.TransformChain.Count);
200                 }
201
202                 [Test]
203                 public void Null () 
204                 {
205                         // null DigestMethod -> "" DigestMethod !!!
206                         reference.DigestMethod = null;
207                         AssertNull ("DigestMethod null", reference.DigestMethod);
208                 }
209
210                 [Test]
211                 [ExpectedException (typeof (NullReferenceException))]
212                 public void Bad1 () 
213                 {
214                         reference.Uri = "#MyObjectId";
215                         // not enough info
216                         XmlElement bad = reference.GetXml ();
217                 }
218
219                 [Test]
220                 public void Bad2 () 
221                 {
222                         // bad hash - there's no validation!
223                         reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#mono";
224                 }
225
226                 const string xml = @"<player bats=""left"" id=""10012"" throws=""right"">
227         <!-- Here&apos;s a comment -->
228         <name>Alfonso Soriano</name>
229         <position>2B</position>
230         <team>New York Yankees</team>
231 <dsig:Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" xmlns:dsig=""http://www.w3.org/2000/09/xmldsig#"">"
232 + @"<dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-withcomments-20010315""/><dsig:SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/>"
233 + @"<dsig:Reference URI=""""><dsig:Transforms><dsig:Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/></dsig:Transforms><dsig:DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><dsig:DigestValue>nDF2V/bzRd0VE3EwShWtsBzTEDc=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue>fbye4Xm//RPUTsLd1dwJPo0gPZYX6gVYCEB/gz2348EARNk/nCCch1fFfpuqAGMKg4ayVC0yWkUyE5V4QB33jaGlh9wuNQSjxs6TIvFwSsT+0ioDgVgFv0gVeasbyNL4rFEHuAWL8QKwDT9L6b2wUvJC90DmpBs9GMR2jTZIWlM=</dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>MIIC0DCCAjmgAwIBAgIDD0JBMA0GCSqGSIb3DQEBBAUAMHwxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazERMA8GA1UEBxMITmV3IFlvcmsxGTAXBgNVBAoTEFBoYW9zIFRlY2hub2xvZ3kxFDASBgNVBAsTC0VuZ2luZWVyaW5nMRYwFAYDVQQDEw1UZXN0IENBIChSU0EpMB4XDTAyMDQyOTE5MTY0MFoXDTEyMDQyNjE5MTY0MFowgYAxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazERMA8GA1UEBxMITmV3IFlvcmsxGTAXBgNVBAoTEFBoYW9zIFRlY2hub2xvZ3kxFDASBgNVBAsTC0VuZ2luZWVyaW5nMRowGAYDVQQDExFUZXN0IENsaWVudCAoUlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgIb6nAB9oS/AI5jIj6WymvQhRxiMlE07G4abmMliYi5zWzvaFE2tnU+RZIBgtoXcgDEIU/vsLQut7nzCn9mHxC8JEaV4D4U91j64AyZakShqJw7qjJfqUxxPL0yJv2oFiouPDjGuJ9JPi0NrsZq+yfWfM54s4b9SNkcOIVMybZUCAwEAAaNbMFkwDAYDVR0TAQH/BAIwADAPBgNVHQ8BAf8EBQMDB9gAMBkGA1UdEQQSMBCBDnRlY2hAcGhhb3MuY29tMB0GA1UdDgQWBBQT58rBCxPmVLeZaYGRqVROnQlFbzANBgkqhkiG9w0BAQQFAAOBgQCxbCovFST25t+ryN1RipqozxJQcguKfeCwbfgBNobzcRvoW0kSIf7zi4mtQajDM0NfslFF51/dex5Rn64HmFFshSwSvQQMyf5Cfaqv2XQ60OXq6nAFG6WbHoge6RqfIez2MWDLoSB6plsjKtMmL3mcybBhROtX5GGuLx1NtfhNFQ==</dsig:X509Certificate><dsig:X509IssuerSerial><dsig:X509IssuerName>CN=Test CA (RSA),OU=Engineering,O=Phaos Technology,L=New York,ST=New York,C=US</dsig:X509IssuerName><dsig:X509SerialNumber>1000001</dsig:X509SerialNumber></dsig:X509IssuerSerial><dsig:X509SubjectName>CN=Test Client (RSA),OU=Engineering,O=Phaos Technology,L=New York,ST=New York,C=US</dsig:X509SubjectName><dsig:X509SKI>E+fKwQsT5lS3mWmBkalUTp0JRW8=</dsig:X509SKI></dsig:X509Data></dsig:KeyInfo></dsig:Signature></player>";
234
235
236                 [Test]
237                 public void KeepDocument ()
238                 {
239                         string result = @"<dsig:Reference URI="""" xmlns:dsig=""http://www.w3.org/2000/09/xmldsig#""><dsig:Transforms><dsig:Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature"" /></dsig:Transforms><dsig:DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1"" /><dsig:DigestValue>nDF2V/bzRd0VE3EwShWtsBzTEDc=</dsig:DigestValue></dsig:Reference>";
240
241                         XmlDocument doc = new XmlDocument ();
242                         doc.LoadXml (xml);
243                         XmlElement org = (XmlElement) doc.SelectSingleNode ("//*[local-name()='Reference']");
244                         Reference r = new Reference ();
245                         r.LoadXml (org);
246                         XmlElement el = r.GetXml ();
247                         AssertEquals (doc, el.OwnerDocument);
248                         AssertEquals (org, el);
249                         AssertEquals (result, el.OuterXml);
250                 }
251         }
252 }