Example usage for org.bouncycastle.asn1.x500 X500Name X500Name

List of usage examples for org.bouncycastle.asn1.x500 X500Name X500Name

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x500 X500Name X500Name.

Prototype

public X500Name(String dirName) 

Source Link

Usage

From source file:org.xdi.oxauth.model.crypto.OxAuthCryptoProvider.java

License:MIT License

public X509Certificate generateV3Certificate(KeyPair keyPair, String issuer, String signatureAlgorithm,
        Long expirationTime) throws CertIOException, OperatorCreationException, CertificateException {
    PrivateKey privateKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();

    // Signers name
    X500Name issuerName = new X500Name(issuer);

    // Subjects name - the same as we are self signed.
    X500Name subjectName = new X500Name(issuer);

    // Serial//from w  ww  .j av  a  2s.c  o m
    BigInteger serial = new BigInteger(256, new SecureRandom());

    // Not before
    Date notBefore = new Date(System.currentTimeMillis() - 10000);
    Date notAfter = new Date(expirationTime);

    // Create the certificate - version 3
    JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(issuerName, serial, notBefore,
            notAfter, subjectName, publicKey);

    ASN1EncodableVector purposes = new ASN1EncodableVector();
    purposes.add(KeyPurposeId.id_kp_serverAuth);
    purposes.add(KeyPurposeId.id_kp_clientAuth);
    purposes.add(KeyPurposeId.anyExtendedKeyUsage);

    ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37").intern();
    builder.addExtension(extendedKeyUsage, false, new DERSequence(purposes));

    ContentSigner signer = new JcaContentSignerBuilder(signatureAlgorithm).setProvider("BC").build(privateKey);
    X509CertificateHolder holder = builder.build(signer);
    X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder);

    return cert;
}

From source file:org.xipki.ca.api.profile.x509.BaseX509Certprofile.java

License:Open Source License

@Override
public SubjectInfo getSubject(final X500Name requestedSubject)
        throws CertprofileException, BadCertTemplateException {
    verifySubjectDNOccurence(requestedSubject);
    checkSubjectContent(requestedSubject);

    RDN[] requstedRDNs = requestedSubject.getRDNs();
    Set<RDNControl> controls = getSubjectDNControls();
    List<RDN> rdns = new LinkedList<>();
    List<ASN1ObjectIdentifier> types = backwardsSubject() ? ObjectIdentifiers.getBackwardDNs()
            : ObjectIdentifiers.getForwardDNs();

    for (ASN1ObjectIdentifier type : types) {
        RDNControl control = null;//from w w  w .j a v  a 2 s.  c o m
        if (controls != null) {
            control = getRDNControl(controls, type);
            if (control == null || control.getMaxOccurs() < 1) {
                continue;
            }
        }

        RDN[] thisRDNs = getRDNs(requstedRDNs, type);
        int n = thisRDNs == null ? 0 : thisRDNs.length;
        if (n == 0) {
            continue;
        }

        if (n == 1) {
            String value = X509Util.rdnValueToString(thisRDNs[0].getFirst().getValue());
            rdns.add(createSubjectRDN(value, type, control, 0));
        } else {
            String[] values = new String[n];
            for (int i = 0; i < n; i++) {
                values[i] = X509Util.rdnValueToString(thisRDNs[i].getFirst().getValue());
            }
            values = sortRDNs(type, values);

            int index = 0;
            for (String value : values) {
                rdns.add(createSubjectRDN(value, type, control, index++));
            }
        }
    }

    X500Name grantedSubject = new X500Name(rdns.toArray(new RDN[0]));
    return new SubjectInfo(grantedSubject, null);
}

From source file:org.xipki.ca.certprofile.XmlX509Certprofile.java

License:Open Source License

