/* * This file is part of the OWASP Proxy, a free intercepting proxy library. * Copyright (C) 2008-2010 Rogan Dawes <rogan@dawes.za.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to: * The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.owasp.proxy.util; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Vector; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; @SuppressWarnings("deprecation") public class BouncyCastleCertificateUtils { private static final String SIGALG = "SHA256WithRSAEncryption"; public static X509Certificate sign(X500Principal subject, PublicKey pubKey, X500Principal issuer, PublicKey caPubKey, PrivateKey caKey, Date begin, Date ends, BigInteger serialNo) throws GeneralSecurityException { try { // X500Name issuerName = new X500Name(issuer.getName()); // X500Name subjectName = new X500Name(subject.getName()); // AlgorithmIdentifier algId = new // AlgorithmIdentifier(pubKey.getAlgorithm()); // SubjectPublicKeyInfo publicKeyInfo = new // SubjectPublicKeyInfo(algId, pubKey.getEncoded()); // // X509v1CertificateBuilder certBuilder = new // X509v1CertificateBuilder(issuerName, serialNo, begin, ends, // subjectName, publicKeyInfo); // ContentSigner cs = new // JcaContentSignerBuilder(SIGALG).setProvider("BC").build(caKey); // X509CertificateHolder holder = certBuilder.build(cs); // Certificate bcCert = holder.toASN1Structure(); // bcCert.get // X509V1CertificateGenerator certGen = new // X509V1CertificateGenerator(); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(serialNo); certGen.setIssuerDN(issuer); certGen.setNotBefore(begin); certGen.setNotAfter(ends); certGen.setSubjectDN(subject); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm(SIGALG); // add Extensions if (subject == issuer) { addCACertificateExtensions(certGen); } else { addCertificateExtensions(pubKey, caPubKey, certGen); } X509Certificate cert = certGen.generate(caKey, "BC"); // note: // private // key of CA return cert; } catch (Exception e) { e.printStackTrace(); throw new CertificateEncodingException("generate: " + e.getMessage(), e); } } private static void addCACertificateExtensions( X509V3CertificateGenerator certGen) throws IOException { // Basic Constraints certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(0)); } private static void addCertificateExtensions(PublicKey pubKey, PublicKey caPubKey, X509V3CertificateGenerator certGen) throws IOException, InvalidKeyException { // CertificateExtensions ext = new CertificateExtensions(); // // ext.set(SubjectKeyIdentifierExtension.NAME, // new SubjectKeyIdentifierExtension(new KeyIdentifier(pubKey) // .getIdentifier())); certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey)); // // ext.set(AuthorityKeyIdentifierExtension.NAME, // new AuthorityKeyIdentifierExtension( // new KeyIdentifier(caPubKey), null, null)); // certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caPubKey)); // // Basic Constraints // ext.set(BasicConstraintsExtension.NAME, new // BasicConstraintsExtension( // /* isCritical */true, /* isCA */false, /* pathLen */5)); // certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false)); // Netscape Cert Type Extension // boolean[] ncteOk = new boolean[8]; // ncteOk[0] = true; // SSL_CLIENT // ncteOk[1] = true; // SSL_SERVER // NetscapeCertTypeExtension ncte = new // NetscapeCertTypeExtension(ncteOk); // ncte = new NetscapeCertTypeExtension(false, // ncte.getExtensionValue()); // ext.set(NetscapeCertTypeExtension.NAME, ncte); // Key Usage Extension // boolean[] kueOk = new boolean[9]; // kueOk[0] = true; // kueOk[2] = true; // "digitalSignature", // (0), // "nonRepudiation", // (1) // "keyEncipherment", // (2), // "dataEncipherment", // (3), // "keyAgreement", // (4), // "keyCertSign", // (5), // "cRLSign", // (6), // "encipherOnly", // (7), // "decipherOnly", // (8) // "contentCommitment" // also (1) // KeyUsageExtension kue = new KeyUsageExtension(kueOk); // ext.set(KeyUsageExtension.NAME, kue); certGen.addExtension(X509Extensions.KeyUsage, true, new X509KeyUsage( X509KeyUsage.digitalSignature + X509KeyUsage.keyEncipherment)); // Extended Key Usage Extension // int[] serverAuthOidData = { 1, 3, 6, 1, 5, 5, 7, 3, 1 }; // ObjectIdentifier serverAuthOid = new // ObjectIdentifier(serverAuthOidData); // int[] clientAuthOidData = { 1, 3, 6, 1, 5, 5, 7, 3, 2 }; // ObjectIdentifier clientAuthOid = new // ObjectIdentifier(clientAuthOidData); // Vector<ObjectIdentifier> v = new Vector<ObjectIdentifier>(); // v.add(serverAuthOid); // v.add(clientAuthOid); // ExtendedKeyUsageExtension ekue = new ExtendedKeyUsageExtension(false, // v); // ext.set(ExtendedKeyUsageExtension.NAME, ekue); // ExtendedKeyUsage extendedKeyUsage = new // ExtendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage); Vector<KeyPurposeId> usages = new Vector<KeyPurposeId>(); usages.add(KeyPurposeId.id_kp_serverAuth); usages.add(KeyPurposeId.id_kp_clientAuth); certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(usages)); } }