Example usage for org.bouncycastle.asn1.x509 GeneralNames fromExtensions

List of usage examples for org.bouncycastle.asn1.x509 GeneralNames fromExtensions

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x509 GeneralNames fromExtensions.

Prototype

public static GeneralNames fromExtensions(Extensions extensions, ASN1ObjectIdentifier extOID) 

Source Link

Usage

From source file:com.yahoo.athenz.auth.util.Crypto.java

License:Apache License

public static String extractX509CSREmail(PKCS10CertificationRequest certReq) {

    String rfc822 = null;//from  w  ww  . jav a2 s.  c o m
    Attribute[] attributes = certReq.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
    for (Attribute attribute : attributes) {
        for (ASN1Encodable value : attribute.getAttributeValues()) {
            Extensions extensions = Extensions.getInstance(value);
            GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName);
            for (GeneralName name : gns.getNames()) {
                if (name.getTagNo() == GeneralName.rfc822Name) {
                    rfc822 = (((DERIA5String) name.getName()).getString());
                    break;
                }
            }
        }
    }
    return rfc822;
}

From source file:com.yahoo.athenz.auth.util.Crypto.java

License:Apache License

public static List<String> extractX509CSRDnsNames(PKCS10CertificationRequest certReq) {

    List<String> dnsNames = new ArrayList<>();
    Attribute[] attributes = certReq.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
    for (Attribute attribute : attributes) {
        for (ASN1Encodable value : attribute.getAttributeValues()) {
            Extensions extensions = Extensions.getInstance(value);
            GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName);
            for (GeneralName name : gns.getNames()) {
                if (name.getTagNo() == GeneralName.dNSName) {
                    dnsNames.add(((DERIA5String) name.getName()).getString());
                }/*from www .ja  v  a 2  s  .  c  o m*/
            }
        }
    }
    return dnsNames;
}

From source file:com.yahoo.athenz.auth.util.Crypto.java

License:Apache License

public static List<String> extractX509CSRIPAddresses(PKCS10CertificationRequest certReq) {

    List<String> ipAddresses = new ArrayList<>();
    Attribute[] attributes = certReq.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
    for (Attribute attribute : attributes) {
        for (ASN1Encodable value : attribute.getAttributeValues()) {
            Extensions extensions = Extensions.getInstance(value);
            GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName);
            for (GeneralName name : gns.getNames()) {
                if (name.getTagNo() == GeneralName.iPAddress) {
                    try {
                        InetAddress addr = InetAddress
                                .getByAddress(((DEROctetString) name.getName()).getOctets());
                        ipAddresses.add(addr.getHostAddress());
                    } catch (UnknownHostException e) {
                    }/*w w  w.j ava 2 s  . c  o  m*/
                }
            }
        }
    }
    return ipAddresses;
}

From source file:com.yahoo.athenz.auth.util.Crypto.java

License:Apache License

