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

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

Introduction

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

Prototype

private GeneralNames(ASN1Sequence seq) 

Source Link

Usage

From source file:org.xipki.pki.ca.server.impl.IdentifiedX509Certprofile.java

License:Open Source License

public ExtensionValues getExtensions(@NonNull final X500Name requestedSubject,
        @NonNull final X500Name grantedSubject, @Nullable final Extensions requestedExtensions,
        @NonNull final SubjectPublicKeyInfo publicKeyInfo, @NonNull final PublicCaInfo publicCaInfo,
        @Nullable final X509Certificate crlSignerCert, @NonNull final Date notBefore,
        @NonNull final Date notAfter) throws CertprofileException, BadCertTemplateException {
    ParamUtil.requireNonNull("publicKeyInfo", publicKeyInfo);
    ExtensionValues values = new ExtensionValues();

    Map<ASN1ObjectIdentifier, ExtensionControl> controls = new HashMap<>(certprofile.getExtensionControls());

    Set<ASN1ObjectIdentifier> neededExtTypes = new HashSet<>();
    Set<ASN1ObjectIdentifier> wantedExtTypes = new HashSet<>();
    if (requestedExtensions != null) {
        Extension reqExtension = requestedExtensions
                .getExtension(ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions);
        if (reqExtension != null) {
            ExtensionExistence ee = ExtensionExistence.getInstance(reqExtension.getParsedValue());
            neededExtTypes.addAll(ee.getNeedExtensions());
            wantedExtTypes.addAll(ee.getWantExtensions());
        }//from   w  w  w . j  ava2s .c  om

        for (ASN1ObjectIdentifier oid : neededExtTypes) {
            if (wantedExtTypes.contains(oid)) {
                wantedExtTypes.remove(oid);
            }

            if (!controls.containsKey(oid)) {
                throw new BadCertTemplateException("could not add needed extension " + oid.getId());
            }
        }
    }

    // SubjectKeyIdentifier
    ASN1ObjectIdentifier extType = Extension.subjectKeyIdentifier;
    ExtensionControl extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        byte[] encodedSpki = publicKeyInfo.getPublicKeyData().getBytes();
        byte[] skiValue = HashAlgoType.SHA1.hash(encodedSpki);
        SubjectKeyIdentifier value = new SubjectKeyIdentifier(skiValue);
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    // Authority key identifier
    extType = Extension.authorityKeyIdentifier;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        byte[] ikiValue = publicCaInfo.getSubjectKeyIdentifer();
        AuthorityKeyIdentifier value = null;
        if (ikiValue != null) {
            if (certprofile.includeIssuerAndSerialInAki()) {
                GeneralNames x509CaSubject = new GeneralNames(new GeneralName(publicCaInfo.getX500Subject()));
                value = new AuthorityKeyIdentifier(ikiValue, x509CaSubject, publicCaInfo.getSerialNumber());
            } else {
                value = new AuthorityKeyIdentifier(ikiValue);
            }
        }

        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    // IssuerAltName
    extType = Extension.issuerAlternativeName;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        GeneralNames value = publicCaInfo.getSubjectAltName();
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    // AuthorityInfoAccess
    extType = Extension.authorityInfoAccess;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        AuthorityInfoAccessControl aiaControl = certprofile.getAiaControl();

        List<String> caIssuers = null;
        if (aiaControl == null || aiaControl.includesCaIssuers()) {
            caIssuers = publicCaInfo.getCaCertUris();
        }

        List<String> ocspUris = null;
        if (aiaControl == null || aiaControl.includesOcsp()) {
            ocspUris = publicCaInfo.getOcspUris();
        }

        if (CollectionUtil.isNonEmpty(caIssuers) || CollectionUtil.isNonEmpty(ocspUris)) {
            AuthorityInformationAccess value = CaUtil.createAuthorityInformationAccess(caIssuers, ocspUris);
            addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
        }
    }

    if (controls.containsKey(Extension.cRLDistributionPoints) || controls.containsKey(Extension.freshestCRL)) {
        X500Name crlSignerSubject = (crlSignerCert == null) ? null
                : X500Name.getInstance(crlSignerCert.getSubjectX500Principal().getEncoded());
        X500Name x500CaPrincipal = publicCaInfo.getX500Subject();

        // CRLDistributionPoints
        extType = Extension.cRLDistributionPoints;
        extControl = controls.remove(extType);
        if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
            if (CollectionUtil.isNonEmpty(publicCaInfo.getCrlUris())) {
                CRLDistPoint value = CaUtil.createCrlDistributionPoints(publicCaInfo.getCrlUris(),
                        x500CaPrincipal, crlSignerSubject);
                addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
            }
        }

        // FreshestCRL
        extType = Extension.freshestCRL;
        extControl = controls.remove(extType);
        if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
            if (CollectionUtil.isNonEmpty(publicCaInfo.getDeltaCrlUris())) {
                CRLDistPoint value = CaUtil.createCrlDistributionPoints(publicCaInfo.getDeltaCrlUris(),
                        x500CaPrincipal, crlSignerSubject);
                addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
            }
        }
    }

    // BasicConstraints
    extType = Extension.basicConstraints;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        BasicConstraints value = CaUtil.createBasicConstraints(certprofile.getCertLevel(),
                certprofile.getPathLenBasicConstraint());
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    // KeyUsage
    extType = Extension.keyUsage;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        Set<KeyUsage> usages = new HashSet<>();
        Set<KeyUsageControl> usageOccs = certprofile.getKeyUsage();
        for (KeyUsageControl k : usageOccs) {
            if (k.isRequired()) {
                usages.add(k.getKeyUsage());
            }
        }

        // the optional KeyUsage will only be set if requested explicitly
        if (requestedExtensions != null && extControl.isRequest()) {
            addRequestedKeyusage(usages, requestedExtensions, usageOccs);
        }

        org.bouncycastle.asn1.x509.KeyUsage value = X509Util.createKeyUsage(usages);
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    // ExtendedKeyUsage
    extType = Extension.extendedKeyUsage;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        List<ASN1ObjectIdentifier> usages = new LinkedList<>();
        Set<ExtKeyUsageControl> usageOccs = certprofile.getExtendedKeyUsages();
        for (ExtKeyUsageControl k : usageOccs) {
            if (k.isRequired()) {
                usages.add(k.getExtKeyUsage());
            }
        }

        // the optional ExtKeyUsage will only be set if requested explicitly
        if (requestedExtensions != null && extControl.isRequest()) {
            addRequestedExtKeyusage(usages, requestedExtensions, usageOccs);
        }

        if (extControl.isCritical() && usages.contains(ObjectIdentifiers.id_anyExtendedKeyUsage)) {
            extControl = new ExtensionControl(false, extControl.isRequired(), extControl.isRequest());
        }

        ExtendedKeyUsage value = X509Util.createExtendedUsage(usages);
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    // ocsp-nocheck
    extType = ObjectIdentifiers.id_extension_pkix_ocsp_nocheck;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        // the extension ocsp-nocheck will only be set if requested explicitly
        DERNull value = DERNull.INSTANCE;
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    // SubjectInfoAccess
    extType = Extension.subjectInfoAccess;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        ASN1Sequence value = null;
        if (requestedExtensions != null && extControl.isRequest()) {
            value = createSubjectInfoAccess(requestedExtensions, certprofile.getSubjectInfoAccessModes());
        }
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }

    ExtensionValues subvalues = certprofile.getExtensions(Collections.unmodifiableMap(controls),
            requestedSubject, grantedSubject, requestedExtensions, notBefore, notAfter);

    Set<ASN1ObjectIdentifier> extTypes = new HashSet<>(controls.keySet());
    for (ASN1ObjectIdentifier type : extTypes) {
        extControl = controls.remove(type);
        boolean addMe = addMe(type, extControl, neededExtTypes, wantedExtTypes);
        if (addMe) {
            ExtensionValue value = null;
            if (requestedExtensions != null && extControl.isRequest()) {
                Extension reqExt = requestedExtensions.getExtension(type);
                if (reqExt != null) {
                    value = new ExtensionValue(reqExt.isCritical(), reqExt.getParsedValue());
                }
            }

            if (value == null) {
                value = subvalues.getExtensionValue(type);
            }

            addExtension(values, type, value, extControl, neededExtTypes, wantedExtTypes);
        }
    }

    Set<ASN1ObjectIdentifier> unprocessedExtTypes = new HashSet<>();
    for (ASN1ObjectIdentifier type : controls.keySet()) {
        if (controls.get(type).isRequired()) {
            unprocessedExtTypes.add(type);
        }
    }

    if (CollectionUtil.isNonEmpty(unprocessedExtTypes)) {
        throw new CertprofileException("could not add required extensions " + toString(unprocessedExtTypes));
    }

    if (CollectionUtil.isNonEmpty(neededExtTypes)) {
        throw new BadCertTemplateException("could not add requested extensions " + toString(neededExtTypes));
    }

    return values;
}

