Java tutorial
/* * Copyright (c) 2008-2011, Martijn Brinkers, Djigzo. * * This file is part of Djigzo email encryption. * * Djigzo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License * version 3, 19 November 2007 as published by the Free Software * Foundation. * * Djigzo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with Djigzo. If not, see <http://www.gnu.org/licenses/> * * Additional permission under GNU AGPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, * wsdl4j-1.6.1.jar (or modified versions of these libraries), * containing parts covered by the terms of Eclipse Public License, * tyrex license, freemarker license, dom4j license, mx4j license, * Spice Software License, Common Development and Distribution License * (CDDL), Common Public License (CPL) the licensors of this Program grant * you additional permission to convey the resulting work. */ package mitm.common.security.certpath; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.security.NoSuchProviderException; import java.security.cert.CertPathBuilderResult; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.TrustAnchor; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Set; import mitm.common.hibernate.HibernateSessionSource; import mitm.common.hibernate.SessionManager; import mitm.common.hibernate.SessionManagerImpl; import mitm.common.hibernate.StandardHibernateSessionSourceImpl; import mitm.common.security.bouncycastle.InitializeBouncycastle; import mitm.common.security.certificate.CertificateUtils; import mitm.common.security.certstore.X509CertStoreExt; import mitm.common.security.certstore.hibernate.X509CertStoreExtAutoCommitFactory; import mitm.common.security.certstore.hibernate.X509CertStoreExtHibernate; import mitm.common.security.certstore.jce.X509CertStoreParameters; import mitm.common.security.crlstore.X509CRLStoreExt; import mitm.common.security.crlstore.hibernate.X509CRLStoreExtAutoCommitFactory; import mitm.common.security.provider.MITMProvider; import mitm.common.util.BigIntegerUtils; import mitm.common.util.CloseableIterator; import mitm.test.TestUtils; import org.apache.commons.lang.time.DateUtils; import org.apache.log4j.PropertyConfigurator; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class CertPathBuilderSpeedTest { private static final File hibernateConfig = new File("test/resources/hibernate.cfg.xml"); private static HibernateSessionSource sessionSource; private static SessionManager sessionManager; private static CertStore certStore; private static X509CertStoreParameters certStoreParams; private static X509CertStoreParameters rootStoreParams; @BeforeClass public static void setUpBeforeClass() throws Exception { PropertyConfigurator.configure("conf/log4j.properties"); InitializeBouncycastle.initialize(); sessionSource = new StandardHibernateSessionSourceImpl(hibernateConfig); sessionManager = new SessionManagerImpl(sessionSource); MITMProvider.initialize(sessionManager); certStoreParams = new X509CertStoreParameters( new X509CertStoreExtAutoCommitFactory(sessionSource, "certificates").create(), new X509CRLStoreExtAutoCommitFactory(sessionSource, "certificates").create()); certStore = CertStore.getInstance(MITMProvider.DATABASE_CERTSTORE, certStoreParams, "mitm"); rootStoreParams = new X509CertStoreParameters( new X509CertStoreExtAutoCommitFactory(sessionSource, "roots").create()); } @Before public void setup() throws Exception { importCertificatesAndCRLs(); } private static void addCRL(String filename, X509CRLStoreExt crlStore) throws Exception { File crlFile = new File("test/resources/testdata/crls", filename); X509CRL crl = TestUtils.loadX509CRL(crlFile); if (!crlStore.contains(crl)) { crlStore.addCRL(crl); } } /* * Test if flush/clear improves import and it does. Don't know why the fastest setting is * when flush/clear is done every iteration */ private static void addCertificatesBulk(String filename, String storeName) throws CertificateException, NoSuchProviderException, CertStoreException, IOException { File file = new File("test/resources/testdata/certificates", filename); Collection<? extends Certificate> certificates = CertificateUtils.readCertificates(file); int i = 0; Session session = sessionSource.newSession(); sessionManager.setSession(session); X509CertStoreExt certStore = new X509CertStoreExtHibernate(storeName, sessionManager); Transaction tx = session.beginTransaction(); try { for (Certificate certificate : certificates) { if (i % 1 == 0) { session.flush(); session.clear(); } if (i % 100 == 0) { tx.commit(); tx = session.beginTransaction(); } if (certificate instanceof X509Certificate) { if (!certStore.contains((X509Certificate) certificate)) { certStore.addCertificate((X509Certificate) certificate); } } i++; } tx.commit(); } finally { sessionSource.closeSession(session); } } private long getCertStoreSize(String storeName) { Session session = sessionSource.newSession(); sessionManager.setSession(session); X509CertStoreExt certStore = new X509CertStoreExtHibernate(storeName, sessionManager); Transaction tx = session.beginTransaction(); try { tx.commit(); return certStore.size(); } finally { sessionSource.closeSession(session); } } private void clearCertStore(String storeName) throws CertStoreException { Session session = sessionSource.newSession(); sessionManager.setSession(session); X509CertStoreExt certStore = new X509CertStoreExtHibernate(storeName, sessionManager); Transaction tx = session.beginTransaction(); try { certStore.removeAllEntries(); tx.commit(); } finally { sessionSource.closeSession(session); } } private void importCertificatesAndCRLs() throws Exception { clearCertStore("roots"); clearCertStore("certificates"); // add roots addCertificatesBulk("windows-xp-all-roots.p7b", "roots"); addCertificatesBulk("mitm-test-root.cer", "roots"); long start = System.currentTimeMillis(); long certStoreSize = getCertStoreSize("certificates"); addCertificatesBulk("random-self-signed-1000.p7b", "certificates"); //addCertificatesBulk("random-self-signed-10000.p7b", "certificates"); //addCertificatesBulk("random-self-signed-40000.p7b", "certificates"); long imported = getCertStoreSize("certificates") - certStoreSize; assertEquals(1000, imported); long diff = System.currentTimeMillis() - start; double timePerCertificate = diff * 0.001 / imported; System.out.println("Import seconds/certificate : " + timePerCertificate); if (timePerCertificate > 0.02) { /*************************************************** * Note: This might fail on slower systems!! ***************************************************/ fail("Import seconds/certificate too slow. Note: This might fail on slower systems!!!"); } addCertificatesBulk("mitm-test-ca.cer", "certificates"); addCertificatesBulk("testCertificates.p7b", "certificates"); addCRL("test-ca.crl", certStoreParams.getCRLStore()); addCRL("test-root-ca-not-revoked.crl", certStoreParams.getCRLStore()); } @Test public void testLoadCertificates() throws Exception { long start = System.currentTimeMillis(); X509CertSelector selector = new X509CertSelector(); CloseableIterator<X509Certificate> it = certStoreParams.getCertStore().getCertificateIterator(selector); int i = 0; while (it.hasNext()) { X509Certificate certificate = it.next(); assertNotNull(certificate); i++; if (i == 10000) { break; } } // close it again (should not be a problem); it.close(); assertTrue(it.isClosed()); // close it again (should not be a problem); it.close(); double secondsPerCertificate = ((System.currentTimeMillis() - start) * 0.001 / i); System.out.println("Total certificates: " + i + ". seconds / certificate: " + secondsPerCertificate); if (secondsPerCertificate > 9E-4) { /*************************************************** * Note: This might fail on slower systems!! ***************************************************/ fail("Seconds / certificate too slow. Note: This might fail on slower systems!!!"); } } /* * Test path building for a certificate with critical extended key usage containing EMAILPROTECTION when * SMIMEExtendedKeyUsageCertPathChecker is added to the path checkers */ @Test public void testBuildPathManyCertificates() throws Exception { int tries = 1000; TrustAnchorBuilder trustAnchorBuilder = new CertStoreTrustAnchorBuilder(rootStoreParams.getCertStore(), 10 * DateUtils.MILLIS_PER_SECOND); long start = System.currentTimeMillis(); Set<TrustAnchor> trustAnchors = trustAnchorBuilder.getTrustAnchors(); for (int i = 0; i < tries; i++) { X509CertSelector selector = new X509CertSelector(); selector.setSerialNumber(BigIntegerUtils.hexDecode("116A448F117FF69FE4F2D4D38F689D7")); selector.setIssuer("EMAILADDRESS=ca@example.com, CN=MITM Test CA, L=Amsterdam, ST=NH, C=NL"); CertificatePathBuilder builder = new PKIXCertificatePathBuilder(); //Set<TrustAnchor> trustAnchors = trustAnchorBuilder.getTrustAnchors(); trustAnchors = trustAnchorBuilder.getTrustAnchors(); builder.setTrustAnchors(trustAnchors); builder.addCertPathChecker(new SMIMEExtendedKeyUsageCertPathChecker()); builder.addCertStore(certStore); builder.setRevocationEnabled(false); CertPathBuilderResult result = builder.buildPath(selector); assertEquals(2, result.getCertPath().getCertificates().size()); } long diff = System.currentTimeMillis() - start; double secondsPerBuild = diff * 0.001 / tries; System.out.println("Seconds / build: " + secondsPerBuild); if (secondsPerBuild > 0.03) { /*************************************************** * Note: This might fail on slower systems!! ***************************************************/ fail("Seconds / build too slow. Note: This might fail on slower systems!!!"); } } }