public static X509Certificate generateX509Certificate(PKCS10CertificationRequest certReq,
        PrivateKey caPrivateKey, X500Name issuer, int validityTimeout, boolean basicConstraints) {

    // set validity for the given number of minutes from now

    Date notBefore = new Date();
    Calendar cal = Calendar.getInstance();
    cal.setTime(notBefore);/*from  ww w .  j a  va 2 s  .  com*/
    cal.add(Calendar.MINUTE, validityTimeout);
    Date notAfter = cal.getTime();

    // Generate self-signed certificate

    X509Certificate cert = null;
    try {
        JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = new JcaPKCS10CertificationRequest(
                certReq);
        PublicKey publicKey = jcaPKCS10CertificationRequest.getPublicKey();

        X509v3CertificateBuilder caBuilder = new JcaX509v3CertificateBuilder(issuer,
                BigInteger.valueOf(System.currentTimeMillis()), notBefore, notAfter, certReq.getSubject(),
                publicKey)
                        .addExtension(Extension.basicConstraints, false, new BasicConstraints(basicConstraints))
                        .addExtension(Extension.keyUsage, true,
                                new X509KeyUsage(X509KeyUsage.digitalSignature | X509KeyUsage.keyEncipherment))
                        .addExtension(Extension.extendedKeyUsage, true,
                                new ExtendedKeyUsage(new KeyPurposeId[] { KeyPurposeId.id_kp_clientAuth,
                                        KeyPurposeId.id_kp_serverAuth }));

        // see if we have the dns/rfc822/ip address extensions specified in the csr

        ArrayList<GeneralName> altNames = new ArrayList<>();
        Attribute[] certAttributes = jcaPKCS10CertificationRequest
                .getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
        if (certAttributes != null && certAttributes.length > 0) {
            for (Attribute attribute : certAttributes) {
                Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));
                GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName);
                if (gns == null) {
                    continue;
                }
                GeneralName[] names = gns.getNames();
                for (int i = 0; i < names.length; i++) {
                    switch (names[i].getTagNo()) {
                    case GeneralName.dNSName:
                    case GeneralName.iPAddress:
                    case GeneralName.rfc822Name:
                        altNames.add(names[i]);
                        break;
                    }
                }
            }
            if (!altNames.isEmpty()) {
                caBuilder.addExtension(Extension.subjectAlternativeName, false,
                        new GeneralNames(altNames.toArray(new GeneralName[altNames.size()])));
            }
        }

        String signatureAlgorithm = getSignatureAlgorithm(caPrivateKey.getAlgorithm(), SHA256);
        ContentSigner caSigner = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BC_PROVIDER)
                .build(caPrivateKey);

        JcaX509CertificateConverter converter = new JcaX509CertificateConverter().setProvider(BC_PROVIDER);
        cert = converter.getCertificate(caBuilder.build(caSigner));

    } catch (CertificateException ex) {
        LOG.error("generateX509Certificate: Caught CertificateException when generating certificate: "
                + ex.getMessage());
        throw new CryptoException(ex);
    } catch (OperatorCreationException ex) {
        LOG.error(
                "generateX509Certificate: Caught OperatorCreationException when creating JcaContentSignerBuilder: "
                        + ex.getMessage());
        throw new CryptoException(ex);
    } catch (InvalidKeyException ex) {
        LOG.error("generateX509Certificate: Caught InvalidKeySpecException, invalid key spec is being used: "
                + ex.getMessage());
        throw new CryptoException(ex);
    } catch (NoSuchAlgorithmException ex) {
        LOG.error(
                "generateX509Certificate: Caught NoSuchAlgorithmException, check to make sure the algorithm is supported by the provider: "
                        + ex.getMessage());
        throw new CryptoException(ex);
    } catch (Exception ex) {
        LOG.error("generateX509Certificate: unable to generate X509 Certificate: " + ex.getMessage());
        throw new CryptoException("Unable to generate X509 Certificate");
    }

    return cert;
}

From source file:edu.nps.moves.mmowgli.CACManager.java

License:Open Source License