From source file:org.xipki.pki.ca.server.impl.util.CaUtil.java

License:Open Source License

public static CRLDistPoint createCrlDistributionPoints(final List<String> crlUris, final X500Name caSubject,
        final X500Name crlSignerSubject) {
    ParamUtil.requireNonEmpty("crlUris", crlUris);
    int size = crlUris.size();
    DistributionPoint[] points = new DistributionPoint[1];

    GeneralName[] names = new GeneralName[size];
    for (int i = 0; i < size; i++) {
        names[i] = new GeneralName(GeneralName.uniformResourceIdentifier, crlUris.get(i));
    }//from w  ww  .  j a v  a 2 s. c o  m
    // Distribution Point
    GeneralNames gns = new GeneralNames(names);
    DistributionPointName pointName = new DistributionPointName(gns);

    GeneralNames crlIssuer = null;
    if (crlSignerSubject != null && !crlSignerSubject.equals(caSubject)) {
        GeneralName crlIssuerName = new GeneralName(crlSignerSubject);
        crlIssuer = new GeneralNames(crlIssuerName);
    }

    points[0] = new DistributionPoint(pointName, null, crlIssuer);

    return new CRLDistPoint(points);
}

From source file:org.xipki.pki.ca.server.impl.X509Ca.java

License:Open Source License

