Skip to content
OcspLookup.java 6.78 KiB
Newer Older
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this
 * file except in compliance with the License. You may obtain
 * a copy of the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 *
 * The Original Code is Java RASP toolkit.
 *
 * The Initial Developer of the Original Code is Lenio. Portions
 * created by Lenio are Copyright (C) 2007 Danish National IT and
 * Telecom Agency (http://www.itst.dk). All Rights Reserved.
 *
 * Contributor(s):
 *   Tommy Dejbjerg Pedersen (tdp@lenio.dk)
 *   Hans Guldager Knudsen, Lenio
 *   Patrik Johansson (p.johansson@accenture.com)
 *   Dennis Sgaard (dennis.j.sogaard@accenture.com)
 *   Mikkel Hippe Brun (mhb@itst.dk)
 *   Finn Hartmann Jordal (fhj@itst.dk)
 *   Christian Lanng (chl@itst.dk).
 *
 */

package dk.gov.oiosi.security.ocsp;

import java.io.IOException;
import java.math.BigInteger;
import java.security.cert.X509Certificate;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.x509.AccessDescription;
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.ocsp.OCSPException;

import dk.certifikat.ocsp.client.OcspCertificateResponse;
import dk.certifikat.ocsp.client.OcspClient;
import dk.certifikat.ocsp.client.OcspRegistry;
import dk.certifikat.ocsp.client.OcspSystemException;
import dk.certifikat.ocsp.client.OcspCertificateResponse.OcspCertificateStatus;
hknudsen's avatar
hknudsen committed
import dk.gov.oiosi.configuration.ConfigurationException;
import dk.gov.oiosi.configuration.ConfigurationHandler;
import dk.gov.oiosi.exception.MainException;
import dk.gov.oiosi.security.CertificateHandlingException;
import dk.gov.oiosi.security.CertificateSubject;

/**
 * Class for checking certificate revocation status against an OCSP server.
 */
public class OcspLookup implements IOcspLookup {

	/**
	 * local log.
	 */
	private Log log = LogFactory.getLog(OcspLookup.class);

	/**
	 * OCSP configuration.
	 */
	private OcspConfig configuration;

	/**
	 * Root certificate
	 */
	private X509Certificate rootcert = null;

	/**
	 * Gets the configuration of the lookup client.
	 * 
	 * @return OCSP configuration
	 */
	public OcspConfig getConfiguration() {
		return configuration;
	}

	/**
	 * Instantiates OcspLookup and loads the OCES default root certificate.
	 * 
	 * @param conf
	 *            Configuration parameters
	 * @throws MainException
	 */
	public OcspLookup(OcspConfig conf) throws MainException {
		configuration = conf;
	}

	/**
	 * 
	 * @param conf
	 * @param rootcert
	 * @throws MainException
	 */
	public OcspLookup(OcspConfig conf, X509Certificate defaultRootCertificate)
			throws MainException {
		configuration = conf;
		rootcert = defaultRootCertificate;
	}

	/**
	 * Default constructor. Attempts to load configuration from configuration
	 * file.
	 * 
	 * @throws ConfigurationException
	 */
	public OcspLookup() throws ConfigurationException {
		configuration = ConfigurationHandler.getInstance().getOcspConfig();
	}

	/**
	 * Checks a certificate status on a ocsp server.
	 * 
	 * @param certificate
	 *            The certificate to check
	 * @return The OcspResponse object that contains the result
	 * @throws OcspException
	 */
	public OcspResponse checkCertificate(X509Certificate certificate)
			throws OcspException {
		OcspResponse response = new OcspResponse();
		OcspCertificateResponse r = null;
		OcspClient client = null;

		try {

			if (rootcert == null) {
				// get the rootcert from configurationsettings
				rootcert = configuration
						.GetDefaultOcesRootCertificateFromStore();
			}
			log.debug("Setting up OCSP client:");
			client = OcspRegistry.getOcspClient();
			
			String serverUrl;
			if (configuration.getServerUrl() == null)
			{
				// Use OCSP server specified in certificate
				serverUrl = GetServerUriFromCertificate(certificate);				
			}
			else
			{
				// Use OCSP server specified in configuration
				serverUrl = configuration.getServerUrl();
			}
						
			client.setResponderUrl(serverUrl);
			client.setCaCert(rootcert);
		} catch (CertificateHandlingException e) {
			log.error("Error handling the certificate" + e.getMessage());
			throw new OcspException(e);
		} catch (Exception e) {
			log.error("Error initailizing validator : " + e.getMessage(), e);
			throw new OcspException(e);
		}

		BigInteger[] serNos = { certificate.getSerialNumber() };
		try {
			log.warn("Getting certificate status for:" + serNos[0]);
			r = client.getCertificateStatus(serNos);
			log.debug("Validating certificate...");
			client.validateCerts(r);
		} catch (OcspSystemException e) {
			log.error("Error validating certificate : " + e.getMessage(), e);
			throw new OcspException(e);
		} catch (OCSPException e) {
			log.error("Error validating certificate : " + e.getMessage(), e);
			throw new OcspException(e);
		}

		if (r.isOk()) {
			OcspCertificateStatus status = r.getCertificateStatus(serNos[0]);
			if ("Good".equals(status.toString())) {
				log.debug("Status of cert " + certificate.getSubjectDN()
						+ " : [" + status + "]");
				response.setIsValid(true);
				response.setNextUpdate(r.getNextUpdate());
			} else {
				log.warn("Certificate validation failed " + serNos[0] + " : ["
						+ status + "]");
				throw new CertificateRevokedException(new CertificateSubject(
						certificate));
			}
		} else {
			log.error("Response returned an error: " + r.getError());
			throw new OcspException("Response returned an error: "
					+ r.getError());
		}
		log.debug("Validating X509 certificate finished.");

		return response;
	}

	public String GetServerUriFromCertificate(X509Certificate certificate)
			throws OcspException {

		try {
			byte[] ext = certificate
					.getExtensionValue(X509Extensions.AuthorityInfoAccess
							.getId());
			ASN1InputStream aIn = new ASN1InputStream(ext);
			aIn = new ASN1InputStream(((ASN1OctetString) aIn.readObject())
					.getOctets());
			ASN1Encodable object = (ASN1Encodable) aIn.readObject();
			AuthorityInformationAccess auth = AuthorityInformationAccess
					.getInstance(object);
			AccessDescription[] acc = auth.getAccessDescriptions();
			return acc[0].getAccessLocation().toString().substring(3);
		} catch (IOException e) {
			throw new OcspException(e);
		}
	}