private static void parseCert(String cert, CACData data) {
    cert = cert.replace(' ', '\r');
    cert = cert.replace("BEGIN\rCERTIFICATE", "BEGIN CERTIFICATE");
    cert = cert.replace("END\rCERTIFICATE", "END CERTIFICATE");
    PEMParser pr = new PEMParser(new StringReader(cert));
    try {//from w  w w.j  a  v a2  s.com
        Object o = pr.readObject();
        pr.close();
        if (o instanceof X509CertificateHolder) {
            X509CertificateHolder x509 = (X509CertificateHolder) o;
            X500Name x500name = x509.getSubject();
            RDN cnRdns[] = x500name.getRDNs(BCStyle.CN);

            String cn = IETFUtils.valueToString(cnRdns[0].getFirst().getValue());
            parseCN(cn, data);

            GeneralNames gns = GeneralNames.fromExtensions(x509.getExtensions(),
                    Extension.subjectAlternativeName);
            if (gns != null) {
                GeneralName[] subjectAltNames = gns.getNames();
                for (GeneralName gn : subjectAltNames) {
                    if (gn.getTagNo() == GeneralName.rfc822Name) { // check for email
                        String s = DERIA5String.getInstance(gn.getName()).getString();
                        if (s.contains("@")) {
                            data.userEmail = s;
                            break;
                        }
                    }
                }
            }

            // Create the unique card identifier (issuer+serial) which when hashed goes into the database for quick login
            String uniqueCertId = x509.getIssuer().toString() + " " + x509.getSerialNumber().toString();

            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(uniqueCertId.getBytes("UTF-8")); // or UTF-16
            byte[] digest = md.digest();
            data.cacId = Hex.encodeHexString(digest);

            /* Alternatively, this will do a salted hash, but the output is not the same for the same input; better security
             * but the login performance would be bad since the user list has to be polled instead of indexed
             try {
               data.cacId = PasswordHash.createHash(uniqueCertId);
             }
             catch(Exception ex) {
               MSysOut.println(MmowgliConstants.SYSTEM_LOGS,"Program error, could not create CAC hash; auto-login disabled");
               data.cacId = null;
             }
             System.out.println("data cacId: "+data.cacId); */

        }
    } catch (IOException | NoSuchAlgorithmException ex) {
        MSysOut.println(MmowgliConstants.SYSTEM_LOGS,
                ex.getClass().getSimpleName() + ": Program error, could not parse CAC");
        data.cacId = null;
        data.isCACPresent = false;
    }

    // Some informational stuff
    /* this gives same info as the x509 methods below  
         RDN rdns[] = x500name.getRDNs();
         for(RDN rdn : rdns) {
            AttributeTypeAndValue[] tandV = rdn.getTypesAndValues();
            for(AttributeTypeAndValue tv : tandV) {
     System.out.println(tv.getType());
     System.out.println(IETFUtils.valueToString(tv.getType()));
     System.out.println(tv.getValue());
     System.out.println(IETFUtils.valueToString(tv.getValue()));
            }
         }
         */
    /*
    System.out.println("X509 version: "+x509.getVersionNumber());
    System.out.println("X509 Serial num: "+x509.getSerialNumber());
    System.out.println("X509 Sig algo: "+x509.getSignatureAlgorithm().getAlgorithm().toASN1Primitive());
    System.out.println("X509 Issuer: "+x509.getIssuer());
    System.out.println("X509 Not before: "+x509.getNotBefore());
    System.out.println("X509 Not after: "+x509.getNotAfter());
    System.out.println("X509 Subject: "+x509.getSubject());
    System.out.println("X509 Subject Public Key Info: "+x509.getSubjectPublicKeyInfo().getAlgorithm().getAlgorithm());
    */
    /* 
     System.out.println("CriticalExtensionOIDs: ");
     Set<?> set = x509.getCriticalExtensionOIDs();
     Iterator<?> itr = set.iterator();
     while(itr.hasNext()) {
       ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)itr.next();
       System.out.println(oid.toString()+" : "+x509.getExtension(oid).getParsedValue());
     }
               
     System.out.println("NonCriticalExtensionOIDs: ");
     set = x509.getNonCriticalExtensionOIDs();
     itr = set.iterator();
     while(itr.hasNext()) {
       ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)itr.next();
       System.out.println(oid.toString()+" : "+x509.getExtension(oid).getParsedValue());
     }
             
     System.out.println("Other api: getExtensionOIDs");
     List<?> lis = x509.getExtensionOIDs();
     itr = lis.iterator();
     while(itr.hasNext()) {
       ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)itr.next();
       System.out.println(oid.toString()+" : "+x509.getExtension(oid).getParsedValue());
     }
            
     System.out.println("From the extensions \"block\"");
     Extensions exts = x509.getExtensions();
     ASN1ObjectIdentifier[] ids = exts.getExtensionOIDs();
     for(ASN1ObjectIdentifier oid : ids) {
       org.bouncycastle.asn1.x509.Extension ext = exts.getExtension(oid);
       System.out.println(oid.toString()+": "+IETFUtils.valueToString(ext.getParsedValue()));
     }
    //     */
}

From source file:eu.betaas.taas.securitymanager.authentication.service.impl.GWEcmqvExtService.java

License:Apache License

