Java tutorial
/* * $Id: PKCS10.java,v 1.3 2008/07/01 11:33:40 vtschopp Exp $ * * Created on May 30, 2006 by tschopp * * Copyright (c) Members of the EGEE Collaboration. 2004. * See http://eu-egee.org/partners/ for details on the copyright holders. * For license conditions see the license file or http://eu-egee.org/license.html */ package org.glite.slcs.pki.bouncycastle; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.StringWriter; import java.security.GeneralSecurityException; import java.security.Principal; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.openssl.PEMWriter; /** * PKCS10 wrapper class for the BouncyCastle {@link PKCS10CertificationRequest} object. * * @author Valery Tschopp <tschopp@switch.ch> * @version $Revision: 1.3 $ */ public class PKCS10 { /** Logging */ static private Log LOG = LogFactory.getLog(PKCS10.class); static { // add only once if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { LOG.info("add BouncyCastle security provider"); Security.addProvider(new BouncyCastleProvider()); } } /** Signature algorithm for the PKCS#10 request */ static public String SIGNATURE_ALGORITHM = "SHA1WithRSA"; /** BouncyCastle PKCS#10 */ private PKCS10CertificationRequest bcPKCS10_ = null; /** * * @param subject * @param publicKey * @param privateKey * @throws GeneralSecurityException */ public PKCS10(String subject, PublicKey publicKey, PrivateKey privateKey) throws GeneralSecurityException { this(subject, publicKey, privateKey, null); } /** * * @param subject * @param publicKey * @param privateKey * @param x509Extensions * @throws GeneralSecurityException */ public PKCS10(String subject, PublicKey publicKey, PrivateKey privateKey, X509Extensions x509Extensions) throws GeneralSecurityException { // subject DN X509PrincipalUtil util = new X509PrincipalUtil(); X509Principal principal = util.createX509Principal(subject); LOG.debug("X509Principal: " + principal); // extensions ASN1Set attributes = new DERSet(); if (x509Extensions != null) { // PKCS9 extensions DERSet extensions = new DERSet(x509Extensions); Attribute attribute = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extensions); attributes = new DERSet(attribute); } // create CSR bcPKCS10_ = new PKCS10CertificationRequest(SIGNATURE_ALGORITHM, principal, publicKey, attributes, privateKey); // verify if (!bcPKCS10_.verify()) { LOG.error("Failed to verify the PKCS#10"); throw new GeneralSecurityException("PKCS#10 verification failed"); } } /** * Private constructor. * * @param pkcs10 * The {@link PKCS10CertificationRequest} to wrap. * @throws GeneralSecurityException * if the {@link PKCS10CertificationRequest} can not be * verified. */ private PKCS10(PKCS10CertificationRequest pkcs10) throws GeneralSecurityException { this.bcPKCS10_ = pkcs10; if (!bcPKCS10_.verify()) { LOG.error("Failed to verify the PKCS#10"); throw new GeneralSecurityException("PKCS#10 verification failed"); } } /** * @return The DER encoded byte array. */ public byte[] getDEREncoded() { return this.bcPKCS10_.getEncoded(); } /** * @return The PEM encoded string representation. */ public String getPEMEncoded() { StringWriter sw = new StringWriter(); PEMWriter pem = new PEMWriter(sw); try { pem.writeObject(this.bcPKCS10_); } catch (IOException e) { LOG.warn("Failed to write PKCS10 in PEM format", e); return null; } finally { try { pem.close(); sw.close(); } catch (IOException e) { // ignored } } return sw.toString(); } /** * Stores the PCKS10 in PEM format. This is OpenSSL compatible. * * @param file * The file to store into. * @throws IOException */ public void storePEMEncoded(File file) throws IOException { FileWriter fw = new FileWriter(file); PEMWriter pem = new PEMWriter(fw); pem.writeObject(this.bcPKCS10_); try { pem.close(); fw.close(); } catch (IOException e) { // ignored LOG.warn(e); } } /** * Stores the DER encoded PKCS#10 in a file. * * @param file * The file to store into. * @throws IOException */ public void storeDEREncoded(File file) throws IOException { FileOutputStream fos = new FileOutputStream(file); byte derBytes[] = bcPKCS10_.getEncoded(); fos.write(derBytes); try { fos.close(); } catch (IOException e) { // ignored LOG.warn(e); } } /** * Reads the PKCS10 from a reader. This is OpenSSL compatible. * * @param reader * @return * @throws IOException * @throws GeneralSecurityException * @see java.io.Reader */ static public PKCS10 readPEMEncoded(Reader reader) throws IOException, GeneralSecurityException { PEMReader pem = new PEMReader(reader); PKCS10CertificationRequest pkcs10csr = (PKCS10CertificationRequest) pem.readObject(); try { pem.close(); } catch (IOException e) { // ignored LOG.warn(e); } PKCS10 pkcs10 = new PKCS10(pkcs10csr); return pkcs10; } /** * @return The subject DN as string. */ public String getSubject() { Principal principal = getPrincipal(); return principal.getName(); } /** * @return The subject DN as Principal */ public Principal getPrincipal() { X509Name subject = this.bcPKCS10_.getCertificationRequestInfo().getSubject(); X509Principal principal = new X509Principal(subject); return principal; } /** * Gets the X509Extensions included in the PKCS10. * * @return The X509Extensions or <code>null</code> if there is no * X509Extensions. */ public X509Extensions getX509Extensions() { X509Extensions x509Extensions = null; ASN1Set attributes = this.bcPKCS10_.getCertificationRequestInfo().getAttributes(); if (attributes.size() > 0) { ASN1Sequence attributeSequence = (ASN1Sequence) attributes.getObjectAt(0); Attribute attribute = new Attribute(attributeSequence); DERObjectIdentifier oid = attribute.getAttrType(); if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) { ASN1Set attributeValues = attribute.getAttrValues(); if (attributeValues.size() > 0) { ASN1Sequence x509extensionsSequence = (ASN1Sequence) attributeValues.getObjectAt(0); x509Extensions = new X509Extensions(x509extensionsSequence); } } } return x509Extensions; } }