Search in sources :

Example 1 with CMPCertificate

use of org.bouncycastle.asn1.cmp.CMPCertificate in project xipki by xipki.

the class CmpCaClient method parseEnrollCertResult.

private X509Certificate parseEnrollCertResult(PKIMessage response) throws Exception {
    PKIBody respBody = response.getBody();
    final int bodyType = respBody.getType();
    if (PKIBody.TYPE_ERROR == bodyType) {
        ErrorMsgContent content = ErrorMsgContent.getInstance(respBody.getContent());
        throw new Exception("Server returned PKIStatus: " + buildText(content.getPKIStatusInfo()));
    } else if (PKIBody.TYPE_CERT_REP != bodyType) {
        throw new Exception(String.format("unknown PKI body type %s instead the expected [%s, %s]", bodyType, PKIBody.TYPE_CERT_REP, PKIBody.TYPE_ERROR));
    }
    CertRepMessage certRep = CertRepMessage.getInstance(respBody.getContent());
    CertResponse[] certResponses = certRep.getResponse();
    if (certResponses.length != 1) {
        throw new Exception("expected 1 CertResponse, but returned " + certResponses.length);
    }
    // We only accept the certificates which are requested.
    CertResponse certResp = certResponses[0];
    PKIStatusInfo statusInfo = certResp.getStatus();
    int status = statusInfo.getStatus().intValue();
    if (status != PKIStatus.GRANTED && status != PKIStatus.GRANTED_WITH_MODS) {
        throw new Exception("Server returned PKIStatus: " + buildText(statusInfo));
    }
    CertifiedKeyPair cvk = certResp.getCertifiedKeyPair();
    if (cvk != null) {
        CMPCertificate cmpCert = cvk.getCertOrEncCert().getCertificate();
        if (cmpCert != null) {
            X509Certificate cert = SdkUtil.parseCert(cmpCert.getX509v3PKCert().getEncoded());
            if (!verify(caCert, cert)) {
                throw new Exception("The returned certificate is not issued by the given CA");
            }
            return cert;
        }
    }
    throw new Exception("Server did not return any certificate");
}
Also used : CMPCertificate(org.bouncycastle.asn1.cmp.CMPCertificate) PKIBody(org.bouncycastle.asn1.cmp.PKIBody) CertResponse(org.bouncycastle.asn1.cmp.CertResponse) PKIStatusInfo(org.bouncycastle.asn1.cmp.PKIStatusInfo) CertRepMessage(org.bouncycastle.asn1.cmp.CertRepMessage) ErrorMsgContent(org.bouncycastle.asn1.cmp.ErrorMsgContent) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) CMPException(org.bouncycastle.cert.cmp.CMPException) InvalidKeyException(java.security.InvalidKeyException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) CertifiedKeyPair(org.bouncycastle.asn1.cmp.CertifiedKeyPair)

Example 2 with CMPCertificate

use of org.bouncycastle.asn1.cmp.CMPCertificate in project xipki by xipki.

the class X509CaCmpResponderImpl method processP10cr.

// method processCertReqMessages
/**
 * handle the PKI body with the choice {@code p10cr}<br/>
 * Since it is not possible to add attribute to the PKCS#10 request (CSR), the certificate
 * profile must be specified in the attribute regInfo-utf8Pairs (1.3.6.1.5.5.7.5.2.1) within
 * PKIHeader.generalInfo
 */
