/** * Copyright (c) Istituto Nazionale di Fisica Nucleare, 2006-2014. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.italiangrid.voms.test.ac; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.KeyStoreException; import java.security.cert.CertificateException; import java.util.Arrays; import java.util.Date; import java.util.EnumSet; import java.util.List; import org.junit.Assert; import org.italiangrid.voms.VOMSError; import org.italiangrid.voms.VOMSValidators; import org.italiangrid.voms.ac.VOMSACValidator; import org.italiangrid.voms.ac.VOMSValidationResult; import org.italiangrid.voms.ac.impl.LocalHostnameResolver; import org.italiangrid.voms.asn1.VOMSACGenerator.ACGenerationProperties; import org.italiangrid.voms.error.VOMSValidationErrorCode; import org.italiangrid.voms.error.VOMSValidationErrorMessage; import org.italiangrid.voms.store.impl.DefaultVOMSTrustStore; import org.italiangrid.voms.test.utils.Fixture; import org.italiangrid.voms.test.utils.Utils; import org.italiangrid.voms.test.utils.VOMSAA; import org.junit.BeforeClass; import org.junit.Test; import eu.emi.security.authn.x509.X509CertChainValidatorExt; import eu.emi.security.authn.x509.impl.PEMCredential; import eu.emi.security.authn.x509.proxy.ProxyCertificate; public class TestACValidator implements Fixture { static PEMCredential holder, holder2; static VOMSACValidator validator; @BeforeClass public static void setup() throws KeyStoreException, CertificateException, IOException { holder = Utils.getTestUserCredential(); holder2 = Utils.getTest1UserCredential(); validator = Utils.getVOMSValidator(); } @Test public void testValidityCheckSuccess() throws Exception { ProxyCertificate proxy = Utils.getVOMSAA().createVOMSProxy(holder, defaultVOFqans); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); assertTrue(results.size() == 1); assertTrue(results.get(0).isValid()); assertEquals(defaultVOFqans, results.get(0).getAttributes().getFQANs()); } @Test public void testTimeValidityFailure() throws Exception { Date start = Utils.getDate(1975, 12, 1); Date end = Utils.getDate(1975, 12, 2); ProxyCertificate proxy = Utils.getVOMSAA().setAcNotBefore(start) .setAcNotAfter(end).createVOMSProxy(holder, defaultVOFqans); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); assertTrue(results.size() == 1); VOMSValidationResult result = results.get(0); Assert.assertFalse(result.isValid()); Assert.assertTrue(result.getValidationErrors().size() == 1); VOMSValidationErrorMessage m = result.getValidationErrors().get(0); Assert.assertEquals(VOMSValidationErrorCode.acNotValidAtCurrentTime, m.getErrorCode()); } @Test public void testHolderCheckFailure() throws Exception { ProxyCertificate proxy = Utils.getVOMSAA().createVOMSProxy(holder, holder2, defaultVOFqans, null, null); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); assertTrue(results.size() == 1); VOMSValidationResult result = results.get(0); Assert.assertFalse(result.isValid()); Assert.assertTrue(result.getValidationErrors().size() == 1); VOMSValidationErrorMessage m = result.getValidationErrors().get(0); Assert.assertEquals(VOMSValidationErrorCode.acHolderDoesntMatchCertChain, m.getErrorCode()); } @Test public void testSignatureCheckFailure() throws Exception { ProxyCertificate proxy = Utils.getVOMSAA().createVOMSProxy(holder, defaultVOFqans); VOMSACValidator validator = Utils.getVOMSValidator(vomsdir_fake_aa_cert); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); assertTrue(results.size() == 1); VOMSValidationResult result = results.get(0); Assert.assertFalse(result.isValid()); Assert.assertTrue(result.getValidationErrors().size() == 2); Assert.assertEquals(VOMSValidationErrorCode.lscFileNotFound, result .getValidationErrors().get(0).getErrorCode()); Assert.assertEquals( VOMSValidationErrorCode.aaCertFailsSignatureVerification, result .getValidationErrors().get(1).getErrorCode()); } @Test public void testExpiredAACredFailure() throws Exception { ProxyCertificate proxy = Utils.getVOMSAA() .setCredential(Utils.getExpiredCredential()) .createVOMSProxy(holder, defaultVOFqans); X509CertChainValidatorExt certValidator = Utils.getCertificateValidator(); VOMSACValidator validator = VOMSValidators.newValidator( new DefaultVOMSTrustStore(Arrays.asList(vomsdir_expired_aa_cert)), certValidator); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); assertTrue(results.size() == 1); VOMSValidationResult result = results.get(0); Assert.assertFalse(result.isValid()); Assert.assertEquals(4, result.getValidationErrors().size()); Assert.assertEquals(VOMSValidationErrorCode.lscFileNotFound, result .getValidationErrors().get(0).getErrorCode()); // Certificate expired notification from CAnL Assert.assertEquals(VOMSValidationErrorCode.canlError, result .getValidationErrors().get(1).getErrorCode()); // This is probably a bug in CAnL: No valid CRL was found for the CA which // issued the chain. But this happens only when validating the expired cert. Assert.assertEquals(VOMSValidationErrorCode.canlError, result .getValidationErrors().get(2).getErrorCode()); Assert.assertEquals(VOMSValidationErrorCode.invalidAaCert, result .getValidationErrors().get(3).getErrorCode()); } @Test public void testEmptyACCertsExtensionSuccess() throws Exception { VOMSAA aa = Utils.getVOMSAA(); aa.setGenerationProperties(EnumSet .of(ACGenerationProperties.INCLUDE_EMPTY_AC_CERTS_EXTENSION)); VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertTrue(r.isValid()); Assert.assertEquals(1, r.getValidationErrors().size()); Assert.assertEquals(VOMSValidationErrorCode.emptyAcCertsExtension, r .getValidationErrors().get(0).getErrorCode()); } @Test public void testMissingACCertsExtensionFailure() throws Exception { VOMSAA aa = Utils.getVOMSAA(); aa.setGenerationProperties(EnumSet .of(ACGenerationProperties.SKIP_AC_CERTS_EXTENSION)); aa.setVoName("test.vo.2"); aa.setHost("wilco.cnaf.infn.it"); aa.setCredential(Utils.getAACredential2()); VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo.2")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertFalse(r.isValid()); Assert.assertEquals(2, r.getValidationErrors().size()); Assert.assertEquals(VOMSValidationErrorCode.emptyAcCertsExtension, r .getValidationErrors().get(0).getErrorCode()); Assert.assertEquals(VOMSValidationErrorCode.aaCertNotFound, r .getValidationErrors().get(1).getErrorCode()); } @Test public void testInvalidLSCSignatureFailure() throws Exception { VOMSAA aa = Utils.getVOMSAA(); aa.setVoName("test.vo.2"); aa.setHost("wilco.cnaf.infn.it"); aa.setCredential(Utils.getAACredential2()); aa.setGenerationProperties(EnumSet .of(ACGenerationProperties.FAKE_SIGNATURE_BITS)); VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo.2")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertFalse(r.isValid()); Assert.assertEquals(2, r.getValidationErrors().size()); Assert.assertEquals( VOMSValidationErrorCode.acCertFailsSignatureVerification, r .getValidationErrors().get(0).getErrorCode()); Assert.assertEquals(VOMSValidationErrorCode.aaCertNotFound, r .getValidationErrors().get(1).getErrorCode()); } @Test public void testUnknownCriticalExtensionFailure() throws Exception { VOMSAA aa = Utils.getVOMSAA(); aa.setGenerationProperties(EnumSet .of(ACGenerationProperties.INCLUDE_FAKE_CRITICAL_EXTENSION)); VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertFalse(r.isValid()); Assert.assertEquals(1, r.getValidationErrors().size()); Assert.assertEquals(VOMSValidationErrorCode.other, r.getValidationErrors() .get(0).getErrorCode()); Assert .assertEquals( "Validation error: unknown critical extension found in VOMS AC: 1.3.6.1.4.1.8005.100.120.82", r.getValidationErrors().get(0).getMessage()); } @Test public void testCriticalAKIDFailure() throws Exception { VOMSAA aa = Utils.getVOMSAA(); aa.setGenerationProperties(EnumSet .of(ACGenerationProperties.INCLUDE_CRITICAL_AKID_EXTENSION)); VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertFalse(r.isValid()); Assert.assertEquals(VOMSValidationErrorCode.other, r.getValidationErrors() .get(0).getErrorCode()); Assert .assertEquals( "Validation error: AuthorityKeyIdentifier AC extension cannot be critical!", r.getValidationErrors().get(0).getMessage()); } @Test public void testCriticalNoRevAvailFailure() throws Exception { VOMSAA aa = Utils.getVOMSAA(); aa.setGenerationProperties(EnumSet .of(ACGenerationProperties.INCLUDE_CRITICAL_NO_REV_AVAIL_EXTENSION)); VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertFalse(r.isValid()); Assert.assertEquals(VOMSValidationErrorCode.other, r.getValidationErrors() .get(0).getErrorCode()); Assert.assertEquals( "Validation error: NoRevAvail AC extension cannot be critical!", r .getValidationErrors().get(0).getMessage()); } @Test public void testTargetValidationSuccess() throws Exception { VOMSAA aa = Utils.getVOMSAA(); String localhostName; try { localhostName = InetAddress.getLocalHost().getCanonicalHostName(); } catch (UnknownHostException e) { throw new VOMSError("Error resolving local hostname: " + e.getMessage(), e); } VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo"), null, Arrays.asList(localhostName)); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertTrue(r.isValid()); } @Test public void testTargetValidationFailure() throws Exception { VOMSAA aa = Utils.getVOMSAA(); VOMSACValidator validator = Utils.getVOMSValidator(); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo"), null, Arrays.asList("camaghe.cnaf.infn.it")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertFalse(r.isValid()); Assert.assertEquals(1, r.getValidationErrors().size()); Assert.assertEquals(VOMSValidationErrorCode.localhostDoesntMatchAcTarget, r .getValidationErrors().get(0).getErrorCode()); } @Test public void testResolveHostnameException() throws Exception { VOMSAA aa = Utils.getVOMSAA(); VOMSACValidator validator = Utils .getVOMSValidator(new LocalHostnameResolver() { public String resolveLocalHostname() throws UnknownHostException { throw new UnknownHostException("misconfigured machine!"); } }); ProxyCertificate proxy = aa.createVOMSProxy(Utils.getTestUserCredential(), Arrays.asList("/test.vo"), null, Arrays.asList("camaghe.cnaf.infn.it")); List<VOMSValidationResult> results = validator.validateWithResult(proxy .getCertificateChain()); Assert.assertEquals(1, results.size()); VOMSValidationResult r = results.get(0); Assert.assertFalse(r.isValid()); Assert.assertEquals(1, r.getValidationErrors().size()); Assert.assertEquals(VOMSValidationErrorCode.other, r.getValidationErrors() .get(0).getErrorCode()); Assert .assertEquals( "Validation error: Error resolving localhost name: misconfigured machine!", r.getValidationErrors().get(0).getMessage()); } }