Java tutorial
/* * ==================================================================== * This file is part of the ebXML Registry by Icar Cnr v3.2 * ("eRICv32" in the following disclaimer). * * "eRICv32" is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * "eRICv32" is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License Version 3 * along with "eRICv32". If not, see <http://www.gnu.org/licenses/>. * * eRICv32 is a forked, derivative work, based on: * - freebXML Registry, a royalty-free, open source implementation of the ebXML Registry standard, * which was published under the "freebxml License, Version 1.1"; * - ebXML OMAR v3.2 Edition, published under the GNU GPL v3 by S. Krushe & P. Arwanitis. * * All derivative software changes and additions are made under * * Copyright (C) 2013 Ing. Antonio Messina <messina@pa.icar.cnr.it> * * This software consists of voluntary contributions made by many * individuals on behalf of the freebxml Software Foundation. For more * information on the freebxml Software Foundation, please see * "http://www.freebxml.org/". * * This product includes software developed by the Apache Software * Foundation (http://www.apache.org/). * * ==================================================================== */ package it.cnr.icar.eric.common.security; import it.cnr.icar.eric.common.CommonResourceBundle; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.security.Provider; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Iterator; import javax.xml.registry.JAXRException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A helper class for X509 Certificates. * * @author Diego Ballve / Digital Artefacts Europe */ public class X509Parser { private static final Log log = LogFactory.getLog(X509Parser.class); /** * Parses a X509Certificate from a DER formatted input stream. Uses the * BouncyCastle provider if available. * * @param inStream The DER InputStream with the certificate. * @return X509Certificate parsed from stream. * @throws JAXRException in case of IOException or CertificateException * while parsing the stream. */ public static X509Certificate parseX509Certificate(InputStream inStream) throws JAXRException { try { //possible options // - der x509 generated by keytool -export // - der x509 generated by openssh x509 (might require BC provider) // Get the CertificateFactory to parse the stream // if BouncyCastle provider available, use it CertificateFactory cf; try { Class<?> clazz = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider"); Constructor<?> constructor = clazz.getConstructor(new Class[] {}); Provider bcProvider = (Provider) constructor.newInstance(new Object[] {}); Security.addProvider(bcProvider); cf = CertificateFactory.getInstance("X.509", "BC"); } catch (Exception e) { // log error if bc present but failed to instanciate/add provider if (!(e instanceof ClassNotFoundException)) { log.error(CommonResourceBundle.getInstance() .getString("message.FailedToInstantiateBouncyCastleProvider")); } // fall back to default provider cf = CertificateFactory.getInstance("X.509"); } // Read the stream to a local variable DataInputStream dis = new DataInputStream(inStream); byte[] bytes = new byte[dis.available()]; dis.readFully(bytes); ByteArrayInputStream certStream = new ByteArrayInputStream(bytes); // Parse the cert stream int i = 0; Collection<? extends Certificate> c = cf.generateCertificates(certStream); X509Certificate[] certs = new X509Certificate[c.toArray().length]; for (Iterator<? extends Certificate> it = c.iterator(); it.hasNext();) { certs[i++] = (X509Certificate) it.next(); } // Some logging.. if (log.isDebugEnabled()) { if (c.size() == 1) { log.debug("One certificate, no chain."); } else { log.debug("Certificate chain length: " + c.size()); } log.debug("Subject DN: " + certs[0].getSubjectDN().getName()); log.debug("Issuer DN: " + certs[0].getIssuerDN().getName()); } // Do we need to return the chain? // do we need to verify if cert is self signed / valid? return certs[0]; } catch (CertificateException e) { String msg = CommonResourceBundle.getInstance().getString("message.parseX509CertificateStreamFailed", new Object[] { e.getClass().getName(), e.getMessage() }); throw new JAXRException(msg, e); } catch (IOException e) { String msg = CommonResourceBundle.getInstance().getString("message.parseX509CertificateStreamFailed", new Object[] { e.getClass().getName(), e.getMessage() }); throw new JAXRException(msg, e); } finally { try { inStream.close(); } catch (IOException e) { inStream = null; } } } }