private PKIBody processP10cr(PKIMessage request, CmpRequestorInfo requestor, ASN1OctetString tid, PKIHeader reqHeader, CertificationRequest p10cr, CmpControl cmpControl, String msgId, AuditEvent event) {
    // verify the POP first
    CertResponse certResp;
    ASN1Integer certReqId = new ASN1Integer(-1);
    boolean certGenerated = false;
    X509Ca ca = getCa();
    if (!securityFactory.verifyPopo(p10cr, getCmpControl().getPopoAlgoValidator())) {
        LOG.warn("could not validate POP for the pkcs#10 requst");
        certResp = buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "invalid POP");
    } else {
        CertificationRequestInfo certTemp = p10cr.getCertificationRequestInfo();
        Extensions extensions = CaUtil.getExtensions(certTemp);
        X500Name subject = certTemp.getSubject();
        SubjectPublicKeyInfo publicKeyInfo = certTemp.getSubjectPublicKeyInfo();
        CmpUtf8Pairs keyvalues = CmpUtil.extract(reqHeader.getGeneralInfo());
        String certprofileName = null;
        Date notBefore = null;
        Date notAfter = null;
        if (keyvalues != null) {
            certprofileName = keyvalues.value(CmpUtf8Pairs.KEY_CERTPROFILE);
            String str = keyvalues.value(CmpUtf8Pairs.KEY_NOTBEFORE);
            if (str != null) {
                notBefore = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
            }
            str = keyvalues.value(CmpUtf8Pairs.KEY_NOTAFTER);
            if (str != null) {
                notAfter = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
            }
        }
        if (certprofileName == null) {
            certResp = buildErrorCertResponse(certReqId, PKIFailureInfo.badCertTemplate, "badCertTemplate", null);
        } else {
            certprofileName = certprofileName.toLowerCase();
            if (!requestor.isCertProfilePermitted(certprofileName)) {
                String msg = "certprofile " + certprofileName + " is not allowed";
                certResp = buildErrorCertResponse(certReqId, PKIFailureInfo.notAuthorized, msg);
            } else {
                CertTemplateData certTemplateData = new CertTemplateData(subject, publicKeyInfo, notBefore, notAfter, extensions, certprofileName);
                certResp = generateCertificates(Arrays.asList(certTemplateData), Arrays.asList(certReqId), requestor, tid, false, request, cmpControl, msgId, event).get(0);
                certGenerated = true;
            }
        }
    }
    CMPCertificate[] caPubs = null;
    if (certGenerated && cmpControl.isSendCaCert()) {
        caPubs = new CMPCertificate[] { ca.getCaInfo().getCertInCmpFormat() };
    }
    CertRepMessage repMessage = new CertRepMessage(caPubs, new CertResponse[] { certResp });
    return new PKIBody(PKIBody.TYPE_CERT_REP, repMessage);
}
Also used : PKIBody(org.bouncycastle.asn1.cmp.PKIBody) CertificationRequestInfo(org.bouncycastle.asn1.pkcs.CertificationRequestInfo) CmpUtf8Pairs(org.xipki.cmp.CmpUtf8Pairs) CertResponse(org.bouncycastle.asn1.cmp.CertResponse) X509Ca(org.xipki.ca.server.impl.X509Ca) CertRepMessage(org.bouncycastle.asn1.cmp.CertRepMessage) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) X500Name(org.bouncycastle.asn1.x500.X500Name) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) Extensions(org.bouncycastle.asn1.x509.Extensions) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) Date(java.util.Date) CertTemplateData(org.xipki.ca.server.impl.CertTemplateData) CMPCertificate(org.bouncycastle.asn1.cmp.CMPCertificate)

Example 3 with CMPCertificate

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

use of org.bouncycastle.asn1.cmp.CMPCertificate in project xipki by xipki.

the class X509CaCmpResponderImpl method cmpGeneralMsg.

