/*
* Hamsam - Instant Messaging API
* Copyright (C) 2003 Raghu K
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package hamsam.util.net.ssl;
import hamsam.util.log.LogManager;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* A helper class to find out whether one particular CA is trusted or not.
*
* @author Raghu
*/
class TrustedCAs
{
/**
* Single instance of this class.
*/
private static TrustedCAs instance = null;
/**
* Mapping from a trusted CA's name to its public key
*/
private ArrayList rootcas;
/**
* Constructor prevents instantiation.
*/
private TrustedCAs()
{
this.rootcas = new ArrayList();
}
/**
* Get an instance of this class.
*
* @return an instance of this class.
* @throws ClassNotFoundException
*/
public static synchronized TrustedCAs getInstance()
{
if(instance == null) {
Logger logger = LogManager.getLogger();
logger.logp(Level.CONFIG, "hamsam.util.net.ssl.trustedCAs", "getInstance", "Loading trusted root CA certificates from ca-list.dat");
instance = new TrustedCAs();
try {
ClassLoader cl = ClassLoader.getSystemClassLoader();
InputStream in = cl.getResourceAsStream("hamsam/util/net/ssl/ca-list.dat");
ZipInputStream zin = new ZipInputStream(in);
ZipEntry entry = zin.getNextEntry();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while(entry != null) {
X509Certificate cert = (X509Certificate)cf.generateCertificate(zin);
logger.logp(Level.CONFIG, "hamsam.util.net.ssl.trustedCAs", "getInstance", "Added certificate: " + cert);
instance.rootcas.add(cert);
entry = zin.getNextEntry();
}
zin.close();
logger.logp(Level.CONFIG, "hamsam.util.net.ssl.trustedCAs", "getInstance", "Load completed successfully");
} catch(CertificateException e) {
logger.logp(Level.WARNING, "hamsam.util.net.ssl.trustedCAs", "getInstance", "Cannot load root certificate", e);
} catch(IOException e) {
logger.logp(Level.WARNING, "hamsam.util.net.ssl.trustedCAs", "getInstance", "Cannot load root certificate", e);
}
}
return instance;
}
public void validate(X509Certificate cert) throws CertificateException
{
Logger logger = LogManager.getLogger();
logger.logp(Level.CONFIG, "hamsam.util.net.ssl.trustedCAs", "validate", "Checking validy of certificate: " + cert);
if(cert == null)
throw new CertificateException("Invalid root certificate");
if(!this.rootcas.contains(cert)) {
Iterator itr = rootcas.iterator();
while(itr.hasNext()) {
X509Certificate root = (X509Certificate) itr.next();
try {
cert.verify(root.getPublicKey());
} catch(CertificateException e) {
continue;
} catch(GeneralSecurityException e) {
continue;
}
logger.logp(Level.CONFIG, "hamsam.util.net.ssl.trustedCAs", "validate", "Certificate is trusted");
return;
}
logger.logp(Level.CONFIG, "hamsam.util.net.ssl.trustedCAs", "validate", "Certificate is untrusted");
throw new CertificateException("Untrusted CA");
}
logger.logp(Level.CONFIG, "hamsam.util.net.ssl.trustedCAs", "validate", "Certificate is trusted");
}
}