Search in sources :

Example 1 with CertTemplate

use of org.bouncycastle.asn1.crmf.CertTemplate in project xipki by xipki.

the class CaLoadTestTemplateEnroll method nextCertRequests.

private Map<Integer, CertRequestWithProfile> nextCertRequests() {
    if (maxRequests > 0) {
        int num = processedRequests.getAndAdd(1);
        if (num >= maxRequests) {
            return null;
        }
    }
    Map<Integer, CertRequestWithProfile> certRequests = new HashMap<>();
    final int n = loadtestEntries.size();
    for (int i = 0; i < n; i++) {
        LoadTestEntry loadtestEntry = loadtestEntries.get(i);
        final int certId = i + 1;
        CertTemplateBuilder certTempBuilder = new CertTemplateBuilder();
        long thisIndex = index.getAndIncrement();
        certTempBuilder.setSubject(loadtestEntry.getX500Name(thisIndex));
        SubjectPublicKeyInfo spki = loadtestEntry.getSubjectPublicKeyInfo();
        certTempBuilder.setPublicKey(spki);
        CertTemplate certTemplate = certTempBuilder.build();
        CertRequest certRequest = new CertRequest(certId, certTemplate, null);
        CertRequestWithProfile requestWithCertprofile = new CertRequestWithProfile(loadtestEntry.getCertprofile(), certRequest);
        certRequests.put(certId, requestWithCertprofile);
    }
    return certRequests;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CertTemplateBuilder(org.bouncycastle.asn1.crmf.CertTemplateBuilder) HashMap(java.util.HashMap) EnrollCertRequest(org.xipki.ca.client.api.dto.EnrollCertRequest) CertRequest(org.bouncycastle.asn1.crmf.CertRequest) CertTemplate(org.bouncycastle.asn1.crmf.CertTemplate) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo)

Example 2 with CertTemplate

use of org.bouncycastle.asn1.crmf.CertTemplate in project xipki by xipki.

the class X509CaCmpResponderImpl method processCertReqMessages.