// method cmpRevokeOrUnrevokeOrRemoveCertificates
private PKIBody cmpGeneralMsg(PKIHeaderBuilder respHeader, CmpControl cmpControl, PKIHeader reqHeader, PKIBody reqBody, CmpRequestorInfo requestor, ASN1OctetString tid, String msgId, AuditEvent event) throws InsuffientPermissionException {
    GenMsgContent genMsgBody = GenMsgContent.getInstance(reqBody.getContent());
    InfoTypeAndValue[] itvs = genMsgBody.toInfoTypeAndValueArray();
    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue entry : itvs) {
            String itvType = entry.getInfoType().getId();
            if (KNOWN_GENMSG_IDS.contains(itvType)) {
                itv = entry;
                break;
            }
        }
    }
    if (itv == null) {
        String statusMessage = "PKIBody type " + PKIBody.TYPE_GEN_MSG + " is only supported with the sub-types " + KNOWN_GENMSG_IDS.toString();
        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badRequest, statusMessage);
    }
    InfoTypeAndValue itvResp = null;
    ASN1ObjectIdentifier infoType = itv.getInfoType();
    int failureInfo;
    try {
        X509Ca ca = getCa();
        if (CMPObjectIdentifiers.it_currentCRL.equals(infoType)) {
            event.addEventType(CaAuditConstants.TYPE_CMP_genm_currentCrl);
            checkPermission(requestor, PermissionConstants.GET_CRL);
            CertificateList crl = ca.getBcCurrentCrl();
            if (itv.getInfoValue() == null) {
                // as defined in RFC 4210
                crl = ca.getBcCurrentCrl();
            } else {
                // xipki extension
                ASN1Integer crlNumber = ASN1Integer.getInstance(itv.getInfoValue());
                crl = ca.getBcCrl(crlNumber.getPositiveValue());
            }
            if (crl == null) {
                String statusMessage = "no CRL is available";
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.systemFailure, statusMessage);
            }
            itvResp = new InfoTypeAndValue(infoType, crl);
        } else if (ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.equals(infoType)) {
            ASN1Encodable asn1 = itv.getInfoValue();
            ASN1Integer asn1Code = null;
            ASN1Encodable reqValue = null;
            try {
                ASN1Sequence seq = ASN1Sequence.getInstance(asn1);
                asn1Code = ASN1Integer.getInstance(seq.getObjectAt(0));
                if (seq.size() > 1) {
                    reqValue = seq.getObjectAt(1);
                }
            } catch (IllegalArgumentException ex) {
                String statusMessage = "invalid value of the InfoTypeAndValue for " + ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.getId();
                return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badRequest, statusMessage);
            }
            ASN1Encodable respValue;
            int action = asn1Code.getPositiveValue().intValue();
            switch(action) {
                case XiSecurityConstants.CMP_ACTION_GEN_CRL:
                    event.addEventType(CaAuditConstants.TYPE_CMP_genm_genCrl);
                    checkPermission(requestor, PermissionConstants.GEN_CRL);
                    X509CRL tmpCrl = ca.generateCrlOnDemand(msgId);
                    if (tmpCrl == null) {
                        String statusMessage = "CRL generation is not activated";
                        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.systemFailure, statusMessage);
                    } else {
                        respValue = CertificateList.getInstance(tmpCrl.getEncoded());
                    }
                    break;
                case XiSecurityConstants.CMP_ACTION_GET_CRL_WITH_SN:
                    event.addEventType(CaAuditConstants.TYPE_CMP_genm_crlForNumber);
                    checkPermission(requestor, PermissionConstants.GET_CRL);
                    ASN1Integer crlNumber = ASN1Integer.getInstance(reqValue);
                    respValue = ca.getBcCrl(crlNumber.getPositiveValue());
                    if (respValue == null) {
                        String statusMessage = "no CRL is available";
                        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.systemFailure, statusMessage);
                    }
                    break;
                case XiSecurityConstants.CMP_ACTION_GET_CAINFO:
                    event.addEventType(CaAuditConstants.TYPE_CMP_genm_cainfo);
                    Set<Integer> acceptVersions = new HashSet<>();
                    if (reqValue != null) {
                        ASN1Sequence seq = DERSequence.getInstance(reqValue);
                        int size = seq.size();
                        for (int i = 0; i < size; i++) {
                            ASN1Integer ai = ASN1Integer.getInstance(seq.getObjectAt(i));
                            acceptVersions.add(ai.getPositiveValue().intValue());
                        }
                    }
                    if (CollectionUtil.isEmpty(acceptVersions)) {
                        acceptVersions.add(1);
                    }
                    String systemInfo = getSystemInfo(requestor, acceptVersions);
                    respValue = new DERUTF8String(systemInfo);
                    break;
                default:
                    String statusMessage = "unsupported XiPKI action code '" + action + "'";
                    return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.badRequest, statusMessage);
            }
            // end switch (action)
            ASN1EncodableVector vec = new ASN1EncodableVector();
            vec.add(asn1Code);
            if (respValue != null) {
                vec.add(respValue);
            }
            itvResp = new InfoTypeAndValue(infoType, new DERSequence(vec));
        } else if (ObjectIdentifiers.id_xipki_cmp_cacerts.equals(infoType)) {
            event.addEventType(CaAuditConstants.TYPE_CMP_genm_cacerts);
            CMPCertificate caCert = ca.getCaInfo().getCertInCmpFormat();
            itvResp = new InfoTypeAndValue(infoType, new DERSequence(caCert));
        }
        GenRepContent genRepContent = new GenRepContent(itvResp);
        return new PKIBody(PKIBody.TYPE_GEN_REP, genRepContent);
    } catch (OperationException ex) {
        failureInfo = getPKiFailureInfo(ex);
        ErrorCode code = ex.getErrorCode();
        String errorMessage;
        switch(code) {
            case DATABASE_FAILURE:
            case SYSTEM_FAILURE:
                errorMessage = code.name();
                break;
            default:
                errorMessage = code.name() + ": " + ex.getErrorMessage();
                break;
        }
        return buildErrorMsgPkiBody(PKIStatus.rejection, failureInfo, errorMessage);
    } catch (CRLException ex) {
        String statusMessage = "CRLException: " + ex.getMessage();
        return buildErrorMsgPkiBody(PKIStatus.rejection, PKIFailureInfo.systemFailure, statusMessage);
    }
}
Also used : DERUTF8String(org.bouncycastle.asn1.DERUTF8String) PKIBody(org.bouncycastle.asn1.cmp.PKIBody) X509CRL(java.security.cert.X509CRL) Set(java.util.Set) HashSet(java.util.HashSet) GenMsgContent(org.bouncycastle.asn1.cmp.GenMsgContent) GenRepContent(org.bouncycastle.asn1.cmp.GenRepContent) X509Ca(org.xipki.ca.server.impl.X509Ca) CertificateList(org.bouncycastle.asn1.x509.CertificateList) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) CMPCertificate(org.bouncycastle.asn1.cmp.CMPCertificate) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) DERSequence(org.bouncycastle.asn1.DERSequence) InfoTypeAndValue(org.bouncycastle.asn1.cmp.InfoTypeAndValue) ASN1EncodableVector(org.bouncycastle.asn1.ASN1EncodableVector) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) ErrorCode(org.xipki.ca.api.OperationException.ErrorCode) CRLException(java.security.cert.CRLException) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) OperationException(org.xipki.ca.api.OperationException)

