org.nimbustools.auto_common.ezpz_ca.CAFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.nimbustools.auto_common.ezpz_ca.CAFactory.java

Source

/*
 * Copyright 1999-2008 University of Chicago
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package org.nimbustools.auto_common.ezpz_ca;

import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERInputStream;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.X509V3CertificateGenerator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;

public class CAFactory {

    private final KeyPairGenerator kpGen;
    private final X509V3CertificateGenerator certGen;

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public CAFactory() throws Exception {
        this.kpGen = KeyPairGenerator.getInstance("RSA", "BC");
        this.kpGen.initialize(1024, new SecureRandom());
        this.certGen = new X509V3CertificateGenerator();
    }

    public X509Certificate create(String baseName, int months, KeyPair keyPair) throws Exception {

        final X509Principal newprincipal = new X509Principal("O=Auto,OU=" + baseName + ",CN=CA");

        this.certGen.reset();

        /*
          "The entity that created the certificate is responsible for  assigning
          it a serial number to distinguish it from other certificates it issues.
          This information is used in numerous ways, for example when a
          certificate is revoked its serial number is placed in a Certificate
          Revocation List (CRL)"
        */
        this.certGen.setSerialNumber(BigInteger.ZERO);

        final Calendar expires = Calendar.getInstance();
        expires.add(Calendar.MONTH, months);
        this.certGen.setNotBefore(new Date(System.currentTimeMillis() - 10000));
        this.certGen.setNotAfter(expires.getTime());

        this.certGen.setSubjectDN(newprincipal);
        this.certGen.setIssuerDN(newprincipal);
        this.certGen.setSignatureAlgorithm("SHA1withRSA");

        final PublicKey pubkey = keyPair.getPublic();
        this.certGen.setPublicKey(pubkey);

        // begin X509/BC security nastiness, not sure these are the very best
        // choices but it is working...

        final ByteArrayInputStream in = new ByteArrayInputStream(pubkey.getEncoded());
        final SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo(
                (ASN1Sequence) new DERInputStream(in).readObject());
        final SubjectKeyIdentifier ski = new SubjectKeyIdentifier(spki);

        final ByteArrayInputStream in2 = new ByteArrayInputStream(newprincipal.getEncoded());
        final GeneralNames generalNames = new GeneralNames((ASN1Sequence) new DERInputStream(in2).readObject());
        final AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(spki, generalNames, BigInteger.ZERO);

        this.certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));

        /*
        this.certGen.addExtension(X509Extensions.KeyUsage,
                              true,
                              new KeyUsage(KeyUsage.digitalSignature |
                                           KeyUsage.keyEncipherment));
        */

        this.certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, ski);

        this.certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, aki);

        this.certGen.addExtension(X509Extensions.KeyUsage, false,
                new KeyUsage(KeyUsage.cRLSign | KeyUsage.keyCertSign));

        return this.certGen.generateX509Certificate(keyPair.getPrivate());
    }

    public KeyPair createNewKeyPair() {
        return this.kpGen.generateKeyPair();
    }

    /*
     * mini test
     */
    public static void main(String[] args) throws Exception {
        final CAFactory caFactory = new CAFactory();
        final X509Certificate caCert = caFactory.create("321lfn432oifno", 24, caFactory.createNewKeyPair());
        caCert.checkValidity();
        System.out.println(caCert.getSubjectDN().toString());
    }
}