public EcmqvMessage initEcmqv(byte[] ephPubX, byte[] ephPubY, byte[] certByte) {
    // decode the certificate
    X509CertificateHolder cert = null;/*  ww  w.j ava 2  s  .  c  o m*/
    try {
        cert = new X509CertificateHolder(certByte);
    } catch (IOException e1) {
        log.error("Error in decoding the submitted certificate!!");
        e1.printStackTrace();
    }

    // validate the certificate
    boolean isCertValid = false;

    try {
        isCertValid = validateCert(cert);
    } catch (Exception e) {
        log.error("Error in verifying the submitted certificate: " + e.getMessage());
        e.printStackTrace();
    }

    if (!isCertValid) {
        log.error("The submitted certificate is not valid!!");
        return null;
    }
    log.debug("Passed the certificate validation!!");

    // decode the ephemeral public key
    try {
        ephPub = ECKeyPairGen.generateECPublicKey192(new BigInteger(ephPubX), new BigInteger(ephPubY));
    } catch (Exception e) {
        log.error("Error in decoding the submitted ephemeral public key: " + e.getMessage());
        e.printStackTrace();
    }

    // perform embedded public key validation
    boolean pubValid = ECMQVUtils.validateEmbedPubKey(ephPub);
    if (!pubValid) {
        log.error("The submitted ephemeral public key is not valid!!");
        return null;
    }
    log.debug("Passed the embedded ephemeral public key validation!!");

    // generates its own ephemeral key pairs, we assume that in this stage the 
    // ephemeral key pairs were not generated
    AsymmetricCipherKeyPair myEphKp = ECKeyPairGen.generateECKeyPair192();

    myEphPub = (ECPublicKeyParameters) myEphKp.getPublic();
    myEphPriv = (ECPrivateKeyParameters) myEphKp.getPrivate();

    // computes the implicit signature --> the static private key was obtained
    // when we validate the certificate (upon loading the KeyStore)
    BigInteger implSig = ECMQVUtils.computeImplicitSig(myEphPub, myEphPriv, statPriv);

    // calculates the shared key K
    ECPoint K = null;
    try {
        K = ECMQVUtils.calculateSharedKey(ephPub,
                (ECPublicKeyParameters) PublicKeyFactory.createKey(cert.getSubjectPublicKeyInfo()),
                ephPub.getParameters().getH(), implSig);
    } catch (IOException e) {
        log.error("Error in calculating the shared key K: " + e.getMessage());
        e.printStackTrace();
    }

    // derive 2 symmetric keys from the shared key K
    byte[] Kx = K.normalize().getXCoord().toBigInteger().toByteArray();
    int Lx = K.normalize().getXCoord().toBigInteger().bitLength();
    double x = Math.log(Lx) / Math.log(2.0);
    double L = Math.pow(2, 1 + Math.ceil(x));

    byte[] deriveK = ECMQVUtils.deriveKeyHKDF(Kx, (int) L / 8);

    // k1 and k2 split from newKey --> k1: to be MACed, k2: the session key
    k1 = new byte[deriveK.length / 2];
    k2 = new byte[deriveK.length / 2];
    int c = 0;
    for (byte b : deriveK) {
        if (c < deriveK.length / 2) {
            k1[c] = b;
        } else {
            k2[c - deriveK.length / 2] = b;
        }
        c++;
    }

    // retrieving my user friendly name from the SubjectAlternativeNames in my 
    // certificate
    Extensions myExs = myCert.getExtensions();
    if (myExs != null) {
        GeneralNames gns = GeneralNames.fromExtensions(myExs, Extension.subjectAlternativeName);
        for (int i = 0; i < gns.getNames().length; i++) {
            myUFN = gns.getNames()[i].getName().toString();
        }
    }

    // retrieving other GW user friendly name from the SubjectAlternativeNames 
    // in the submitted certificate
    Extensions oExs = cert.getExtensions();
    if (oExs != null) {
        GeneralNames gns = GeneralNames.fromExtensions(oExs, Extension.subjectAlternativeName);
        for (int i = 0; i < gns.getNames().length; i++) {
            ufn = gns.getNames()[i].getName().toString();
        }
    }

    // compute the MAC to be sent to the other gateway
    byte[] myMac = ECMQVUtils.computeMAC("2", myUFN, ufn, myEphPub.getQ().getEncoded(),
            ephPub.getQ().getEncoded(), k1);

    EcmqvMessage eMsg = new EcmqvMessage();
    eMsg.setMyMac(myMac);
    try {
        eMsg.setMyCertificate(myCert.getEncoded());
    } catch (IOException e) {
        log.error("Error in encoding the certificate: " + e.getMessage());
        e.printStackTrace();
    }

    eMsg.setEphemeralPublicX(myEphPub.getQ().normalize().getXCoord().toBigInteger().toByteArray());
    eMsg.setEphemeralPublicY(myEphPub.getQ().normalize().getXCoord().toBigInteger().toByteArray());

    return eMsg;
}

From source file:eu.betaas.taas.securitymanager.authentication.service.impl.GWEcmqvIntService.java

License:Apache License