Example 5 with CMPCertificate

use of org.bouncycastle.asn1.cmp.CMPCertificate in project xipki by xipki.

the class X509CmpRequestor method requestCertificate0.

private EnrollCertResultResp requestCertificate0(PKIMessage reqMessage, Map<BigInteger, String> reqIdIdMap, int expectedBodyType, RequestResponseDebug debug) throws CmpRequestorException, PkiErrorException {
    PkiResponse response = signAndSend(reqMessage, debug);
    checkProtection(response);
    PKIBody respBody = response.getPkiMessage().getBody();
    final int bodyType = respBody.getType();
    if (PKIBody.TYPE_ERROR == bodyType) {
        ErrorMsgContent content = ErrorMsgContent.getInstance(respBody.getContent());
        throw new PkiErrorException(content.getPKIStatusInfo());
    } else if (expectedBodyType != bodyType) {
        throw new CmpRequestorException(String.format("unknown PKI body type %s instead the expected [%s, %s]", bodyType, expectedBodyType, PKIBody.TYPE_ERROR));
    }
    CertRepMessage certRep = CertRepMessage.getInstance(respBody.getContent());
    CertResponse[] certResponses = certRep.getResponse();
    EnrollCertResultResp result = new EnrollCertResultResp();
    // CA certificates
    CMPCertificate[] caPubs = certRep.getCaPubs();
    if (caPubs != null && caPubs.length > 0) {
        for (int i = 0; i < caPubs.length; i++) {
            if (caPubs[i] != null) {
                result.addCaCertificate(caPubs[i]);
            }
        }
    }
    CertificateConfirmationContentBuilder certConfirmBuilder = null;
    if (!CmpUtil.isImplictConfirm(response.getPkiMessage().getHeader())) {
        certConfirmBuilder = new CertificateConfirmationContentBuilder();
    }
    boolean requireConfirm = false;
    // We only accept the certificates which are requested.
    for (CertResponse certResp : certResponses) {
        PKIStatusInfo statusInfo = certResp.getStatus();
        int status = statusInfo.getStatus().intValue();
        BigInteger certReqId = certResp.getCertReqId().getValue();
        String thisId = reqIdIdMap.get(certReqId);
        if (thisId != null) {
            reqIdIdMap.remove(certReqId);
        } else if (reqIdIdMap.size() == 1) {
            thisId = reqIdIdMap.values().iterator().next();
            reqIdIdMap.clear();
        }
        if (thisId == null) {
            // ignore it. this cert is not requested by me
            continue;
        }
        ResultEntry resultEntry;
        if (status == PKIStatus.GRANTED || status == PKIStatus.GRANTED_WITH_MODS) {
            CertifiedKeyPair cvk = certResp.getCertifiedKeyPair();
            if (cvk == null) {
                return null;
            }
            CMPCertificate cmpCert = cvk.getCertOrEncCert().getCertificate();
            if (cmpCert == null) {
                return null;
            }
            resultEntry = new EnrollCertResultEntry(thisId, cmpCert, status);
            if (certConfirmBuilder != null) {
                requireConfirm = true;
                X509CertificateHolder certHolder = null;
                try {
                    certHolder = new X509CertificateHolder(cmpCert.getEncoded());
                } catch (IOException ex) {
                    resultEntry = new ErrorResultEntry(thisId, ClientErrorCode.PKISTATUS_RESPONSE_ERROR, PKIFailureInfo.systemFailure, "could not decode the certificate");
                }
                if (certHolder != null) {
                    certConfirmBuilder.addAcceptedCertificate(certHolder, certReqId);
                }
            }
        } else {
            PKIFreeText statusString = statusInfo.getStatusString();
            String errorMessage = (statusString == null) ? null : statusString.getStringAt(0).getString();
            int failureInfo = statusInfo.getFailInfo().intValue();
            resultEntry = new ErrorResultEntry(thisId, status, failureInfo, errorMessage);
        }
        result.addResultEntry(resultEntry);
    }
    if (CollectionUtil.isNonEmpty(reqIdIdMap)) {
        for (BigInteger reqId : reqIdIdMap.keySet()) {
            ErrorResultEntry ere = new ErrorResultEntry(reqIdIdMap.get(reqId), ClientErrorCode.PKISTATUS_NO_ANSWER);
            result.addResultEntry(ere);
        }
    }
    if (!requireConfirm) {
        return result;
    }
    PKIMessage confirmRequest = buildCertConfirmRequest(response.getPkiMessage().getHeader().getTransactionID(), certConfirmBuilder);
    response = signAndSend(confirmRequest, debug);
    checkProtection(response);
    return result;
}
Also used : ErrorResultEntry(org.xipki.ca.client.api.dto.ErrorResultEntry) RevokeCertResultEntry(org.xipki.ca.client.api.dto.RevokeCertResultEntry) EnrollCertResultEntry(org.xipki.ca.client.api.dto.EnrollCertResultEntry) ResultEntry(org.xipki.ca.client.api.dto.ResultEntry) PkiResponse(org.xipki.cmp.PkiResponse) PKIStatusInfo(org.bouncycastle.asn1.cmp.PKIStatusInfo) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) DEROctetString(org.bouncycastle.asn1.DEROctetString) CMPCertificate(org.bouncycastle.asn1.cmp.CMPCertificate) PkiErrorException(org.xipki.ca.client.api.PkiErrorException) CertifiedKeyPair(org.bouncycastle.asn1.cmp.CertifiedKeyPair) PKIMessage(org.bouncycastle.asn1.cmp.PKIMessage) PKIBody(org.bouncycastle.asn1.cmp.PKIBody) CertificateConfirmationContentBuilder(org.bouncycastle.cert.cmp.CertificateConfirmationContentBuilder) CertResponse(org.bouncycastle.asn1.cmp.CertResponse) ErrorResultEntry(org.xipki.ca.client.api.dto.ErrorResultEntry) CertRepMessage(org.bouncycastle.asn1.cmp.CertRepMessage) IOException(java.io.IOException) PKIFreeText(org.bouncycastle.asn1.cmp.PKIFreeText) EnrollCertResultResp(org.xipki.ca.client.api.dto.EnrollCertResultResp) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BigInteger(java.math.BigInteger) EnrollCertResultEntry(org.xipki.ca.client.api.dto.EnrollCertResultEntry) ErrorMsgContent(org.bouncycastle.asn1.cmp.ErrorMsgContent)

