Example usage for org.bouncycastle.asn1.x509 X509ExtensionsGenerator generate

List of usage examples for org.bouncycastle.asn1.x509 X509ExtensionsGenerator generate

Introduction

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

Prototype

public X509Extensions generate() 

Source Link

Document

Generate an X509Extensions object based on the current state of the generator.

Usage

From source file:com.otterca.common.crypto.SimplePolicyGeneratorImpl.java

License:Apache License

/**
 * @see com.otterca.common.crypto.X509ExtensionGenerator#getExtension(X500Principal,
 *      X509Certificate)/*from   www  . ja  va 2 s  . c  om*/
 */
@Override
public byte[] getExtension(X500Principal subject, X509Certificate issuer) throws IOException {
    X509ExtensionsGenerator generator = new X509ExtensionsGenerator();

    List<PolicyInformation> policies = new ArrayList<PolicyInformation>();

    PolicyInformation info = getCpsPolicyInformation();
    if (info != null) {
        policies.add(info);
    }

    info = getUserNoticePolicyInformation();
    if (info != null) {
        policies.add(info);
    }

    byte[] bytes = null;
    if (!policies.isEmpty()) {
        CertificatePolicies certificatePolicies = new CertificatePolicies(
                policies.toArray(emptyPolicyInformationArray));
        generator.addExtension(X509Extensions.CertificatePolicies, false, certificatePolicies);
        bytes = generator.generate().getEncoded();
    }

    return bytes;
}

From source file:org.ejbca.core.model.ca.caadmin.X509CA.java

License:Open Source License

/**
 * sequence is ignored by X509CA//  w  w w  .  j  a v  a 2  s .  com
 */