public byte[] responseEcmqv(EcmqvMessage eMsg) throws Exception {
    // decode the certificate
    X509CertificateHolder cert = new X509CertificateHolder(eMsg.getMyCertificate());

    // decode the ECPublicKey
    ECPublicKeyParameters ephPub = ECKeyPairGen.generateECPublicKey192(
            new BigInteger(eMsg.getEphemeralPublicX()), new BigInteger(eMsg.getEphemeralPublicY()));
    // get the MAC 2
    byte[] mac2 = eMsg.getMyMac();

    // validate the certificate
    boolean isCertValid = false;
    isCertValid = validateCert(cert);/*from  ww w .java2 s. c o m*/

    if (!isCertValid) {
        log.error("The submitted certificate is not valid!!");
        return null;
    }
    log.debug("Passed the certificate validation!!");

    // perform embedded public key validation
    boolean pubValid = ECMQVUtils.validateEmbedPubKey(ephPub);
    if (!pubValid) {
        log.error("The submitted ephemeral public key is not valid!!");
        return null;
    }
    log.debug("Passed the embedded ephemeral public key validation!!");
    // set the ephPub with this received ephPub
    this.ephPub = ephPub;

    // now, no need to generate my own ephemeral key here, because it is done
    // compute the implicit signature
    BigInteger implSig = ECMQVUtils.computeImplicitSig(myEphPub, myEphPriv, statPriv);

    // calculates the shared key K
    ECPublicKeyParameters statPub = (ECPublicKeyParameters) PublicKeyFactory
            .createKey(cert.getSubjectPublicKeyInfo());
    org.bouncycastle.math.ec.ECPoint K = ECMQVUtils.calculateSharedKey(this.ephPub, statPub,
            this.ephPub.getParameters().getH(), implSig);

    // derive 2 symmetric keys from the shared key K
    byte[] Kx = K.normalize().getXCoord().toBigInteger().toByteArray();
    int Lx = K.normalize().getXCoord().toBigInteger().bitLength();
    double x = Math.log(Lx) / Math.log(2.0);
    double L = Math.pow(2, 1 + Math.ceil(x));

    byte[] deriveK = ECMQVUtils.deriveKeyHKDF(Kx, (int) L / 8);

    // k1 and k2 split from newKey --> k1: to be MACed, k2: the session key
    k1 = new byte[deriveK.length / 2];
    k2 = new byte[deriveK.length / 2];
    int c = 0;
    for (byte b : deriveK) {
        if (c < deriveK.length / 2) {
            k1[c] = b;
        } else {
            k2[c - deriveK.length / 2] = b;
        }
        c++;
    }

    // retrieving my user friendly name from the SubjectAlternativeNames in my 
    // certificate
    Extensions myExs = myCert.getExtensions();
    if (myExs != null) {
        GeneralNames gns = GeneralNames.fromExtensions(myExs, Extension.subjectAlternativeName);
        for (int i = 0; i < gns.getNames().length; i++) {
            myUFN = gns.getNames()[i].getName().toString();
        }
    }

    // retrieving other GW user friendly name from the SubjectAlternativeNames 
    // in the submitted certificate
    Extensions oExs = cert.getExtensions();
    if (oExs != null) {
        GeneralNames gns = GeneralNames.fromExtensions(oExs, Extension.subjectAlternativeName);
        for (int i = 0; i < gns.getNames().length; i++) {
            ufn = gns.getNames()[i].getName().toString();
        }
    }

    // validate MAC 2, which is received from other GW
    boolean isMac2Valid = verifyMac2(mac2, ufn, myUFN, this.ephPub, myEphPub, k1);

    // compute the MAC to be sent to the other gateway
    if (!isMac2Valid) {
        log.error("Fails to verify the received MAC (2)!!");
        return null;
    }
    log.debug("Successfully verifies the received MAC (2)!!");

    byte[] mac3 = ECMQVUtils.computeMAC("3", myUFN, ufn, myEphPub.getQ().getEncoded(),
            ephPub.getQ().getEncoded(), k1);

    return mac3;
}

From source file:net.felsing.client_cert.utilities.CertificateFabric.java

License:Open Source License

