Search in sources :

Example 6 with NameId

use of org.xipki.ca.api.NameId in project xipki by xipki.

the class CaManagerQueryExecutor method getUser.

UserEntry getUser(String username, boolean nullable) throws CaMgmtException {
    ParamUtil.requireNonNull("username", username);
    NameId ident = new NameId(null, username);
    final String sql = sqls.sqlSelectUser;
    ResultSet rs = null;
    PreparedStatement ps = null;
    try {
        ps = prepareStatement(sql);
        int idx = 1;
        ps.setString(idx++, ident.getName());
        rs = ps.executeQuery();
        if (!rs.next()) {
            if (nullable) {
                return null;
            } else {
                throw new CaMgmtException("unknown user " + username);
            }
        }
        int id = rs.getInt("ID");
        ident.setId(id);
        boolean active = rs.getBoolean("ACTIVE");
        String hashedPassword = rs.getString("PASSWORD");
        return new UserEntry(ident, active, hashedPassword);
    } catch (SQLException ex) {
        throw new CaMgmtException(datasource, sql, ex);
    } finally {
        datasource.releaseResources(ps, rs);
    }
}
Also used : CaMgmtException(org.xipki.ca.server.mgmt.api.CaMgmtException) NameId(org.xipki.ca.api.NameId) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) CaHasUserEntry(org.xipki.ca.server.mgmt.api.CaHasUserEntry) ChangeUserEntry(org.xipki.ca.server.mgmt.api.ChangeUserEntry) AddUserEntry(org.xipki.ca.server.mgmt.api.AddUserEntry) UserEntry(org.xipki.ca.server.mgmt.api.UserEntry)

Example 7 with NameId

use of org.xipki.ca.api.NameId in project xipki by xipki.

the class CaManagerQueryExecutor method getCaHasUsersForUser.

// method addUserToCa
Map<String, CaHasUserEntry> getCaHasUsersForUser(String user, CaIdNameMap idNameMap) throws CaMgmtException {
    Integer existingId = getIdForName(sqls.sqlSelectUserId, user);
    if (existingId == null) {
        throw new CaMgmtException(concat("user '", user, " ' does not exist"));
    }
    final String sql = "SELECT CA_ID,PERMISSION,PROFILES FROM CA_HAS_USER WHERE USER_ID=?";
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {
        ps = prepareStatement(sql);
        ps.setInt(1, existingId);
        rs = ps.executeQuery();
        Map<String, CaHasUserEntry> ret = new HashMap<>();
        while (rs.next()) {
            int permission = rs.getInt("PERMISSION");
            String str = rs.getString("PROFILES");
            List<String> list = StringUtil.splitByComma(str);
            Set<String> profiles = (list == null) ? null : new HashSet<>(list);
            CaHasUserEntry caHasUser = new CaHasUserEntry(new NameId(existingId, user));
            caHasUser.setPermission(permission);
            caHasUser.setProfiles(profiles);
            int caId = rs.getInt("CA_ID");
            String caName = idNameMap.getCaName(caId);
            ret.put(caName, caHasUser);
        }
        return ret;
    } catch (SQLException ex) {
        throw new CaMgmtException(datasource, sql, ex);
    } finally {
        datasource.releaseResources(ps, rs);
    }
}
Also used : CaHasUserEntry(org.xipki.ca.server.mgmt.api.CaHasUserEntry) HashMap(java.util.HashMap) NameId(org.xipki.ca.api.NameId) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CaMgmtException(org.xipki.ca.server.mgmt.api.CaMgmtException) ResultSet(java.sql.ResultSet)

Example 8 with NameId

use of org.xipki.ca.api.NameId in project xipki by xipki.

the class CaManagerQueryExecutor method createCaHasRequestors.

