Example usage for org.bouncycastle.asn1.x509 Extensions getExtension

List of usage examples for org.bouncycastle.asn1.x509 Extensions getExtension

Introduction

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

Prototype

public Extension getExtension(ASN1ObjectIdentifier oid) 

Source Link

Document

return the extension represented by the object identifier passed in.

Usage

From source file:com.guardtime.asn1.Asn1Util.java

License:Apache License

/**
 * Verifies that the given extensions list does not contain any critical
 * extensions./*from w  ww .  jav  a 2  s  . co  m*/
 *
 * @param exts
 *            the extensions list to check.
 * @throws Asn1FormatException
 *             if the lists is not properly formatted or contains critical
 *             extensions.
 */
static void checkExtensions(Extensions exts) throws Asn1FormatException {
    if (exts == null) {
        // no extensions, nothing to check
        return;
    }
    Enumeration e = exts.oids();
    if (!e.hasMoreElements()) {
        // empty extensions lists are not allowed per X.509 specifications
        throw new Asn1FormatException("empty extensions list");
    }
    while (e.hasMoreElements()) {
        ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier((String) e.nextElement());
        Extension ext = exts.getExtension(oid);
        if (ext == null) {
            // should never happen, but...
            throw new Asn1FormatException("empty extension " + oid.getId());
        }
        if (ext.isCritical()) {
            throw new Asn1FormatException("unknown critical extension " + oid.getId());
        }
    }
}

From source file:net.ripe.rpki.commons.provisioning.x509.pkcs10.RpkiCaCertificateRequestParser.java

License:BSD License

private void extractSiaUris() throws RpkiCaCertificateRequestParserException {
    try {/*from w  ww.j  ava 2 s.  c o  m*/
        Extensions extensions = getPkcs9Extensions();
        Extension extension = extensions.getExtension(X509Extension.subjectInfoAccess);

        ASN1Sequence accessDescriptorSequence = (ASN1Sequence) ASN1Sequence
                .fromByteArray(extension.getExtnValue().getOctets());

        @SuppressWarnings("unchecked")
        Enumeration<DERSequence> objects = accessDescriptorSequence.getObjects();
        while (objects.hasMoreElements()) {
            AccessDescription accessDescription = AccessDescription.getInstance(objects.nextElement());
            X509CertificateInformationAccessDescriptor accessDescriptor = new X509CertificateInformationAccessDescriptor(
                    accessDescription);
            ASN1ObjectIdentifier oid = accessDescriptor.getMethod();
            if (oid.equals(X509CertificateInformationAccessDescriptor.ID_AD_CA_REPOSITORY)) {
                caRepositoryUri = accessDescriptor.getLocation();
            } else if (oid.equals(X509CertificateInformationAccessDescriptor.ID_AD_RPKI_MANIFEST)) {
                manifestUri = accessDescriptor.getLocation();
            } else {
                throw new RpkiCaCertificateRequestParserException(
                        "Don't understand access descriptor using method: " + oid);
            }
        }
    } catch (IOException e) {
        throw new RpkiCaCertificateRequestParserException(e);
    }

}

From source file:org.apache.nifi.registry.security.util.CertificateUtils.java

License:Apache License

/**
 * Generates an issued {@link X509Certificate} from the given issuer certificate and {@link KeyPair}
 *
 * @param dn the distinguished name to use
 * @param publicKey the public key to issue the certificate to
 * @param extensions extensions extracted from the CSR
 * @param issuer the issuer's certificate
 * @param issuerKeyPair the issuer's keypair
 * @param signingAlgorithm the signing algorithm to use
 * @param days the number of days it should be valid for
 * @return an issued {@link X509Certificate} from the given issuer certificate and {@link KeyPair}
 * @throws CertificateException if there is an error issuing the certificate
 *///from   ww w  . ja v a 2s  . c  o m
public static X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, Extensions extensions,
        X509Certificate issuer, KeyPair issuerKeyPair, String signingAlgorithm, int days)
        throws CertificateException {
    try {
        ContentSigner sigGen = new JcaContentSignerBuilder(signingAlgorithm)
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(issuerKeyPair.getPrivate());
        SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
        Date startDate = new Date();
        Date endDate = new Date(startDate.getTime() + TimeUnit.DAYS.toMillis(days));

        X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
                reverseX500Name(new X500Name(issuer.getSubjectX500Principal().getName())),
                getUniqueSerialNumber(), startDate, endDate, reverseX500Name(new X500Name(dn)), subPubKeyInfo);

        certBuilder.addExtension(Extension.subjectKeyIdentifier, false,
                new JcaX509ExtensionUtils().createSubjectKeyIdentifier(publicKey));

        certBuilder.addExtension(Extension.authorityKeyIdentifier, false,
                new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(issuerKeyPair.getPublic()));
        // Set certificate extensions
        // (1) digitalSignature extension
        certBuilder.addExtension(Extension.keyUsage, true,
                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment
                        | KeyUsage.keyAgreement | KeyUsage.nonRepudiation));

        certBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));

        // (2) extendedKeyUsage extension
        certBuilder.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(
                new KeyPurposeId[] { KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth }));

        // (3) subjectAlternativeName
        if (extensions != null && extensions.getExtension(Extension.subjectAlternativeName) != null) {
            certBuilder.addExtension(Extension.subjectAlternativeName, false,
                    extensions.getExtensionParsedValue(Extension.subjectAlternativeName));
        }

        X509CertificateHolder certificateHolder = certBuilder.build(sigGen);
        return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME)
                .getCertificate(certificateHolder);
    } catch (CertIOException | NoSuchAlgorithmException | OperatorCreationException e) {
        throw new CertificateException(e);
    }
}