private void getSubjectAlternativeNames(PKCS10CertificationRequest csr) {
    subjectAlternativeNames = new ArrayList<>(new ArrayList<>());
    // GeneralName.otherName is lowest and
    // GeneralName.registeredID is highest id
    for (int i = GeneralName.otherName; i <= GeneralName.registeredID; i++) {
        subjectAlternativeNames.add(new ArrayList<>());
    }// w ww  .ja va2s.c o  m

    try {
        Attribute[] certAttributes = csr.getAttributes();
        for (Attribute attribute : certAttributes) {
            if (attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {
                // @ToDo: Is there really one object only?
                Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));
                GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName);
                if (gns != null) {
                    GeneralName[] names = gns.getNames();
                    for (GeneralName name : names) {
                        subjectAlternativeNames.get(name.getTagNo()).add(name.getName().toString());
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

From source file:org.apache.nifi.toolkit.tls.util.TlsHelperTest.java

License:Apache License

private List<String> extractSanFromCsr(JcaPKCS10CertificationRequest csr) {
    List<String> sans = new ArrayList<>();
    Attribute[] certAttributes = csr.getAttributes();
    for (Attribute attribute : certAttributes) {
        if (attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {
            Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));
            GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName);
            GeneralName[] names = gns.getNames();
            for (GeneralName name : names) {
                logger.info("Type: " + name.getTagNo() + " | Name: " + name.getName());
                String title = "";
                if (name.getTagNo() == GeneralName.dNSName) {
                    title = "DNS";
                } else if (name.getTagNo() == GeneralName.iPAddress) {
                    title = "IP Address";
                    // name.toASN1Primitive();
                } else if (name.getTagNo() == GeneralName.otherName) {
                    title = "Other Name";
                }//w ww  .j  a v a 2 s . co m
                sans.add(title + ": " + name.getName());
            }
        }
    }

    return sans;
}

From source file:org.cryptable.pki.communication.PKICMPMessagesTest.java

License:Open Source License

/**
 * Check the extensions in the certification request
 *
 * @throws OperatorCreationException//from   w w w.  j a va  2s  .c  om
 * @throws PKICMPMessageException
 * @throws CertificateEncodingException
 * @throws IOException
 * @throws CRMFException
 * @throws CMPException
 * @throws CMSException
 */
@Test
public void testCertificationWithExtensions()
        throws OperatorCreationException, PKICMPMessageException, CertificateEncodingException, IOException,
        CRMFException, CMPException, CMSException, NoSuchFieldException, IllegalAccessException {
    String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

    KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

    List<Extension> extensionList = new ArrayList<Extension>();
    // KeyUsage
    extensionList.add(new Extension(X509Extension.keyUsage, true,
            new KeyUsage(KeyUsage.digitalSignature | KeyUsage.nonRepudiation).getEncoded()));
    // Extended keyUsage
    List<KeyPurposeId> keyPurposeIds = new ArrayList<KeyPurposeId>();
    keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_clientAuth));
    keyPurposeIds.add(KeyPurposeId.getInstance(KeyPurposeId.id_kp_emailProtection));
    extensionList.add(new Extension(X509Extension.extendedKeyUsage, false,
            new ExtendedKeyUsage(keyPurposeIds.toArray(new KeyPurposeId[keyPurposeIds.size()])).getEncoded()));
    // Subject alternative names
    List<GeneralName> generalNames = new ArrayList<GeneralName>();
    generalNames.add(new GeneralName(GeneralName.dNSName, "www1.cryptable.org"));
    generalNames.add(new GeneralName(GeneralName.dNSName, "www2.cryptable.org"));
    GeneralNames subjectAlternativeName = new GeneralNames(
            generalNames.toArray(new GeneralName[generalNames.size()]));
    extensionList.add(
            new Extension(X509Extension.subjectAlternativeName, false, subjectAlternativeName.getEncoded()));

    PKICMPMessages pkiMessages = new PKICMPMessages();
    pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
    pkiMessages.setExtensions(extensionList.toArray(new Extension[extensionList.size()]));
    byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

    ASN1InputStream asn1InputStream = new ASN1InputStream(result);
    ASN1Primitive asn1Primitive = asn1InputStream.readObject();
    PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

    CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
            .toCertReqMsgArray();
    // KeyUsage
    KeyUsage verifyKeyUsage = KeyUsage.getInstance(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions()
            .getExtensionParsedValue(Extension.keyUsage));
    Assert.assertEquals(KeyUsage.digitalSignature | KeyUsage.nonRepudiation,
            verifyKeyUsage.getBytes()[0] & 0xFF);
    // Extended KeyUsage
    ExtendedKeyUsage verifyExtendedKeyUsage = ExtendedKeyUsage
            .fromExtensions(certReqMsgs[0].getCertReq().getCertTemplate().getExtensions());
    Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_clientAuth));
    Assert.assertTrue(verifyExtendedKeyUsage.hasKeyPurposeId(KeyPurposeId.id_kp_emailProtection));
    // Subject Alternative Name
    GeneralNames verifyGeneralNames = GeneralNames.fromExtensions(
            certReqMsgs[0].getCertReq().getCertTemplate().getExtensions(), Extension.subjectAlternativeName);
    Assert.assertTrue(generalNames.contains(verifyGeneralNames.getNames()[0]));
    Assert.assertTrue(generalNames.contains(verifyGeneralNames.getNames()[1]));
}