2 * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.] Licensed under the Apache License,
3 * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy
4 * of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in
5 * writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
6 * OF ANY KIND, either express or implied. See the License for the specific language governing permissions and
7 * limitations under the License.
10 package edu.internet2.middleware.shibboleth.common;
13 import java.io.IOException;
14 import java.security.KeyStore;
15 import java.security.KeyStoreException;
16 import java.security.NoSuchAlgorithmException;
17 import java.security.cert.CertificateException;
18 import java.security.cert.X509Certificate;
19 import java.util.Arrays;
21 import junit.framework.TestCase;
23 import org.apache.log4j.BasicConfigurator;
24 import org.apache.log4j.Level;
25 import org.apache.log4j.Logger;
26 import org.opensaml.Configuration;
27 import org.opensaml.saml2.metadata.EntityDescriptor;
28 import org.opensaml.saml2.metadata.SPSSODescriptor;
29 import org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider;
30 import org.opensaml.saml2.metadata.provider.MetadataProvider;
31 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
32 import org.opensaml.security.TrustEngine;
33 import org.opensaml.security.X509EntityCredential;
34 import org.opensaml.security.impl.SimpleX509EntityCredential;
36 import edu.internet2.middleware.shibboleth.common.ShibResource.ResourceNotAvailableException;
37 import edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrustEngine;
40 * Test suite for SAML/Shibboleth trust validation.
42 * @author Walter Hoehn
44 public class TrustTests extends TestCase {
46 public TrustTests(String name) {
49 BasicConfigurator.resetConfiguration();
50 BasicConfigurator.configure();
51 Logger.getRootLogger().setLevel(Level.DEBUG);
56 public static void main(String[] args) {
58 junit.textui.TestRunner.run(CredentialsTests.class);
59 BasicConfigurator.configure();
60 Logger.getRootLogger().setLevel(Level.OFF);
63 protected void setUp() throws Exception {
68 public void testInlineX509CertValidate() {
71 // Pull the role descriptor from example metadata
72 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata1.xml"));
73 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
74 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
76 // Use a pre-defined cert
77 KeyStore keyStore = KeyStore.getInstance("JKS");
78 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
79 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
80 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inliine1");
82 // Try to validate against the metadata
83 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
84 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
85 .asList(new X509Certificate[]{cert})), role);
87 fail("Validation should have succeeded.");
90 } catch (MetadataProviderException e) {
91 fail("Error in test specification: " + e);
92 } catch (ResourceNotAvailableException e) {
93 fail("Error in test specification: " + e);
94 } catch (IOException e) {
95 fail("Error in test specification: " + e);
96 } catch (NoSuchAlgorithmException e) {
97 fail("Error in test specification: " + e);
98 } catch (CertificateException e) {
99 fail("Error in test specification: " + e);
100 } catch (KeyStoreException e) {
101 fail("Error in test specification: " + e);
105 public void testInlineX509CertValidationFail() {
108 // Pull the role descriptor from example metadata
109 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata1.xml"));
110 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
111 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
113 // Use a pre-defined cert
114 KeyStore keyStore = KeyStore.getInstance("JKS");
115 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
116 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
117 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inline2");
119 // Try to validate against the metadata
120 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
121 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
122 .asList(new X509Certificate[]{cert})), role);
124 fail("Validation should have failed.");
127 } catch (MetadataProviderException e) {
128 fail("Error in test specification: " + e);
129 } catch (ResourceNotAvailableException e) {
130 fail("Error in test specification: " + e);
131 } catch (IOException e) {
132 fail("Error in test specification: " + e);
133 } catch (NoSuchAlgorithmException e) {
134 fail("Error in test specification: " + e);
135 } catch (CertificateException e) {
136 fail("Error in test specification: " + e);
137 } catch (KeyStoreException e) {
138 fail("Error in test specification: " + e);
142 public void testPkixX509CertValidate() {
145 // Pull the role descriptor from example metadata
146 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata2.xml"));
147 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
148 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
150 // Use a pre-defined cert
151 KeyStore keyStore = KeyStore.getInstance("JKS");
152 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
153 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
154 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inliine1");
156 // Try to validate against the metadata
157 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
158 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
159 .asList(new X509Certificate[]{cert})), role);
161 fail("Validation should have succeeded.");
164 } catch (MetadataProviderException e) {
165 fail("Error in test specification: " + e);
166 } catch (ResourceNotAvailableException e) {
167 fail("Error in test specification: " + e);
168 } catch (IOException e) {
169 fail("Error in test specification: " + e);
170 } catch (NoSuchAlgorithmException e) {
171 fail("Error in test specification: " + e);
172 } catch (CertificateException e) {
173 fail("Error in test specification: " + e);
174 } catch (KeyStoreException e) {
175 fail("Error in test specification: " + e);
179 public void testPkixX509CertValidateRecurseEntities() {
182 // Pull the role descriptor from example metadata
183 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata3.xml"));
184 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
185 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
187 // Use a pre-defined cert
188 KeyStore keyStore = KeyStore.getInstance("JKS");
189 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
190 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
191 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inliine1");
193 // Try to validate against the metadata
194 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
195 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
196 .asList(new X509Certificate[]{cert})), role);
198 fail("Validation should have succeeded.");
201 } catch (MetadataProviderException e) {
202 fail("Error in test specification: " + e);
203 } catch (ResourceNotAvailableException e) {
204 fail("Error in test specification: " + e);
205 } catch (IOException e) {
206 fail("Error in test specification: " + e);
207 } catch (NoSuchAlgorithmException e) {
208 fail("Error in test specification: " + e);
209 } catch (CertificateException e) {
210 fail("Error in test specification: " + e);
211 } catch (KeyStoreException e) {
212 fail("Error in test specification: " + e);
216 public void testPkixX509CertValidateRecurseEntitiesWBadFirst() {
219 // Pull the role descriptor from example metadata
220 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata12.xml"));
221 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
222 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
224 // Use a pre-defined cert
225 KeyStore keyStore = KeyStore.getInstance("JKS");
226 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
227 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
228 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inliine1");
230 // Try to validate against the metadata
231 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
232 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
233 .asList(new X509Certificate[]{cert})), role);
235 fail("Validation should have succeeded.");
238 } catch (MetadataProviderException e) {
239 fail("Error in test specification: " + e);
240 } catch (ResourceNotAvailableException e) {
241 fail("Error in test specification: " + e);
242 } catch (IOException e) {
243 fail("Error in test specification: " + e);
244 } catch (NoSuchAlgorithmException e) {
245 fail("Error in test specification: " + e);
246 } catch (CertificateException e) {
247 fail("Error in test specification: " + e);
248 } catch (KeyStoreException e) {
249 fail("Error in test specification: " + e);
252 public void testPkixX509CertValidateRecurseEntitiesWMultipleKeyAuthoritiesOnOneDescriptor() {
255 // Pull the role descriptor from example metadata
256 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata13.xml"));
257 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
258 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
260 // Use a pre-defined cert
261 KeyStore keyStore = KeyStore.getInstance("JKS");
262 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
263 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
264 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inliine1");
266 // Try to validate against the metadata
267 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
268 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
269 .asList(new X509Certificate[]{cert})), role);
271 fail("Validation should have succeeded.");
274 } catch (MetadataProviderException e) {
275 fail("Error in test specification: " + e);
276 } catch (ResourceNotAvailableException e) {
277 fail("Error in test specification: " + e);
278 } catch (IOException e) {
279 fail("Error in test specification: " + e);
280 } catch (NoSuchAlgorithmException e) {
281 fail("Error in test specification: " + e);
282 } catch (CertificateException e) {
283 fail("Error in test specification: " + e);
284 } catch (KeyStoreException e) {
285 fail("Error in test specification: " + e);
289 public void testPkixX509CertValidateWithCAPath() {
292 // Pull the role descriptor from example metadata
293 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata4.xml"));
294 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
295 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
297 // Use a pre-defined cert
298 KeyStore keyStore = KeyStore.getInstance("JKS");
299 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
300 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
301 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inline3");
303 // Try to validate against the metadata
304 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
305 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
306 .asList(new X509Certificate[]{cert})), role);
308 fail("Validation should have succeeded.");
311 } catch (MetadataProviderException e) {
312 fail("Error in test specification: " + e);
313 } catch (ResourceNotAvailableException e) {
314 fail("Error in test specification: " + e);
315 } catch (IOException e) {
316 fail("Error in test specification: " + e);
317 } catch (NoSuchAlgorithmException e) {
318 fail("Error in test specification: " + e);
319 } catch (CertificateException e) {
320 fail("Error in test specification: " + e);
321 } catch (KeyStoreException e) {
322 fail("Error in test specification: " + e);
326 public void testPkixX509CertFailBadNameMatch() {
329 // Pull the role descriptor from example metadata
330 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata11.xml"));
331 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
332 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
334 // Use a pre-defined cert
335 KeyStore keyStore = KeyStore.getInstance("JKS");
336 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
337 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
338 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inline3");
340 // Try to validate against the metadata
341 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
342 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
343 .asList(new X509Certificate[]{cert})), role);
345 fail("Validation should have failed. DN in cert does not match the metadata.");
348 } catch (MetadataProviderException e) {
349 fail("Error in test specification: " + e);
350 } catch (ResourceNotAvailableException e) {
351 fail("Error in test specification: " + e);
352 } catch (IOException e) {
353 fail("Error in test specification: " + e);
354 } catch (NoSuchAlgorithmException e) {
355 fail("Error in test specification: " + e);
356 } catch (CertificateException e) {
357 fail("Error in test specification: " + e);
358 } catch (KeyStoreException e) {
359 fail("Error in test specification: " + e);
363 public void testPkixX509CertFailValidateWithPathTooLong() {
366 // Pull the role descriptor from example metadata
367 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata6.xml"));
368 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
369 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
371 // Use a pre-defined cert
372 KeyStore keyStore = KeyStore.getInstance("JKS");
373 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
374 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
375 X509Certificate endEntity = (X509Certificate) keyStore.getCertificate("inline3");
376 X509Certificate intermediate = (X509Certificate) keyStore.getCertificate("im");
378 // Try to validate against the metadata
379 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
380 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays.asList(new X509Certificate[]{
381 endEntity, intermediate})), role);
383 fail("Validation should not have succeeded.");
386 } catch (MetadataProviderException e) {
387 fail("Error in test specification: " + e);
388 } catch (ResourceNotAvailableException e) {
389 fail("Error in test specification: " + e);
390 } catch (IOException e) {
391 fail("Error in test specification: " + e);
392 } catch (NoSuchAlgorithmException e) {
393 fail("Error in test specification: " + e);
394 } catch (CertificateException e) {
395 fail("Error in test specification: " + e);
396 } catch (KeyStoreException e) {
397 fail("Error in test specification: " + e);
401 public void testPkixX509CertValidateWithClientSuppliedIntermediate() {
404 // Pull the role descriptor from example metadata
405 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata5.xml"));
406 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
407 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
409 // Use a pre-defined cert
410 KeyStore keyStore = KeyStore.getInstance("JKS");
411 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
412 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
413 X509Certificate endEntity = (X509Certificate) keyStore.getCertificate("inline3");
414 X509Certificate intermediate = (X509Certificate) keyStore.getCertificate("im");
416 // Try to validate against the metadata
417 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
418 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays.asList(new X509Certificate[]{
419 endEntity, intermediate})), role);
421 fail("Validation should have succeeded.");
424 } catch (MetadataProviderException e) {
425 fail("Error in test specification: " + e);
426 } catch (ResourceNotAvailableException e) {
427 fail("Error in test specification: " + e);
428 } catch (IOException e) {
429 fail("Error in test specification: " + e);
430 } catch (NoSuchAlgorithmException e) {
431 fail("Error in test specification: " + e);
432 } catch (CertificateException e) {
433 fail("Error in test specification: " + e);
434 } catch (KeyStoreException e) {
435 fail("Error in test specification: " + e);
439 public void testCRL() {
442 // Pull the role descriptor from example metadata
443 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata7.xml"));
444 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
445 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
447 // Use a pre-defined cert
448 KeyStore keyStore = KeyStore.getInstance("JKS");
449 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
450 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
451 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inline4");
453 // Try to validate against the metadata
454 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
455 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
456 .asList(new X509Certificate[]{cert})), role);
458 fail("Validation should not have succeeded.");
461 } catch (MetadataProviderException e) {
462 fail("Error in test specification: " + e);
463 } catch (ResourceNotAvailableException e) {
464 fail("Error in test specification: " + e);
465 } catch (IOException e) {
466 fail("Error in test specification: " + e);
467 } catch (NoSuchAlgorithmException e) {
468 fail("Error in test specification: " + e);
469 } catch (CertificateException e) {
470 fail("Error in test specification: " + e);
471 } catch (KeyStoreException e) {
472 fail("Error in test specification: " + e);
476 public void testCRLDoesntBreakValid() {
479 // Pull the role descriptor from example metadata
480 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata8.xml"));
481 EntityDescriptor entity = metadata.getEntityDescriptor("urn-x:testSP1");
482 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
484 // Use a pre-defined cert
485 KeyStore keyStore = KeyStore.getInstance("JKS");
486 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
487 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
488 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inline4");
490 // Try to validate against the metadata
491 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
492 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
493 .asList(new X509Certificate[]{cert})), role);
495 fail("Validation should have succeeded.");
498 } catch (MetadataProviderException e) {
499 fail("Error in test specification: " + e);
500 } catch (ResourceNotAvailableException e) {
501 fail("Error in test specification: " + e);
502 } catch (IOException e) {
503 fail("Error in test specification: " + e);
504 } catch (NoSuchAlgorithmException e) {
505 fail("Error in test specification: " + e);
506 } catch (CertificateException e) {
507 fail("Error in test specification: " + e);
508 } catch (KeyStoreException e) {
509 fail("Error in test specification: " + e);
513 public void testPkixX509CertValidateWithExactProviderIdMatch() {
516 // Pull the role descriptor from example metadata
517 MetadataProvider metadata = new FilesystemMetadataProvider(new File("data/metadata9.xml"));
518 EntityDescriptor entity = metadata.getEntityDescriptor("Walter Hoehn");
519 SPSSODescriptor role = (SPSSODescriptor) entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
521 // Use a pre-defined cert
522 KeyStore keyStore = KeyStore.getInstance("JKS");
523 keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
524 new char[]{'t', 'e', 's', 't', '1', '2', '3'});
525 X509Certificate cert = (X509Certificate) keyStore.getCertificate("inliine1");
527 // Try to validate against the metadata
528 TrustEngine<X509EntityCredential> validator = new ShibbolethTrustEngine();
529 boolean successful = validator.validate(new SimpleX509EntityCredential(Arrays
530 .asList(new X509Certificate[]{cert})), role);
532 fail("Validation should have succeeded.");
535 } catch (MetadataProviderException e) {
536 fail("Error in test specification: " + e);
537 } catch (ResourceNotAvailableException e) {
538 fail("Error in test specification: " + e);
539 } catch (IOException e) {
540 fail("Error in test specification: " + e);
541 } catch (NoSuchAlgorithmException e) {
542 fail("Error in test specification: " + e);
543 } catch (CertificateException e) {
544 fail("Error in test specification: " + e);
545 } catch (KeyStoreException e) {
546 fail("Error in test specification: " + e);