/* * Copyright (c) 2011-2012 ICM Uniwersytet Warszawski All rights reserved. * See LICENCE.txt file for licensing information. */ package eu.emi.security.authn.x509.ns; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.Collections; import org.junit.Assert; import org.apache.commons.io.FileUtils; import org.junit.Test; import eu.emi.security.authn.x509.NamespaceCheckingMode; import eu.emi.security.authn.x509.ProxySupport; import eu.emi.security.authn.x509.RevocationParameters; import eu.emi.security.authn.x509.StoreUpdateListener; import eu.emi.security.authn.x509.ValidationResult; import eu.emi.security.authn.x509.impl.CertificateUtils; import eu.emi.security.authn.x509.impl.CertificateUtils.Encoding; import eu.emi.security.authn.x509.impl.OpensslCertChainValidator; import eu.emi.security.authn.x509.impl.ValidatorParams; /** * Integration test using {@link OpensslCertChainValidator} and testing (mostly) whether its * namespace handling is working properly. * @author K. Benedyczak */ public class OpensslDirTest { private static final int DELAY = 100; private static final String PMA_NS_ACCEPTING = "TO Issuer \"/C=EU/O=EMITest/CN=The root CA1\" " + "PERMIT Subject \"/C=EU/O=EMITest/CN=.*\""; private static final String PMA_NS_REJECTING = "TO Issuer \"/C=EU/O=EMITest/CN=The root CA1\" " + "PERMIT Subject \"/C=EU/O=EMINest/CN=.*\""; private static final String GLOBUS_NS_ACCEPTING = "access_id_CA X509 '/C=EU/O=EMITest/CN=The root CA1'\n"+ "pos_rights globus CA:sign\n" + "cond_subjects globus '\"/C=EU/O=EMITest/CN=*\"'"; private static final String GLOBUS_NS_REJECTING = "access_id_CA X509 '/C=EU/O=EMITest/CN=The root CA1'\n"+ "pos_rights globus CA:sign\n" + "cond_subjects globus '\"/C=EU/O=EMITest/CN=Zuser*\"'"; private File nsFile; private File spFile; private int test=0; private volatile int[] notCounter = new int[10]; @Test public void test() throws Exception { File dir = initDir(); nsFile = new File(dir, "77ab7b18.namespaces"); spFile = new File(dir, "77ab7b18.signing_policy"); X509Certificate cert = CertificateUtils.loadCertificate( new FileInputStream("src/test/testCAs/ca-simple/CA-issued/user1/newcert.pem"), Encoding.PEM); OpensslCertChainValidator validators[] = new OpensslCertChainValidator[] { new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.IGNORE, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.EUGRIDPMA, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(0))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.EUGRIDPMA_AND_GLOBUS, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(1))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.EUGRIDPMA_AND_GLOBUS_REQUIRE, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(2))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.EUGRIDPMA_GLOBUS, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(3))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.EUGRIDPMA_GLOBUS_REQUIRE, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(4))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.EUGRIDPMA_REQUIRE, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(5))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.GLOBUS, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(6))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.GLOBUS_EUGRIDPMA, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(7))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.GLOBUS_EUGRIDPMA_REQUIRE, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(8))), false), new OpensslCertChainValidator(dir.toString(), false, NamespaceCheckingMode.GLOBUS_REQUIRE, DELAY, new ValidatorParams(RevocationParameters.IGNORE, ProxySupport.ALLOW, Collections.singletonList(new MyListener(9))), false), }; //case: no ns declarations. // All with require should fail, the rest succeed. boolean []results = new boolean[] { true, true, true, false, true, false, false, true, true, false, false }; check(cert, validators, results); //case: only EUGRIDPMA is present and is accepting. // All should accept except GLOBUS_REQUIRE results = new boolean[] { true, true, true, true, true, true, true, true, true, true, false }; updateAndWait(null, PMA_NS_ACCEPTING); check(cert, validators, results); //case: only GLOBUS is present and is accepting. // All should accept except EUGRIDPMA_REQUIRE results = new boolean[] { true, true, true, true, true, true, false, true, true, true, true }; updateAndWait(GLOBUS_NS_ACCEPTING, null); check(cert, validators, results); //case: only EUGRIDPMA is present and is rejecting. // All having EUGRIDPMA enabled should fail, and GL_REQ too results = new boolean[] { true, false, false, false, false, false, false, true, false, false, false }; updateAndWait(null, PMA_NS_REJECTING); check(cert, validators, results); //case: only GLOBUS is present and is rejecting. // All having GLOBUS enabled should fail, and EU_REQ too results = new boolean[] { true, true, false, false, false, false, false, false, false, false, false }; updateAndWait(GLOBUS_NS_REJECTING, null); check(cert, validators, results); //case6: GLOBUS is rejecting EU is accepting. // All having GLOBUS first should fail, all with AND too, the rest pass results = new boolean[] { true, true, false, false, true, true, true, false, false, false, false }; updateAndWait(GLOBUS_NS_REJECTING, PMA_NS_ACCEPTING); check(cert, validators, results); //case7: GLOBUS accepting EU is rejecting. // All having EU first should fail, all with AND too, the rest pass results = new boolean[] { true, false, false, false, false, false, false, true, true, true, true }; updateAndWait(GLOBUS_NS_ACCEPTING, PMA_NS_REJECTING); check(cert, validators, results); //case: both are accepting // All should pass results = new boolean[] { true, true, true, true, true, true, true, true, true, true, true }; updateAndWait(GLOBUS_NS_ACCEPTING, PMA_NS_ACCEPTING); check(cert, validators, results); //case: both are rejecting // only ignore should pass results = new boolean[] { true, false, false, false, false, false, false, false, false, false, false }; updateAndWait(GLOBUS_NS_REJECTING, PMA_NS_REJECTING); check(cert, validators, results); for (OpensslCertChainValidator v: validators) v.dispose(); } private synchronized void incCounter(int n) { notCounter[n]++; } private void updateAndWait(String globus, String eu) throws IOException, InterruptedException { boolean[] withGlobus = {false, true, true, true, true, false, true, true, true, true}; boolean[] withEu = {true, true, true, true, true, true, false, true, true, false}; synchronized (this) { for (int i=0; i<10; i++) notCounter[i] = 0; if (globus != null) FileUtils.writeStringToFile(spFile, globus); if (eu != null) FileUtils.writeStringToFile(nsFile, eu); for (int i=0; i<10; i++) { int possible = 0; if (withGlobus[i] && globus != null) possible++; if (withEu[i] && eu != null) possible++; if (notCounter[i] < possible) { wait(50); i--; } } } Thread.sleep(100); //overkill to be 100% sure: we got notification about all policies being successfully //reread, but those needs to be also updated (100ms for calling two setters ;-) } private void check(X509Certificate cert, OpensslCertChainValidator validators[], boolean []results) { System.out.println("------\nTEST " + ++test + "\n"); for (int i=0; i<validators.length; i++) { OpensslCertChainValidator v = validators[i]; ValidationResult res = v.validate(new X509Certificate[] {cert}); System.out.println(i + ") got result: " + res); Assert.assertEquals("Error at position " + i, results[i], res.isValid()); } nsFile.delete(); spFile.delete(); } private static File initDir() throws IOException { File dir = new File("target/test-tmp/openssl-nsTest"); FileUtils.deleteDirectory(dir); dir.mkdirs(); File caFile = new File("src/test/testCAs/ca-simple/CA-files/cacert.pem"); File destFile = new File(dir, "77ab7b18.0"); FileUtils.copyFile(caFile, destFile); return dir; } private class MyListener implements StoreUpdateListener { int number; public MyListener(int n) { number = n; } @Override public void loadingNotification(String location, String type, Severity level, Exception cause) { if (!type.equals(StoreUpdateListener.EACL_NAMESPACE) && !type.equals(StoreUpdateListener.EUGRIDPMA_NAMESPACE)) return; if (level != Severity.NOTIFICATION) System.err.println(type + " loading probelm: " + location + " " + cause); else incCounter(number); } } }