private static Extension createCertificateIssuerExtension(final X500Name certificateIssuer) {
    try {/*from  ww  w .ja  v a  2  s .  c o m*/
        GeneralNames generalNames = new GeneralNames(new GeneralName(certificateIssuer));
        return new Extension(Extension.certificateIssuer, true, generalNames.getEncoded());
    } catch (IOException ex) {
        throw new IllegalArgumentException("error encoding reason: " + ex.getMessage(), ex);
    }
}

From source file:org.xipki.security.P10RequestGenerator.java

License:Open Source License

public static GeneralNames createGeneralNames(final List<String> taggedValues) throws BadInputException {
    if (CollectionUtil.isEmpty(taggedValues)) {
        return null;
    }/* www  . j  ava  2s.  c  o  m*/

    int n = taggedValues.size();
    GeneralName[] names = new GeneralName[n];
    for (int i = 0; i < n; i++) {
        names[i] = createGeneralName(taggedValues.get(i));
    }
    return new GeneralNames(names);
}

From source file:org.xwiki.crypto.pkix.internal.extension.BcExtensionUtils.java

License:Open Source License

/**
 * Convert a collection of X.509 general names to Bouncy Castle general names.
 *
 * @param genNames a collection of X.509 general names.
 * @return a bouncy castle general names.
 *//*  ww  w .j  a  v  a  2 s.c o m*/
public static GeneralNames getGeneralNames(X509GeneralName[] genNames) {
    GeneralName[] names = new GeneralName[genNames.length];

    int i = 0;
    for (X509GeneralName name : genNames) {
        if (name instanceof BcGeneralName) {
            names[i++] = ((BcGeneralName) name).getGeneralName();
        } else {
            throw new IllegalArgumentException("Unexpected general name: " + name.getClass().toString());
        }
    }

    return new GeneralNames(names);
}

From source file:org.xwiki.crypto.x509.internal.X509Keymaker.java

License:Open Source License

/**
 * Create a new X509 client certificate.
 *
 * @param forCert the public key which will be embedded in the certificate, whoever has the matching private key
 *                "owns" the certificate.
 * @param toSignWith the private key in this pair will be used to sign the certificate.
 * @param daysOfValidity number of days the cert should be valid for.
 * @param nonRepudiable this should only be true if the private key is not stored on the server.
 * @param webId the URI to put as the alternative name (for FOAFSSL webId compatibility)
 * @param userName a String representation of the name of the user getting the certificate.
 * @return a new X509 certificate.// w  w w .  j  a  va  2s  . com
 * @throws GeneralSecurityException if something goes wrong.
 */