From source file:org.cesecore.certificates.ca.X509CA.java

License:Open Source License

/**
 * Sequence is ignored by X509CA. The ctParams argument will NOT be kept after the function call returns,
 * and is allowed to contain references to session beans.
 * // w w w .  j  a  va2  s  .c o m
 * @throws CAOfflineException if the CA wasn't active
 * @throws InvalidAlgorithmException if the signing algorithm in the certificate profile (or the CA Token if not found) was invalid.  
 * @throws IllegalValidityException if validity was invalid
 * @throws IllegalNameException if the name specified in the certificate request was invalid
 * @throws CertificateExtensionException if any of the certificate extensions were invalid
 * @throws OperatorCreationException if CA's private key contained an unknown algorithm or provider
 * @throws CertificateCreateException if an error occurred when trying to create a certificate. 
 * @throws SignatureException if the CA's certificate's and request's certificate's and signature algorithms differ
 */
private Certificate generateCertificate(final EndEntityInformation subject, final RequestMessage request,
        final PublicKey publicKey, final int keyusage, final Date notBefore, final Date notAfter,
        final CertificateProfile certProfile, final Extensions extensions, final String sequence,
        final PublicKey caPublicKey, final PrivateKey caPrivateKey, final String provider,
        CertificateGenerationParams certGenParams) throws CAOfflineException, InvalidAlgorithmException,
        IllegalValidityException, IllegalNameException, CertificateExtensionException,
        OperatorCreationException, CertificateCreateException, SignatureException {

    // We must only allow signing to take place if the CA itself is 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() != CAConstants.CA_ACTIVE) && ((getStatus() != CAConstants.CA_EXPIRED))) {
        final 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 = getCAToken().getSignatureAlgorithm();
    } else {
        sigAlg = certProfile.getSignatureAlgorithm();
    }
    // Check that the signature algorithm is one of the allowed ones
    if (!ArrayUtils.contains(AlgorithmConstants.AVAILABLE_SIGALGS, sigAlg)) {
        final String msg = intres.getLocalizedMessage("createcert.invalidsignaturealg", sigAlg);
        throw new InvalidAlgorithmException(msg);
    }
    // Check if this is a root CA we are creating
    final boolean isRootCA = certProfile.getType() == CertificateConstants.CERTTYPE_ROOTCA;

    final X509Certificate cacert = (X509Certificate) getCACertificate();
    // Check CA certificate PrivateKeyUsagePeriod if it exists (throws CAOfflineException if it exists and is not within this time)
    CertificateValidity.checkPrivateKeyUsagePeriod(cacert);
    // Get certificate validity time notBefore and notAfter
    final CertificateValidity val = new CertificateValidity(subject, certProfile, notBefore, notAfter, cacert,
            isRootCA);

    final BigInteger serno;
    {
        // 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();
        if (certProfile.getAllowCertSerialNumberOverride()) {
            if (ei != null && ei.certificateSerialNumber() != null) {
                serno = ei.certificateSerialNumber();
            } else {
                serno = SernoGeneratorRandom.instance().getSerno();
            }
        } else {
            serno = SernoGeneratorRandom.instance().getSerno();
            if ((ei != null) && (ei.certificateSerialNumber() != null)) {
                final String msg = intres.getLocalizedMessage(
                        "createcert.certprof_not_allowing_cert_sn_override_using_normal",
                        ei.certificateSerialNumber().toString(16));
                log.info(msg);
            }
        }
    }

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

    final X500NameStyle nameStyle;
    if (getUsePrintableStringSubjectDN()) {
        nameStyle = PrintableStringNameStyle.INSTANCE;
    } else {
        nameStyle = CeSecoreNameStyle.INSTANCE;
    }

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

    // Will we use LDAP DN order (CN first) or X500 DN order (CN last) for the subject DN
    final boolean ldapdnorder;
    if ((getUseLdapDNOrder() == false) || (certProfile.getUseLdapDnOrder() == false)) {
        ldapdnorder = false;
    } else {
        ldapdnorder = true;
    }
    final X500Name subjectDNName;
    if (certProfile.getAllowDNOverride() && (request != null) && (request.getRequestX500Name() != null)) {
        subjectDNName = request.getRequestX500Name();
        if (log.isDebugEnabled()) {
            log.debug("Using X509Name from request instead of user's registered.");
        }
    } else {
        final ExtendedInformation ei = subject.getExtendedinformation();
        if (certProfile.getAllowDNOverrideByEndEntityInformation() && ei != null
                && ei.getRawSubjectDn() != null) {
            final String stripped = StringTools.strip(ei.getRawSubjectDn());
            final String escapedPluses = CertTools.handleUnescapedPlus(stripped);
            final String emptiesRemoved = DNFieldsUtil.removeAllEmpties(escapedPluses);
            final X500Name subjectDNNameFromEei = CertTools.stringToUnorderedX500Name(emptiesRemoved,
                    CeSecoreNameStyle.INSTANCE);
            if (subjectDNNameFromEei.toString().length() > 0) {
                subjectDNName = subjectDNNameFromEei;
                if (log.isDebugEnabled()) {
                    log.debug(
                            "Using X500Name from end entity information instead of user's registered subject DN fields.");
                    log.debug("ExtendedInformation.getRawSubjectDn(): " + ei.getRawSubjectDn() + " will use: "
                            + CeSecoreNameStyle.INSTANCE.toString(subjectDNName));
                }
            } else {
                subjectDNName = CertTools.stringToBcX500Name(dn, nameStyle, ldapdnorder);
            }
        } else {
            subjectDNName = CertTools.stringToBcX500Name(dn, nameStyle, ldapdnorder);
        }
    }
    // Make sure the DN does not contain dangerous characters
    if (StringTools.hasStripChars(subjectDNName.toString())) {
        if (log.isTraceEnabled()) {
            log.trace("DN with illegal name: " + subjectDNName);
        }
        final String msg = intres.getLocalizedMessage("createcert.illegalname");
        throw new IllegalNameException(msg);
    }
    if (log.isDebugEnabled()) {
        log.debug("Using subjectDN: " + subjectDNName.toString());
    }

    // We must take the issuer DN directly from the CA-certificate otherwise we risk re-ordering the DN
    // which many applications do not like.
    X500Name issuerDNName;
    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");
        }
        issuerDNName = subjectDNName;
    } else {
        issuerDNName = X500Name.getInstance(cacert.getSubjectX500Principal().getEncoded());
        if (log.isDebugEnabled()) {
            log.debug("Using issuer DN directly from the CA certificate: " + issuerDNName.toString());
        }
    }

    SubjectPublicKeyInfo pkinfo;
    try {
        pkinfo = new SubjectPublicKeyInfo((ASN1Sequence) ASN1Primitive.fromByteArray(publicKey.getEncoded()));
    } catch (IOException e) {
        throw new IllegalStateException("Caught unexpected IOException.", e);
    }
    final X509v3CertificateBuilder certbuilder = new X509v3CertificateBuilder(issuerDNName, serno,
            val.getNotBefore(), val.getNotAfter(), subjectDNName, pkinfo);

    // Only created and used if Certificate Transparency is enabled
    final X509v3CertificateBuilder precertbuilder = certProfile.isUseCertificateTransparencyInCerts()
            ? new X509v3CertificateBuilder(issuerDNName, serno, val.getNotBefore(), val.getNotAfter(),
                    subjectDNName, pkinfo)
            : null;

    // Check that the certificate fulfills name constraints
    if (cacert instanceof X509Certificate) {
        GeneralNames altNameGNs = null;
        String altName = subject.getSubjectAltName();
        if (certProfile.getUseSubjectAltNameSubSet()) {
            altName = certProfile.createSubjectAltNameSubSet(altName);
        }
        if (altName != null && altName.length() > 0) {
            altNameGNs = CertTools.getGeneralNamesFromAltName(altName);
        }
        CertTools.checkNameConstraints((X509Certificate) cacert, subjectDNName, altNameGNs);
    }

    // If the subject has Name Constraints, then name constraints must be enabled in the certificate profile!
    if (subject.getExtendedinformation() != null) {
        final ExtendedInformation ei = subject.getExtendedinformation();
        final List<String> permittedNC = ei.getNameConstraintsPermitted();
        final List<String> excludedNC = ei.getNameConstraintsExcluded();
        if ((permittedNC != null && !permittedNC.isEmpty()) || (excludedNC != null && !excludedNC.isEmpty())) {
            if (!certProfile.getUseNameConstraints()) {
                throw new CertificateCreateException(
                        "Tried to issue a certificate with Name Constraints without having enabled NC in the certificate profile.");
            }
        }
    }

    //
    // X509 Certificate Extensions
    //

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

    // First we check if there is general extension override, and add all extensions from
    // the request in that case
    if (certProfile.getAllowExtensionOverride() && extensions != null) {
        ASN1ObjectIdentifier[] oids = extensions.getExtensionOIDs();
        for (ASN1ObjectIdentifier oid : oids) {
            final Extension ext = extensions.getExtension(oid);
            if (log.isDebugEnabled()) {
                log.debug("Overriding extension with oid: " + oid);
            }
            try {
                extgen.addExtension(oid, ext.isCritical(), ext.getParsedValue());
            } catch (IOException e) {
                throw new IllegalStateException("Caught unexpected IOException.", e);
            }
        }
    }

    // Second we see if there is Key usage override
    Extensions 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)) {
            final KeyUsage ku = new KeyUsage(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(Extension.keyUsage) == null) {
                try {
                    extgen.addExtension(Extension.keyUsage, certProfile.getKeyUsageCritical(), ku);
                } catch (IOException e) {
                    throw new IllegalStateException("Caught unexpected IOException.", e);
                }
            } 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
    final CertificateExtensionFactory fact = CertificateExtensionFactory.getInstance();
    final List<String> usedStdCertExt = certProfile.getUsedStandardCertificateExtensions();
    final Iterator<String> certStdExtIter = usedStdCertExt.iterator();
    overridenexts = extgen.generate();
    while (certStdExtIter.hasNext()) {
        final 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 ASN1ObjectIdentifier(oid)) == null) {
            final CertificateExtension certExt = fact.getStandardCertificateExtension(oid, certProfile);
            if (certExt != null) {
                final byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey,
                        val);
                if (value != null) {
                    extgen.addExtension(new ASN1ObjectIdentifier(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
    final List<Integer> usedCertExt = certProfile.getUsedCertificateExtensions();
    final Iterator<Integer> certExtIter = usedCertExt.iterator();
    while (certExtIter.hasNext()) {
        final Integer id = certExtIter.next();
        final 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 ASN1ObjectIdentifier(certExt.getOID())) == null) {
                final byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey,
                        val);
                if (value != null) {
                    extgen.addExtension(new ASN1ObjectIdentifier(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
    final Extensions exts = extgen.generate();
    ASN1ObjectIdentifier[] oids = exts.getExtensionOIDs();
    try {
        for (ASN1ObjectIdentifier oid : oids) {
            final Extension extension = exts.getExtension(oid);
            if (oid.equals(Extension.subjectAlternativeName)) { // subjectAlternativeName extension value needs special handling
                ExtensionsGenerator sanExtGen = getSubjectAltNameExtensionForCert(extension,
                        precertbuilder != null);
                Extensions sanExts = sanExtGen.generate();
                Extension eext = sanExts.getExtension(oid);
                certbuilder.addExtension(oid, eext.isCritical(), eext.getParsedValue()); // adding subjetAlternativeName extension to certbuilder
                if (precertbuilder != null) { // if a pre-certificate is to be published to a CTLog
                    eext = getSubjectAltNameExtensionForCTCert(extension).generate().getExtension(oid);
                    precertbuilder.addExtension(oid, eext.isCritical(), eext.getParsedValue()); // adding subjectAlternativeName extension to precertbuilder

                    eext = sanExts.getExtension(new ASN1ObjectIdentifier("1.3.6.1.4.1.11129.2.4.6"));
                    if (eext != null) {
                        certbuilder.addExtension(eext.getExtnId(), eext.isCritical(), eext.getParsedValue()); // adding nrOfRedactedLabels extension to certbuilder
                    }
                }
            } else { // if not a subjectAlternativeName extension, just add it to both certbuilder and precertbuilder 
                final boolean isCritical = extension.isCritical();
                // We must get the raw octets here in order to be able to create invalid extensions that is not constructed from proper ASN.1
                final byte[] value = extension.getExtnValue().getOctets();
                certbuilder.addExtension(extension.getExtnId(), isCritical, value);
                if (precertbuilder != null) {
                    precertbuilder.addExtension(extension.getExtnId(), isCritical, value);
                }
            }
        }

        // Add Certificate Transparency extension. It needs to access the certbuilder and
        // the CA key so it has to be processed here inside X509CA.
        if (ct != null && certProfile.isUseCertificateTransparencyInCerts()
                && certGenParams.getConfiguredCTLogs() != null
                && certGenParams.getCTAuditLogCallback() != null) {

            // Create pre-certificate
            // A critical extension is added to prevent this cert from being used
            ct.addPreCertPoison(precertbuilder);

            // Sign pre-certificate
            /*
             *  TODO: Should be able to use a special CT signing certificate.
             *  It should have CA=true and ExtKeyUsage=PRECERTIFICATE_SIGNING_OID,
             *  and should not have any other key usages.
             */
            final ContentSigner signer = new BufferingContentSigner(
                    new JcaContentSignerBuilder(sigAlg).setProvider(provider).build(caPrivateKey), 20480);
            final X509CertificateHolder certHolder = precertbuilder.build(signer);
            final X509Certificate cert = (X509Certificate) CertTools
                    .getCertfromByteArray(certHolder.getEncoded());

            // Get certificate chain
            final List<Certificate> chain = new ArrayList<Certificate>();
            chain.add(cert);
            chain.addAll(getCertificateChain());

            // Submit to logs and get signed timestamps
            byte[] sctlist = null;
            try {
                sctlist = ct.fetchSCTList(chain, certProfile, certGenParams.getConfiguredCTLogs());
            } finally {
                // Notify that pre-cert has been successfully or unsuccessfully submitted so it can be audit logged.
                certGenParams.getCTAuditLogCallback().logPreCertSubmission(this, subject, cert,
                        sctlist != null);
            }
            if (sctlist != null) { // can be null if the CTLog has been deleted from the configuration
                ASN1ObjectIdentifier sctOid = new ASN1ObjectIdentifier(CertificateTransparency.SCTLIST_OID);
                certbuilder.addExtension(sctOid, false, new DEROctetString(sctlist));
            }
        } else {
            if (log.isDebugEnabled()) {
                String cause = "";
                if (ct == null) {
                    cause += "CT is not available in this version of EJBCA.";
                } else {
                    if (!certProfile.isUseCertificateTransparencyInCerts()) {
                        cause += "CT is not enabled in the certificate profile. ";
                    }
                    if (certGenParams == null) {
                        cause += "Certificate generation parameters was null.";
                    } else if (certGenParams.getCTAuditLogCallback() == null) {
                        cause += "No CT audit logging callback was passed to X509CA.";
                    } else if (certGenParams.getConfiguredCTLogs() == null) {
                        cause += "There are no CT logs configured in System Configuration.";
                    }
                }
                log.debug("Not logging to CT. " + cause);
            }
        }
    } catch (CertificateException e) {
        throw new CertificateCreateException(
                "Could not process CA's private key when parsing Certificate Transparency extension.", e);
    } catch (IOException e) {
        throw new CertificateCreateException(
                "IOException was caught when parsing Certificate Transparency extension.", e);
    } catch (CTLogException e) {
        throw new CertificateCreateException(
                "An exception occurred because too many CT servers were down to satisfy the certificate profile.",
                e);
    }

    //
    // End of extensions
    //

    if (log.isTraceEnabled()) {
        log.trace(">certgen.generate");
    }
    final ContentSigner signer = new BufferingContentSigner(
            new JcaContentSignerBuilder(sigAlg).setProvider(provider).build(caPrivateKey), 20480);
    final X509CertificateHolder certHolder = certbuilder.build(signer);
    X509Certificate cert;
    try {
        cert = (X509Certificate) CertTools.getCertfromByteArray(certHolder.getEncoded());
    } catch (IOException e) {
        throw new IllegalStateException("Unexpected IOException caught when parsing certificate holder.", e);
    } catch (CertificateException e) {
        throw new CertificateCreateException("Could not create certificate from CA's private key,", e);
    }
    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...
    final 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;
    }
    try {
        cert.verify(verifyKey);
    } catch (InvalidKeyException e) {
        throw new CertificateCreateException("CA's public key was invalid,", e);
    } catch (NoSuchAlgorithmException e) {
        throw new CertificateCreateException(e);
    } catch (NoSuchProviderException e) {
        throw new IllegalStateException("Provider was unknown", e);
    } catch (CertificateException e) {
        throw new CertificateCreateException(e);
    }

    // If we have a CA-certificate, verify that we have all path verification stuff correct
    if (cacert != null) {
        final byte[] aki = CertTools.getAuthorityKeyId(cert);
        final byte[] ski = CertTools.getSubjectKeyId(isRootCA ? cert : cacert);
        if ((aki != null) && (ski != null)) {
            final boolean eq = Arrays.equals(aki, ski);
            if (!eq) {
                final String akistr = new String(Hex.encode(aki));
                final String skistr = new String(Hex.encode(ski));
                final String msg = intres.getLocalizedMessage("createcert.errorpathverifykeyid", akistr,
                        skistr);
                log.error(msg);
                // This will differ if we create link certificates, NewWithOld, therefore we can not throw an exception here.
            }
        }
        final Principal issuerDN = cert.getIssuerX500Principal();
        final Principal caSubjectDN = cacert.getSubjectX500Principal();
        if ((issuerDN != null) && (caSubjectDN != null)) {
            final boolean eq = issuerDN.equals(caSubjectDN);
            if (!eq) {
                final String msg = intres.getLocalizedMessage("createcert.errorpathverifydn",
                        issuerDN.getName(), caSubjectDN.getName());
                log.error(msg);
                throw new CertificateCreateException(msg);
            }
        }
    }
    // Before returning from this method, we will set the private key and provider in the request message, in case the response  message needs to be signed
    if (request != null) {
        request.setResponseKeyInfo(caPrivateKey, provider);
    }
    if (log.isDebugEnabled()) {
        log.debug("X509CA: generated certificate, CA " + this.getCAId() + " for DN: "
                + subject.getCertificateDN());
    }
    return cert;
}

From source file:org.cesecore.certificates.certificate.certextensions.BasicCertificateExtensionTest.java

License:Open Source License

@Test
public void test20CertExtensionEncoding() throws Exception {
    Properties props = new Properties();
    props.put("id1.property.encoding", "DERIA5STRING");
    props.put("id1.property.value", "This is a printable string");

    BasicCertificateExtension baseExt = new BasicCertificateExtension();
    baseExt.init(1, "1.2.3", false, props);

    byte[] value = baseExt.getValueEncoded(null, null, null, null, null, null);

    ExtensionsGenerator extgen = new ExtensionsGenerator();
    extgen.addExtension(new ASN1ObjectIdentifier(baseExt.getOID()), baseExt.isCriticalFlag(), value);
    Extensions exts = extgen.generate();
    ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(baseExt.getOID());
    Extension ext = exts.getExtension(oid);
    assertNotNull(ext);//w ww . j  av  a  2 s  .  c om
    // Read the extension value, it's a DERIA5String wrapped in an ASN1OctetString
    ASN1OctetString str = ext.getExtnValue();
    ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(str.getOctets()));
    DERIA5String ia5str = (DERIA5String) aIn.readObject();
    aIn.close();
    assertEquals("This is a printable string", ia5str.getString());
}

From source file:org.cesecore.certificates.certificate.CertificateCreateSessionBean.java

License:Open Source License

@Override
public CertificateResponseMessage createCertificate(final AuthenticationToken admin,
        final EndEntityInformation endEntityInformation, final CA ca, final RequestMessage req,
        final Class<? extends ResponseMessage> responseClass, CertificateGenerationParams certGenParams,
        final long updateTime)
        throws CryptoTokenOfflineException, SignRequestSignatureException, IllegalKeyException,
        IllegalNameException, CustomCertificateSerialNumberException, CertificateCreateException,
        CertificateRevokeException, CertificateSerialNumberException, AuthorizationDeniedException,
        IllegalValidityException, CAOfflineException, InvalidAlgorithmException, CertificateExtensionException {
    if (log.isTraceEnabled()) {
        log.trace(">createCertificate(IRequestMessage, CA)");
    }/*from ww  w  . j av a2 s  . c o m*/
    CertificateResponseMessage ret = null;
    try {
        final CAToken catoken = ca.getCAToken();
        final CryptoToken cryptoToken = cryptoTokenManagementSession.getCryptoToken(catoken.getCryptoTokenId());
        final String alias = catoken.getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CERTSIGN);
        // See if we need some key material to decrypt request
        if (req.requireKeyInfo()) {
            // You go figure...scep encrypts message with the public CA-cert
            req.setKeyInfo(ca.getCACertificate(), cryptoToken.getPrivateKey(alias),
                    cryptoToken.getEncProviderName());
        }
        // Verify the request
        final PublicKey reqpk;
        try {
            if (!req.verify()) {
                throw new SignRequestSignatureException(
                        intres.getLocalizedMessage("createcert.popverificationfailed"));
            }
            reqpk = req.getRequestPublicKey();
            if (reqpk == null) {
                final String msg = intres.getLocalizedMessage("createcert.nokeyinrequest");
                throw new InvalidKeyException(msg);
            }
        } catch (InvalidKeyException e) {
            // If we get an invalid key exception here, we should throw an IllegalKeyException to the caller
            // The catch of InvalidKeyException in the end of this method, catches error from the CA crypto token
            throw new IllegalKeyException(e);
        }

        final Date notBefore = req.getRequestValidityNotBefore(); // Optionally requested validity
        final Date notAfter = req.getRequestValidityNotAfter(); // Optionally requested validity
        final Extensions exts = req.getRequestExtensions(); // Optionally requested extensions
        int keyusage = -1;
        if (exts != null) {
            if (log.isDebugEnabled()) {
                log.debug(
                        "we have extensions, see if we can override KeyUsage by looking for a KeyUsage extension in request");
            }
            final Extension ext = exts.getExtension(Extension.keyUsage);
            if (ext != null) {
                final ASN1OctetString os = ext.getExtnValue();
                DERBitString bs;
                try {
                    bs = new DERBitString(os.getEncoded());
                } catch (IOException e) {
                    throw new IllegalStateException("Unexpected IOException caught.");
                }
                keyusage = bs.intValue();
                if (log.isDebugEnabled()) {
                    log.debug("We have a key usage request extension: " + keyusage);
                }
            }
        }
        String sequence = null;
        byte[] ki = req.getRequestKeyInfo();
        // CVC sequence is only 5 characters, don't fill with a lot of garbage here, it must be a readable string
        if ((ki != null) && (ki.length > 0) && (ki.length < 10)) {
            final String str = new String(ki);
            // A cvc sequence must be ascii printable, otherwise it's some binary data
            if (StringUtils.isAsciiPrintable(str)) {
                sequence = new String(ki);
            }
        }

        CertificateDataWrapper certWrapper = createCertificate(admin, endEntityInformation, ca, req, reqpk,
                keyusage, notBefore, notAfter, exts, sequence, certGenParams, updateTime);
        // Create the response message with all nonces and checks etc
        ret = ResponseMessageUtils.createResponseMessage(responseClass, req, ca.getCertificateChain(),
                cryptoToken.getPrivateKey(alias), cryptoToken.getEncProviderName());
        ResponseStatus status = ResponseStatus.SUCCESS;
        FailInfo failInfo = null;
        String failText = null;
        if ((certWrapper == null) && (status == ResponseStatus.SUCCESS)) {
            status = ResponseStatus.FAILURE;
            failInfo = FailInfo.BAD_REQUEST;
        } else {
            ret.setCertificate(certWrapper.getCertificate());
            ret.setCACert(ca.getCACertificate());
            ret.setBase64CertData(certWrapper.getBase64CertData());
            ret.setCertificateData(certWrapper.getCertificateData());
        }
        ret.setStatus(status);
        if (failInfo != null) {
            ret.setFailInfo(failInfo);
            ret.setFailText(failText);
        }
        ret.create();
    } catch (InvalidKeyException e) {
        throw new CertificateCreateException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new CertificateCreateException(e);
    } catch (NoSuchProviderException e) {
        throw new CertificateCreateException(e);
    } catch (CertificateEncodingException e) {
        throw new CertificateCreateException(e);
    } catch (CRLException e) {
        throw new CertificateCreateException(e);
    }

    if (log.isTraceEnabled()) {
        log.trace("<createCertificate(IRequestMessage, CA)");
    }
    return ret;
}

From source file:org.cesecore.certificates.certificate.request.PKCS10RequestMessage.java

License:Open Source License

@Override
public String getPassword() {
    if (password != null) {
        return password;
    }//w w  w .ja  v  a  2s . c o m
    try {
        if (pkcs10 == null) {
            init();
        }
    } catch (NullPointerException e) {
        log.error("PKCS10 not initated! " + e.getMessage());
        return null;
    }

    String ret = null;
    Attribute[] attributes = pkcs10.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_challengePassword);
    ASN1Encodable obj = null;
    if (attributes.length == 0) {
        // See if we have it embedded in an extension request instead
        attributes = pkcs10.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
        if (attributes.length == 0) {
            return null;
        }
        if (log.isDebugEnabled()) {
            log.debug("got extension request");
        }
        ASN1Set values = attributes[0].getAttrValues();
        if (values.size() == 0) {
            return null;
        }
        Extensions exts = Extensions.getInstance(values.getObjectAt(0));
        Extension ext = exts.getExtension(PKCSObjectIdentifiers.pkcs_9_at_challengePassword);
        if (ext == null) {
            if (log.isDebugEnabled()) {
                log.debug("no challenge password extension");
            }
            return null;
        }
        obj = ext.getExtnValue();
    } else {
        // If it is a challengePassword directly, it's just to grab the value
        ASN1Set values = attributes[0].getAttrValues();
        obj = values.getObjectAt(0);
    }

    if (obj != null) {
        ASN1String str = null;

        try {
            str = DERPrintableString.getInstance((obj));
        } catch (IllegalArgumentException ie) {
            // This was not printable string, should be utf8string then according to pkcs#9 v2.0
            str = DERUTF8String.getInstance((obj));
        }

        if (str != null) {
            ret = str.getString();
        }
    }

    return ret;
}

From source file:org.cesecore.certificates.certificate.request.PKCS10RequestMessage.java

License:Open Source License

@Override
public String getRequestAltNames() {
    String ret = null;/*from   w  ww .j a va  2s  . c  om*/
    try {
        Extensions exts = getRequestExtensions();
        if (exts != null) {
            Extension ext = exts.getExtension(Extension.subjectAlternativeName);
            if (ext != null) {
                // Finally read the value
                ret = CertTools.getAltNameStringFromExtension(ext);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("no subject altName extension");
                }
            }
        }
    } catch (IllegalArgumentException e) {
        if (log.isDebugEnabled()) {
            log.debug(
                    "pkcs_9_extensionRequest does not contain Extensions that it should, ignoring invalid encoded extension request.");
        }
    }
    return ret;
}