private CertRepMessage processCertReqMessages(PKIMessage request, CmpRequestorInfo requestor, ASN1OctetString tid, PKIHeader reqHeader, CertReqMessages kur, boolean keyUpdate, CmpControl cmpControl, String msgId, AuditEvent event) {
    CmpRequestorInfo tmpRequestor = (CmpRequestorInfo) requestor;
    CertReqMsg[] certReqMsgs = kur.toCertReqMsgArray();
    final int n = certReqMsgs.length;
    Map<Integer, CertTemplateData> certTemplateDatas = new HashMap<>(n * 10 / 6);
    Map<Integer, CertResponse> certResponses = new HashMap<>(n * 10 / 6);
    Map<Integer, ASN1Integer> certReqIds = new HashMap<>(n * 10 / 6);
    // pre-process requests
    for (int i = 0; i < n; i++) {
        if (cmpControl.isGroupEnroll() && certTemplateDatas.size() != i) {
            // last certReqMsg cannot be used to enroll certificate
            break;
        }
        CertReqMsg reqMsg = certReqMsgs[i];
        CertificateRequestMessage req = new CertificateRequestMessage(reqMsg);
        ASN1Integer certReqId = reqMsg.getCertReq().getCertReqId();
        certReqIds.put(i, certReqId);
        if (!req.hasProofOfPossession()) {
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "no POP", null));
            continue;
        }
        if (!verifyPopo(req, tmpRequestor.isRa())) {
            LOG.warn("could not validate POP for request {}", certReqId.getValue());
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "invalid POP", null));
            continue;
        }
        CmpUtf8Pairs keyvalues = CmpUtil.extract(reqMsg.getRegInfo());
        String certprofileName = (keyvalues == null) ? null : keyvalues.value(CmpUtf8Pairs.KEY_CERTPROFILE);
        if (certprofileName == null) {
            String msg = "no certificate profile";
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badCertTemplate, msg));
            continue;
        }
        certprofileName = certprofileName.toLowerCase();
        if (!tmpRequestor.isCertProfilePermitted(certprofileName)) {
            String msg = "certprofile " + certprofileName + " is not allowed";
            certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.notAuthorized, msg));
            continue;
        }
        CertTemplate certTemp = req.getCertTemplate();
        OptionalValidity validity = certTemp.getValidity();
        Date notBefore = null;
        Date notAfter = null;
        if (validity != null) {
            Time time = validity.getNotBefore();
            if (time != null) {
                notBefore = time.getDate();
            }
            time = validity.getNotAfter();
            if (time != null) {
                notAfter = time.getDate();
            }
        }
        CertTemplateData certTempData = new CertTemplateData(certTemp.getSubject(), certTemp.getPublicKey(), notBefore, notAfter, certTemp.getExtensions(), certprofileName);
        certTemplateDatas.put(i, certTempData);
    }
    if (certResponses.size() == n) {
        // all error
        CertResponse[] certResps = new CertResponse[n];
        for (int i = 0; i < n; i++) {
            certResps[i] = certResponses.get(i);
        }
        return new CertRepMessage(null, certResps);
    }
    if (cmpControl.isGroupEnroll() && certTemplateDatas.size() != n) {
        // at least one certRequest cannot be used to enroll certificate
        int lastFailureIndex = certTemplateDatas.size();
        BigInteger failCertReqId = certReqIds.get(lastFailureIndex).getPositiveValue();
        CertResponse failCertResp = certResponses.get(lastFailureIndex);
        PKIStatus failStatus = PKIStatus.getInstance(new ASN1Integer(failCertResp.getStatus().getStatus()));
        PKIFailureInfo failureInfo = new PKIFailureInfo(failCertResp.getStatus().getFailInfo());
        CertResponse[] certResps = new CertResponse[n];
        for (int i = 0; i < n; i++) {
            if (i == lastFailureIndex) {
                certResps[i] = failCertResp;
                continue;
            }
            ASN1Integer certReqId = certReqIds.get(i);
            String msg = "error in certReq " + failCertReqId;
            PKIStatusInfo tmpStatus = generateRejectionStatus(failStatus, failureInfo.intValue(), msg);
            certResps[i] = new CertResponse(certReqId, tmpStatus);
        }
        return new CertRepMessage(null, certResps);
    }
    final int k = certTemplateDatas.size();
    List<CertTemplateData> certTemplateList = new ArrayList<>(k);
    List<ASN1Integer> certReqIdList = new ArrayList<>(k);
    Map<Integer, Integer> reqIndexToCertIndexMap = new HashMap<>(k * 10 / 6);
    for (int i = 0; i < n; i++) {
        if (!certTemplateDatas.containsKey(i)) {
            continue;
        }
        certTemplateList.add(certTemplateDatas.get(i));
        certReqIdList.add(certReqIds.get(i));
        reqIndexToCertIndexMap.put(i, certTemplateList.size() - 1);
    }
    List<CertResponse> generateCertResponses = generateCertificates(certTemplateList, certReqIdList, tmpRequestor, tid, keyUpdate, request, cmpControl, msgId, event);
    boolean anyCertEnrolled = false;
    CertResponse[] certResps = new CertResponse[n];
    for (int i = 0; i < n; i++) {
        if (certResponses.containsKey(i)) {
            certResps[i] = certResponses.get(i);
        } else {
            int respIndex = reqIndexToCertIndexMap.get(i);
            certResps[i] = generateCertResponses.get(respIndex);
            if (!anyCertEnrolled && certResps[i].getCertifiedKeyPair() != null) {
                anyCertEnrolled = true;
            }
        }
    }
    CMPCertificate[] caPubs = null;
    if (anyCertEnrolled && cmpControl.isSendCaCert()) {
        caPubs = new CMPCertificate[] { getCa().getCaInfo().getCertInCmpFormat() };
    }
    return new CertRepMessage(caPubs, certResps);
}
Also used : CmpUtf8Pairs(org.xipki.cmp.CmpUtf8Pairs) HashMap(java.util.HashMap) CertificateRequestMessage(org.bouncycastle.cert.crmf.CertificateRequestMessage) PKIStatusInfo(org.bouncycastle.asn1.cmp.PKIStatusInfo) ArrayList(java.util.ArrayList) ASN1GeneralizedTime(org.bouncycastle.asn1.ASN1GeneralizedTime) Time(org.bouncycastle.asn1.x509.Time) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) CertTemplateData(org.xipki.ca.server.impl.CertTemplateData) CMPCertificate(org.bouncycastle.asn1.cmp.CMPCertificate) CertTemplate(org.bouncycastle.asn1.crmf.CertTemplate) CertReqMsg(org.bouncycastle.asn1.crmf.CertReqMsg) CertResponse(org.bouncycastle.asn1.cmp.CertResponse) CertRepMessage(org.bouncycastle.asn1.cmp.CertRepMessage) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) Date(java.util.Date) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) BigInteger(java.math.BigInteger) PKIFailureInfo(org.bouncycastle.asn1.cmp.PKIFailureInfo) OptionalValidity(org.bouncycastle.asn1.crmf.OptionalValidity) PKIStatus(org.bouncycastle.asn1.cmp.PKIStatus) BigInteger(java.math.BigInteger)

