org.signserver.validationservice.server.ValidationTestUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.signserver.validationservice.server.ValidationTestUtils.java

Source

/*************************************************************************
 *                                                                       *
 *  SignServer: The OpenSource Automated Signing Server                  *
 *                                                                       *
 *  This software 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 any later version.                    *
 *                                                                       *
 *  See terms of license at gnu.org.                                     *
 *                                                                       *
 *************************************************************************/
package org.signserver.validationservice.server;

import java.io.IOException;
import java.math.BigInteger;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.CRLException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.CRLNumber;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.jce.X509KeyUsage;
import org.bouncycastle.x509.X509V2CRLGenerator;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.ejbca.core.model.ca.caadmin.IllegalKeyStoreException;
import org.ejbca.core.model.ca.catoken.CATokenOfflineException;
import org.ejbca.core.model.ca.crl.RevokedCertInfo;
import org.ejbca.util.Base64;
import org.ejbca.util.CertTools;

/**
 * Contains help methods for testing the validation service
 * 
 * 
 * @author Philip Vendil 30 nov 2007
 *
 * @version $Id: ValidationTestUtils.java 3580 2013-06-25 12:55:18Z netmackan $
 */
public class ValidationTestUtils {

    public static X509Certificate genCert(String dn, String issuerdn, PrivateKey privKey, PublicKey pubKey,
            Date startDate, Date endDate, boolean isCA) throws CertificateEncodingException, InvalidKeyException,
            IllegalStateException, NoSuchAlgorithmException, SignatureException {
        return genCert(dn, issuerdn, privKey, pubKey, startDate, endDate, isCA, 0);
    }

    public static X509Certificate genCert(String dn, String issuerdn, PrivateKey privKey, PublicKey pubKey,
            Date startDate, Date endDate, boolean isCA, int keyUsage) throws CertificateEncodingException,
            InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, SignatureException {
        return genCert(dn, issuerdn, privKey, pubKey, startDate, endDate, isCA, keyUsage, null);
    }

    public static X509Certificate genCert(String dn, String issuerdn, PrivateKey privKey, PublicKey pubKey,
            Date startDate, Date endDate, boolean isCA, int keyUsage, CRLDistPoint crlDistPoint)
            throws CertificateEncodingException, InvalidKeyException, IllegalStateException,
            NoSuchAlgorithmException, SignatureException {
        X509V3CertificateGenerator certgen = new X509V3CertificateGenerator();

        byte[] serno = new byte[8];
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed((new Date().getTime()));
        random.nextBytes(serno);
        certgen.setSerialNumber((new java.math.BigInteger(serno)).abs());
        certgen.setNotBefore(startDate);
        certgen.setNotAfter(endDate);
        certgen.setSignatureAlgorithm("SHA1WithRSA");
        certgen.setSubjectDN(CertTools.stringToBcX509Name(dn));
        certgen.setIssuerDN(CertTools.stringToBcX509Name(issuerdn));
        certgen.setPublicKey(pubKey);

        // CRL Distribution point
        if (crlDistPoint != null) {
            certgen.addExtension(X509Extensions.CRLDistributionPoints, false, crlDistPoint);
        }

        // Basic constranits is always critical and MUST be present at-least in CA-certificates.
        BasicConstraints bc = new BasicConstraints(isCA);
        certgen.addExtension(X509Extensions.BasicConstraints.getId(), true, bc);

        // Put critical KeyUsage in CA-certificates
        if (keyUsage == 0) {
            if (isCA == true) {
                int keyusage = X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign;
                X509KeyUsage ku = new X509KeyUsage(keyusage);
                certgen.addExtension(X509Extensions.KeyUsage.getId(), true, ku);
            }
        } else {
            X509KeyUsage ku = new X509KeyUsage(keyUsage);
            certgen.addExtension(X509Extensions.KeyUsage.getId(), true, ku);
        }
        X509Certificate cert = certgen.generate(privKey);

        return cert;
    }

    public static String genPEMStringFromChain(List<X509Certificate> chain) throws CertificateEncodingException {
        String beginKey = "\n-----BEGIN CERTIFICATE-----\n";
        String endKey = "\n-----END CERTIFICATE-----\n";
        String retval = "";
        for (X509Certificate cert : chain) {
            retval += beginKey;
            retval += new String(Base64.encode(cert.getEncoded(), true));
            retval += endKey;
        }

        return retval;
    }

    public static X509CRL genCRL(X509Certificate cacert, PrivateKey privKey, DistributionPoint dp,
            Collection<RevokedCertInfo> certs, int crlPeriod, int crlnumber)
            throws CATokenOfflineException, IllegalKeyStoreException, IOException, SignatureException,
            NoSuchProviderException, InvalidKeyException, CRLException, NoSuchAlgorithmException {
        final String sigAlg = "SHA1WithRSA";

        boolean crlDistributionPointOnCrlCritical = true;
        boolean crlNumberCritical = false;

        Date thisUpdate = new Date();
        Date nextUpdate = new Date();

        // crlperiod is hours = crlperiod*60*60*1000 milliseconds
        nextUpdate.setTime(nextUpdate.getTime() + (crlPeriod * (long) (60 * 60 * 1000)));
        X509V2CRLGenerator crlgen = new X509V2CRLGenerator();
        crlgen.setThisUpdate(thisUpdate);
        crlgen.setNextUpdate(nextUpdate);
        crlgen.setSignatureAlgorithm(sigAlg);

        CRLNumber crlnum = new CRLNumber(BigInteger.valueOf(crlnumber));
        crlgen.addExtension(X509Extensions.CRLNumber.getId(), crlNumberCritical, crlnum);

        // Make DNs
        crlgen.setIssuerDN(cacert.getSubjectX500Principal());

        if (certs != null) {
            Iterator<RevokedCertInfo> it = certs.iterator();
            while (it.hasNext()) {
                RevokedCertInfo certinfo = it.next();
                crlgen.addCRLEntry(certinfo.getUserCertificate(), certinfo.getRevocationDate(),
                        certinfo.getReason());
            }
        }

        // CRL Distribution point URI         
        IssuingDistributionPoint idp = new IssuingDistributionPoint(dp.getDistributionPoint(), false, false, null,
                false, false);

        // According to the RFC, IDP must be a critical extension.
        // Nonetheless, at the moment, Mozilla is not able to correctly
        // handle the IDP extension and discards the CRL if it is critical.
        crlgen.addExtension(X509Extensions.IssuingDistributionPoint.getId(), crlDistributionPointOnCrlCritical,
                idp);

        X509CRL crl;
        crl = crlgen.generate(privKey, "BC");
        // Verify before sending back
        crl.verify(cacert.getPublicKey());

        return crl;
    }

    public static CRLDistPoint generateDistPointWithUrl(URL cdpUrl) {
        GeneralName gn = new GeneralName(GeneralName.uniformResourceIdentifier,
                new DERIA5String(cdpUrl.toExternalForm()));
        GeneralNames gns = new GeneralNames(gn);
        DistributionPointName dpn = new DistributionPointName(0, gns);
        return new CRLDistPoint(new DistributionPoint[] { new DistributionPoint(dpn, null, null) });
    }

    public static CRLDistPoint generateDistPointWithIssuer(String issuer) {
        GeneralName gn = new GeneralName(new X509Name(issuer));
        GeneralNames gns = new GeneralNames(gn);
        DistributionPointName dpn = new DistributionPointName(0, gns);
        return new CRLDistPoint(new DistributionPoint[] { new DistributionPoint(dpn, null, null) });
    }
}