public Certificate generateCertificate(UserDataVO subject, X509Name requestX509Name, PublicKey publicKey,
        int keyusage, Date notBefore, Date notAfter, CertificateProfile certProfile, X509Extensions extensions,
        String sequence, PublicKey caPublicKey, PrivateKey caPrivateKey, String provider) throws Exception {

    // We must only allow signing to take place if the CA itself if on line, even if the token is on-line.
    // We have to allow expired as well though, so we can renew expired CAs
    if ((getStatus() != SecConst.CA_ACTIVE) && ((getStatus() != SecConst.CA_EXPIRED))) {
        String msg = intres.getLocalizedMessage("error.caoffline", getName(), getStatus());
        if (log.isDebugEnabled()) {
            log.debug(msg); // This is something we handle so no need to log with higher priority
        }
        throw new CAOfflineException(msg);
    }

    final String sigAlg;
    if (certProfile.getSignatureAlgorithm() == null) {
        sigAlg = getCAInfo().getCATokenInfo().getSignatureAlgorithm();
    } else {
        sigAlg = certProfile.getSignatureAlgorithm();
    }
    final X509Certificate cacert = (X509Certificate) getCACertificate();
    String dn = subject.getCertificateDN();
    // Check if this is a root CA we are creating
    final boolean isRootCA = certProfile.getType() == CertificateProfile.TYPE_ROOTCA;

    // Get certificate validity time notBefore and notAfter
    final CertificateValidity val = new CertificateValidity(subject, certProfile, notBefore, notAfter, cacert,
            isRootCA);

    final X509V3CertificateGenerator certgen = new X509V3CertificateGenerator();
    {
        // Serialnumber is either random bits, where random generator is initialized by the serno generator.
        // Or a custom serial number defined in the end entity object
        final ExtendedInformation ei = subject.getExtendedinformation();
        BigInteger customSN = ei != null ? ei.certificateSerialNumber() : null;
        if (customSN != null) {
            if (!certProfile.getAllowCertSerialNumberOverride()) {
                final String msg = intres.getLocalizedMessage(
                        "signsession.certprof_not_allowing_cert_sn_override_using_normal",
                        customSN.toString(16));
                log.info(msg);
                customSN = null;
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Using custom serial number: " + customSN.toString(16));
                }
            }
        }
        final BigInteger serno = customSN != null ? customSN : SernoGenerator.instance().getSerno();
        certgen.setSerialNumber(serno);
    }
    certgen.setNotBefore(val.getNotBefore());
    certgen.setNotAfter(val.getNotAfter());
    certgen.setSignatureAlgorithm(sigAlg);

    // Make DNs
    if (certProfile.getUseSubjectDNSubSet()) {
        dn = certProfile.createSubjectDNSubSet(dn);
    }

    if (certProfile.getUseCNPostfix()) {
        dn = CertTools.insertCNPostfix(dn, certProfile.getCNPostfix());
    }

    X509NameEntryConverter converter = null;
    if (getUsePrintableStringSubjectDN()) {
        converter = new PrintableStringEntryConverter();
    } else {
        converter = new X509DefaultEntryConverter();
    }
    // Will we use LDAP DN order (CN first) or X500 DN order (CN last) for the subject DN
    boolean ldapdnorder = true;
    if ((getUseLdapDNOrder() == false) || (certProfile.getUseLdapDnOrder() == false)) {
        ldapdnorder = false;
    }
    X509Name subjectDNName = CertTools.stringToBcX509Name(dn, converter, ldapdnorder);
    if (certProfile.getAllowDNOverride() && (requestX509Name != null)) {
        subjectDNName = requestX509Name;
        if (log.isDebugEnabled()) {
            log.debug("Using X509Name from request instead of user's registered.");
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("Using subjectDN: " + subjectDNName.toString());
    }
    certgen.setSubjectDN(subjectDNName);
    // We must take the issuer DN directly from the CA-certificate otherwise we risk re-ordering the DN
    // which many applications do not like.
    if (isRootCA) {
        // This will be an initial root CA, since no CA-certificate exists
        // Or it is a root CA, since the cert is self signed. If it is a root CA we want to use the same encoding for subject and issuer,
        // it might have changed over the years.
        if (log.isDebugEnabled()) {
            log.debug("Using subject DN also as issuer DN, because it is a root CA");
        }
        certgen.setIssuerDN(subjectDNName);
    } else {
        javax.security.auth.x500.X500Principal issuerPrincipal = cacert.getSubjectX500Principal();
        if (log.isDebugEnabled()) {
            log.debug("Using issuer DN directly from the CA certificate: " + issuerPrincipal.getName());
        }
        certgen.setIssuerDN(issuerPrincipal);
    }
    certgen.setPublicKey(publicKey);

    //
    // X509 Certificate Extensions
    //

    // Extensions we will add to the certificate, later when we have filled the structure with 
    // everything we want.
    X509ExtensionsGenerator extgen = new X509ExtensionsGenerator();

    // First we check if there is general extension override, and add all extensions from 
    // the request in that case
    if (certProfile.getAllowExtensionOverride() && extensions != null) {
        Enumeration en = extensions.oids();
        while (en != null && en.hasMoreElements()) {
            DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement();
            X509Extension ext = extensions.getExtension(oid);
            if (log.isDebugEnabled()) {
                log.debug("Overriding extension with oid: " + oid);
            }
            extgen.addExtension(oid, ext.isCritical(), ext.getValue().getOctets());
        }
    }

    // Second we see if there is Key usage override
    X509Extensions overridenexts = extgen.generate();
    if (certProfile.getAllowKeyUsageOverride() && (keyusage >= 0)) {
        if (log.isDebugEnabled()) {
            log.debug("AllowKeyUsageOverride=true. Using KeyUsage from parameter: " + keyusage);
        }
        if ((certProfile.getUseKeyUsage() == true) && (keyusage >= 0)) {
            X509KeyUsage ku = new X509KeyUsage(keyusage);
            // We don't want to try to add custom extensions with the same oid if we have already added them 
            // from the request, if AllowExtensionOverride is enabled.
            // Two extensions with the same oid is not allowed in the standard.
            if (overridenexts.getExtension(X509Extensions.KeyUsage) == null) {
                extgen.addExtension(X509Extensions.KeyUsage, certProfile.getKeyUsageCritical(), ku);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug(
                            "KeyUsage was already overridden by an extension, not using KeyUsage from parameter.");
                }
            }
        }
    }

    // Third, check for standard Certificate Extensions that should be added.
    // Standard certificate extensions are defined in CertificateProfile and CertificateExtensionFactory
    // and implemented in package org.ejbca.core.model.certextensions.standard
    CertificateExtensionFactory fact = CertificateExtensionFactory.getInstance();
    List<String> usedStdCertExt = certProfile.getUsedStandardCertificateExtensions();
    Iterator<String> certStdExtIter = usedStdCertExt.iterator();
    overridenexts = extgen.generate();
    while (certStdExtIter.hasNext()) {
        String oid = certStdExtIter.next();
        // We don't want to try to add standard extensions with the same oid if we have already added them 
        // from the request, if AllowExtensionOverride is enabled.
        // Two extensions with the same oid is not allowed in the standard.
        if (overridenexts.getExtension(new DERObjectIdentifier(oid)) == null) {
            CertificateExtension certExt = fact.getStandardCertificateExtension(oid, certProfile);
            if (certExt != null) {
                byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey);
                if (value != null) {
                    extgen.addExtension(new DERObjectIdentifier(certExt.getOID()), certExt.isCriticalFlag(),
                            value);
                }
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Extension with oid " + oid
                        + " has been overridden, standard extension will not be added.");
            }
        }
    }

    // Fourth, check for custom Certificate Extensions that should be added.
    // Custom certificate extensions is defined in certextensions.properties
    fact = CertificateExtensionFactory.getInstance();
    List<Integer> usedCertExt = certProfile.getUsedCertificateExtensions();
    Iterator<Integer> certExtIter = usedCertExt.iterator();
    while (certExtIter.hasNext()) {
        Integer id = certExtIter.next();
        CertificateExtension certExt = fact.getCertificateExtensions(id);
        if (certExt != null) {
            // We don't want to try to add custom extensions with the same oid if we have already added them 
            // from the request, if AllowExtensionOverride is enabled.
            // Two extensions with the same oid is not allowed in the standard.
            if (overridenexts.getExtension(new DERObjectIdentifier(certExt.getOID())) == null) {
                byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey);
                if (value != null) {
                    extgen.addExtension(new DERObjectIdentifier(certExt.getOID()), certExt.isCriticalFlag(),
                            value);
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Extension with oid " + certExt.getOID()
                            + " has been overridden, custom extension will not be added.");
                }
            }
        }
    }

    // Finally add extensions to certificate generator
    X509Extensions exts = extgen.generate();
    Enumeration en = exts.oids();
    while (en.hasMoreElements()) {
        DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement();
        X509Extension ext = exts.getExtension(oid);
        certgen.addExtension(oid, ext.isCritical(), ext.getValue().getOctets());
    }

    //
    // End of extensions
    //

    X509Certificate cert;
    if (log.isTraceEnabled()) {
        log.trace(">certgen.generate");
    }
    cert = certgen.generate(caPrivateKey, provider);
    if (log.isTraceEnabled()) {
        log.trace("<certgen.generate");
    }

    // Verify using the CA certificate before returning
    // If we can not verify the issued certificate using the CA certificate we don't want to issue this cert
    // because something is wrong...
    PublicKey verifyKey;
    // We must use the configured public key if this is a rootCA, because then we can renew our own certificate, after changing
    // the keys. In this case the _new_ key will not match the current CA certificate.
    if ((cacert != null) && (!isRootCA)) {
        verifyKey = cacert.getPublicKey();
    } else {
        verifyKey = caPublicKey;
    }
    cert.verify(verifyKey);

    // If we have a CA-certificate, verify that we have all path verification stuff correct
    if (cacert != null) {
        byte[] aki = CertTools.getAuthorityKeyId(cert);
        byte[] ski = CertTools.getSubjectKeyId(isRootCA ? cert : cacert);
        if ((aki != null) && (ski != null)) {
            boolean eq = Arrays.equals(aki, ski);
            if (!eq) {
                String akistr = new String(Hex.encode(aki));
                String skistr = new String(Hex.encode(ski));
                log.error(intres.getLocalizedMessage("signsession.errorpathverifykeyid", akistr, skistr));
            }
        }
        Principal issuerDN = cert.getIssuerX500Principal();
        Principal subjectDN = cacert.getSubjectX500Principal();
        if ((issuerDN != null) && (subjectDN != null)) {
            boolean eq = issuerDN.equals(subjectDN);
            if (!eq) {
                log.error(intres.getLocalizedMessage("signsession.errorpathverifydn", issuerDN.getName(),
                        subjectDN.getName()));
            }
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("X509CA: generated certificate, CA " + this.getCAId() + " for DN: "
                + subject.getCertificateDN());
    }
    return cert;
}