// method createCaInfo
Set<CaHasRequestorEntry> createCaHasRequestors(NameId ca) throws CaMgmtException {
    Map<Integer, String> idNameMap = getIdNameMap("REQUESTOR");
    final String sql = "SELECT REQUESTOR_ID,RA,PERMISSION,PROFILES FROM CA_HAS_REQUESTOR WHERE CA_ID=?";
    PreparedStatement stmt = null;
    ResultSet rs = null;
    try {
        stmt = prepareStatement(sql);
        stmt.setInt(1, ca.getId());
        rs = stmt.executeQuery();
        Set<CaHasRequestorEntry> ret = new HashSet<>();
        while (rs.next()) {
            int id = rs.getInt("REQUESTOR_ID");
            String name = idNameMap.get(id);
            boolean ra = rs.getBoolean("RA");
            int permission = rs.getInt("PERMISSION");
            String str = rs.getString("PROFILES");
            List<String> list = StringUtil.splitByComma(str);
            Set<String> profiles = (list == null) ? null : new HashSet<>(list);
            CaHasRequestorEntry entry = new CaHasRequestorEntry(new NameId(id, name));
            entry.setRa(ra);
            entry.setPermission(permission);
            entry.setProfiles(profiles);
            ret.add(entry);
        }
        return ret;
    } catch (SQLException ex) {
        throw new CaMgmtException(datasource, sql, ex);
    } finally {
        datasource.releaseResources(stmt, rs);
    }
}
Also used : NameId(org.xipki.ca.api.NameId) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CaMgmtException(org.xipki.ca.server.mgmt.api.CaMgmtException) ResultSet(java.sql.ResultSet) CaHasRequestorEntry(org.xipki.ca.server.mgmt.api.CaHasRequestorEntry) HashSet(java.util.HashSet)

Example 9 with NameId

use of org.xipki.ca.api.NameId in project xipki by xipki.

the class X509Ca method createGrantedCertTemplate.

