Example usage for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers pkcs_9_at_friendlyName

List of usage examples for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers pkcs_9_at_friendlyName

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers pkcs_9_at_friendlyName.

Prototype

ASN1ObjectIdentifier pkcs_9_at_friendlyName

To view the source code for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers pkcs_9_at_friendlyName.

Click Source Link

Document

PKCS#9: 1.2.840.113549.1.9.20

Usage

From source file:org.openmaji.implementation.security.utility.cert.CertUtil.java

License:Open Source License

/**
 * Creates a lower level certificate, adding authority key-id and subject
  * key-id extensions to the resulting certificate (version 3).
 * /*w w  w . ja va 2  s.c  om*/
 * @param pubKey
 * @param serialNumber
 * @param name
 * @param notBefore
 * @param notAfter
 * @param signatureAlgorithm
 * @param issuerPrivKey
 * @param issuerCert
 * @param friendlyName
 * @return X509Certificate
 * @throws Exception
 */
public static X509Certificate createCert(PublicKey pubKey, BigInteger serialNumber, String name, Date notBefore,
        Date notAfter, String signatureAlgorithm, PrivateKey issuerPrivKey, X509Certificate issuerCert,
        String friendlyName) throws Exception {
    byte[] nameBytes = new X500Principal(name).getEncoded();

    //
    // create the certificate - version 3
    //
    v3CertGen.reset();

    v3CertGen.setSerialNumber(serialNumber);
    v3CertGen.setIssuerDN(new X509Principal(issuerCert.getSubjectX500Principal().getEncoded()));
    v3CertGen.setNotBefore(notBefore);
    v3CertGen.setNotAfter(notAfter);
    v3CertGen.setSubjectDN(new X509Principal(nameBytes));
    v3CertGen.setPublicKey(pubKey);
    v3CertGen.setSignatureAlgorithm(signatureAlgorithm);

    //
    // add the extensions
    //
    v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, createSubjectKeyId(pubKey));

    v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
            createAuthorityKeyId(issuerCert.getPublicKey(),
                    new X509Principal(issuerCert.getSubjectX500Principal().getEncoded()), serialNumber));

    v3CertGen.addExtension(X509Extensions.BasicConstraints, false, new BasicConstraints(false));

    v3CertGen.addExtension(MiscObjectIdentifiers.netscapeCertType, false,
            new NetscapeCertType(NetscapeCertType.sslServer | NetscapeCertType.sslClient
                    | NetscapeCertType.objectSigning | NetscapeCertType.smime));

    X509Certificate cert = v3CertGen.generateX509Certificate(issuerPrivKey);

    if (friendlyName != null) {
        PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;

        bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString(friendlyName));
        bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, createSubjectKeyId(pubKey));
    }

    return cert;
}

From source file:org.openuat.channel.X509CertificateGenerator.java

License:Open Source License

/** This method implements the public one, but offers an additional parameter which is only used when
 * creating a new CA, namely the export alias to use.
 * @param commonName @see #createCertificate(String, int, String, String)
 * @param validityDays @see #createCertificate(String, int, String, String)
 * @param exportFile @see #createCertificate(String, int, String, String)
 * @param exportPassword @see #createCertificate(String, int, String, String)
 * @param exportAlias If this additional parameter is null, a default value will be used as the "friendly name" in the PKCS12 file.
 * @return @see #createCertificate(String, int, String, String)
 * //from   www. j  a  v  a  2  s  .  c  o  m
 * @see #X509CertificateGenerator(boolean)
 */