public synchronized X509Certificate makeClientCertificate(final PublicKey forCert, final KeyPair toSignWith,
        final int daysOfValidity, final boolean nonRepudiable, final String webId, final String userName)
        throws GeneralSecurityException {
    try {
        // the UID (same for issuer since this certificate confers no authority)
        final X509Name dName = new X509Name("UID=" + userName);

        this.prepareGenericCertificate(forCert, daysOfValidity, dName, dName);

        // Not a CA
        certGenerator.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false));

        // Client cert
        certGenerator.addExtension(MiscObjectIdentifiers.netscapeCertType, false,
                new NetscapeCertType(NetscapeCertType.sslClient | NetscapeCertType.smime));

        // Key Usage extension.
        int keyUsage = KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment
                | KeyUsage.keyAgreement;
        if (nonRepudiable) {
            keyUsage |= KeyUsage.nonRepudiation;
        }
        certGenerator.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(keyUsage));

        // Set the authority key identifier to be the CA key which we are using.
        certGenerator.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
                new AuthorityKeyIdentifierStructure(toSignWith.getPublic()));

        // FOAFSSL compatibility.
        final GeneralNames subjectAltNames = new GeneralNames(
                new GeneralName(GeneralName.uniformResourceIdentifier, webId));
        certGenerator.addExtension(X509Extensions.SubjectAlternativeName, true, subjectAltNames);

        return this.generate(toSignWith);

    } finally {
        // Clean up after ourselves so that it is more difficult to try to extract private keys from the heap.
        this.certGenerator.reset();
    }
}

From source file:se.tillvaxtverket.tsltrust.webservice.daemon.ca.CertificationAuthority.java

License:Open Source License

public AaaCertificate createCertificate(AaaCertificate orgCert, BigInteger certSerial,
        AaaCertificate issuerCert, String algorithm, List<Extension> extensions) {

    AaaCertificate cert = null;/*w w w  .  ja  v a2s .  c om*/
    // create a new certificate
    try {
        CertRequestModel reqModel = new CertRequestModel();
        reqModel.setIssuerDN(issuerCert.getSubject());
        reqModel.setPublicKey(orgCert.getCert().getPublicKey());
        reqModel.setSerialNumber(certSerial);
        reqModel.setSubjectDN(orgCert.getSubject());
        reqModel.setNotBefore(orgCert.getNotBefore());
        if (issuerCert.getNotAfter().after(orgCert.getNotAfter())) {
            reqModel.setNotAfter(orgCert.getNotAfter());
        } else {
            reqModel.setNotAfter(issuerCert.getNotAfter());
        }

        // Add AKI
        X509ExtensionUtils extUtil = CertUtils.getX509ExtensionUtils();
        AuthorityKeyIdentifier aki = extUtil.createAuthorityKeyIdentifier(issuerCert);
        extensions.add(new Extension(Extension.authorityKeyIdentifier, false, aki.getEncoded("DER")));

        DistributionPoint dp = new DistributionPoint(
                new DistributionPointName(
                        new GeneralNames(new GeneralName(GeneralName.uniformResourceIdentifier, crlDpUrl))),
                null, null);
        CRLDistPoint cdp = new CRLDistPoint(new DistributionPoint[] { dp });
        extensions.add(new Extension(Extension.cRLDistributionPoints, false, cdp.getEncoded("DER")));

        reqModel.setExtensionList(extensions);
        reqModel.setSigner(
                new JcaContentSignerBuilder(algorithm).build((PrivateKey) key_store.getKey(ROOT, KS_PASSWORD)));

        cert = new AaaCertificate(reqModel);
    } catch (Exception ex) {
        cert = null;
        LOG.warning("Error creating the certificate: " + ex.getMessage());
    }

    return cert;
}

From source file:se.tillvaxtverket.tsltrust.webservice.daemon.ca.CertificationAuthority.java

License:Open Source License