private GrantedCertTemplate createGrantedCertTemplate(CertTemplateData certTemplate, RequestorInfo requestor, boolean keyUpdate) throws OperationException {
    ParamUtil.requireNonNull("certTemplate", certTemplate);
    if (caInfo.getRevocationInfo() != null) {
        throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is revoked");
    }
    IdentifiedX509Certprofile certprofile = getX509Certprofile(certTemplate.getCertprofileName());
    if (certprofile == null) {
        throw new OperationException(ErrorCode.UNKNOWN_CERT_PROFILE, "unknown cert profile " + certTemplate.getCertprofileName());
    }
    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 NameId certprofileIdent = certprofile.getIdent();
    if (certprofile.getVersion() != X509CertVersion.v3) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, "unknown cert version " + certprofile.getVersion());
    }
    if (certprofile.isOnlyForRa()) {
        if (requestor == null || !requestor.isRa()) {
            throw new OperationException(ErrorCode.NOT_PERMITTED, "profile " + certprofileIdent + " not applied to non-RA");
        }
    }
    X500Name requestedSubject = removeEmptyRdns(certTemplate.getSubject());
    if (!certprofile.isSerialNumberInReqPermitted()) {
        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");
        }
    }
    Date now = new Date();
    Date reqNotBefore;
    if (certTemplate.getNotBefore() != null && certTemplate.getNotBefore().after(now)) {
        reqNotBefore = certTemplate.getNotBefore();
    } else {
        reqNotBefore = now;
    }
    Date grantedNotBefore = certprofile.getNotBefore(reqNotBefore);
    // notBefore in the past is not permitted
    if (grantedNotBefore.before(now)) {
        grantedNotBefore = now;
    }
    if (certprofile.hasMidnightNotBefore()) {
        grantedNotBefore = setToMidnight(grantedNotBefore, certprofile.getTimezone());
    }
    if (grantedNotBefore.before(caInfo.getNotBefore())) {
        grantedNotBefore = caInfo.getNotBefore();
        if (certprofile.hasMidnightNotBefore()) {
            grantedNotBefore = setToMidnight(grantedNotBefore, certprofile.getTimezone());
        }
    }
    long time = caInfo.getNoNewCertificateAfter();
    if (grantedNotBefore.getTime() > time) {
        throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is not permitted to issue certifate after " + new Date(time));
    }
    SubjectPublicKeyInfo grantedPublicKeyInfo;
    try {
        grantedPublicKeyInfo = X509Util.toRfc3279Style(certTemplate.getPublicKeyInfo());
    } catch (InvalidKeySpecException ex) {
        LogUtil.warn(LOG, ex, "invalid SubjectPublicKeyInfo");
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid SubjectPublicKeyInfo");
    }
    // public key
    try {
        grantedPublicKeyInfo = certprofile.checkPublicKey(grantedPublicKeyInfo);
    } catch (BadCertTemplateException ex) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
    }
    // CHECK weak public key, like RSA key (ROCA)
    if (grantedPublicKeyInfo.getAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) {
        try {
            ASN1Sequence seq = ASN1Sequence.getInstance(grantedPublicKeyInfo.getPublicKeyData().getOctets());
            if (seq.size() != 2) {
                throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid format of RSA public key");
            }
            BigInteger modulus = ASN1Integer.getInstance(seq.getObjectAt(0)).getPositiveValue();
            if (RSABrokenKey.isAffected(modulus)) {
                throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "RSA public key is too weak");
            }
        } catch (IllegalArgumentException ex) {
            throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid format of RSA public key");
        }
    }
    Date gsmckFirstNotBefore = null;
    if (certprofile.getspecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
        gsmckFirstNotBefore = grantedNotBefore;
        RDN[] cnRdns = requestedSubject.getRDNs(ObjectIdentifiers.DN_CN);
        if (cnRdns != null && cnRdns.length > 0) {
            String requestedCn = X509Util.rdnValueToString(cnRdns[0].getFirst().getValue());
            Long gsmckFirstNotBeforeInSecond = certstore.getNotBeforeOfFirstCertStartsWithCommonName(requestedCn, certprofileIdent);
            if (gsmckFirstNotBeforeInSecond != null) {
                gsmckFirstNotBefore = 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(gsmckFirstNotBefore);
            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
    }
    // end if
    // subject
    SubjectInfo subjectInfo;
    try {
        subjectInfo = certprofile.getSubject(requestedSubject);
    } catch (CertprofileException ex) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, "exception in cert profile " + certprofileIdent);
    } catch (BadCertTemplateException ex) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
    }
    X500Name grantedSubject = subjectInfo.getGrantedSubject();
    // make sure that empty subject is not permitted
    ASN1ObjectIdentifier[] attrTypes = grantedSubject.getAttributeTypes();
    if (attrTypes == null || attrTypes.length == 0) {
        throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "empty subject is not permitted");
    }
    // make sure that the grantedSubject does not equal the CA's subject
    if (X509Util.canonicalizName(grantedSubject).equals(caInfo.getPublicCaInfo().getC14nSubject())) {
        throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate with the same subject as CA is not allowed");
    }
    boolean duplicateKeyPermitted = caInfo.isDuplicateKeyPermitted();
    if (duplicateKeyPermitted && !certprofile.isDuplicateKeyPermitted()) {
        duplicateKeyPermitted = false;
    }
    byte[] subjectPublicKeyData = grantedPublicKeyInfo.getPublicKeyData().getBytes();
    long fpPublicKey = FpIdCalculator.hash(subjectPublicKeyData);
    if (keyUpdate) {
        CertStatus certStatus = certstore.getCertStatusForSubject(caIdent, grantedSubject);
        if (certStatus == CertStatus.REVOKED) {
            throw new OperationException(ErrorCode.CERT_REVOKED);
        } else if (certStatus == CertStatus.UNKNOWN) {
            throw new OperationException(ErrorCode.UNKNOWN_CERT);
        }
    } else {
        if (!duplicateKeyPermitted) {
            if (certstore.isCertForKeyIssued(caIdent, fpPublicKey)) {
                throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate for the given public key already issued");
            }
        }
    // duplicateSubject check will be processed later
    }
    // end if(keyUpdate)
    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(grantedNotBefore);
    if (maxNotAfter.getTime() > MAX_CERT_TIME_MS) {
        maxNotAfter = new Date(MAX_CERT_TIME_MS);
    }
    // CHECKSTYLE:SKIP
    Date origMaxNotAfter = maxNotAfter;
    if (certprofile.getspecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
        String str = certprofile.setParameter(SpecialX509CertprofileBehavior.PARAMETER_MAXLIFTIME);
        long maxLifetimeInDays = Long.parseLong(str);
        Date maxLifetime = new Date(gsmckFirstNotBefore.getTime() + maxLifetimeInDays * DAY_IN_MS - MS_PER_SECOND);
        if (maxNotAfter.after(maxLifetime)) {
            maxNotAfter = maxLifetime;
        }
    }
    Date grantedNotAfter = certTemplate.getNotAfter();
    if (grantedNotAfter != null) {
        if (grantedNotAfter.after(maxNotAfter)) {
            grantedNotAfter = maxNotAfter;
            msgBuilder.append(", notAfter modified");
        }
    } else {
        grantedNotAfter = maxNotAfter;
    }
    if (grantedNotAfter.after(caInfo.getNotAfter())) {
        ValidityMode mode = caInfo.getValidityMode();
        if (mode == ValidityMode.CUTOFF) {
            grantedNotAfter = 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)
    }
    if (certprofile.hasMidnightNotBefore() && !maxNotAfter.equals(origMaxNotAfter)) {
        Calendar cal = Calendar.getInstance(certprofile.getTimezone());
        cal.setTime(new Date(grantedNotAfter.getTime() - DAY_IN_MS));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 0);
        grantedNotAfter = cal.getTime();
    }
    String warning = null;
    if (msgBuilder.length() > 2) {
        warning = msgBuilder.substring(2);
    }
    GrantedCertTemplate gct = new GrantedCertTemplate(certTemplate.getExtensions(), certprofile, grantedNotBefore, grantedNotAfter, requestedSubject, grantedPublicKeyInfo, fpPublicKey, subjectPublicKeyData, signer, warning);
    gct.setGrantedSubject(grantedSubject);
    return gct;
}
Also used : DERUTF8String(org.bouncycastle.asn1.DERUTF8String) NameId(org.xipki.ca.api.NameId) CertValidity(org.xipki.ca.api.profile.CertValidity) X500Name(org.bouncycastle.asn1.x500.X500Name) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) ValidityMode(org.xipki.ca.server.mgmt.api.ValidityMode) SimpleTimeZone(java.util.SimpleTimeZone) CertprofileException(org.xipki.ca.api.profile.CertprofileException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) RDN(org.bouncycastle.asn1.x500.RDN) OperationException(org.xipki.ca.api.OperationException) Calendar(java.util.Calendar) SubjectInfo(org.xipki.ca.api.profile.x509.SubjectInfo) Date(java.util.Date) IssuingDistributionPoint(org.bouncycastle.asn1.x509.IssuingDistributionPoint) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) ConcurrentContentSigner(org.xipki.security.ConcurrentContentSigner) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) BadCertTemplateException(org.xipki.ca.api.BadCertTemplateException) BigInteger(java.math.BigInteger) SimpleDateFormat(java.text.SimpleDateFormat) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 10 with NameId

