Merge pull request #2396 from akoeplinger/flaky-osx-socket-test
[mono.git] / mcs / class / System / Test / System.Security.Cryptography.X509Certificates / Pkits_4_03_VerifyingNameChaining.cs
1 //
2 // Pkits_4_03_VerifyingNameChaining.cs -
3 //      NUnit tests for Pkits 4.3 : Verifying Name Chaining
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] It doesn't looks like any checks is done between the 
42          * EE issuer and CA subject names.
43          *
44          * See PkitsTest.cs for more details
45          */
46
47         [TestFixture]
48         [Category ("PKITS")]
49         public class Pkits_4_03_VerifyingNameChaining: PkitsTest {
50
51                 public X509Certificate2 NameOrderingCACert {
52                         get { return GetCertificate ("NameOrderingCACert.crt"); }
53                 }
54
55                 public X509Certificate2 UIDCACert {
56                         get { return GetCertificate ("UIDCACert.crt"); }
57                 }
58
59                 public X509Certificate2 RFC3280MandatoryAttributeTypesCACert {
60                         get { return GetCertificate ("RFC3280MandatoryAttributeTypesCACert.crt"); }
61                 }
62                         
63                 public X509Certificate2 RFC3280OptionalAttributeTypesCACert {
64                         get { return GetCertificate ("RFC3280OptionalAttributeTypesCACert.crt"); }
65                 }
66
67                 public X509Certificate2 UTF8StringEncodedNamesCACert {
68                         get { return GetCertificate ("UTF8StringEncodedNamesCACert.crt"); }
69                 }
70
71                 public X509Certificate2 RolloverfromPrintableStringtoUTF8StringCACert {
72                         get { return GetCertificate ("RolloverfromPrintableStringtoUTF8StringCACert.crt"); }
73                 }
74
75                 public X509Certificate2 UTF8StringCaseInsensitiveMatchCACert {
76                         get { return GetCertificate ("UTF8StringCaseInsensitiveMatchCACert.crt"); }
77                 }
78
79                 [Test]
80                 [Category ("NotDotNet")] // test case is RFC3280 compliant
81                 public void T01_InvalidNameChainingEE ()
82                 {
83                         X509Certificate2 ee = GetCertificate ("InvalidNameChainingTest1EE.crt");
84                         X509Chain chain = new X509Chain ();
85                         // INFO: different ee.issuer/ca.subject names
86                         // ee.IssuerName.Name           "CN=Good CA Root, O=Test Certificates, C=US"
87                         // GoodCACert.SubjectName.Name  "CN=Good CA, O=Test Certificates, C=US"
88                         Assert.IsFalse (chain.Build (ee), "Build");
89                         CheckChainStatus (X509ChainStatusFlags.InvalidNameConstraints, chain.ChainStatus, "ChainStatus");
90                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
91                         CheckChainStatus (X509ChainStatusFlags.InvalidNameConstraints, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
92                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
93                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
94                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
95                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
96                 }
97
98                 [Test]
99                 [Category ("NotWorking")] // WONTFIX - this isn't RFC3280 compliant
100                 public void T01_InvalidNameChainingEE_MS ()
101                 {
102                         X509Certificate2 ee = GetCertificate ("InvalidNameChainingTest1EE.crt");
103                         X509Chain chain = new X509Chain ();
104
105                         // MS-BAD / this is NOT valid wrt RFC3280
106                         // I don't like this result. MS builds the chain (using AKI/SKI) then can't find
107                         // the CRL (based on the wrong CA name?) which isn't what the test looks for.
108
109                         Assert.IsFalse (chain.Build (ee), "Build");
110                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
111                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
112                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
113                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
114                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
115                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
116                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
117
118                         // Here's a proof of this, disabling the revocation check for the end-entity results in
119                         // a success
120
121                         chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreEndRevocationUnknown;
122                         Assert.IsTrue (chain.Build (ee), "Build-Bug");
123                 }
124
125                 [Test]
126                 [Category ("NotDotNet")] // test case is RFC3280 compliant
127                 public void T02_InvalidNameChainingOrder ()
128                 {
129                         X509Certificate2 ee = GetCertificate ("InvalidNameChainingOrderTest2EE.crt");
130                         X509Chain chain = new X509Chain ();
131                         // INFO: different (order) ee.issuer/ca.subject names
132                         // ee.Issuer                    "CN=Name Ordering CA, OU=Organizational Unit Name 1, OU=Organizational Unit Name 2, O=Test Certificates, C=US"
133                         // NameOrderingCACert.Subject   "CN=Name Ordering CA, OU=Organizational Unit Name 2, OU=Organizational Unit Name 1, O=Test Certificates, C=US"
134                         Assert.IsFalse (chain.Build (ee), "Build");
135                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.InvalidNameConstraints, chain.ChainStatus, "ChainStatus");
136                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
137                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.InvalidNameConstraints, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
138                         Assert.AreEqual (NameOrderingCACert, chain.ChainElements[1].Certificate, "NameOrderingCACert");
139                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "NameOrderingCACert.Status");
140                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
141                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
142                 }
143
144                 [Test]
145                 [Category ("NotWorking")] // WONTFIX - this isn't RFC3280 compliant
146                 public void T02_InvalidNameChainingOrder_MS ()
147                 {
148                         X509Certificate2 ee = GetCertificate ("InvalidNameChainingOrderTest2EE.crt");
149                         X509Chain chain = new X509Chain ();
150
151                         // MS-BAD / this is NOT valid wrt RFC3280
152                         // I don't like this result. MS builds the chain (using AKI/SKI) then can't find
153                         // the CRL (based on the wrong CA name?) which isn't what the test looks for.
154
155                         Assert.IsFalse (chain.Build (ee), "Build");
156                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
157                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
158                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
159                         Assert.AreEqual (NameOrderingCACert, chain.ChainElements[1].Certificate, "NameOrderingCACert");
160                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "NameOrderingCACert.Status");
161                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
162                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
163
164                         // Here's a proof of this, disabling the revocation check for the end-entity results in
165                         // a success
166
167                         chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreEndRevocationUnknown;
168                         Assert.IsTrue (chain.Build (ee), "Build-Bug");
169                 }
170
171                 [Test]
172                 [Category ("NotDotNet")] // test case is RFC3280 compliant
173                 public void T03_ValidNameChainingWhitespace ()
174                 {
175                         X509Certificate2 ee = GetCertificate ("ValidNameChainingWhitespaceTest3EE.crt");
176                         X509Chain chain = new X509Chain ();
177                         // INFO: different (spaces) ee.issuer/ca.subject names
178                         // ee.Issuer            "CN=Good     CA, O=Test  Certificates, C=US"
179                         // GoodCACert.Subject   "CN=Good CA, O=Test Certificates, C=US"
180                         Assert.IsTrue (chain.Build (ee), "Build");
181                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
182                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
183                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
184                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
185                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
186                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
187                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
188                 }
189
190                 [Test]
191                 [Category ("NotWorking")] // WONTFIX - this isn't RFC3280 compliant
192                 public void T03_ValidNameChainingWhitespace_MS ()
193                 {
194                         X509Certificate2 ee = GetCertificate ("ValidNameChainingWhitespaceTest3EE.crt");
195                         X509Chain chain = new X509Chain ();
196
197                         // MS-BAD / this is valid wrt RFC3280
198                         // MS doesn't support internal whitespace compression. It seems MS builds the chain 
199                         // (using AKI/SKI) then can't find the CRL (which isn't what the test looks for).
200
201                         Assert.IsFalse (chain.Build (ee), "Build");
202                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
203                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
204                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
205                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
206                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
207                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
208                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
209
210                         // Here's a proof of this, disabling the revocation check for the end-entity results in
211                         // a success
212
213                         chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreEndRevocationUnknown;
214                         Assert.IsTrue (chain.Build (ee), "Build-Bug");
215                 }
216
217                 [Test]
218                 [Category ("NotDotNet")] // test case is RFC3280 compliant
219                 public void T04_ValidNameChainingWhitespace ()
220                 {
221                         X509Certificate2 ee = GetCertificate ("ValidNameChainingWhitespaceTest4EE.crt");
222                         X509Chain chain = new X509Chain ();
223                         // INFO: different (spaces) ee.issuer/ca.subject names
224                         // ee.Issuer            "CN=\"   Good CA\", O=\"Test Certificates   \", C=US"
225                         // GoodCACert.Subject   "CN=Good CA, O=Test Certificates, C=US"
226                         Assert.IsTrue (chain.Build (ee), "Build");
227                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
228                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
229                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
230                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
231                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
232                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
233                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
234                 }
235
236                 [Test]
237                 [Category ("NotWorking")] // WONTFIX - this isn't RFC3280 compliant
238                 public void T04_ValidNameChainingWhitespace_MS ()
239                 {
240                         X509Certificate2 ee = GetCertificate ("ValidNameChainingWhitespaceTest4EE.crt");
241                         X509Chain chain = new X509Chain ();
242
243                         // MS-BAD / this is valid wrt RFC3280
244                         // MS doesn't support internal whitespace compression. It seems MS builds the chain 
245                         // (using AKI/SKI) then can't find the CRL (which isn't what the test looks for).
246
247                         Assert.IsFalse (chain.Build (ee), "Build");
248                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
249                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
250                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
251                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
252                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
253                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
254                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
255
256                         // Here's a proof of this, disabling the revocation check for the end-entity results in
257                         // a success
258
259                         chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreEndRevocationUnknown;
260                         Assert.IsTrue (chain.Build (ee), "Build-Bug");
261                 }
262
263                 [Test]
264                 [Category ("NotDotNet")] // test case is RFC3280 compliant
265                 public void T05_ValidNameChainingCapitalization ()
266                 {
267                         X509Certificate2 ee = GetCertificate ("ValidNameChainingCapitalizationTest5EE.crt");
268                         X509Chain chain = new X509Chain ();
269                         // INFO: different (capitalization) ee.issuer/ca.subject names
270                         // ee.Issuer            "CN=GOOD CA, O=Test Certificates, C=US"
271                         // GoodCACert.Subject   "CN=Good CA, O=Test Certificates, C=US"
272                         Assert.IsTrue (chain.Build (ee), "Build");
273                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
274                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
275                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
276                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
277                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
278                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
279                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
280                 }
281
282                 [Test]
283                 [Category ("NotWorking")] // WONTFIX - this isn't RFC3280 compliant
284                 public void T05_ValidNameChainingCapitalization_MS ()
285                 {
286                         X509Certificate2 ee = GetCertificate ("ValidNameChainingCapitalizationTest5EE.crt");
287                         X509Chain chain = new X509Chain ();
288
289                         // MS-BAD / this is valid wrt RFC3280
290                         // NOTE: X509FindType.FindBySubjectDistinguishedName deals (correctly) with capitalization 
291                         // issues. However it seems MS can't find the CRL based on the name with a different 
292                         // capitalization so FALSE is returned
293
294                         Assert.IsFalse (chain.Build (ee), "Build");
295                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
296                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
297                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
298                         Assert.AreEqual (GoodCACert, chain.ChainElements[1].Certificate, "GoodCACert");
299                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "GoodCACert.Status");
300                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
301                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
302
303                         // Here's a proof of this, disabling the revocation check for the end-entity results in
304                         // a success
305
306                         chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreEndRevocationUnknown;
307                         Assert.IsTrue (chain.Build (ee), "Build-Bug");
308                 }
309
310                 [Test]
311                 public void T06_ValidNameChainingUIDs ()
312                 {
313                         X509Certificate2 ee = GetCertificate ("ValidNameUIDsTest6EE.crt");
314                         X509Chain chain = new X509Chain ();
315                         Assert.IsTrue (chain.Build (ee), "Build");
316                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
317                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
318                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
319                         Assert.AreEqual (UIDCACert, chain.ChainElements[1].Certificate, "UIDCACert");
320                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UIDCACert.Status");
321                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
322                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
323                 }
324
325                 [Test]
326                 public void T07_ValidRFC3280MandatoryAttributeTypes ()
327                 {
328                         X509Certificate2 ee = GetCertificate ("ValidRFC3280MandatoryAttributeTypesTest7EE.crt");
329                         X509Chain chain = new X509Chain ();
330                         Assert.IsTrue (chain.Build (ee), "Build");
331                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
332                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
333                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
334                         Assert.AreEqual (RFC3280MandatoryAttributeTypesCACert, chain.ChainElements[1].Certificate, "RFC3280MandatoryAttributeTypesCACert");
335                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "RFC3280MandatoryAttributeTypesCACert.Status");
336                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
337                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
338                 }
339
340                 [Test]
341                 public void T08_ValidRFC3280OptionalAttributeTypes ()
342                 {
343                         X509Certificate2 ee = GetCertificate ("ValidRFC3280OptionalAttributeTypesTest8EE.crt");
344                         X509Chain chain = new X509Chain ();
345                         Assert.IsTrue (chain.Build (ee), "Build");
346                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
347                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
348                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
349                         Assert.AreEqual (RFC3280OptionalAttributeTypesCACert, chain.ChainElements[1].Certificate, "RFC3280OptionalAttributeTypesCACert");
350                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "RFC3280OptionalAttributeTypesCACert.Status");
351                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
352                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
353                 }
354
355                 [Test]
356                 public void T09_ValidUTF8StringEncodedNames ()
357                 {
358                         X509Certificate2 ee = GetCertificate ("ValidUTF8StringEncodedNamesTest9EE.crt");
359                         X509Chain chain = new X509Chain ();
360                         Assert.IsTrue (chain.Build (ee), "Build");
361                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
362                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
363                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
364                         Assert.AreEqual (UTF8StringEncodedNamesCACert, chain.ChainElements[1].Certificate, "UTF8StringEncodedNamesCACert");
365                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UTF8StringEncodedNamesCACert.Status");
366                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
367                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
368                 }
369
370                 [Test]
371                 public void T10_ValidRolloverFromPrintableStringToUTF8String ()
372                 {
373                         X509Certificate2 ee = GetCertificate ("ValidRolloverfromPrintableStringtoUTF8StringTest10EE.crt");
374                         X509Chain chain = new X509Chain ();
375                         Assert.IsTrue (chain.Build (ee), "Build");
376                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
377                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
378                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
379                         Assert.AreEqual (RolloverfromPrintableStringtoUTF8StringCACert, chain.ChainElements[1].Certificate, "RolloverfromPrintableStringtoUTF8StringCACert");
380                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "RolloverfromPrintableStringtoUTF8StringCACert.Status");
381                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
382                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
383                 }
384
385                 [Test]
386                 [Category ("NotDotNet")] // test case is RFC3280 compliant
387                 public void T11_ValidUTF8StringCaseInsensitiveMatch ()
388                 {
389                         X509Certificate2 ee = GetCertificate ("ValidUTF8StringCaseInsensitiveMatchTest11EE.crt");
390                         X509Chain chain = new X509Chain ();
391                         // INFO: different ee.issuer/ca.subject names (spaces & cases)
392                         // ee.Issuer                                    "CN=utf8string case  insensitive match CA, O=\"  test certificates  \", C=US"
393                         // UTF8StringCaseInsensitiveMatchCACert.Subject "CN=UTF8String Case Insensitive Match CA, O=Test Certificates, C=US"
394                         Assert.IsTrue (chain.Build (ee), "Build");
395                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainStatus, "ChainStatus");
396                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
397                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
398                         Assert.AreEqual (UTF8StringCaseInsensitiveMatchCACert, chain.ChainElements[1].Certificate, "UTF8StringCaseInsensitiveMatchCACert");
399                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UTF8StringCaseInsensitiveMatchCACert.Status");
400                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
401                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
402                 }
403
404                 [Test]
405                 [Category ("NotWorking")] // WONTFIX - this isn't RFC3280 compliant
406                 public void T11_ValidUTF8StringCaseInsensitiveMatch_MS ()
407                 {
408                         X509Certificate2 ee = GetCertificate ("ValidUTF8StringCaseInsensitiveMatchTest11EE.crt");
409                         X509Chain chain = new X509Chain ();
410                         // MS-BAD / this is valid wrt RFC3280
411                         Assert.IsFalse (chain.Build (ee), "Build");
412                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus, "ChainStatus");
413                         Assert.AreEqual (ee, chain.ChainElements[0].Certificate, "EndEntity");
414                         CheckChainStatus (X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainElements[0].ChainElementStatus, "EndEntity.Status");
415                         Assert.AreEqual (UTF8StringCaseInsensitiveMatchCACert, chain.ChainElements[1].Certificate, "UTF8StringCaseInsensitiveMatchCACert");
416                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[1].ChainElementStatus, "UTF8StringCaseInsensitiveMatchCACert.Status");
417                         Assert.AreEqual (TrustAnchorRoot, chain.ChainElements[2].Certificate, "TrustAnchorRoot");
418                         CheckChainStatus (X509ChainStatusFlags.NoError, chain.ChainElements[2].ChainElementStatus, "TrustAnchorRoot.Status");
419                 }
420         }
421 }
422