@Override
public SubjectInfo getSubject(final X500Name requestedSubject)
        throws CertprofileException, BadCertTemplateException {
    verifySubjectDNOccurence(requestedSubject);
    checkSubjectContent(requestedSubject);

    RDN[] requstedRDNs = requestedSubject.getRDNs();
    Set<RDNControl> occurences = getSubjectDNControls();
    List<RDN> rdns = new LinkedList<>();
    List<ASN1ObjectIdentifier> types = backwardsSubject() ? ObjectIdentifiers.getBackwardDNs()
            : ObjectIdentifiers.getForwardDNs();

    for (ASN1ObjectIdentifier type : types) {
        if (Extension.subjectAlternativeName.equals(type) || Extension.subjectInfoAccess.equals(type)) {
            continue;
        }//from  ww  w. j  av  a 2s.  c o  m

        RDNControl control = null;
        if (occurences != null) {
            control = getRDNControl(occurences, type);
            if (control == null || control.getMaxOccurs() < 1) {
                continue;
            }
        }

        RDN[] thisRDNs = getRDNs(requstedRDNs, type);
        int n = thisRDNs == null ? 0 : thisRDNs.length;
        if (n == 0) {
            continue;
        }

        if (n == 1) {
            String value = X509Util.rdnValueToString(thisRDNs[0].getFirst().getValue());
            rdns.add(createSubjectRDN(value, type, control, 0));
        } else {
            String[] values = new String[n];
            for (int i = 0; i < n; i++) {
                values[i] = X509Util.rdnValueToString(thisRDNs[i].getFirst().getValue());
            }
            values = sortRDNs(type, values);

            int i = 0;
            for (String value : values) {
                rdns.add(createSubjectRDN(value, type, control, i++));
            }
        }
    }

    X500Name grantedSubject = new X500Name(rdns.toArray(new RDN[0]));
    return new SubjectInfo(grantedSubject, null);
}

From source file:org.xipki.ca.certprofile.XmlX509CertprofileUtil.java

License:Open Source License

private static GeneralSubtree buildGeneralSubtree(final GeneralSubtreeBaseType type)
        throws CertprofileException {
    GeneralName base = null;/*from   w  w  w .ja  v a 2  s .  com*/
    if (type.getDirectoryName() != null) {
        base = new GeneralName(X509Util.reverse(new X500Name(type.getDirectoryName())));
    } else if (type.getDNSName() != null) {
        base = new GeneralName(GeneralName.dNSName, type.getDNSName());
    } else if (type.getIpAddress() != null) {
        base = new GeneralName(GeneralName.iPAddress, type.getIpAddress());
    } else if (type.getRfc822Name() != null) {
        base = new GeneralName(GeneralName.rfc822Name, type.getRfc822Name());
    } else if (type.getUri() != null) {
        base = new GeneralName(GeneralName.uniformResourceIdentifier, type.getUri());
    } else {
        throw new RuntimeException("should not reach here, unknown child of GeneralSubtreeBaseType");
    }

    Integer i = type.getMinimum();
    if (i != null && i < 0) {
        throw new CertprofileException("negative minimum is not allowed: " + i);
    }

    BigInteger minimum = (i == null) ? null : BigInteger.valueOf(i.intValue());

    i = type.getMaximum();
    if (i != null && i < 0) {
        throw new CertprofileException("negative maximum is not allowed: " + i);
    }

    BigInteger maximum = (i == null) ? null : BigInteger.valueOf(i.intValue());

    return new GeneralSubtree(base, minimum, maximum);
}

From source file:org.xipki.ca.client.shell.EnrollCertCommand.java

License:Open Source License

