it.zero11.acme.utils.X509Utils.java Source code

Java tutorial

Introduction

Here is the source code for it.zero11.acme.utils.X509Utils.java

Source

/**
 * Copyright (C) 2015 Zero11 S.r.l.
 *
 * 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 it.zero11.acme.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.AccessDescription;
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;

public class X509Utils {
    public static final String DEFAULT_ALGHORITM = "RSA";

    public static PKCS10CertificationRequest generateCSR(String[] commonNames, KeyPair pair)
            throws OperatorCreationException, IOException {
        X500NameBuilder namebuilder = new X500NameBuilder(X500Name.getDefaultStyle());
        namebuilder.addRDN(BCStyle.CN, commonNames[0]);

        List<GeneralName> subjectAltNames = new ArrayList<>(commonNames.length);
        for (String cn : commonNames)
            subjectAltNames.add(new GeneralName(GeneralName.dNSName, cn));
        GeneralNames subjectAltName = new GeneralNames(subjectAltNames.toArray(new GeneralName[0]));

        ExtensionsGenerator extGen = new ExtensionsGenerator();
        extGen.addExtension(Extension.subjectAlternativeName, false, subjectAltName.toASN1Primitive());

        PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(namebuilder.build(),
                pair.getPublic());
        p10Builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());
        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
        ContentSigner signer = csBuilder.build(pair.getPrivate());
        PKCS10CertificationRequest request = p10Builder.build(signer);
        return request;
    }

    public static KeyPair generateKeyPair(int size) throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(DEFAULT_ALGHORITM);
        keyGen.initialize(size);
        return keyGen.generateKeyPair();
    }

    public static KeyPair loadPEMKeyPair(InputStream privateKeyInputStream) throws IOException {
        try (PEMParser pemParser = new PEMParser(new InputStreamReader(privateKeyInputStream))) {
            PEMKeyPair keyPair = (PEMKeyPair) pemParser.readObject();
            return new JcaPEMKeyConverter().getKeyPair(keyPair);
        }
    }

    public static void savePEM(OutputStream outputStream, Object object) throws IOException {
        try (JcaPEMWriter writer = new JcaPEMWriter(new PrintWriter(outputStream))) {
            writer.writeObject(object);
        }
    }

    public static String getCACertificateURL(X509Certificate certificate) throws IOException {
        byte[] bOctets = ((ASN1OctetString) ASN1Primitive
                .fromByteArray(certificate.getExtensionValue(Extension.authorityInfoAccess.getId()))).getOctets();
        AuthorityInformationAccess access = AuthorityInformationAccess
                .getInstance(ASN1Sequence.fromByteArray(bOctets));
        for (AccessDescription ad : access.getAccessDescriptions()) {
            if (ad.getAccessMethod().equals(X509ObjectIdentifiers.id_ad_caIssuers)) {
                return ad.getAccessLocation().getName().toString();
            }
        }
        return null;
    }
}