Example 3 with CertTemplate

use of org.bouncycastle.asn1.crmf.CertTemplate 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 4 with CertTemplate

use of org.bouncycastle.asn1.crmf.CertTemplate 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)

Example 5 with CertTemplate

use of org.bouncycastle.asn1.crmf.CertTemplate in project xipki by xipki.

the class X509CaCmpResponderImpl method unRevokeRemoveCertificates.

private PKIBody unRevokeRemoveCertificates(PKIMessage request, RevReqContent rr, int permission, CmpControl cmpControl, String msgId) {
    RevDetails[] revContent = rr.toRevDetailsArray();
    RevRepContentBuilder repContentBuilder = new RevRepContentBuilder();
    final int n = revContent.length;
    // test the request
    for (int i = 0; i < n; i++) {
        RevDetails revDetails = revContent[i];
        CertTemplate certDetails = revDetails.getCertDetails();
        X500Name issuer = certDetails.getIssuer();
        ASN1Integer serialNumber = certDetails.getSerialNumber();
        try {
            X500Name caSubject = getCa().getCaInfo().getCert().getSubjectAsX500Name();
            if (issuer == null) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "issuer is not present");
            }
            if (!issuer.equals(caSubject)) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "issuer does not target at the CA");
            }
            if (serialNumber == null) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "serialNumber is not present");
            }
            if (certDetails.getSigningAlg() != null || certDetails.getValidity() != null || certDetails.getSubject() != null || certDetails.getPublicKey() != null || certDetails.getIssuerUID() != null || certDetails.getSubjectUID() != null) {
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "only version, issuer and serialNumber in RevDetails.certDetails are " + "allowed, but more is specified");
            }
            if (certDetails.getExtensions() == null) {
                if (cmpControl.isRrAkiRequired()) {
                    return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "issuer's AKI not present");
                }
            } else {
                Extensions exts = certDetails.getExtensions();
                ASN1ObjectIdentifier[] oids = exts.getCriticalExtensionOIDs();
                if (oids != null) {
                    for (ASN1ObjectIdentifier oid : oids) {
                        if (!Extension.authorityKeyIdentifier.equals(oid)) {
                            return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "unknown critical extension " + oid.getId());
                        }
                    }
                }
                Extension ext = exts.getExtension(Extension.authorityKeyIdentifier);
                if (ext == null) {
                    return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "issuer's AKI not present");
                } else {
                    AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(ext.getParsedValue());
                    if (aki.getKeyIdentifier() == null) {
                        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "issuer's AKI not present");
                    }
                    boolean issuerMatched = true;
                    byte[] caSki = getCa().getCaInfo().getCert().getSubjectKeyIdentifier();
                    if (!Arrays.equals(caSki, aki.getKeyIdentifier())) {
                        issuerMatched = false;
                    }
                    if (issuerMatched && aki.getAuthorityCertSerialNumber() != null) {
                        BigInteger caSerial = getCa().getCaInfo().getSerialNumber();
                        if (!caSerial.equals(aki.getAuthorityCertSerialNumber())) {
                            issuerMatched = false;
                        }
                    }
                    if (issuerMatched && aki.getAuthorityCertIssuer() != null) {
                        GeneralName[] names = aki.getAuthorityCertIssuer().getNames();
                        for (GeneralName name : names) {
                            if (name.getTagNo() != GeneralName.directoryName) {
                                issuerMatched = false;
                                break;
                            }
                            if (!caSubject.equals(name.getName())) {
                                issuerMatched = false;
                                break;
                            }
                        }
                    }
                    if (!issuerMatched) {
                        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate, "issuer does not target at the CA");
                    }
                }
            }
        } catch (IllegalArgumentException ex) {
            return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badRequest, "the request is not invalid");
        }
    }
    // end for
    byte[] encodedRequest = null;
    if (getCa().getCaInfo().isSaveRequest()) {
        try {
            encodedRequest = request.getEncoded();
        } catch (IOException ex) {
            LOG.warn("could not encode request");
        }
    }
    Long reqDbId = null;
    for (int i = 0; i < n; i++) {
        RevDetails revDetails = revContent[i];
        CertTemplate certDetails = revDetails.getCertDetails();
        ASN1Integer serialNumber = certDetails.getSerialNumber();
        // serialNumber is not null due to the check in the previous for-block.
        X500Name caSubject = getCa().getCaInfo().getCert().getSubjectAsX500Name();
        BigInteger snBigInt = serialNumber.getPositiveValue();
        CertId certId = new CertId(new GeneralName(caSubject), serialNumber);
        PKIStatusInfo status;
        try {
            Object returnedObj = null;
            Long certDbId = null;
            X509Ca ca = getCa();
            if (PermissionConstants.UNREVOKE_CERT == permission) {
                // unrevoke
                returnedObj = ca.unrevokeCertificate(snBigInt, msgId);
                if (returnedObj != null) {
                    certDbId = ((X509CertWithDbId) returnedObj).getCertId();
                }
            } else if (PermissionConstants.REMOVE_CERT == permission) {
                // remove
                returnedObj = ca.removeCertificate(snBigInt, msgId);
            } else {
                // revoke
                Date invalidityDate = null;
                CrlReason reason = null;
                Extensions crlDetails = revDetails.getCrlEntryDetails();
                if (crlDetails != null) {
                    ASN1ObjectIdentifier extId = Extension.reasonCode;
                    ASN1Encodable extValue = crlDetails.getExtensionParsedValue(extId);
                    if (extValue != null) {
                        int reasonCode = ASN1Enumerated.getInstance(extValue).getValue().intValue();
                        reason = CrlReason.forReasonCode(reasonCode);
                    }
                    extId = Extension.invalidityDate;
                    extValue = crlDetails.getExtensionParsedValue(extId);
                    if (extValue != null) {
                        try {
                            invalidityDate = ASN1GeneralizedTime.getInstance(extValue).getDate();
                        } catch (ParseException ex) {
                            throw new OperationException(ErrorCode.INVALID_EXTENSION, "invalid extension " + extId.getId());
                        }
                    }
                }
                if (reason == null) {
                    reason = CrlReason.UNSPECIFIED;
                }
                returnedObj = ca.revokeCertificate(snBigInt, reason, invalidityDate, msgId);
                if (returnedObj != null) {
                    certDbId = ((X509CertWithRevocationInfo) returnedObj).getCert().getCertId();
                }
            }
            if (returnedObj == null) {
                throw new OperationException(ErrorCode.UNKNOWN_CERT, "cert not exists");
            }
            if (certDbId != null && ca.getCaInfo().isSaveRequest()) {
                if (reqDbId == null) {
                    reqDbId = ca.addRequest(encodedRequest);
                }
                ca.addRequestCert(reqDbId, certDbId);
            }
            status = new PKIStatusInfo(PKIStatus.granted);
        } catch (OperationException ex) {
            ErrorCode code = ex.getErrorCode();
            LOG.warn("{}, OperationException: code={}, message={}", PermissionConstants.getTextForCode(permission), code.name(), ex.getErrorMessage());
            String errorMessage;
            switch(code) {
                case DATABASE_FAILURE:
                case SYSTEM_FAILURE:
                    errorMessage = code.name();
                    break;
                default:
                    errorMessage = code.name() + ": " + ex.getErrorMessage();
                    break;
            }
            // end switch code
            int failureInfo = getPKiFailureInfo(ex);
            status = generateRejectionStatus(failureInfo, errorMessage);
        }
        // end try
        repContentBuilder.add(status, certId);
    }
    return new PKIBody(PKIBody.TYPE_REVOCATION_REP, repContentBuilder.build());
}
Also used : PKIStatusInfo(org.bouncycastle.asn1.cmp.PKIStatusInfo) X509Ca(org.xipki.ca.server.impl.X509Ca) AuthorityKeyIdentifier(org.bouncycastle.asn1.x509.AuthorityKeyIdentifier) X500Name(org.bouncycastle.asn1.x500.X500Name) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) Extensions(org.bouncycastle.asn1.x509.Extensions) CertTemplate(org.bouncycastle.asn1.crmf.CertTemplate) CrlReason(org.xipki.security.CrlReason) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) RevDetails(org.bouncycastle.asn1.cmp.RevDetails) OperationException(org.xipki.ca.api.OperationException) PKIBody(org.bouncycastle.asn1.cmp.PKIBody) RevRepContentBuilder(org.bouncycastle.asn1.cmp.RevRepContentBuilder) CertId(org.bouncycastle.asn1.crmf.CertId) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) IOException(java.io.IOException) Date(java.util.Date) Extension(org.bouncycastle.asn1.x509.Extension) BigInteger(java.math.BigInteger) GeneralName(org.bouncycastle.asn1.x509.GeneralName) ParseException(java.text.ParseException) ErrorCode(org.xipki.ca.api.OperationException.ErrorCode) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Aggregations

BigInteger (java.math.BigInteger)5 OperationException (org.xipki.ca.api.OperationException)5 Date (java.util.Date)4 HashMap (java.util.HashMap)4 CertTemplate (org.bouncycastle.asn1.crmf.CertTemplate)4 SubjectPublicKeyInfo (org.bouncycastle.asn1.x509.SubjectPublicKeyInfo)4 ArrayList (java.util.ArrayList)3 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)3 DERUTF8String (org.bouncycastle.asn1.DERUTF8String)3 X500Name (org.bouncycastle.asn1.x500.X500Name)3 X509Ca (org.xipki.ca.server.impl.X509Ca)3 IOException (java.io.IOException)2 ParseException (java.text.ParseException)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 DERPrintableString (org.bouncycastle.asn1.DERPrintableString)2 CRLDistPoint (org.bouncycastle.asn1.x509.CRLDistPoint)2 Extensions (org.bouncycastle.asn1.x509.Extensions)2 IssuingDistributionPoint (org.bouncycastle.asn1.x509.IssuingDistributionPoint)2 InsuffientPermissionException (org.xipki.ca.api.InsuffientPermissionException)2 NameId (org.xipki.ca.api.NameId)2