@Override
protected Object _doExecute() throws Exception {
    EnrollCertRequestType request = new EnrollCertRequestType(EnrollCertRequestType.Type.CERT_REQ);

    CertTemplateBuilder certTemplateBuilder = new CertTemplateBuilder();

    ConcurrentContentSigner signer = getSigner(hashAlgo, new SignatureAlgoControl(rsaMgf1, dsaPlain));
    X509CertificateHolder ssCert = signer.getCertificateAsBCObject();

    X500Name x500Subject = subject == null ? ssCert.getSubject() : new X500Name(subject);
    certTemplateBuilder.setSubject(x500Subject);
    certTemplateBuilder.setPublicKey(ssCert.getSubjectPublicKeyInfo());

    if (needExtensionTypes == null) {
        needExtensionTypes = new LinkedList<>();
    }//from   w  w  w.j  a  v a2 s  .  co m

    // SubjectAltNames
    List<Extension> extensions = new LinkedList<>();
    if (isNotEmpty(subjectAltNames)) {
        extensions.add(P10RequestGenerator.createExtensionSubjectAltName(subjectAltNames, false));
        needExtensionTypes.add(Extension.subjectAlternativeName.getId());
    }

    // SubjectInfoAccess
    if (isNotEmpty(subjectInfoAccesses)) {
        extensions.add(P10RequestGenerator.createExtensionSubjectInfoAccess(subjectInfoAccesses, false));
        needExtensionTypes.add(Extension.subjectInfoAccess.getId());
    }

    // Keyusage
    if (isNotEmpty(keyusages)) {
        Set<KeyUsage> usages = new HashSet<>();
        for (String usage : keyusages) {
            usages.add(KeyUsage.getKeyUsage(usage));
        }
        org.bouncycastle.asn1.x509.KeyUsage extValue = X509Util.createKeyUsage(usages);
        ASN1ObjectIdentifier extType = Extension.keyUsage;
        extensions.add(new Extension(extType, false, extValue.getEncoded()));
        needExtensionTypes.add(extType.getId());
    }

    // ExtendedKeyusage
    if (isNotEmpty(extkeyusages)) {
        Set<ASN1ObjectIdentifier> oids = new HashSet<>(SecurityUtil.textToASN1ObjectIdentifers(extkeyusages));
        ExtendedKeyUsage extValue = X509Util.createExtendedUsage(oids);
        ASN1ObjectIdentifier extType = Extension.extendedKeyUsage;
        extensions.add(new Extension(extType, false, extValue.getEncoded()));
        needExtensionTypes.add(extType.getId());
    }

    if (isNotEmpty(needExtensionTypes) || isNotEmpty(wantExtensionTypes)) {
        ExtensionExistence ee = new ExtensionExistence(
                SecurityUtil.textToASN1ObjectIdentifers(needExtensionTypes),
                SecurityUtil.textToASN1ObjectIdentifers(wantExtensionTypes));
        extensions.add(new Extension(ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions, false,
                ee.toASN1Primitive().getEncoded()));
    }

    if (isNotEmpty(extensions)) {
        Extensions asn1Extensions = new Extensions(extensions.toArray(new Extension[0]));
        certTemplateBuilder.setExtensions(asn1Extensions);
    }

    CertRequest certReq = new CertRequest(1, certTemplateBuilder.build(), null);

    ProofOfPossessionSigningKeyBuilder popoBuilder = new ProofOfPossessionSigningKeyBuilder(certReq);
    ContentSigner contentSigner = signer.borrowContentSigner();
    POPOSigningKey popoSk;
    try {
        popoSk = popoBuilder.build(contentSigner);
    } finally {
        signer.returnContentSigner(contentSigner);
    }

    ProofOfPossession popo = new ProofOfPossession(popoSk);

    EnrollCertRequestEntryType reqEntry = new EnrollCertRequestEntryType("id-1", profile, certReq, popo);
    request.addRequestEntry(reqEntry);

    RequestResponseDebug debug = getRequestResponseDebug();
    EnrollCertResult result;
    try {
        result = caClient.requestCerts(request, caName, user, debug);
    } finally {
        saveRequestResponse(debug);
    }

    X509Certificate cert = null;
    if (result != null) {
        String id = result.getAllIds().iterator().next();
        CertOrError certOrError = result.getCertificateOrError(id);
        cert = (X509Certificate) certOrError.getCertificate();
    }

    if (cert == null) {
        throw new CmdFailure("no certificate received from the server");
    }

    File certFile = new File(outputFile);
    saveVerbose("saved certificate to file", certFile, cert.getEncoded());

    return null;
}

From source file:org.xipki.ca.qa.impl.X509CertprofileQAImpl.java

License:Open Source License

private void checkExtensionNameConstraintsSubtrees(final StringBuilder failureMsg, final String description,
        final GeneralSubtree[] subtrees, final List<QaGeneralSubtree> expectedSubtrees) {
    int iSize = subtrees == null ? 0 : subtrees.length;
    int eSize = expectedSubtrees == null ? 0 : expectedSubtrees.size();
    if (iSize != eSize) {
        failureMsg.append("size of " + description + " is '" + iSize + "' but expected '" + eSize + "'");
        failureMsg.append("; ");
        return;//w  ww . j a v a 2  s.c  om
    }

    for (int i = 0; i < iSize; i++) {
        GeneralSubtree iSubtree = subtrees[i];
        QaGeneralSubtree eSubtree = expectedSubtrees.get(i);
        BigInteger bigInt = iSubtree.getMinimum();
        int iMinimum = bigInt == null ? 0 : bigInt.intValue();
        Integer _int = eSubtree.getMinimum();
        int eMinimum = _int == null ? 0 : _int.intValue();
        String desc = description + " [" + i + "]";
        if (iMinimum != eMinimum) {
            failureMsg.append("minimum of " + desc + " is '" + iMinimum + "' but expected '" + eMinimum + "'");
            failureMsg.append("; ");
        }

        bigInt = iSubtree.getMaximum();
        Integer iMaximum = bigInt == null ? null : bigInt.intValue();
        Integer eMaximum = eSubtree.getMaximum();
        if (iMaximum != eMaximum) {
            failureMsg.append("maxmum of " + desc + " is '" + iMaximum + "' but expected '" + eMaximum + "'");
            failureMsg.append("; ");
        }

        GeneralName iBase = iSubtree.getBase();

        GeneralName eBase;
        if (eSubtree.getDirectoryName() != null) {
            eBase = new GeneralName(X509Util.reverse(new X500Name(eSubtree.getDirectoryName())));
        } else if (eSubtree.getDNSName() != null) {
            eBase = new GeneralName(GeneralName.dNSName, eSubtree.getDNSName());
        } else if (eSubtree.getIpAddress() != null) {
            eBase = new GeneralName(GeneralName.iPAddress, eSubtree.getIpAddress());
        } else if (eSubtree.getRfc822Name() != null) {
            eBase = new GeneralName(GeneralName.rfc822Name, eSubtree.getRfc822Name());
        } else if (eSubtree.getUri() != null) {
            eBase = new GeneralName(GeneralName.uniformResourceIdentifier, eSubtree.getUri());
        } else {
            throw new RuntimeException("should not reach here, unknown child of GeneralName");
        }

        if (iBase.equals(eBase) == false) {
            failureMsg.append("base of " + desc + " is '" + iBase + "' but expected '" + eBase + "'");
            failureMsg.append("; ");
        }
    }
}

