/* * Copyright (c) 2012 ICM Uniwersytet Warszawski All rights reserved. * See LICENCE.txt file for licensing information. */ package eu.emi.security.authn.x509.ocsp; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.ConnectException; import java.net.URL; import java.net.UnknownHostException; import java.security.cert.X509Certificate; import static org.junit.Assert.*; import org.apache.commons.io.FileUtils; import org.bouncycastle.cert.ocsp.OCSPException; import org.bouncycastle.cert.ocsp.OCSPReq; import org.bouncycastle.cert.ocsp.OCSPResp; import org.bouncycastle.cert.ocsp.SingleResp; import org.junit.Test; import org.junit.experimental.categories.Category; import eu.emi.security.authn.x509.RiskyIntegrationTests; import eu.emi.security.authn.x509.X509Credential; import eu.emi.security.authn.x509.helpers.ocsp.OCSPCachingClient; import eu.emi.security.authn.x509.helpers.ocsp.OCSPClientImpl; import eu.emi.security.authn.x509.helpers.ocsp.OCSPResponseStructure; import eu.emi.security.authn.x509.helpers.ocsp.OCSPResult; import eu.emi.security.authn.x509.impl.CertificateUtils; import eu.emi.security.authn.x509.impl.CertificateUtils.Encoding; public class CacheTest { private static class MockOCSPClient extends OCSPClientImpl { public int fullQuery = 0; public int lowlevelQuery = 0; public int verifications = 0; @Override public OCSPResult queryForCertificate(URL responder, X509Certificate toCheckCert, X509Certificate issuerCert, X509Credential requester, boolean addNonce, int timeout) throws IOException, OCSPException { fullQuery++; return super.queryForCertificate(responder, toCheckCert, issuerCert, requester, addNonce, timeout); } @Override public OCSPReq createRequest(X509Certificate toCheckCert, X509Certificate issuerCert, X509Credential requester, boolean addNonce) throws OCSPException { return super.createRequest(toCheckCert, issuerCert, requester, addNonce); } @Override public OCSPResponseStructure send(URL responder, OCSPReq requestO, int timeout) throws IOException { lowlevelQuery++; return super.send(responder, requestO, timeout); } @Override public SingleResp verifyResponse(OCSPResp response, X509Certificate toCheckCert, X509Certificate issuerCert, byte[] checkNonce) throws OCSPException { verifications++; return super.verifyResponse(response, toCheckCert, issuerCert, checkNonce); } } @Test @Category(RiskyIntegrationTests.class) public void test() throws Exception { MockOCSPClient client = new MockOCSPClient(); URL responder = new URL("http://ocsp.usertrust.com"); FileInputStream fis = new FileInputStream("src/test/resources/ocsp/terena-ssl.pem"); X509Certificate toCheck = CertificateUtils.loadCertificate(fis, Encoding.PEM); fis = new FileInputStream("src/test/resources/ocsp/usertrust-ca.pem"); X509Certificate issuerCert = CertificateUtils.loadCertificate(fis, Encoding.PEM); OCSPResult result; OCSPCachingClient notCaching = new OCSPCachingClient(-1, null, null); result = notCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(1, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(1, client.verifications); result = notCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(2, client.fullQuery); assertEquals(2, client.lowlevelQuery); assertEquals(2, client.verifications); OCSPCachingClient memCaching = new OCSPCachingClient(1000, null, null); client = new MockOCSPClient(); result = memCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(1, client.verifications); result = memCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(1, client.verifications); Thread.sleep(1100); result = memCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(0, client.fullQuery); assertEquals(2, client.lowlevelQuery); assertEquals(2, client.verifications); File dir = new File("target/ocsp_cache"); FileUtils.deleteDirectory(dir); dir.mkdirs(); OCSPCachingClient diskCaching = new OCSPCachingClient(1000, dir, "ocspcache_"); client = new MockOCSPClient(); result = diskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(1, client.verifications); result = diskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(1, client.verifications); diskCaching.clearMemoryCache(); result = diskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(2, client.verifications); diskCaching.clearMemoryCache(); Thread.sleep(1100); result = diskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); assertEquals(OCSPResult.Status.good, result.getStatus()); assertEquals(0, client.fullQuery); assertEquals(2, client.lowlevelQuery); assertEquals(4, client.verifications); } @Test public void testErrorCaching() throws Exception { MockOCSPClient client = new MockOCSPClient(); URL responder = new URL("http://127.100.100.100"); FileInputStream fis = new FileInputStream("src/test/resources/ocsp/terena-ssl.pem"); X509Certificate toCheck = CertificateUtils.loadCertificate(fis, Encoding.PEM); fis = new FileInputStream("src/test/resources/ocsp/usertrust-ca.pem"); X509Certificate issuerCert = CertificateUtils.loadCertificate(fis, Encoding.PEM); File diskCache = new File("target/ocspCache"); diskCache.mkdirs(); OCSPCachingClient memAndDiskCaching = new OCSPCachingClient(1000, diskCache, "cache_"); client = new MockOCSPClient(); try { memAndDiskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); fail("Should get exception"); } catch (UnknownHostException e) { //ok } catch (ConnectException e) { //also ok } assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(0, client.verifications); try { memAndDiskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); fail("Should get exception"); } catch (UnknownHostException e) { //ok } catch (ConnectException e) { //also ok } assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(0, client.verifications); memAndDiskCaching.clearMemoryCache(); try { memAndDiskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); fail("Should get exception"); } catch (UnknownHostException e) { //ok } catch (ConnectException e) { //also ok } assertEquals(0, client.fullQuery); assertEquals(1, client.lowlevelQuery); assertEquals(0, client.verifications); Thread.sleep(1000); try { memAndDiskCaching.queryForCertificate(responder, toCheck, issuerCert, null, false, 5000, client); fail("Should get exception"); } catch (UnknownHostException e) { //ok } catch (ConnectException e) { //also ok } assertEquals(0, client.fullQuery); assertEquals(2, client.lowlevelQuery); assertEquals(0, client.verifications); FileUtils.deleteDirectory(diskCache); } }