Skip to content
OcspLookup.java 9.17 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
 *   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.math.BigInteger;
import java.security.cert.X509Certificate;

import javax.security.auth.Subject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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;
import dk.gov.oiosi.configuration.RaspConfigurationHandler;
import dk.gov.oiosi.exception.MainException;
import dk.gov.oiosi.security.CertificateSubject;

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

    private Log log = LogFactory.getLog(OcspLookup.class);
    private static String  TEST_CA_CERT_NAME = "ocestestca2.cer";
    private static String  CA_CERT_NAME = "ocesca.cer";

    
    OcspConfig _configuration;
    X509Certificate _defaultOcesRootCertificate;

    /// <summary>
    /// Gets the configuration of the lookup client
    /// </summary>
    public OcspConfig getConfiguration() {
        return _configuration; 
    }

    /// <summary>
    /// To be able to call the CheckCertificate method asynchron, we create a delegate.
    /// </summary>
    /// <param name="certificate">the certificate to check</param>
    /// <returns>the OcSpResponse object to store the result</returns>
    //public delegate OcspResponse AsyncOcspCall(X509Certificate2 certificate);

    private void init(OcspConfig configuration) throws MainException {
        /*
        try {
            // TODO: review exception handling, perform validation checks
            // 1. Set configuration
            _configuration = configuration;

            // 2. Get default certificate:
            _defaultOcesRootCertificate = _configuration.GetDefaultOcesRootCertificateFromStore();
        } catch (UriFormatException) {
            throw;
        } catch (ArgumentNullException) {
            throw;
        } catch (OverflowException) {
            throw;
        } catch (FormatException) {
            throw;
        } catch (CryptographicUnexpectedOperationException) {
            throw;
        } catch (CryptographicException) {
            throw;
        } catch (Exception) {
            throw;
        }
        */
    }

    /// <summary>
    /// Instantiates OcspLookup and loads the OCES default root certificate
    /// </summary>
    /// <param name="configuration">Configuration parameters</param>
    public OcspLookup(OcspConfig configuration) throws MainException {
        // init(configuration);
        _configuration = configuration;
    }

    /// <summary>
    /// Default constructor. Attempts to load configuration from configuration file.
    /// </summary>
    public OcspLookup() throws Exception {
        //OcspConfig configuration = RaspConfigurationHandler.GetConfigurationSection<OcspConfig>();
        OcspConfig configuration = RaspConfigurationHandler.getInstance().getOcspConfig();
        //init(configuration);
        _configuration = configuration;

    }

    /// <summary>
    /// Checks a certificate status on a ocsp server
    /// </summary>
    /// <param name="certificate">The certificate to check</param>
    /// <returns>The OcspResponse object that contains the result</returns>
    /// <exception cref="CheckCertificateOcspUnexpectedException">This exception is thrown, if an unexpected exception is thrown during the method</exception>
 /*
    private OcspResponse checkCertificateCall(X509Certificate certificate) {
        OcspResponse response = new OcspResponse();

        try {
            //1. instantiate ocsp library
            OcspClient ocsp = new OcspClient(_defaultOcesRootCertificate.RawData);

            //2. make binary request

            //converts hexadecimal to decimal
            uint uiHex = new uint();
            byte[] req = null;
            if (certificate != null) {
                uiHex = System.Convert.ToUInt32(certificate.SerialNumber, 16);
                req = ocsp.MakeOcspRequest(uiHex.ToString());

                //3. send request
                byte[] resp = ocsp.Send(req, _configuration.ServerUrl.ToString());

                //4. check result
                if (ocsp.GetValidSerials(resp).Contains(uiHex.ToString())) {
                    response.IsValid = true;
                }
            } else {
                throw new CheckCertificateOcspUnexpectedException();
            }
        } catch (ArgumentNullException) {
            throw;
        } catch (OverflowException) {
            throw;
        } catch (FormatException) {
            throw;
        } catch (CryptographicUnexpectedOperationException) {
            throw;
        } catch (CryptographicException) {
            throw;
        } catch (Exception e) {
            throw new CheckCertificateOcspUnexpectedException(e);
        }
        return response;
    }
*/
    /// <summary>
    /// Checks a certificate status on a ocsp server
    /// </summary>
    /// <param name="certificate">The certificate to check</param>
    /// <returns>The OcspResponse object that contains the result</returns>
    /// <exception cref="CheckCertificateOcspUnexpectedException">This exception is thrown, if an unexpected exception is thrown during the method</exception>
    public OcspResponse checkCertificate(X509Certificate certificate) throws OcspException, MainException {
        //To call the CheckCertificate asynchronously, we initialize the delegate and call it with IAsyncResult

        System.out.println("OCSP CHECK : " + certificate.getSerialNumber() + " : " + certificate.getSubjectDN() + " : " + certificate.getIssuerDN() );
        OcspResponse response = new OcspResponse();
        OcspCertificateResponse r = null;
        OcspClient client = null;
        try {
            log.debug("Setting up OCSP client:");
            client = OcspRegistry.getOcspClient();
            String serverUrl = _configuration.getServerUrl();
            client.setResponderUrl(serverUrl);
            if( serverUrl.indexOf("test") > 0 ) {
                log.warn("OCSP using Test server");
                client.setCaCertInClassPath(TEST_CA_CERT_NAME);
            } else {
                log.debug("OCSP using production server");
                client.setCaCertInClassPath(CA_CERT_NAME);
            }

        } 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.getSubjectDN() ) );
            }
        } 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;
    }
}