use of org.xipki.ca.api.NameId in project xipki by xipki.

the class X509Ca method generateCertificates.

private List<X509CertificateInfo> generateCertificates(List<CertTemplateData> certTemplates, RequestorInfo requestor, boolean keyUpdate, RequestType reqType, byte[] transactionId, String msgId) throws OperationExceptionWithIndex {
    ParamUtil.requireNonEmpty("certTemplates", certTemplates);
    final int n = certTemplates.size();
    List<GrantedCertTemplate> gcts = new ArrayList<>(n);
    for (int i = 0; i < n; i++) {
        CertTemplateData certTemplate = certTemplates.get(i);
        try {
            GrantedCertTemplate gct = createGrantedCertTemplate(certTemplate, requestor, keyUpdate);
            gcts.add(gct);
        } catch (OperationException ex) {
            throw new OperationExceptionWithIndex(i, ex);
        }
    }
    List<X509CertificateInfo> certInfos = new ArrayList<>(n);
    OperationExceptionWithIndex exception = null;
    for (int i = 0; i < n; i++) {
        if (exception != null) {
            break;
        }
        GrantedCertTemplate gct = gcts.get(i);
        final NameId certprofilIdent = gct.certprofile.getIdent();
        final String subjectText = gct.grantedSubjectText;
        LOG.info("     START generateCertificate: CA={}, profile={}, subject='{}'", caIdent, certprofilIdent, subjectText);
        boolean successful = false;
        try {
            X509CertificateInfo certInfo = generateCertificate(gct, requestor, false, reqType, transactionId, msgId);
            successful = true;
            certInfos.add(certInfo);
            if (LOG.isInfoEnabled()) {
                String prefix = certInfo.isAlreadyIssued() ? "RETURN_OLD_CERT" : "SUCCESSFUL";
                X509CertWithDbId cert = certInfo.getCert();
                LOG.info("{} generateCertificate: CA={}, profile={}, subject='{}', serialNumber={}", prefix, caIdent, certprofilIdent, cert.getSubject(), LogUtil.formatCsn(cert.getCert().getSerialNumber()));
            }
        } catch (OperationException ex) {
            exception = new OperationExceptionWithIndex(i, ex);
        } catch (Throwable th) {
            exception = new OperationExceptionWithIndex(i, new OperationException(ErrorCode.SYSTEM_FAILURE, th));
        } finally {
            if (!successful) {
                LOG.warn("    FAILED generateCertificate: CA={}, profile={}, subject='{}'", caIdent, certprofilIdent, subjectText);
            }
        }
    }
    if (exception != null) {
        LOG.error("could not generate certificate for request[{}], reverted all generated" + " certificates", exception.getIndex());
        // delete generated certificates
        for (X509CertificateInfo m : certInfos) {
            BigInteger serial = m.getCert().getCert().getSerialNumber();
            try {
                removeCertificate(serial, msgId);
            } catch (Throwable thr) {
                LogUtil.error(LOG, thr, "could not delete certificate serial=" + serial);
            }
        }
        LogUtil.warn(LOG, exception);
        throw exception;
    }
    return certInfos;
}
Also used : NameId(org.xipki.ca.api.NameId) ArrayList(java.util.ArrayList) X509CertificateInfo(org.xipki.ca.api.publisher.x509.X509CertificateInfo) X509CertWithDbId(org.xipki.ca.api.X509CertWithDbId) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) IssuingDistributionPoint(org.bouncycastle.asn1.x509.IssuingDistributionPoint) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) BigInteger(java.math.BigInteger) OperationException(org.xipki.ca.api.OperationException)