From source file:org.xipki.ca.qa.shell.NegEnrollCertCommand.java

License:Open Source License

@Override
protected Object _doExecute() throws Exception {
    EnrollCertRequestType request = new EnrollCertRequestType(EnrollCertRequestType.Type.CERT_REQ);

    CertTemplateBuilder certTemplateBuilder = new CertTemplateBuilder();
    ConcurrentContentSigner signer = getSigner(hashAlgo, new SignatureAlgoControl(rsaMgf1, dsaPlain));
    X509CertificateHolder ssCert = signer.getCertificateAsBCObject();

    X500Name x500Subject = subject == null ? ssCert.getSubject() : new X500Name(subject);
    certTemplateBuilder.setSubject(x500Subject);
    certTemplateBuilder.setPublicKey(ssCert.getSubjectPublicKeyInfo());
    CertRequest certReq = new CertRequest(1, certTemplateBuilder.build(), null);

    ProofOfPossessionSigningKeyBuilder popoBuilder = new ProofOfPossessionSigningKeyBuilder(certReq);
    ContentSigner contentSigner = signer.borrowContentSigner();
    POPOSigningKey popoSk;//w w  w  . ja  va 2 s . co  m
    try {
        popoSk = popoBuilder.build(contentSigner);
    } finally {
        signer.returnContentSigner(contentSigner);
    }

    ProofOfPossession popo = new ProofOfPossession(popoSk);

    EnrollCertRequestEntryType reqEntry = new EnrollCertRequestEntryType("id-1", profile, certReq, popo);
    request.addRequestEntry(reqEntry);

    EnrollCertResult result;
    RequestResponseDebug debug = getRequestResponseDebug();
    try {
        result = caClient.requestCerts(request, caName, user, debug);
    } finally {
        saveRequestResponse(debug);
    }

    X509Certificate cert = null;
    if (result != null) {
        String id = result.getAllIds().iterator().next();
        CertOrError certOrError = result.getCertificateOrError(id);
        cert = (X509Certificate) certOrError.getCertificate();
    }

    if (cert != null) {
        throw new CmdFailure("no certificate is excepted, but received one");
    }

    return null;
}

From source file:org.xipki.ca.server.impl.store.CertStoreQueryExecutor.java

License:Open Source License