From source file:org.cesecore.util.CertToolsTest.java

License:Open Source License

@Test
public void test19getAltNameStringFromExtension() throws Exception {
    {/*from  w  w w.j ava  2s .c om*/
        PKCS10CertificationRequest p10 = new JcaPKCS10CertificationRequest(p10ReqWithAltNames);
        Attribute attribute = p10.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)[0];
        // The set of attributes contains a sequence of with type oid
        // PKCSObjectIdentifiers.pkcs_9_at_extensionRequest
        boolean found = false;
        DERSet s = (DERSet) attribute.getAttrValues();
        Extensions exts = Extensions.getInstance(s.getObjectAt(0));
        Extension ext = exts.getExtension(Extension.subjectAlternativeName);
        if (ext != null) {
            found = true;
            String altNames = CertTools.getAltNameStringFromExtension(ext);
            assertEquals("dNSName=ort3-kru.net.polisen.se, iPAddress=10.252.255.237", altNames);

        }
        assertTrue(found);
    }
    {
        PKCS10CertificationRequest p10 = new JcaPKCS10CertificationRequest(p10ReqWithAltNames2);
        // The set of attributes contains a sequence of with type oid
        // PKCSObjectIdentifiers.pkcs_9_at_extensionRequest
        Attribute attribute = p10.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)[0];
        boolean found = false;
        DERSet s = (DERSet) attribute.getAttrValues();
        Extensions exts = Extensions.getInstance(s.getObjectAt(0));
        Extension ext = exts.getExtension(Extension.subjectAlternativeName);
        if (ext != null) {
            found = true;
            String altNames = CertTools.getAltNameStringFromExtension(ext);
            assertEquals("dNSName=foo.bar.com, iPAddress=10.0.0.1", altNames);
        }
        assertTrue(found);
    }

}

