Java tutorial
/* * Copyright (c) 2008-2012, 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.crl; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SignatureException; import java.security.cert.CRL; import java.security.cert.CRLException; import java.security.cert.X509CRL; import java.security.cert.X509CRLSelector; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import mitm.common.security.SecurityFactory; import mitm.common.security.SecurityFactoryFactory; import mitm.common.security.crlstore.BasicCRLStore; import mitm.common.security.crlstore.CRLStoreException; import mitm.common.util.Check; import mitm.common.util.CloseableIterator; import mitm.common.util.CloseableIteratorException; import org.apache.commons.lang.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CRLLocator { private final static Logger logger = LoggerFactory.getLogger(CRLLocator.class); private final SecurityFactory securityFactory = SecurityFactoryFactory.getSecurityFactory(); /* * Collection of CRL stores is synchronized for thread safety. */ private final Set<BasicCRLStore> crlStores = Collections.synchronizedSet(new HashSet<BasicCRLStore>()); public CRLLocator(Set<BasicCRLStore> crlStores) { Check.notNull(crlStores, "crlStores"); this.crlStores.addAll(crlStores); } public CRLLocator(BasicCRLStore... crlStores) { Check.notNull(crlStores, "crlStores"); this.crlStores.addAll(Arrays.asList(crlStores)); } /* * Filters out CRLs that should not be searched for because they are not correct or corrupt. */ private boolean acceptCRL(X509Certificate issuer, X509CRL crl) throws NoSuchProviderException { boolean accept = false; try { /* * make sure the CRL is signed by the issuer. */ crl.verify(issuer.getPublicKey(), securityFactory.getNonSensitiveProvider()); accept = true; } catch (InvalidKeyException e) { logger.error("CRL could not be verified.", e); accept = false; } catch (CRLException e) { logger.error("CRL could not be verified.", e); accept = false; } catch (NoSuchAlgorithmException e) { logger.error("CRL could not be verified.", e); accept = false; } catch (SignatureException e) { /* * This can happen if a CRL is found that is not issued by the issuer. The CRL * is found because the subject is equal to the issuer but it is not really * issued by the issuer. Can happen for example if you have multiple CAs with * the same subject */ if (logger.isDebugEnabled()) { logger.error("CRL could not be verified. Hash not correct", e); } else { logger.error("CRL could not be verified. Hash not correct. Message: " + ExceptionUtils.getRootCauseMessage(e)); } accept = false; } return accept; } /* * Returns a list of all the CRLs issued by the issuer */ public List<X509CRL> findCRLs(X509Certificate issuer) throws NoSuchProviderException { List<X509CRL> crls = new LinkedList<X509CRL>(); X509CRLSelector crlSelector = new X509CRLSelector(); crlSelector.addIssuer(issuer.getSubjectX500Principal()); /* * step through all the stores and get all the relevant CRLs from the stores */ for (BasicCRLStore store : crlStores) { try { CloseableIterator<? extends CRL> crlIterator = store.getCRLIterator(crlSelector); try { while (crlIterator.hasNext()) { CRL crl = crlIterator.next(); if (!(crl instanceof X509CRL)) { logger.warn("Only X509CRLs are supported. Skipping this CRL."); continue; } X509CRL x509CRL = (X509CRL) crl; if (acceptCRL(issuer, x509CRL)) { crls.add(x509CRL); } } } finally { crlIterator.close(); } } catch (CRLStoreException e) { /* * log and continue search * */ logger.error("Error getting CRLs. Skipping this store.", e); continue; } catch (CloseableIteratorException e) { /* * log and continue search */ logger.error("Error stepping through the CRL store. Skipping this store.", e); continue; } } return crls; } }