Aggregations

NameId (org.xipki.ca.api.NameId)43 CaMgmtException (org.xipki.ca.server.mgmt.api.CaMgmtException)31 PreparedStatement (java.sql.PreparedStatement)12 SQLException (java.sql.SQLException)12 ResultSet (java.sql.ResultSet)9 OperationException (org.xipki.ca.api.OperationException)9 CmdFailure (org.xipki.console.karaf.CmdFailure)9 BigInteger (java.math.BigInteger)8 DERPrintableString (org.bouncycastle.asn1.DERPrintableString)6 CaHasRequestorEntry (org.xipki.ca.server.mgmt.api.CaHasRequestorEntry)6 X509Certificate (java.security.cert.X509Certificate)5 DERUTF8String (org.bouncycastle.asn1.DERUTF8String)5 CaHasUserEntry (org.xipki.ca.server.mgmt.api.CaHasUserEntry)5 X509CaEntry (org.xipki.ca.server.mgmt.api.x509.X509CaEntry)5 Date (java.util.Date)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 CaStatus (org.xipki.ca.server.mgmt.api.CaStatus)4 X509CaUris (org.xipki.ca.server.mgmt.api.x509.X509CaUris)4 ConfPairs (org.xipki.common.ConfPairs)4 IllegalCmdParamException (org.xipki.console.karaf.IllegalCmdParamException)4