public X509CRLHolder revokeCertificates() {
    long currentTime = System.currentTimeMillis();
    long nextUpdateTime = currentTime + crlValPeriod;
    List<DbCert> certList = CaSQLiteUtil.getCertificates(caDir, true);

    DbCAParam cp = CaSQLiteUtil.getParameter(caDir, CRL_SERIAL_KEY);
    if (cp == null) {
        return null;
    }// ww  w .j ava  2s.  com
    long nextCrlSerial = cp.getIntValue();

    try {

        AaaCRL crl = new AaaCRL(new Date(currentTime), new Date(nextUpdateTime), caRoot,
                (PrivateKey) key_store.getKey(ROOT, KS_PASSWORD), CertFactory.SHA256WITHRSA, crlFile);

        List<Extension> extList = new ArrayList<Extension>();
        // Add AKI
        X509ExtensionUtils extu = CertUtils.getX509ExtensionUtils();
        AuthorityKeyIdentifier aki = extu.createAuthorityKeyIdentifier(caRoot);
        extList.add(new Extension(Extension.authorityKeyIdentifier, false, aki.getEncoded("DER")));

        // CRLNumber to be adjusted to an incremental number
        CRLNumber crlNumber = new CRLNumber(BigInteger.valueOf(nextCrlSerial));
        extList.add(new Extension(Extension.cRLNumber, false, crlNumber.getEncoded("DER")));

        GeneralNames distributionPointName = new GeneralNames(
                new GeneralName(GeneralName.uniformResourceIdentifier, crlDpUrl));
        DistributionPointName dpn = new DistributionPointName(distributionPointName);
        IssuingDistributionPoint idp = new IssuingDistributionPoint(dpn, false, false);
        extList.add(new Extension(Extension.issuingDistributionPoint, true, idp.getEncoded("DER")));

        // IssuingDistributionPoint
        List<CRLEntryData> crlEdList = new ArrayList<>();

        certList.forEach((dbCert) -> {
            Date revTime = new Date();
            BigInteger serialNumber = dbCert.getCertificate().getSerialNumber();
            crlEdList.add(new CRLEntryData(serialNumber, new Date(dbCert.getRevDate()),
                    CRLReason.privilegeWithdrawn));
        });

        crl.updateCrl(new Date(currentTime), new Date(nextUpdateTime), crlEdList, extList);

        logRevocation(certList);

        // receive CRL
        latestCrl = crl.getCrl();
        cp.setIntValue(nextCrlSerial + 1);
        CaSQLiteUtil.storeParameter(cp, caDir);
        // Store CRL
        FileOps.saveByteFile(FileOps.readBinaryFile(crlFile), exportCrlFile);
        return latestCrl;

    } catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException
            | CRLException | CertificateException | OperatorCreationException ex) {
        LOG.warning(ex.getMessage());
        return null;
    }
}

From source file:se.tillvaxtverket.ttsigvalws.ttwssigvalidation.pdf.PdfBoxSigUtil.java

License:Open Source License

public static ASN1EncodableVector getSignedCertAttr(DigestAlgorithm digestAlgo, X509Certificate certificate,
        boolean includeIssuerSerial)
        throws NoSuchAlgorithmException, CertificateEncodingException, IOException {
    final X500Name issuerX500Name = new X509CertificateHolder(certificate.getEncoded()).getIssuer();
    final GeneralName generalName = new GeneralName(issuerX500Name);
    final GeneralNames generalNames = new GeneralNames(generalName);
    final BigInteger serialNumber = certificate.getSerialNumber();
    final IssuerSerial issuerSerial = new IssuerSerial(generalNames, serialNumber);

    ASN1EncodableVector signedCert = new ASN1EncodableVector();

    boolean essSigCertV2;
    ASN1ObjectIdentifier signedCertOid;//from w  w w  .j av a  2s.c o  m
    switch (digestAlgo) {
    case SHA1:
        signedCertOid = new ASN1ObjectIdentifier(PdfObjectIds.ID_AA_SIGNING_CERTIFICATE_V1);
        essSigCertV2 = false;
        break;
    default:
        signedCertOid = new ASN1ObjectIdentifier(PdfObjectIds.ID_AA_SIGNING_CERTIFICATE_V2);
        essSigCertV2 = true;
    }

    MessageDigest md = MessageDigest.getInstance(digestAlgo.getName());
    md.update(certificate.getEncoded());
    byte[] certHash = md.digest();
    DEROctetString certHashOctetStr = new DEROctetString(certHash);

    signedCert.add(signedCertOid);

    ASN1EncodableVector attrValSet = new ASN1EncodableVector();
    ASN1EncodableVector signingCertObjSeq = new ASN1EncodableVector();
    ASN1EncodableVector essCertV2Seq = new ASN1EncodableVector();
    ASN1EncodableVector certSeq = new ASN1EncodableVector();
    ASN1EncodableVector algoSeq = new ASN1EncodableVector();
    algoSeq.add(new ASN1ObjectIdentifier(digestAlgo.getOid()));
    algoSeq.add(DERNull.INSTANCE);
    if (essSigCertV2) {
        certSeq.add(new DERSequence(algoSeq));
    }
    //Add cert hash
    certSeq.add(new DEROctetString(certHash));
    if (includeIssuerSerial) {
        certSeq.add(issuerSerial);
    }

    //Finalize assembly
    essCertV2Seq.add(new DERSequence(certSeq));
    signingCertObjSeq.add(new DERSequence(essCertV2Seq));
    attrValSet.add(new DERSequence(signingCertObjSeq));
    signedCert.add(new DERSet(attrValSet));

    return signedCert;
}

