2 // X509ChainTest.cs - NUnit tests for X509Chain
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
32 using NUnit
.Framework
;
35 using System
.Security
.Cryptography
;
36 using System
.Security
.Cryptography
.X509Certificates
;
39 namespace MonoTests
.System
.Security
.Cryptography
.X509Certificates
{
42 public class X509ChainTest
{
44 private X509Certificate2Collection empty
;
45 private X509Certificate2Collection collection
;
47 private X509Certificate2 cert_empty
;
48 private X509Certificate2 cert1
;
49 private X509Certificate2 cert2
;
50 private X509Certificate2 cert3
;
53 public void FixtureSetUp ()
55 cert_empty
= new X509Certificate2 ();
56 cert1
= new X509Certificate2 (X509Certificate2Test
.farscape_pfx
, "farscape", X509KeyStorageFlags
.Exportable
);
57 cert2
= new X509Certificate2 (Encoding
.ASCII
.GetBytes (X509Certificate2Test
.base64_cert
));
59 empty
= new X509Certificate2Collection ();
60 collection
= new X509Certificate2Collection ();
61 collection
.Add (cert1
);
62 collection
.Add (cert2
);
65 // this method avoid having a dependance on the order of status
66 public void CheckChainStatus (X509ChainStatusFlags expected
, X509ChainStatus
[] status
, string msg
)
68 if ((expected
== X509ChainStatusFlags
.NoError
) && (status
.Length
== 0))
71 X509ChainStatusFlags actual
= X509ChainStatusFlags
.NoError
;
72 foreach (X509ChainStatus s
in status
) {
75 Assert
.AreEqual (expected
, actual
, msg
);
78 private void CheckDefaultChain (X509Chain c
)
80 Assert
.AreEqual (0, c
.ChainElements
.Count
, "ChainElements");
81 Assert
.IsNotNull (c
.ChainPolicy
, "ChainPolicy");
82 Assert
.AreEqual (0, c
.ChainStatus
.Length
, "ChainStatus");
83 // check default policy
84 CheckDefaultPolicy (c
.ChainPolicy
);
87 private void CheckDefaultPolicy (X509ChainPolicy p
)
89 Assert
.AreEqual (0, p
.ApplicationPolicy
.Count
, "ApplicationPolicy");
90 Assert
.AreEqual (0, p
.CertificatePolicy
.Count
, "CertificatePolicy");
91 Assert
.AreEqual (0, p
.ExtraStore
.Count
, "ExtraStore");
92 Assert
.AreEqual (X509RevocationFlag
.ExcludeRoot
, p
.RevocationFlag
, "RevocationFlag");
93 Assert
.AreEqual (X509RevocationMode
.Online
, p
.RevocationMode
, "RevocationMode");
94 Assert
.AreEqual (0, p
.UrlRetrievalTimeout
.Ticks
, "UrlRetrievalTimeout");
95 Assert
.AreEqual (X509VerificationFlags
.NoFlag
, p
.VerificationFlags
, "VerificationFlags");
96 Assert
.IsTrue (p
.VerificationTime
<= DateTime
.Now
, "VerificationTime");
100 public void ConstructorEmpty ()
102 X509Chain c
= new X509Chain ();
103 CheckDefaultChain (c
);
107 public void ConstructorMachineContextFalse ()
109 X509Chain c
= new X509Chain (false);
110 CheckDefaultChain (c
);
114 public void ConstructorMachineContextTrue ()
116 X509Chain c
= new X509Chain (true);
117 CheckDefaultChain (c
);
121 [ExpectedException (typeof (ArgumentException
))]
122 public void Build_Null ()
124 X509Chain c
= new X509Chain ();
129 [ExpectedException (typeof (ArgumentException
))]
130 public void Build_Empty ()
132 X509Chain c
= new X509Chain ();
133 c
.Build (cert_empty
);
137 public void Build_Twice_SameCertificate ()
139 X509Chain c
= new X509Chain ();
140 Assert
.IsFalse (c
.Build (cert1
), "Build-1a");
141 Assert
.IsFalse (c
.Build (cert1
), "Build-2a");
145 public void Build_Twice_DifferentCertificate ()
147 X509Chain c
= new X509Chain ();
148 Assert
.IsFalse (c
.Build (cert1
), "Build-1");
149 Assert
.IsFalse (c
.Build (cert2
), "Build-2");
153 public void Build_Twice_WithReset ()
155 X509Chain c
= new X509Chain ();
156 Assert
.IsFalse (c
.Build (cert1
), "Build-1");
158 Assert
.IsFalse (c
.Build (cert2
), "Build-2");
160 CheckDefaultChain (c
);
163 private void CheckCert1 (X509Chain c
)
165 X509VerificationFlags success_mask
;
167 switch (c
.ChainPolicy
.RevocationMode
) {
168 case X509RevocationMode
.Offline
:
169 case X509RevocationMode
.Online
:
170 success_mask
= X509VerificationFlags
.IgnoreNotTimeValid
| X509VerificationFlags
.AllowUnknownCertificateAuthority
;
172 case X509RevocationMode
.NoCheck
:
174 success_mask
= X509VerificationFlags
.AllowUnknownCertificateAuthority
;
178 Assert
.AreEqual (((c
.ChainPolicy
.VerificationFlags
& success_mask
) == success_mask
), c
.Build (cert1
), "Build");
179 Assert
.AreEqual (1, c
.ChainElements
.Count
, "ChainElements");
180 Assert
.AreEqual (String
.Empty
, c
.ChainElements
[0].Information
, "ChainElements[0].Information");
181 Assert
.AreEqual (cert1
, c
.ChainElements
[0].Certificate
, "ChainElements[0].Certificate");
183 switch (c
.ChainPolicy
.RevocationMode
) {
184 case X509RevocationMode
.Offline
:
185 case X509RevocationMode
.Online
:
186 CheckChainStatus (X509ChainStatusFlags
.PartialChain
| X509ChainStatusFlags
.RevocationStatusUnknown
| X509ChainStatusFlags
.OfflineRevocation
, c
.ChainStatus
, "c.ChainStatus");
187 CheckChainStatus (X509ChainStatusFlags
.RevocationStatusUnknown
| X509ChainStatusFlags
.OfflineRevocation
, c
.ChainElements
[0].ChainElementStatus
, "c.ChainElements[0].ChainElementStatus");
189 case X509RevocationMode
.NoCheck
:
190 CheckChainStatus (X509ChainStatusFlags
.PartialChain
, c
.ChainStatus
, "c.ChainStatus");
191 CheckChainStatus (X509ChainStatusFlags
.NoError
, c
.ChainElements
[0].ChainElementStatus
, "c.ChainElements[0].ChainElementStatus");
197 public void Build_Cert1_X509RevocationMode_Offline ()
199 X509Chain c
= new X509Chain ();
200 c
.ChainPolicy
.RevocationMode
= X509RevocationMode
.Offline
; // default
201 foreach (X509VerificationFlags vf
in Enum
.GetValues (typeof (X509VerificationFlags
))) {
202 c
.ChainPolicy
.VerificationFlags
= vf
;
209 [Category ("InetAccess")]
210 public void Build_Cert1_X509RevocationMode_Online ()
212 X509Chain c
= new X509Chain ();
213 c
.ChainPolicy
.RevocationMode
= X509RevocationMode
.Online
;
214 foreach (X509VerificationFlags vf
in Enum
.GetValues (typeof (X509VerificationFlags
))) {
215 c
.ChainPolicy
.VerificationFlags
= vf
;
222 public void Build_Cert1_X509RevocationMode_NoCheck ()
224 X509Chain c
= new X509Chain ();
225 c
.ChainPolicy
.RevocationMode
= X509RevocationMode
.NoCheck
;
226 foreach (X509VerificationFlags vf
in Enum
.GetValues (typeof (X509VerificationFlags
))) {
227 c
.ChainPolicy
.VerificationFlags
= vf
;
233 private void CheckCert2 (X509Chain c
)
235 X509VerificationFlags success_mask
= X509VerificationFlags
.IgnoreNotTimeValid
| X509VerificationFlags
.AllowUnknownCertificateAuthority
;
236 Assert
.AreEqual (((c
.ChainPolicy
.VerificationFlags
& success_mask
) == success_mask
), c
.Build (cert2
), "Build");
237 Assert
.AreEqual (1, c
.ChainElements
.Count
, "ChainElements");
238 Assert
.AreEqual (String
.Empty
, c
.ChainElements
[0].Information
, "ChainElements[0].Information");
239 Assert
.AreEqual (cert2
, c
.ChainElements
[0].Certificate
, "ChainElements[0].Certificate");
241 CheckChainStatus (X509ChainStatusFlags
.UntrustedRoot
| X509ChainStatusFlags
.NotTimeValid
, c
.ChainStatus
, "c.ChainStatus");
242 CheckChainStatus (X509ChainStatusFlags
.UntrustedRoot
| X509ChainStatusFlags
.NotTimeValid
, c
.ChainElements
[0].ChainElementStatus
, "c.ChainElements[0].ChainElementStatus");
246 public void Build_Cert2 ()
248 X509Chain c
= new X509Chain ();
249 foreach (X509VerificationFlags vf
in Enum
.GetValues (typeof (X509VerificationFlags
))) {
250 c
.ChainPolicy
.VerificationFlags
= vf
;
254 // minimal criteria for success
255 c
.ChainPolicy
.VerificationFlags
= X509VerificationFlags
.IgnoreNotTimeValid
| X509VerificationFlags
.AllowUnknownCertificateAuthority
;
262 X509Chain c
= new X509Chain ();
263 c
.ChainPolicy
.ApplicationPolicy
.Add (new Oid ("1.2.3"));
264 c
.ChainPolicy
.CertificatePolicy
.Add (new Oid ("1.2.4"));
265 c
.ChainPolicy
.ExtraStore
.AddRange (collection
);
266 c
.ChainPolicy
.RevocationFlag
= X509RevocationFlag
.EntireChain
;
267 c
.ChainPolicy
.RevocationMode
= X509RevocationMode
.Offline
;
268 c
.ChainPolicy
.UrlRetrievalTimeout
= new TimeSpan (1000);
269 c
.ChainPolicy
.VerificationFlags
= X509VerificationFlags
.IgnoreWrongUsage
;
270 c
.ChainPolicy
.VerificationTime
= DateTime
.MinValue
;
272 // resetting the chain doesn't reset the policy
273 Assert
.AreEqual (1, c
.ChainPolicy
.ApplicationPolicy
.Count
, "ApplicationPolicy");
274 Assert
.AreEqual (1, c
.ChainPolicy
.CertificatePolicy
.Count
, "CertificatePolicy");
275 Assert
.AreEqual (2, c
.ChainPolicy
.ExtraStore
.Count
, "ExtraStore");
276 Assert
.AreEqual (X509RevocationFlag
.EntireChain
, c
.ChainPolicy
.RevocationFlag
, "RevocationFlag");
277 Assert
.AreEqual (X509RevocationMode
.Offline
, c
.ChainPolicy
.RevocationMode
, "RevocationMode");
278 Assert
.AreEqual (1000, c
.ChainPolicy
.UrlRetrievalTimeout
.Ticks
, "UrlRetrievalTimeout");
279 Assert
.AreEqual (X509VerificationFlags
.IgnoreWrongUsage
, c
.ChainPolicy
.VerificationFlags
, "VerificationFlags");
280 Assert
.AreEqual (DateTime
.MinValue
, c
.ChainPolicy
.VerificationTime
, "VerificationTime");
284 public void StaticCreation ()
286 X509Chain c
= X509Chain
.Create ();
287 CheckDefaultChain (c
);
291 public void CreateViaCryptoConfig ()
293 // X509Chain can be changed using CryptoConfig
294 Assert
.AreEqual (typeof (X509Chain
), CryptoConfig
.CreateFromName ("X509Chain").GetType (), "X509Chain");
295 Assert
.IsNull (CryptoConfig
.CreateFromName ("System.Security.Cryptography.X509Certificates.X509Chain"), "System.Security.Cryptography.X509Certificates.X509Chain");