net.ripe.rpki.commons.crypto.util.BouncyCastleUtil.java Source code

Java tutorial

Introduction

Here is the source code for net.ripe.rpki.commons.crypto.util.BouncyCastleUtil.java

Source

/**
 * The BSD License
 *
 * Copyright (c) 2010-2012 RIPE NCC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   - Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   - Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *   - Neither the name of the RIPE NCC nor the names of its contributors may be
 *     used to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package net.ripe.rpki.commons.crypto.util;

import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSSignedDataParser;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import org.bouncycastle.util.Selector;
import org.bouncycastle.util.StoreException;

import javax.security.auth.x500.X500Principal;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public final class BouncyCastleUtil {

    public static final DigestCalculatorProvider DIGEST_CALCULATOR_PROVIDER = new BcDigestCalculatorProvider();

    private BouncyCastleUtil() {
    }

    public static final class X509CRLHolderStoreSelector implements Selector {
        @Override
        public boolean match(Object obj) {
            return obj instanceof X509CRLHolder;
        }

        @Override
        public Object clone() {
            return this;
        }
    }

    public static final class X509CertificateHolderStoreSelector implements Selector {
        @Override
        public boolean match(Object obj) {
            return obj instanceof X509CertificateHolder;
        }

        @Override
        public Object clone() {
            return this;
        }
    }

    /**
     * NOTE: JcaX509ExtensionUtils is not tread safe.
     * We always need to get a new instance of it.
     *
     * @return a new instance of JcaX509ExtensionUtils
     */
    private static JcaX509ExtensionUtils newJcaX509ExtensionUtils() {
        try {
            return new JcaX509ExtensionUtils();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    public static AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey publicKey) {
        return newJcaX509ExtensionUtils().createAuthorityKeyIdentifier(publicKey);
    }

    public static SubjectKeyIdentifier createSubjectKeyIdentifier(PublicKey publicKey) {
        return newJcaX509ExtensionUtils().createSubjectKeyIdentifier(publicKey);
    }

    public static X500Name principalToName(X500Principal dn) {
        return X500Name.getInstance(dn.getEncoded());
    }

    public static SubjectPublicKeyInfo createSubjectPublicKeyInfo(PublicKey key) {
        return SubjectPublicKeyInfo.getInstance(key.getEncoded());
    }

    public static X509Certificate holderToCertificate(X509CertificateHolder holder) throws CertificateException {
        return new JcaX509CertificateConverter().getCertificate(holder);
    }

    public static List<? extends X509Certificate> extractCertificates(CMSSignedDataParser signedDataParser)
            throws StoreException, CMSException, CertificateException {
        @SuppressWarnings("unchecked")
        Collection<X509CertificateHolder> holders = signedDataParser.getCertificates()
                .getMatches(new X509CertificateHolderStoreSelector());
        List<X509Certificate> result = new ArrayList<X509Certificate>();
        for (X509CertificateHolder holder : holders) {
            result.add(holderToCertificate(holder));
        }
        return result;
    }

    public static X509CRL holderToCrl(X509CRLHolder holder) throws CRLException {
        return new JcaX509CRLConverter().getCRL(holder);
    }

    public static List<? extends X509CRL> extractCrls(CMSSignedDataParser signedDataParser)
            throws StoreException, CMSException, CRLException {
        @SuppressWarnings("unchecked")
        Collection<X509CRLHolder> holders = signedDataParser.getCRLs().getMatches(new X509CRLHolderStoreSelector());
        List<X509CRL> result = new ArrayList<X509CRL>();
        for (X509CRLHolder holder : holders) {
            result.add(holderToCrl(holder));
        }
        return result;
    }
}