From source file:org.ejbca.core.protocol.cmp.CmpMessageHelper.java

License:Open Source License

public static RevDetails getNovosecRevDetails(RevReqContent revContent) {
    // Novosec implements RFC2510, while bouncycastle 1.47 implements RFC4210.
    ////w  ww  .j  a v a  2  s .c o m
    // In RFC2510/novosec, the RevDetails structure looks like this:
    //              RevDetails ::= SEQUENCE {
    //                                  certDetails         CertTemplate,
    //                                  revocationReason    ReasonFlags      OPTIONAL,
    //                                  badSinceDate        GeneralizedTime  OPTIONAL,
    //                                  crlEntryDetails     Extensions       OPTIONAL
    //             }
    //
    // In RFC4210/bouncycastle, the REVDetails structure looks like this:
    //                 RevDetails ::= SEQUENCE {
    //                                  certDetails         CertTemplate,
    //                                  crlEntryDetails     Extensions       OPTIONAL
    //                  }
    //
    // This means that there is a chance that the request generated using novosec specifies the revocation reason in 'revocationReason' and not
    // as an extension, leading to Ejbca not being able to parse the request using bouncycastle OR not setting the correct revocation reason.

    ASN1Encodable o2 = ((DERSequence) revContent.toASN1Primitive()).getObjectAt(0);
    ASN1Encodable o3 = ((DERSequence) o2).getObjectAt(0);
    CertTemplate ct = CertTemplate.getInstance(o3);

    ReasonFlags reasonbits = null;
    Extensions crlEntryDetails = null;
    int seqSize = ((DERSequence) o2).size();
    for (int i = 1; i < seqSize; i++) {
        ASN1Encodable o4 = ((DERSequence) o2).getObjectAt(i);
        if (o4 instanceof DERBitString) {
            reasonbits = new ReasonFlags((DERBitString) o4);
        } else if (o4 instanceof DERGeneralizedTime) {
            DERGeneralizedTime.getInstance(o4); // bad since time, not used in the bouncycastle class
        } else if (o4 instanceof DERSequence) {
            crlEntryDetails = Extensions.getInstance(o4);
        }
    }

    if ((crlEntryDetails != null) && (reasonbits != null)) {
        Extension reason = crlEntryDetails.getExtension(Extension.reasonCode);
        if (reason == null) {
            reason = new Extension(Extension.reasonCode, true,
                    ASN1OctetString.getInstance(reasonbits.getBytes()));
        }
    } else if ((crlEntryDetails == null) && (reasonbits != null)) {
        ExtensionsGenerator extgen = new ExtensionsGenerator();
        try {
            extgen.addExtension(Extension.reasonCode, true, ASN1OctetString.getInstance(reasonbits.getBytes()));
            crlEntryDetails = extgen.generate();
        } catch (IOException e) {
            LOG.error(e.getLocalizedMessage(), e);
        }
    }

    //The constructor RevDetails(certTemplate, crlEntryDetails) only sets 'crlEntryDetails' and ignores 'certTemplate'
    //This is a reported bug in bouncycastle. For now, the only way to have both of them set is to create a ASN1/DERSequence 
    ASN1EncodableVector seq = new ASN1EncodableVector();
    seq.add(ct);
    seq.add(crlEntryDetails);
    RevDetails res = RevDetails.getInstance(new DERSequence(seq));
    return res;
}