1 //
2 // Pkits_4_04_BasicCertificateRevocationTests.cs -
3 //	NUnit tests for Pkits 4.4 : Basic Certificate Revocation Tests
4 //
5 // Author:
6 //	Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 
30 
31 using NUnit.Framework;
32 
33 using System;
34 using System.Security.Cryptography.X509Certificates;
35 
36 namespace MonoTests.System.Security.Cryptography.X509Certificates {
37 
38 	/*
39 	 * Notes
40 	 *
41 	 * [MS/XP][!RFC3280] Unknown critical extensions results in
42 	 * RevocationStatusUnknown instead of Revoked - even if the CRL
43 	 * list the certificate serial number as revoked!
44 	 *
45 	 * [MS/XP][!RFC3280] Doesn't support having different keys for
46 	 * signing certificates and CRL.
47 	 *
48 	 * See PkitsTest.cs for more details
49 	 */
50 
51 	[TestFixture]
52 	[Category ("PKITS")]
53 	public class Pkits_4_04_BasicCertificateRevocationTests: PkitsTest {
54 
55 		public X509Certificate2 NoCRLCACert {
56 			get { return GetCertificate ("NoCRLCACert.crt"); }
57 		}
58 
59 		public X509Certificate2 RevokedsubCACert {
60 			get { return GetCertificate ("RevokedsubCACert.crt"); }
61 		}
62 
63 		public X509Certificate2 BadCRLSignatureCACert {
64 			get { return GetCertificate ("BadCRLSignatureCACert.crt"); }
65 		}
66 
67 		public X509Certificate2 BadCRLIssuerNameCACert {
68 			get { return GetCertificate ("BadCRLIssuerNameCACert.crt"); }
69 		}
70 
71 		public X509Certificate2 WrongCRLCACert {
72 			get { return GetCertificate ("WrongCRLCACert.crt"); }
73 		}
74 
75 		public X509Certificate2 TwoCRLsCACert {
76 			get { return GetCertificate ("TwoCRLsCACert.crt"); }
77 		}
78 
79 		public X509Certificate2 UnknownCRLEntryExtensionCACert {
80 			get { return GetCertificate ("UnknownCRLEntryExtensionCACert.crt"); }
81 		}
82 
83 		public X509Certificate2 UnknownCRLExtensionCACert {
84 			get { return GetCertificate ("UnknownCRLExtensionCACert.crt"); }
85 		}
86 
87 		public X509Certificate2 OldCRLnextUpdateCACert {
88 			get { return GetCertificate ("OldCRLnextUpdateCACert.crt"); }
89 		}
90 
91 		public X509Certificate2 Pre2000CRLnextUpdateCACert {
92 			get { return GetCertificate ("pre2000CRLnextUpdateCACert.crt"); }
93 		}
94 
95 		public X509Certificate2 GeneralizedTimeCRLnextUpdateCACert {
96 			get { return GetCertificate ("GeneralizedTimeCRLnextUpdateCACert.crt"); }
97 		}
98 
99 		public X509Certificate2 NegativeSerialNumberCACert {
100 			get { return GetCertificate ("NegativeSerialNumberCACert.crt"); }
101 		}
102 
103 		public X509Certificate2 LongSerialNumberCACert {
104 			get { return GetCertificate ("LongSerialNumberCACert.crt"); }
105 		}
106 
107 		public X509Certificate2 SeparateCertificateandCRLKeysCertificateSigningCACert {
108 			get { return GetCertificate ("SeparateCertificateandCRLKeysCertificateSigningCACert.crt"); }
109 		}
110 
111 		public X509Certificate2 SeparateCertificateandCRLKeysCA2CertificateSigningCACert {
112 			get { return GetCertificate ("SeparateCertificateandCRLKeysCA2CertificateSigningCACert.crt"); }
113 		}
114 
115 		[Test]
T01_MissingCRL()116 		public void T01_MissingCRL ()
117 		{
118 			X509Certificate2 ee = GetCertificate ("InvalidMissingCRLTest1EE.crt");
119 			X509Chain chain = new X509Chain ();
120 			Assert.IsFalse (chain.Build (ee), "Build");
121 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
122 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
123 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
124 			Assert.AreEqual (NoCRLCACert, chain.ChainElements[1].Certificate, "NoCRLCACert");
125 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "NoCRLCACert.Status");
126 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
127 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
128 		}
129 
130 		[Test]
T02_InvalidRevokedCA()131 		public void T02_InvalidRevokedCA ()
132 		{
133 			X509Certificate2 ee = GetCertificate ("InvalidRevokedCATest2EE.crt");
134 			X509Chain chain = new X509Chain ();
135 			Assert.IsFalse (chain.Build (ee), "Build");
136 			CheckChainStatus (X509ChainStatusFlags.Revoked | X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation, chain.ChainStatus, "ChainStatus");
137 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
138 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
139 			Assert.AreEqual (RevokedsubCACert, chain.ChainElements[1].Certificate, "RevokedsubCACert");
140 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainElements[1].ChainElementStatus, "RevokedsubCACert.Status");
141 			Assert.AreEqual (GoodCACert, chain.ChainElements[2].Certificate, "GoodCACert");
142 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "GoodCACert.Status");
143 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[3].Certificate, "TrustAnchorRoot");
144 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[3].ChainElementStatus, "TrustAnchorRoot.Status");
145 		}
146 
147 		[Test]
T03_InvalidRevokedEE()148 		public void T03_InvalidRevokedEE ()
149 		{
150 			X509Certificate2 ee = GetCertificate ("InvalidRevokedEETest3EE.crt");
151 			X509Chain chain = new X509Chain ();
152 			Assert.IsFalse (chain.Build (ee), "Build");
153 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainStatus, "ChainStatus");
154 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
155 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
156 			Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
157 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
158 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
159 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
160 		}
161 
162 		[Test]
T04_InvalidBadCrlSignature()163 		public void T04_InvalidBadCrlSignature ()
164 		{
165 			X509Certificate2 ee = GetCertificate ("InvalidBadCRLSignatureTest4EE.crt");
166 			X509Chain chain = new X509Chain ();
167 			Assert.IsFalse (chain.Build (ee), "Build");
168 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
169 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
170 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
171 			Assert.AreEqual (BadCRLSignatureCACert, chain.ChainElements[1].Certificate, "BadCRLSignatureCACert");
172 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "BadCRLSignatureCACert.Status");
173 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
174 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
175 		}
176 
177 		[Test]
T05_InvalidBadCrlIssuerName()178 		public void T05_InvalidBadCrlIssuerName ()
179 		{
180 			X509Certificate2 ee = GetCertificate ("InvalidBadCRLIssuerNameTest5EE.crt");
181 			X509Chain chain = new X509Chain ();
182 			Assert.IsFalse (chain.Build (ee), "Build");
183 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
184 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
185 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
186 			Assert.AreEqual (BadCRLIssuerNameCACert, chain.ChainElements[1].Certificate, "BadCRLIssuerNameCACert");
187 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "BadCRLIssuerNameCACert.Status");
188 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
189 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
190 		}
191 
192 		[Test]
T06_InvalidWrongCrl()193 		public void T06_InvalidWrongCrl ()
194 		{
195 			X509Certificate2 ee = GetCertificate ("InvalidWrongCRLTest6EE.crt");
196 			X509Chain chain = new X509Chain ();
197 			Assert.IsFalse (chain.Build (ee), "Build");
198 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
199 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
200 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
201 			Assert.AreEqual (WrongCRLCACert, chain.ChainElements[1].Certificate, "WrongCRLCACert");
202 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "WrongCRLCACert.Status");
203 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
204 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
205 		}
206 
207 		[Test]
T07_ValidTwoCrls()208 		public void T07_ValidTwoCrls ()
209 		{
210 			X509Certificate2 ee = GetCertificate ("ValidTwoCRLsTest7EE.crt");
211 			X509Chain chain = new X509Chain ();
212 			Assert.IsTrue (chain.Build (ee), "Build");
213 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
214 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
215 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
216 			Assert.AreEqual (TwoCRLsCACert, chain.ChainElements[1].Certificate, "TwoCRLsCACert");
217 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "TwoCRLsCACert.Status");
218 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
219 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
220 		}
221 
222 		[Test]
T08_InvalidUnknownCrlEntryExtension()223 		public void T08_InvalidUnknownCrlEntryExtension ()
224 		{
225 			X509Certificate2 ee = GetCertificate ("InvalidUnknownCRLEntryExtensionTest8EE.crt");
226 			X509Chain chain = new X509Chain ();
227 			Assert.IsFalse (chain.Build (ee), "Build");
228 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainStatus, "ChainStatus");
229 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
230 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
231 			Assert.AreEqual (UnknownCRLEntryExtensionCACert, chain.ChainElements[1].Certificate, "UnknownCRLEntryExtensionCACert");
232 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UnknownCRLEntryExtensionCACert.Status");
233 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
234 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
235 		}
236 
237 		[Test]
238 		[Category ("NotDotNet")] // test case is RFC3280 compliant
T09_InvalidUnknownCrlExtension()239 		public void T09_InvalidUnknownCrlExtension ()
240 		{
241 			X509Certificate2 ee = GetCertificate ("InvalidUnknownCRLExtensionTest9EE.crt");
242 			X509Chain chain = new X509Chain ();
243 			Assert.IsFalse (chain.Build (ee), "Build");
244 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainStatus, "ChainStatus");
245 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
246 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
247 			Assert.AreEqual (UnknownCRLExtensionCACert, chain.ChainElements[1].Certificate, "UnknownCRLExtensionCACert");
248 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UnknownCRLExtensionCACert.Status");
249 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
250 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
251 		}
252 
253 		[Test]
254 		[Category ("NotWorking")] // WONTFIX - this isn't RFC3280 compliant
T09_InvalidUnknownCrlExtension_MS()255 		public void T09_InvalidUnknownCrlExtension_MS ()
256 		{
257 			X509Certificate2 ee = GetCertificate ("InvalidUnknownCRLExtensionTest9EE.crt");
258 			X509Chain chain = new X509Chain ();
259 			Assert.IsFalse (chain.Build (ee), "Build");
260 			// MS-BAD - the certificate is REVOKED even if we don't completely understand
261 			// the critical extensions included in the certificate
262 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
263 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
264 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
265 			Assert.AreEqual (UnknownCRLExtensionCACert, chain.ChainElements[1].Certificate, "UnknownCRLExtensionCACert");
266 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UnknownCRLExtensionCACert.Status");
267 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
268 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
269 		}
270 
271 		[Test]
T10_InvalidUnknownCrlExtension()272 		public void T10_InvalidUnknownCrlExtension ()
273 		{
274 			X509Certificate2 ee = GetCertificate ("InvalidUnknownCRLExtensionTest10EE.crt");
275 			X509Chain chain = new X509Chain ();
276 			Assert.IsFalse (chain.Build (ee), "Build");
277 			// X.509.7.3 we should consider the EE as revoked (RevocationStatusUnknown seems fuzzy)
278 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
279 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
280 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
281 			Assert.AreEqual (UnknownCRLExtensionCACert, chain.ChainElements[1].Certificate, "UnknownCRLExtensionCACert");
282 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UnknownCRLExtensionCACert.Status");
283 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
284 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
285 		}
286 
287 		[Test]
T11_InvalidOldCrlNextUpdate()288 		public void T11_InvalidOldCrlNextUpdate ()
289 		{
290 			X509Certificate2 ee = GetCertificate ("InvalidOldCRLnextUpdateTest11EE.crt");
291 			X509Chain chain = new X509Chain ();
292 			Assert.IsFalse (chain.Build (ee), "Build");
293 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation, chain.ChainStatus, "ChainStatus");
294 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
295 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
296 			Assert.AreEqual (OldCRLnextUpdateCACert, chain.ChainElements[1].Certificate, "OldCRLnextUpdateCACert");
297 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "OldCRLnextUpdateCACert.Status");
298 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
299 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
300 		}
301 
302 		[Test]
T12_InvalidPre2000CrlNextUpdate()303 		public void T12_InvalidPre2000CrlNextUpdate ()
304 		{
305 			X509Certificate2 ee = GetCertificate ("Invalidpre2000CRLnextUpdateTest12EE.crt");
306 			X509Chain chain = new X509Chain ();
307 			Assert.IsFalse (chain.Build (ee), "Build");
308 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation, chain.ChainStatus, "ChainStatus");
309 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
310 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
311 			Assert.AreEqual (Pre2000CRLnextUpdateCACert, chain.ChainElements[1].Certificate, "Pre2000CRLnextUpdateCACert");
312 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "Pre2000CRLnextUpdateCACert.Status");
313 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
314 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
315 		}
316 
317 		[Test]
T13_ValidGeneralizedTimeCrlNextUpdate()318 		public void T13_ValidGeneralizedTimeCrlNextUpdate ()
319 		{
320 			X509Certificate2 ee = GetCertificate ("ValidGeneralizedTimeCRLnextUpdateTest13EE.crt");
321 			X509Chain chain = new X509Chain ();
322 			Assert.IsTrue (chain.Build (ee), "Build");
323 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
324 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
325 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
326 			Assert.AreEqual (GeneralizedTimeCRLnextUpdateCACert, chain.ChainElements[1].Certificate, "GeneralizedTimeCRLnextUpdateCACert");
327 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GeneralizedTimeCRLnextUpdateCACert.Status");
328 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
329 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
330 		}
331 
332 		[Test]
T14_ValidNegativeSerialNumber()333 		public void T14_ValidNegativeSerialNumber ()
334 		{
335 			X509Certificate2 ee = GetCertificate ("ValidNegativeSerialNumberTest14EE.crt");
336 			X509Chain chain = new X509Chain ();
337 			Assert.IsTrue (chain.Build (ee), "Build");
338 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
339 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
340 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
341 			Assert.AreEqual (NegativeSerialNumberCACert, chain.ChainElements[1].Certificate, "NegativeSerialNumberCACert");
342 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "NegativeSerialNumberCACert.Status");
343 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
344 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
345 		}
346 
347 		[Test]
T15_InvalidNegativeSerialNumber()348 		public void T15_InvalidNegativeSerialNumber ()
349 		{
350 			X509Certificate2 ee = GetCertificate ("InvalidNegativeSerialNumberTest15EE.crt");
351 			X509Chain chain = new X509Chain ();
352 			Assert.IsFalse (chain.Build (ee), "Build");
353 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainStatus, "ChainStatus");
354 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
355 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
356 			Assert.AreEqual (NegativeSerialNumberCACert, chain.ChainElements[1].Certificate, "NegativeSerialNumberCACert");
357 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "NegativeSerialNumberCACert.Status");
358 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
359 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
360 		}
361 
362 		[Test]
T16_ValidLongSerialNumber()363 		public void T16_ValidLongSerialNumber ()
364 		{
365 			X509Certificate2 ee = GetCertificate ("ValidLongSerialNumberTest16EE.crt");
366 			X509Chain chain = new X509Chain ();
367 			Assert.IsTrue (chain.Build (ee), "Build");
368 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
369 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
370 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
371 			Assert.AreEqual (LongSerialNumberCACert, chain.ChainElements[1].Certificate, "LongSerialNumberCACert");
372 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "LongSerialNumberCACert.Status");
373 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
374 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
375 		}
376 
377 		[Test]
T17_ValidLongSerialNumber()378 		public void T17_ValidLongSerialNumber ()
379 		{
380 			X509Certificate2 ee = GetCertificate ("ValidLongSerialNumberTest17EE.crt");
381 			X509Chain chain = new X509Chain ();
382 			Assert.IsTrue (chain.Build (ee), "Build");
383 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
384 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
385 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
386 			Assert.AreEqual (LongSerialNumberCACert, chain.ChainElements[1].Certificate, "LongSerialNumberCACert");
387 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "LongSerialNumberCACert.Status");
388 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
389 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
390 		}
391 
392 		[Test]
T18_InvalidLongSerialNumber()393 		public void T18_InvalidLongSerialNumber ()
394 		{
395 			X509Certificate2 ee = GetCertificate ("InvalidLongSerialNumberTest18EE.crt");
396 			X509Chain chain = new X509Chain ();
397 			Assert.IsFalse (chain.Build (ee), "Build");
398 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainStatus, "ChainStatus");
399 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
400 			CheckChainStatus (X509ChainStatusFlags.Revoked, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
401 			Assert.AreEqual (LongSerialNumberCACert, chain.ChainElements[1].Certificate, "LongSerialNumberCACert");
402 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "LongSerialNumberCACert.Status");
403 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
404 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
405 		}
406 
407 		[Test]
T19_ValidSeparateCertificateAndCrlKeys()408 		public void T19_ValidSeparateCertificateAndCrlKeys ()
409 		{
410 			X509Certificate2 ee = GetCertificate ("ValidSeparateCertificateandCRLKeysTest19EE.crt");
411 			X509Chain chain = new X509Chain ();
412 
413 			// MS-BAD - doesn't support different keys for signing certificates and CRL
414 
415 			Assert.IsFalse (chain.Build (ee), "Build");
416 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
417 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
418 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
419 			Assert.AreEqual (SeparateCertificateandCRLKeysCertificateSigningCACert, chain.ChainElements[1].Certificate, "SeparateCertificateandCRLKeysCertificateSigningCACert");
420 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "SeparateCertificateandCRLKeysCertificateSigningCACert.Status");
421 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
422 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
423 		}
424 
425 		[Test]
T20_InvalidSeparateCertificateAndCrlKeys()426 		public void T20_InvalidSeparateCertificateAndCrlKeys ()
427 		{
428 			X509Certificate2 ee = GetCertificate ("InvalidSeparateCertificateandCRLKeysTest20EE.crt");
429 			X509Chain chain = new X509Chain ();
430 			// looks ok but in fact it's confused
431 			Assert.IsFalse (chain.Build (ee), "Build");
432 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
433 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
434 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
435 			Assert.AreEqual (SeparateCertificateandCRLKeysCertificateSigningCACert, chain.ChainElements[1].Certificate, "SeparateCertificateandCRLKeysCertificateSigningCACert");
436 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "SeparateCertificateandCRLKeysCertificateSigningCACert.Status");
437 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
438 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
439 		}
440 
441 		[Test]
T21_InvalidSeparateCertificateAndCrlKeys()442 		public void T21_InvalidSeparateCertificateAndCrlKeys ()
443 		{
444 			X509Certificate2 ee = GetCertificate ("InvalidSeparateCertificateandCRLKeysTest21EE.crt");
445 			X509Chain chain = new X509Chain ();
446 			// looks ok but in fact it's confused
447 			Assert.IsFalse (chain.Build (ee), "Build");
448 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
449 			Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
450 			CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
451 			Assert.AreEqual (SeparateCertificateandCRLKeysCA2CertificateSigningCACert, chain.ChainElements[1].Certificate, "SeparateCertificateandCRLKeysCA2CertificateSigningCACert");
452 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "SeparateCertificateandCRLKeysCA2CertificateSigningCACert.Status");
453 			Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
454 			CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
455 		}
456 	}
457 }
458 
459