From source file:test.be.fedict.eid.applet.PkiTestUtils.java

License:Open Source License

static X509Certificate generateCertificate(PublicKey subjectPublicKey, String subjectDn, DateTime notBefore,
        DateTime notAfter, X509Certificate issuerCertificate, PrivateKey issuerPrivateKey, boolean caFlag,
        int pathLength, String crlUri, String ocspUri, KeyUsage keyUsage)
        throws IOException, InvalidKeyException, IllegalStateException, NoSuchAlgorithmException,
        SignatureException, CertificateException {
    String signatureAlgorithm = "SHA1withRSA";
    X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
    certificateGenerator.reset();//from w w  w.  j  av  a2  s.  co  m
    certificateGenerator.setPublicKey(subjectPublicKey);
    certificateGenerator.setSignatureAlgorithm(signatureAlgorithm);
    certificateGenerator.setNotBefore(notBefore.toDate());
    certificateGenerator.setNotAfter(notAfter.toDate());
    X509Principal issuerDN;
    if (null != issuerCertificate) {
        issuerDN = new X509Principal(issuerCertificate.getSubjectX500Principal().toString());
    } else {
        issuerDN = new X509Principal(subjectDn);
    }
    certificateGenerator.setIssuerDN(issuerDN);
    certificateGenerator.setSubjectDN(new X509Principal(subjectDn));
    certificateGenerator.setSerialNumber(new BigInteger(128, new SecureRandom()));

    certificateGenerator.addExtension(X509Extensions.SubjectKeyIdentifier, false,
            createSubjectKeyId(subjectPublicKey));
    PublicKey issuerPublicKey;
    issuerPublicKey = subjectPublicKey;
    certificateGenerator.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
            createAuthorityKeyId(issuerPublicKey));

    if (caFlag) {
        if (-1 == pathLength) {
            certificateGenerator.addExtension(X509Extensions.BasicConstraints, false,
                    new BasicConstraints(true));
        } else {
            certificateGenerator.addExtension(X509Extensions.BasicConstraints, false,
                    new BasicConstraints(pathLength));
        }
    }

    if (null != crlUri) {
        GeneralName gn = new GeneralName(GeneralName.uniformResourceIdentifier, new DERIA5String(crlUri));
        GeneralNames gns = new GeneralNames(new DERSequence(gn));
        DistributionPointName dpn = new DistributionPointName(0, gns);
        DistributionPoint distp = new DistributionPoint(dpn, null, null);
        certificateGenerator.addExtension(X509Extensions.CRLDistributionPoints, false, new DERSequence(distp));
    }

    if (null != ocspUri) {
        GeneralName ocspName = new GeneralName(GeneralName.uniformResourceIdentifier, ocspUri);
        AuthorityInformationAccess authorityInformationAccess = new AuthorityInformationAccess(
                X509ObjectIdentifiers.ocspAccessMethod, ocspName);
        certificateGenerator.addExtension(X509Extensions.AuthorityInfoAccess.getId(), false,
                authorityInformationAccess);
    }

    if (null != keyUsage) {
        certificateGenerator.addExtension(X509Extensions.KeyUsage, true, keyUsage);
    }

    X509Certificate certificate;
    certificate = certificateGenerator.generate(issuerPrivateKey);

    /*
     * Next certificate factory trick is needed to make sure that the
     * certificate delivered to the caller is provided by the default
     * security provider instead of BouncyCastle. If we don't do this trick
     * we might run into trouble when trying to use the CertPath validator.
     */
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    certificate = (X509Certificate) certificateFactory
            .generateCertificate(new ByteArrayInputStream(certificate.getEncoded()));
    return certificate;
}