String getLatestSN(final X500Name nameWithSN) throws OperationException {
    RDN[] rdns1 = nameWithSN.getRDNs();// ww  w .jav  a 2 s  . co m
    RDN[] rdns2 = new RDN[rdns1.length];
    for (int i = 0; i < rdns1.length; i++) {
        RDN rdn = rdns1[i];
        if (rdn.getFirst().getType().equals(ObjectIdentifiers.DN_SERIALNUMBER)) {
            rdns2[i] = new RDN(ObjectIdentifiers.DN_SERIALNUMBER, new DERPrintableString("%"));
        } else {
            rdns2[i] = rdn;
        }
    }

    String namePattern = X509Util.getRFC4519Name(new X500Name(rdns2));

    final String sql = dataSource.createFetchFirstSelectSQL("SUBJECT FROM CERT WHERE SUBJECT LIKE ?", 1,
            "NOTBEFORE DESC");
    ResultSet rs = null;
    PreparedStatement ps;
    try {
        ps = borrowPreparedStatement(sql);
    } catch (DataAccessException e) {
        throw new OperationException(ErrorCode.DATABASE_FAILURE, e.getMessage());
    }

    try {
        ps.setString(1, namePattern);
        rs = ps.executeQuery();
        if (rs.next()) {
            String str = rs.getString("SUBJECT");
            X500Name lastName = new X500Name(str);
            RDN[] rdns = lastName.getRDNs(ObjectIdentifiers.DN_SERIALNUMBER);
            if (rdns == null || rdns.length == 0) {
                return null;
            } else {
                return X509Util.rdnValueToString(rdns[0].getFirst().getValue());
            }
        }
    } catch (SQLException e) {
        throw new OperationException(ErrorCode.DATABASE_FAILURE, e.getMessage());
    } finally {
        releaseDbResources(ps, rs);
    }

    return null;
}

From source file:org.xipki.ca.server.impl.X509CA.java

License:Open Source License

