@Test
void generateIntermediateCertificateVersion3() throws Exception
{

    CertifiedPublicKey caCertificate =
        factory.getInstance(signerFactory.getInstance(true, rsaPrivateKey),
            new X509CertificateGenerationParameters(
                //<validity in days>,
                builder.addBasicConstraints(true)
                    .addKeyUsage(true, EnumSet.of(KeyUsage.keyCertSign,
                        KeyUsage.cRLSign))
                    .build()))
            .generate(new DistinguishedName("CN=Test CA"), rsaPublicKey,
                new X509CertificateParameters());
    //dumpCert(caCertificate);
    X509CertifiedPublicKey caKey = (X509CertifiedPublicKey) caCertificate;
    builder = componentManager.getInstance(X509ExtensionBuilder.class);
    CertificateGenerator generator = factory.getInstance(
        CertifyingSigner.getInstance(true, new CertifiedKeyPair(rsaPrivateKey, caCertificate), signerFactory),
        new X509CertificateGenerationParameters(
            //<validity in days>,
            builder.addBasicConstraints(0)
                .addKeyUsage(EnumSet.of(KeyUsage.keyCertSign,
                    KeyUsage.cRLSign))
                .build()));
    CertifiedPublicKey interCAcert =
        generator.generate(new DistinguishedName("CN=Test Intermediate CA"), interCaDsaPublicKey,
            new X509CertificateParameters());
    //dumpCert(interCAcert);
    assertTrue(interCAcert.isSignedBy(rsaPublicKey), "Signature should match Root CA key.");
    assertThat(interCAcert.getIssuer(), equalTo(caCertificate.getSubject()));
    assertThat(interCAcert.getSubject(), equalTo(new DistinguishedName("CN=Test Intermediate CA")));
    assertThat(interCAcert, instanceOf(X509CertifiedPublicKey.class));
    X509CertifiedPublicKey interCaKey = (X509CertifiedPublicKey) interCAcert;
    assertThat(interCaKey.getVersionNumber(), equalTo(3));
    assertTrue(interCaKey.getExtensions().isCritical(X509Extensions.BASIC_CONSTRAINTS_OID),
        "Basic constraints should be critical.");
    assertTrue(interCaKey.getExtensions().hasCertificateAuthorityBasicConstraints(),
        "Basic constraints should be set to CA.");
    assertThat(interCaKey.getExtensions().getBasicConstraintsPathLen(), Matchers.equalTo(0));
    assertTrue(interCaKey.getExtensions().isCritical(KeyUsage.OID), "KeyUsage extension should be critical.");
    assertThat(interCaKey.getExtensions().getKeyUsage(), equalTo(EnumSet.of(KeyUsage.keyCertSign,
        KeyUsage.cRLSign)));
    assertThat(interCaKey.getAuthorityKeyIdentifier(),
        equalTo(caKey.getSubjectKeyIdentifier()));
    builder = componentManager.getInstance(X509ExtensionBuilder.class);
    generator = factory.getInstance(
        CertifyingSigner.getInstance(true, new CertifiedKeyPair(interCaDsaPrivateKey, interCAcert),
            componentManager.getInstance(SignerFactory.class, "DSAwithSHA1")),
        new X509CertificateGenerationParameters(
            //<validity in days>,
            builder.addKeyUsage(EnumSet.of(KeyUsage.digitalSignature,
                KeyUsage.dataEncipherment))
                .addExtendedKeyUsage(false,
                    new ExtendedKeyUsages(new String[]{ ExtendedKeyUsages.EMAIL_PROTECTION }))
                .build()));
    builder = componentManager.getInstance(X509ExtensionBuilder.class);
    CertifiedPublicKey certificate =
        generator.generate(new DistinguishedName("CN=Test End Entity"), dsaPublicKey,
            new X509CertificateParameters(
                builder.addSubjectAltName(false,
                    new X509GeneralName[]{
                        new X509Rfc822Name("test@example.com")
                    })
                    .build()
            ));
    //dumpCert(certificate);
    assertTrue(certificate.isSignedBy(interCaDsaPublicKey), "Signature should match intermediate CA key.");
    assertThat(certificate.getIssuer(), equalTo(interCAcert.getSubject()));
    assertThat(certificate.getSubject(), equalTo(new DistinguishedName("CN=Test End Entity")));
    assertThat(certificate, instanceOf(X509CertifiedPublicKey.class));
    X509CertifiedPublicKey key = (X509CertifiedPublicKey) certificate;
    assertThat(key.getAuthorityKeyIdentifier(),
        equalTo(interCaKey.getSubjectKeyIdentifier()));
}