com.axway.ebxml.KeyInfoWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.axway.ebxml.KeyInfoWriter.java

Source

/**
* Copyright 2010 Axway Inc
*
* 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 com.axway.ebxml;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;

import javax.xml.parsers.ParserConfigurationException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileOutputStream;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Utility for building the ds:KeyInfo Element to include within the Certificate Element of an
 * ebXML CPP or CPA version 2.
 * (see <a href="http://www.oasis-open.org/committees/ebxml-cppa/documents/ebcpp-2.0.pdf">ebXML Collaboration-Protocol Profile and Agreement Specification version 2 )
 */
public class KeyInfoWriter {
    private static Log logger = LogFactory.getLog(KeyInfoWriter.class);

    private static KeyInfoWriter keyInfoWriter;

    private KeyInfoWriter() {
        org.apache.xml.security.Init.init();
    }

    /**
     * Get the singleton instance of the <link>KeyInfoWriter</link>
     * @return <link>KeyInfoWriter</link> instance
     */
    public static synchronized KeyInfoWriter getInstance() {
        if (keyInfoWriter == null)
            keyInfoWriter = new KeyInfoWriter();

        return keyInfoWriter;
    }

    /**
     * Builds <code>KeyInfo</code> instance given an array of <code>X509Certificate</code>. The
     * <code>KeyInfo</code> can be serialized and used within the Certificate element of an ebXML CPP or CPA
     * @param certs Array of certificates to include. The certificates in the array must be related in a certificate chain
     *      The first certificate in the array must be the end-entity certificate.
     * @return Initialized <code>KeyInfo</code> ready to be serialized
     * @throws IllegalArgumentException Null or Empty certificate list is passed as parameter
     * @throws KeyInfoWriterException Thrown when there is any other error encountered. The <code>KeyInfoWriterException</code>
     *  may wrap other exceptions caught within this method.
     */
    public KeyInfo buildKeyInfo(X509Certificate[] certs) throws KeyInfoWriterException {
        if (certs == null || certs.length == 0)
            throw new IllegalArgumentException("cert is null or empty");

        try {
            org.w3c.dom.Document doc = XmlUtil.buildDocument();

            KeyInfo keyInfo = new KeyInfo(doc);
            X509Data x509Data;
            for (X509Certificate cert : certs) {
                if (cert == certs[0]) // Only add KeyInfo for the first certificate in the chain (the end entity certificate)
                    keyInfo.add(cert.getPublicKey());
                x509Data = buildX509Data(doc, cert); // Add X509Data elements for all the certificates in the chain
                keyInfo.add(x509Data);
            }

            doc.appendChild(keyInfo.getElement());
            return keyInfo;
        } catch (ParserConfigurationException e) {
            logger.error("Exception writing KeyInfo", e);
            throw new KeyInfoWriterException(e);
        } catch (XMLSecurityException e) {
            logger.error("Exception writing KeyInfo", e);
            throw new KeyInfoWriterException(e);
        }
    }

    /**
     * Builds the X509Data element sub-element of the KeyInfo element
     * @param doc Containing document to create the element for. Cannot be null.
     * @param cert <code>X509Certificate</code> to create the <code>X509Data</code> element for. Cannot be null.
     * @return Populated <code>X509Data</code>
     * @throws XMLSecurityException
     */
    private X509Data buildX509Data(org.w3c.dom.Document doc, X509Certificate cert) throws XMLSecurityException {
        X509Data x509Data;
        x509Data = new X509Data(doc);
        x509Data.addIssuerSerial(cert.getIssuerDN().getName(), cert.getSerialNumber());
        x509Data.addSubjectName(cert);
        x509Data.addCertificate(cert);
        return x509Data;
    }

    /**
     * Loads the certificate (or certificate chain) from <code>certificatePath</code> builds the KeyInfo element
     * and writes the resulting XML to the path specified by <code>outputPath</code>
     * @param certificatePath Path to the certificate to build the KeyInfo element for. The certificate can be p7b encoded
     * or DER encoded.
     * @param outputPath Path/Filename to write the KeyInfo element into. Null indicates System.out
     * @throws KeyInfoWriterException Thrown if there is any error in loading the certificate, creating the KeyInfo element or
     * serializing the result.
     */
    public void writeKeyInfo(String certificatePath, String outputPath) throws KeyInfoWriterException {
        try {
            logger.info("Loading certificate " + certificatePath);
            X509Certificate[] certificates = new CertificateChain(certificatePath).getCertificates();
            KeyInfo keyInfo = buildKeyInfo(certificates);
            logger.info("Writing KeyInfo to " + (outputPath == null ? "System.out" : outputPath));
            FileOutputStream stream = outputPath == null ? null : new FileOutputStream(outputPath);
            XmlUtil.writeTo(keyInfo.getDocument(), stream);
        } catch (FileNotFoundException e) {
            logger.error("Exception writing KeyInfo", e);
            throw new KeyInfoWriterException(e);
        } catch (CertificateException e) {
            logger.error("Exception writing KeyInfo", e);
            throw new KeyInfoWriterException(e);
        } catch (IOException e) {
            logger.error("Exception writing KeyInfo", e);
            throw new KeyInfoWriterException(e);
        }
    }

    /**
     * Runs the KeyInfoWriter Utility
     * @param args Usage: java com.axway.ebxml.KeyInfoWriter certificatePath [outputFilePath]. If the outputFilePath
     * parameter is not included the resulting KeyInfo element XML will be written to System.out
     */
    public static void main(String[] args) {
        if (args.length != 1 && args.length != 2) {
            System.out.println("Usage: java com.axway.ebxml.KeyInfoWriter certificatePath [outputFilePath]");
            return;
        }

        try {
            String certificatePath = args[0];
            String outputFilePath = args.length == 1 ? null : args[1];
            KeyInfoWriter writer = KeyInfoWriter.getInstance();
            writer.writeKeyInfo(certificatePath, outputFilePath);
        } catch (Exception e) {
            logger.error(e);
            e.printStackTrace();
        }
    }
}