Aggregations

CMPCertificate (org.bouncycastle.asn1.cmp.CMPCertificate)6 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)4 DERUTF8String (org.bouncycastle.asn1.DERUTF8String)4 CertRepMessage (org.bouncycastle.asn1.cmp.CertRepMessage)4 CertResponse (org.bouncycastle.asn1.cmp.CertResponse)4 PKIBody (org.bouncycastle.asn1.cmp.PKIBody)4 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)3 PKIStatusInfo (org.bouncycastle.asn1.cmp.PKIStatusInfo)3 IOException (java.io.IOException)2 BigInteger (java.math.BigInteger)2 X509Certificate (java.security.cert.X509Certificate)2 ArrayList (java.util.ArrayList)2 Date (java.util.Date)2 HashMap (java.util.HashMap)2 CertifiedKeyPair (org.bouncycastle.asn1.cmp.CertifiedKeyPair)2 ErrorMsgContent (org.bouncycastle.asn1.cmp.ErrorMsgContent)2 EnrollCertResultEntry (org.xipki.ca.client.api.dto.EnrollCertResultEntry)2 ErrorResultEntry (org.xipki.ca.client.api.dto.ErrorResultEntry)2 ResultEntry (org.xipki.ca.client.api.dto.ResultEntry)2 RevokeCertResultEntry (org.xipki.ca.client.api.dto.RevokeCertResultEntry)2