private X509CertificateInfo intern_generateCertificate(final boolean requestedByRA,
        final RequestorInfo requestor, final String certprofileLocalName, final String user,
        X500Name requestedSubject, SubjectPublicKeyInfo publicKeyInfo, Date notBefore, Date notAfter,
        final org.bouncycastle.asn1.x509.Extensions extensions, final boolean keyUpdate)
        throws OperationException {
    if (caInfo.getRevocationInfo() != null) {
        throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is revoked");
    }//from   www .  ja  v  a 2s. c o m

    IdentifiedX509Certprofile certprofile = getX509Certprofile(certprofileLocalName);

    if (certprofile == null) {
        throw new OperationException(ErrorCode.UNKNOWN_CERT_PROFILE,
                "unknown cert profile " + certprofileLocalName);
    }

    ConcurrentContentSigner signer = caInfo.getSigner(certprofile.getSignatureAlgorithms());
    if (signer == null) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                "CA does not support any signature algorithm restricted by the cert profile");
    }

    final String certprofileName = certprofile.getName();
    if (certprofile.getVersion() != X509CertVersion.V3) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, "unknown cert version " + certprofile);
    }

    if (certprofile.isOnlyForRA() && requestedByRA == false) {
        throw new OperationException(ErrorCode.INSUFFICIENT_PERMISSION,
                "profile " + certprofileName + " not applied to non-RA");
    }

    requestedSubject = removeEmptyRDNs(requestedSubject);

    if (certprofile.isSerialNumberInReqPermitted() == false) {
        RDN[] rdns = requestedSubject.getRDNs(ObjectIdentifiers.DN_SN);
        if (rdns != null && rdns.length > 0) {
            throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE,
                    "subjectDN SerialNumber in request is not permitted");
        }
    }

    notBefore = certprofile.getNotBefore(notBefore);
    if (notBefore == null) {
        notBefore = new Date();
    }

    if (certprofile.hasMidnightNotBefore()) {
        notBefore = setToMidnight(notBefore, certprofile.getTimezone());
    }

    if (notBefore.before(caInfo.getNotBefore())) {
        notBefore = caInfo.getNotBefore();
        if (certprofile.hasMidnightNotBefore()) {
            notBefore = setToMidnight(new Date(notBefore.getTime() + DAY), certprofile.getTimezone());
        }
    }

    long t = caInfo.getNoNewCertificateAfter();
    if (notBefore.getTime() > t) {
        throw new OperationException(ErrorCode.NOT_PERMITTED,
                "CA is not permitted to issue certifate after " + new Date(t));
    }

    try {
        publicKeyInfo = X509Util.toRfc3279Style(publicKeyInfo);
    } catch (InvalidKeySpecException e) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid SubjectPublicKeyInfo");
    }

    // public key
    try {
        publicKeyInfo = certprofile.checkPublicKey(publicKeyInfo);
    } catch (BadCertTemplateException e) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
    }

    Date gSMC_KFirstNotBefore = null;
    if (certprofile.getSpecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
        gSMC_KFirstNotBefore = notBefore;

        RDN[] cnRDNs = requestedSubject.getRDNs(ObjectIdentifiers.DN_CN);
        if (cnRDNs != null && cnRDNs.length > 0) {
            String requestedCN = X509Util.rdnValueToString(cnRDNs[0].getFirst().getValue());
            Long gsmckFirstNotBeforeInSecond = certstore.getNotBeforeOfFirstCertStartsWithCN(requestedCN,
                    certprofileName);
            if (gsmckFirstNotBeforeInSecond != null) {
                gSMC_KFirstNotBefore = new Date(gsmckFirstNotBeforeInSecond * MS_PER_SECOND);
            }

            // append the commonName with '-' + yyyyMMdd
            SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMdd");
            dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
            String yyyyMMdd = dateF.format(gSMC_KFirstNotBefore);
            String suffix = "-" + yyyyMMdd;

            // append the -yyyyMMdd to the commonName
            RDN[] rdns = requestedSubject.getRDNs();
            for (int i = 0; i < rdns.length; i++) {
                if (ObjectIdentifiers.DN_CN.equals(rdns[i].getFirst().getType())) {
                    rdns[i] = new RDN(ObjectIdentifiers.DN_CN, new DERUTF8String(requestedCN + suffix));
                }
            }
            requestedSubject = new X500Name(rdns);
        }
    } // end if

    // subject
    SubjectInfo subjectInfo;
    try {
        subjectInfo = certprofile.getSubject(requestedSubject);
    } catch (CertprofileException e) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, "exception in cert profile " + certprofileName);
    } catch (BadCertTemplateException e) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
    }

    X500Name grantedSubject = subjectInfo.getGrantedSubject();

    // make sure that the grantedSubject does not equal the CA's subject
    if (grantedSubject.equals(caInfo.getPublicCAInfo().getX500Subject())) {
        throw new OperationException(ErrorCode.ALREADY_ISSUED,
                "certificate with the same subject as CA is not allowed");
    }

    DuplicationMode keyMode = caInfo.getDuplicateKeyMode();
    if (keyMode == DuplicationMode.PERMITTED && certprofile.isDuplicateKeyPermitted() == false) {
        keyMode = DuplicationMode.FORBIDDEN_WITHIN_PROFILE;
    }

    DuplicationMode subjectMode = caInfo.getDuplicateSubjectMode();
    if (subjectMode == DuplicationMode.PERMITTED && certprofile.isDuplicateSubjectPermitted() == false) {
        subjectMode = DuplicationMode.FORBIDDEN_WITHIN_PROFILE;
    }

    String sha1FpSubject = X509Util.sha1sum_canonicalized_name(grantedSubject);
    String grandtedSubjectText = X509Util.getRFC4519Name(grantedSubject);

    byte[] subjectPublicKeyData = publicKeyInfo.getPublicKeyData().getBytes();
    String sha1FpPublicKey = SecurityUtil.sha1sum(subjectPublicKeyData);

    if (keyUpdate) {
        CertStatus certStatus = certstore.getCertStatusForSubject(caInfo.getCertificate(), grantedSubject);
        if (certStatus == CertStatus.Revoked) {
            throw new OperationException(ErrorCode.CERT_REVOKED);
        } else if (certStatus == CertStatus.Unknown) {
            throw new OperationException(ErrorCode.UNKNOWN_CERT);
        }
    } else {
        // try to get certificate with the same subject, key and certificate profile
        SubjectKeyProfileBundle bundle = certstore.getLatestCert(caInfo.getCertificate(), sha1FpSubject,
                sha1FpPublicKey, certprofileName);

        if (bundle != null) {
            /*
             * If there exists a certificate whose public key, subject and profile match the request,
             * returns the certificate if it is not revoked, otherwise OperationException with
             * ErrorCode CERT_REVOKED will be thrown
             */
            if (bundle.isRevoked()) {
                throw new OperationException(ErrorCode.CERT_REVOKED);
            } else {
                X509CertWithDBCertId issuedCert = certstore.getCertForId(bundle.getCertId());
                if (issuedCert == null) {
                    throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                            "could not find certificate in table RAWCERT for CERT_ID " + bundle.getCertId());
                } else {
                    X509CertificateInfo certInfo;
                    try {
                        certInfo = new X509CertificateInfo(issuedCert, caInfo.getCertificate(),
                                subjectPublicKeyData, certprofileName);
                    } catch (CertificateEncodingException e) {
                        throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                                "could not construct CertificateInfo: " + e.getMessage());
                    }
                    certInfo.setAlreadyIssued(true);
                    return certInfo;
                }
            }
        } // end if(bundle)

        if (keyMode != DuplicationMode.PERMITTED) {
            if (keyMode == DuplicationMode.FORBIDDEN) {
                if (certstore.isCertForKeyIssued(caInfo.getCertificate(), sha1FpPublicKey)) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given public key already issued");
                }
            } else if (keyMode == DuplicationMode.FORBIDDEN_WITHIN_PROFILE) {
                if (certstore.isCertForKeyIssued(caInfo.getCertificate(), sha1FpPublicKey, certprofileName)) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given public key and profile " + certprofileName
                                    + " already issued");
                }
            } else {
                throw new RuntimeException("should not reach here, unknown key DuplicationMode " + keyMode);
            }
        } // end if(keyMode)

        if (subjectMode != DuplicationMode.PERMITTED) {
            final boolean incSerial = certprofile.incSerialNumberIfSubjectExists();
            final boolean certIssued;
            if (subjectMode == DuplicationMode.FORBIDDEN) {
                certIssued = certstore.isCertForSubjectIssued(caInfo.getCertificate(), sha1FpSubject);
                if (certIssued && incSerial == false) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given subject " + grandtedSubjectText + " already issued");
                }
            } else if (subjectMode == DuplicationMode.FORBIDDEN_WITHIN_PROFILE) {
                certIssued = certstore.isCertForSubjectIssued(caInfo.getCertificate(), sha1FpSubject,
                        certprofileName);
                if (certIssued && incSerial == false) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate for the given subject "
                            + grandtedSubjectText + " and profile " + certprofileName + " already issued");
                }
            } else {
                throw new RuntimeException("should not reach here, unknown subject DuplicationMode " + keyMode);
            } // end if(subjectMode)

            if (certIssued) {
                String latestSN;
                try {
                    Object[] objs = incSerialNumber(certprofile, grantedSubject, null);
                    latestSN = certstore.getLatestSN((X500Name) objs[0]);
                } catch (BadFormatException e) {
                    throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                            "BadFormatException: " + e.getMessage());
                }

                boolean foundUniqueSubject = false;
                // maximal 100 tries
                for (int i = 0; i < 100; i++) {
                    try {
                        Object[] objs = incSerialNumber(certprofile, grantedSubject, latestSN);
                        grantedSubject = (X500Name) objs[0];
                        latestSN = (String) objs[1];
                    } catch (BadFormatException e) {
                        throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                                "BadFormatException: " + e.getMessage());
                    }

                    foundUniqueSubject = (certstore.certIssuedForSubject(caInfo.getCertificate(),
                            X509Util.sha1sum_canonicalized_name(grantedSubject)) == false);
                    if (foundUniqueSubject) {
                        break;
                    }
                }

                if (foundUniqueSubject == false) {
                    throw new OperationException(ErrorCode.ALREADY_ISSUED,
                            "certificate for the given subject " + grandtedSubjectText + " and profile "
                                    + certprofileName
                                    + " already issued, and could not create new unique serial number");
                }
            } // end if(certIssued)
        }
    } // end if(subjectMode != DuplicationMode.PERMITTED)

    try {
        boolean addedCertInProcess = certstore.addCertInProcess(sha1FpPublicKey, sha1FpSubject);
        if (addedCertInProcess == false) {
            throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate with the given subject "
                    + grandtedSubjectText + " and/or public key already in process");
        }

        StringBuilder msgBuilder = new StringBuilder();

        if (subjectInfo.getWarning() != null) {
            msgBuilder.append(", ").append(subjectInfo.getWarning());
        }

        CertValidity validity = certprofile.getValidity();

        if (validity == null) {
            validity = caInfo.getMaxValidity();
        } else if (validity.compareTo(caInfo.getMaxValidity()) > 0) {
            validity = caInfo.getMaxValidity();
        }

        Date maxNotAfter = validity.add(notBefore);
        Date origMaxNotAfter = maxNotAfter;

        if (certprofile.getSpecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
            String s = certprofile.getParameter(SpecialX509CertprofileBehavior.PARAMETER_MAXLIFTIME);
            long maxLifetimeInDays = Long.parseLong(s);
            Date maxLifetime = new Date(
                    gSMC_KFirstNotBefore.getTime() + maxLifetimeInDays * DAY - MS_PER_SECOND);
            if (maxNotAfter.after(maxLifetime)) {
                maxNotAfter = maxLifetime;
            }
        }

        if (notAfter != null) {
            if (notAfter.after(maxNotAfter)) {
                notAfter = maxNotAfter;
                msgBuilder.append(", NotAfter modified");
            }
        } else {
            notAfter = maxNotAfter;
        }

        if (notAfter.after(caInfo.getNotAfter())) {
            ValidityMode mode = caInfo.getValidityMode();
            if (mode == ValidityMode.CUTOFF) {
                notAfter = caInfo.getNotAfter();
            } else if (mode == ValidityMode.STRICT) {
                throw new OperationException(ErrorCode.NOT_PERMITTED,
                        "notAfter outside of CA's validity is not permitted");
            } else if (mode == ValidityMode.LAX) {
                // permitted
            } else {
                throw new RuntimeException("should not reach here, unknown CA ValidityMode " + mode);
            } // end if(mode)
        } // end if(notAfter)

        if (certprofile.hasMidnightNotBefore() && maxNotAfter.equals(origMaxNotAfter) == false) {
            Calendar c = Calendar.getInstance(certprofile.getTimezone());
            c.setTime(new Date(notAfter.getTime() - DAY));
            c.set(Calendar.HOUR_OF_DAY, 23);
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
            c.set(Calendar.MILLISECOND, 0);
            notAfter = c.getTime();
        }

        try {
            RdnUpperBounds.checkUpperBounds(grantedSubject);
        } catch (BadCertTemplateException e) {
            throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
        }

        X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
                caInfo.getPublicCAInfo().getX500Subject(), caInfo.nextSerial(), notBefore, notAfter,
                grantedSubject, publicKeyInfo);

        X509CertificateInfo ret;

        try {
            X509CrlSignerEntryWrapper crlSigner = getCrlSigner();
            X509Certificate crlSignerCert = crlSigner == null ? null : crlSigner.getCert();

            ExtensionValues extensionTuples = certprofile.getExtensions(requestedSubject, extensions,
                    publicKeyInfo, caInfo.getPublicCAInfo(), crlSignerCert);
            if (extensionTuples != null) {
                for (ASN1ObjectIdentifier extensionType : extensionTuples.getExtensionTypes()) {
                    ExtensionValue extValue = extensionTuples.getExtensionValue(extensionType);
                    certBuilder.addExtension(extensionType, extValue.isCritical(), extValue.getValue());
                }
            }

            ContentSigner contentSigner;
            try {
                contentSigner = signer.borrowContentSigner();
            } catch (NoIdleSignerException e) {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                        "NoIdleSignerException: " + e.getMessage());
            }

            Certificate bcCert;
            try {
                bcCert = certBuilder.build(contentSigner).toASN1Structure();
            } finally {
                signer.returnContentSigner(contentSigner);
            }

            byte[] encodedCert = bcCert.getEncoded();

            X509Certificate cert = (X509Certificate) cf
                    .engineGenerateCertificate(new ByteArrayInputStream(encodedCert));
            if (verifySignature(cert) == false) {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                        "could not verify the signature of generated certificate");
            }

            X509CertWithDBCertId certWithMeta = new X509CertWithDBCertId(cert, encodedCert);

            ret = new X509CertificateInfo(certWithMeta, caInfo.getCertificate(), subjectPublicKeyData,
                    certprofileName);
            ret.setUser(user);
            ret.setRequestor(requestor);

            if (intern_publishCertificate(ret) == 1) {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE, "could not save certificate");
            }
        } catch (BadCertTemplateException e) {
            throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, e.getMessage());
        } catch (Throwable t2) {
            final String message = "could not generate certificate";
            if (LOG.isErrorEnabled()) {
                LOG.error(LogUtil.buildExceptionLogFormat(message), t2.getClass().getName(), t2.getMessage());
            }
            LOG.debug(message, t2);

            throw new OperationException(ErrorCode.SYSTEM_FAILURE,
                    t2.getClass().getName() + ": " + t2.getMessage());
        }

        if (msgBuilder.length() > 2) {
            ret.setWarningMessage(msgBuilder.substring(2));
        }

        return ret;
    } finally {
        try {
            certstore.delteCertInProcess(sha1FpPublicKey, sha1FpSubject);
        } catch (OperationException e) {
        }
    }
}

From source file:org.xipki.ca.server.impl.X509CA.java

License:Open Source License

private static X500Name removeEmptyRDNs(final X500Name name) {
    RDN[] rdns = name.getRDNs();/*from ww w  .  ja v  a  2  s.co m*/
    List<RDN> l = new ArrayList<RDN>(rdns.length);
    boolean changed = false;
    for (RDN rdn : rdns) {
        String textValue = X509Util.rdnValueToString(rdn.getFirst().getValue());
        if (StringUtil.isBlank(textValue)) {
            changed = true;
        } else {
            l.add(rdn);
        }
    }

    if (changed) {
        return new X500Name(l.toArray(new RDN[0]));
    } else {
        return name;
    }
}