dk.itst.oiosaml.security.SecurityHelper.java Source code

Java tutorial

Introduction

Here is the source code for dk.itst.oiosaml.security.SecurityHelper.java

Source

/*
 * 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 OIOSAML Java Service Provider.
 * 
 * The Initial Developer of the Original Code is Trifork A/S. Portions 
 * created by Trifork A/S are Copyright (C) 2008 Danish National IT 
 * and Telecom Agency (http://www.itst.dk). All Rights Reserved.
 * 
 * Contributor(s):
 *   Joakim Recht <jre@trifork.com>
 *   Rolf Njor Jensen <rolf@trifork.com>
 *
 */
package dk.itst.oiosaml.security;

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.KeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Date;

import org.apache.xml.security.algorithms.JCEMapper;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.util.Base64;

/**
 * Some utility methods for doing security, credential, key and JCE related tests.
 */
public class SecurityHelper {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static final String VERSION = "$Id: SecurityHelper.java 2836 2008-05-14 06:22:24Z jre $";

    private SecurityHelper() {
    }

    /**
     * Build Java certificate from base64 encoding.
     * 
     * @param base64Cert base64-encoded certificate
     * @return a native Java X509 certificate
     * @throws CertificateException thrown if there is an error constructing certificate
     */
    public static java.security.cert.X509Certificate buildJavaX509Cert(String base64Cert)
            throws CertificateException {
        CertificateFactory cf = null;
        cf = CertificateFactory.getInstance("X.509");

        ByteArrayInputStream input = new ByteArrayInputStream(Base64.decode(base64Cert));
        java.security.cert.X509Certificate newCert = null;
        newCert = (java.security.cert.X509Certificate) cf.generateCertificate(input);
        return newCert;
    }

    /**
     * Build Java CRL from base64 encoding.
     * 
     * @param base64CRL base64-encoded CRL
     * @return a native Java X509 CRL
     * @throws CertificateException thrown if there is an error constructing certificate
     * @throws CRLException  thrown if there is an error constructing CRL
     */
    public static java.security.cert.X509CRL buildJavaX509CRL(String base64CRL)
            throws CertificateException, CRLException {
        CertificateFactory cf = null;
        cf = CertificateFactory.getInstance("X.509");

        ByteArrayInputStream input = new ByteArrayInputStream(Base64.decode(base64CRL));
        java.security.cert.X509CRL newCRL = null;
        newCRL = (java.security.cert.X509CRL) cf.generateCRL(input);

        return newCRL;
    }

    /**
     * Generates a public key from the given key spec.
     * 
     * @param keySpec {@link KeySpec} specification for the key
     * @param keyAlgorithm key generation algorithm, only DSA and RSA supported
     * 
     * @return the generated {@link PublicKey}
     * 
     * @throws KeyException thrown if the key algorithm is not supported by the JCE or the key spec does not
     *             contain valid information
     */
    public static PublicKey buildKey(KeySpec keySpec, String keyAlgorithm) throws KeyException {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
            return keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new KeyException(keyAlgorithm + "algorithm is not supported by the JCE:" + e.getMessage());
        } catch (InvalidKeySpecException e) {
            throw new KeyException("Invalid key information:" + e.getMessage());
        }
    }

    /**
     * Randomly generates a Java JCE KeyPair object from the specified XML Encryption algorithm URI.
     * 
     * @param algoURI  The XML Encryption algorithm URI
     * @param keyLength  the length of key to generate
     * @return a randomly-generated KeyPair
     * @throws NoSuchProviderException  provider not found
     * @throws NoSuchAlgorithmException  algorithm not found
     */
    public static KeyPair generateKeyPairFromURI(String algoURI, int keyLength)
            throws NoSuchAlgorithmException, NoSuchProviderException {
        String jceAlgorithmName = JCEMapper.getJCEKeyAlgorithmFromURI(algoURI);
        return generateKeyPair(jceAlgorithmName, keyLength, null);
    }

    /**
     * Generate a random asymmetric key pair.
     * 
     * @param algo key algorithm
     * @param keyLength key length
     * @param provider JCA provider
     * @return randomly generated key
     * @throws NoSuchAlgorithmException algorithm not found
     * @throws NoSuchProviderException provider not found
     */
    public static KeyPair generateKeyPair(String algo, int keyLength, String provider)
            throws NoSuchAlgorithmException, NoSuchProviderException {
        KeyPair keyPair = null;
        KeyPairGenerator keyGenerator = null;
        if (provider != null) {
            keyGenerator = KeyPairGenerator.getInstance(algo, provider);
        } else {
            keyGenerator = KeyPairGenerator.getInstance(algo);
        }
        keyGenerator.initialize(keyLength);
        keyPair = keyGenerator.generateKeyPair();
        return keyPair;
    }

    public static X509Certificate generateCertificate(Credential credential, String entityId) throws Exception {
        X500Name issuer = new X500Name("o=keymanager, ou=oiosaml-sp");
        BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
        Date notBefore = new Date();
        Date notAfter = new Date(System.currentTimeMillis() + 1000L * 60L * 60L * 24L * 365L * 10L);
        X500Name subject = new X500Name("cn=" + entityId + ", ou=oiosaml-sp");

        ByteArrayInputStream bIn = new ByteArrayInputStream(credential.getPublicKey().getEncoded());
        SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(
                (ASN1Sequence) new ASN1InputStream(bIn).readObject());

        X509v3CertificateBuilder gen = new X509v3CertificateBuilder(issuer, serialNumber, notBefore, notAfter,
                subject, publicKeyInfo);

        gen.addExtension(X509Extension.subjectKeyIdentifier, false,
                new JcaX509ExtensionUtils().createSubjectKeyIdentifier(credential.getPublicKey()));
        gen.addExtension(X509Extension.authorityKeyIdentifier, false,
                new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(credential.getPublicKey()));

        ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC")
                .build(credential.getPrivateKey());
        X509CertificateHolder certificateHolder = gen.build(sigGen);

        X509Certificate x509Certificate = new JcaX509CertificateConverter().setProvider("BC")
                .getCertificate(certificateHolder);
        return x509Certificate;
    }

}