protected boolean createCertificate(String commonName, int validityDays, String exportFile,
        String exportPassword, String exportAlias) throws IOException, InvalidKeyException, SecurityException,
        SignatureException, NoSuchAlgorithmException, DataLengthException, CryptoException, KeyStoreException,
        CertificateException, InvalidKeySpecException {
    if (commonName == null || exportFile == null || exportPassword == null || validityDays < 1) {
        throw new IllegalArgumentException("Can not work with null parameter");
    }

    logger.info("Generating certificate for distinguished common subject name '" + commonName + "', valid for "
            + validityDays + " days");
    SecureRandom sr = new SecureRandom();

    // the JCE representation
    PublicKey pubKey;
    PrivateKey privKey;

    // the BCAPI representation
    RSAPrivateCrtKeyParameters privateKey = null;

    logger.debug("Creating RSA keypair");
    // generate the keypair for the new certificate
    if (useBCAPI) {
        RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
        // TODO: what are these values??
        gen.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), sr, 1024, 80));
        AsymmetricCipherKeyPair keypair = gen.generateKeyPair();
        logger.debug("Generated keypair, extracting components and creating public structure for certificate");
        RSAKeyParameters publicKey = (RSAKeyParameters) keypair.getPublic();
        privateKey = (RSAPrivateCrtKeyParameters) keypair.getPrivate();
        // used to get proper encoding for the certificate
        RSAPublicKeyStructure pkStruct = new RSAPublicKeyStructure(publicKey.getModulus(),
                publicKey.getExponent());
        logger.debug("New public key is '" + new String(Hex.encodeHex(pkStruct.getEncoded())) + ", exponent="
                + publicKey.getExponent() + ", modulus=" + publicKey.getModulus());
        // TODO: these two lines should go away
        // JCE format needed for the certificate - because getEncoded() is necessary...
        pubKey = KeyFactory.getInstance("RSA")
                .generatePublic(new RSAPublicKeySpec(publicKey.getModulus(), publicKey.getExponent()));
        // and this one for the KeyStore
        privKey = KeyFactory.getInstance("RSA")
                .generatePrivate(new RSAPrivateCrtKeySpec(publicKey.getModulus(), publicKey.getExponent(),
                        privateKey.getExponent(), privateKey.getP(), privateKey.getQ(), privateKey.getDP(),
                        privateKey.getDQ(), privateKey.getQInv()));
    } else {
        // this is the JSSE way of key generation
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024, sr);
        KeyPair keypair = keyGen.generateKeyPair();
        privKey = keypair.getPrivate();
        pubKey = keypair.getPublic();
    }

    Calendar expiry = Calendar.getInstance();
    expiry.add(Calendar.DAY_OF_YEAR, validityDays);

    X509Name x509Name = new X509Name("CN=" + commonName);

    V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator();
    certGen.setSerialNumber(new DERInteger(BigInteger.valueOf(System.currentTimeMillis())));
    if (caCert != null) {
        // Attention: this is a catch! Just using "new X509Name(caCert.getSubjectDN().getName())" will not work!
        // I don't know why, because the issuerDN strings look similar with both versions.
        certGen.setIssuer(PrincipalUtil.getSubjectX509Principal(caCert));
    } else {
        // aha, no CA set, which means that we should create a self-signed certificate (called from createCA)
        certGen.setIssuer(x509Name);
    }
    certGen.setSubject(x509Name);
    DERObjectIdentifier sigOID = X509Util.getAlgorithmOID(CertificateSignatureAlgorithm);
    AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID, new DERNull());
    certGen.setSignature(sigAlgId);
    //certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo(sigAlgId, pkStruct.toASN1Object()));
    // TODO: why does the coding above not work? - make me work without PublicKey class
    certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo(
            (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(pubKey.getEncoded())).readObject()));
    certGen.setStartDate(new Time(new Date(System.currentTimeMillis())));
    certGen.setEndDate(new Time(expiry.getTime()));

    // These X509v3 extensions are not strictly necessary, but be nice and provide them...
    Hashtable extensions = new Hashtable();
    Vector extOrdering = new Vector();
    addExtensionHelper(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey),
            extOrdering, extensions);
    if (caCert != null) {
        // again: only if we have set CA
        addExtensionHelper(X509Extensions.AuthorityKeyIdentifier, false,
                new AuthorityKeyIdentifierStructure(caCert), extOrdering, extensions);
    } else {
        // but if we create a new self-signed cert, set its capability to be a CA
        // this is a critical extension (true)!
        addExtensionHelper(X509Extensions.BasicConstraints, true, new BasicConstraints(0), extOrdering,
                extensions);
    }
    certGen.setExtensions(new X509Extensions(extOrdering, extensions));

    logger.debug("Certificate structure generated, creating SHA1 digest");
    // attention: hard coded to be SHA1+RSA!
    SHA1Digest digester = new SHA1Digest();
    AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine());
    TBSCertificateStructure tbsCert = certGen.generateTBSCertificate();

    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    DEROutputStream dOut = new DEROutputStream(bOut);
    dOut.writeObject(tbsCert);

    // and now sign
    byte[] signature;
    if (useBCAPI) {
        byte[] certBlock = bOut.toByteArray();
        // first create digest
        logger.debug("Block to sign is '" + new String(Hex.encodeHex(certBlock)) + "'");
        digester.update(certBlock, 0, certBlock.length);
        byte[] hash = new byte[digester.getDigestSize()];
        digester.doFinal(hash, 0);
        // and sign that
        if (caCert != null) {
            rsa.init(true, caPrivateKey);
        } else {
            // no CA - self sign
            logger.info("No CA has been set, creating self-signed certificate as a new CA");
            rsa.init(true, privateKey);
        }
        DigestInfo dInfo = new DigestInfo(new AlgorithmIdentifier(X509ObjectIdentifiers.id_SHA1, null), hash);
        byte[] digest = dInfo.getEncoded(ASN1Encodable.DER);
        signature = rsa.processBlock(digest, 0, digest.length);
    } else {
        // or the JCE way
        Signature sig = Signature.getInstance(sigOID.getId());
        if (caCert != null) {
            PrivateKey caPrivKey = KeyFactory.getInstance("RSA")
                    .generatePrivate(new RSAPrivateCrtKeySpec(caPrivateKey.getModulus(),
                            caPrivateKey.getPublicExponent(), caPrivateKey.getExponent(), caPrivateKey.getP(),
                            caPrivateKey.getQ(), caPrivateKey.getDP(), caPrivateKey.getDQ(),
                            caPrivateKey.getQInv()));
            sig.initSign(caPrivKey, sr);
        } else {
            logger.info("No CA has been set, creating self-signed certificate as a new CA");
            sig.initSign(privKey, sr);
        }
        sig.update(bOut.toByteArray());
        signature = sig.sign();
    }
    logger.debug("SHA1/RSA signature of digest is '" + new String(Hex.encodeHex(signature)) + "'");

    // and finally construct the certificate structure
    ASN1EncodableVector v = new ASN1EncodableVector();

    v.add(tbsCert);
    v.add(sigAlgId);
    v.add(new DERBitString(signature));

    X509CertificateObject clientCert = new X509CertificateObject(
            new X509CertificateStructure(new DERSequence(v)));
    logger.debug("Verifying certificate for correct signature with CA public key");
    /*        if (caCert != null) {
               clientCert.verify(caCert.getPublicKey());
            }
            else {
               clientCert.verify(pubKey);
            }*/

    // and export as PKCS12 formatted file along with the private key and the CA certificate 
    logger.debug("Exporting certificate in PKCS12 format");

    PKCS12BagAttributeCarrier bagCert = clientCert;
    // if exportAlias is set, use that, otherwise a default name
    bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
            new DERBMPString(exportAlias == null ? CertificateExportFriendlyName : exportAlias));
    bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
            new SubjectKeyIdentifierStructure(pubKey));

    // this does not work as in the example
    /*PKCS12BagAttributeCarrier   bagKey = (PKCS12BagAttributeCarrier)privKey;
    bagKey.setBagAttribute(
    PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
    new SubjectKeyIdentifierStructure(tmpKey));*/

    Object store;
    if (!useBCAPI) {
        store = java.security.KeyStore.getInstance("PKCS12");
        ((java.security.KeyStore) store).load(null, null);
    } else {
        store = new JDKPKCS12KeyStore(null, sigOID, sigOID);
        ((JDKPKCS12KeyStore) store).engineLoad(null, null);
    }

    FileOutputStream fOut = new FileOutputStream(exportFile);
    X509Certificate[] chain;

    if (caCert != null) {
        chain = new X509Certificate[2];
        // first the client, then the CA certificate - this is the expected order for a certificate chain
        chain[0] = clientCert;
        chain[1] = caCert;
    } else {
        // for a self-signed certificate, there is no chain...
        chain = new X509Certificate[1];
        chain[0] = clientCert;
    }

    if (!useBCAPI) {
        ((java.security.KeyStore) store).setKeyEntry(exportAlias == null ? KeyExportFriendlyName : exportAlias,
                privKey, exportPassword.toCharArray(), chain);
        ((java.security.KeyStore) store).store(fOut, exportPassword.toCharArray());
    } else {
        ((JDKPKCS12KeyStore) store).engineSetKeyEntry(exportAlias == null ? KeyExportFriendlyName : exportAlias,
                privKey, exportPassword.toCharArray(), chain);
        ((JDKPKCS12KeyStore) store).engineStore(fOut, exportPassword.toCharArray());
    }

    return true;
}