Search in sources :

Example 1 with CmpUtf8Pairs

use of org.xipki.security.cmp.CmpUtf8Pairs in project xipki by xipki.

the class CmpResponder method processCertReqMessages.

private CertRepMessage processCertReqMessages(String dfltCertprofileName, PKIMessage request, CmpRequestorInfo requestor, ASN1OctetString tid, CertReqMessages cr, boolean allowKeyGen, CmpControl cmpControl, String msgId, AuditEvent event) throws InsufficientPermissionException {
    CertReqMsg[] certReqMsgs = cr.toCertReqMsgArray();
    final int n = certReqMsgs.length;
    List<CertResponse> resps = new ArrayList<>(1);
    String[] certprofileNames = CmpUtil.extractCertProfile(request.getHeader().getGeneralInfo());
    if (certprofileNames == null) {
        if (dfltCertprofileName != null) {
            certprofileNames = new String[n];
            for (int i = 0; i < n; i++) {
                certprofileNames[i] = dfltCertprofileName;
            }
        }
    }
    boolean kup = (request.getBody().getType() == PKIBody.TYPE_KEY_UPDATE_REQ);
    int numCertprofileNames = (certprofileNames == null) ? 0 : certprofileNames.length;
    if (!kup && (numCertprofileNames != n)) {
        CertResponse[] certResps = new CertResponse[n];
        for (int i = 0; i < n; i++) {
            ASN1Integer certReqId = certReqMsgs[i].getCertReq().getCertReqId();
            String msg = "expected " + n + ", but " + numCertprofileNames + " CertProfile names are specified";
            certResps[i] = new CertResponse(certReqId, generateRejectionStatus(badCertTemplate, msg));
        }
        event.setStatus(AuditStatus.FAILED);
        return new CertRepMessage(null, certResps);
    }
    List<CertTemplateData> certTemplateDatas = new ArrayList<>(n);
    // 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];
        ASN1Integer certReqId = reqMsg.getCertReq().getCertReqId();
        CertificateRequestMessage req = new CertificateRequestMessage(reqMsg);
        CertTemplate certTemp = req.getCertTemplate();
        SubjectPublicKeyInfo publicKey = certTemp.getPublicKey();
        X500Name subject = certTemp.getSubject();
        Extensions extensions = certTemp.getExtensions();
        // till version 5.3.13, UTF8Pairs is used to specify the CertProfile
        CmpUtf8Pairs utf8Pairs = CmpUtil.extractUtf8Pairs(reqMsg.getRegInfo());
        String certprofileName = null;
        if (utf8Pairs != null) {
            certprofileName = utf8Pairs.value(CmpUtf8Pairs.KEY_NOTAFTER);
        }
        if (certprofileName == null && certprofileNames != null) {
            certprofileName = certprofileNames[i];
        }
        if (kup) {
            // The regCtl-oldCertID will be ignored by calling
            // req.getControl(CMPObjectIdentifiers.regCtrl_oldCertID);
            Controls controls = reqMsg.getCertReq().getControls();
            AttributeTypeAndValue oldCertIdAtv = null;
            if (controls != null) {
                ASN1Sequence seq;
                try {
                    seq = ASN1Sequence.getInstance(controls.getEncoded());
                } catch (IOException ex) {
                    addErrCertResp(resps, certReqId, systemFailure, "could not parse the controls");
                    continue;
                }
                final int seqSize = seq.size();
                for (int j = 0; j < seqSize; j++) {
                    AttributeTypeAndValue atv = AttributeTypeAndValue.getInstance(seq.getObjectAt(j));
                    if (atv.getType().equals(CMPObjectIdentifiers.regCtrl_oldCertID)) {
                        oldCertIdAtv = atv;
                        break;
                    }
                }
            }
            if (oldCertIdAtv == null) {
                addErrCertResp(resps, certReqId, badCertTemplate, "no getCtrl oldCertID is specified");
                continue;
            }
            CertId oldCertId = CertId.getInstance(oldCertIdAtv.getValue());
            if (GeneralName.directoryName != oldCertId.getIssuer().getTagNo()) {
                addErrCertResp(resps, certReqId, badCertId, "invalid regCtrl oldCertID");
                continue;
            }
            X500Name issuer = X500Name.getInstance(oldCertId.getIssuer().getName());
            BigInteger serialNumber = oldCertId.getSerialNumber().getValue();
            CertWithRevocationInfo oldCert;
            try {
                oldCert = caManager.getCert(issuer, serialNumber);
            } catch (CaMgmtException ex) {
                addErrCertResp(resps, certReqId, systemFailure, "error while finding certificate with " + "the issuer " + issuer + "and serial number " + serialNumber);
                continue;
            }
            if (oldCert == null) {
                addErrCertResp(resps, certReqId, badCertId, "found no certificate with the issuer " + issuer + "and serial number " + serialNumber);
                continue;
            }
            if (oldCert.isRevoked()) {
                addErrCertResp(resps, certReqId, certRevoked, "could not update a revoked certificate " + "with the issuer " + issuer + "and serial number " + serialNumber);
                continue;
            }
            if (certprofileName == null) {
                certprofileName = oldCert.getCertprofile();
            }
            if (subject == null) {
                subject = oldCert.getCert().getCert().getSubject();
            }
            // extensions
            Map<String, Extension> extns = new HashMap<>();
            if (extensions != null) {
                // add all requested extensions
                ASN1ObjectIdentifier[] oids = extensions.getExtensionOIDs();
                for (ASN1ObjectIdentifier oid : oids) {
                    extns.put(oid.getId(), extensions.getExtension(oid));
                }
            }
            // extract extensions from the certificate
            Extensions oldExtensions = oldCert.getCert().getCert().toBcCert().getExtensions();
            ASN1ObjectIdentifier[] oldOids = oldExtensions.getExtensionOIDs();
            for (ASN1ObjectIdentifier oid : oldOids) {
                String id = oid.getId();
                if (!(extns.containsKey(id) || kupCertExtnIds.contains(id))) {
                    extns.put(id, oldExtensions.getExtension(oid));
                }
            }
            extensions = new Extensions(extns.values().toArray(new Extension[0]));
        }
        if (!requestor.isCertprofilePermitted(certprofileName)) {
            addErrCertResp(resps, certReqId, notAuthorized, "certprofile " + certprofileName + " is not allowed");
            continue;
        }
        if (publicKey != null) {
            if (!req.hasProofOfPossession()) {
                addErrCertResp(resps, certReqId, badPOP, "no POP");
                continue;
            }
            if (!verifyPop(req, publicKey, requestor.isRa())) {
                LOG.warn("could not validate POP for request {}", certReqId.getValue());
                addErrCertResp(resps, certReqId, badPOP, "invalid POP");
                continue;
            }
        } else {
            if (allowKeyGen) {
                checkPermission(requestor, PermissionConstants.GEN_KEYPAIR);
            } else {
                LOG.warn("no public key is specified and key generation is not allowed {}", certReqId.getValue());
                addErrCertResp(resps, certReqId, badCertTemplate, "no public key");
                continue;
            }
        }
        boolean caGenerateKeypair = publicKey == null;
        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();
            }
        }
        certTemplateDatas.add(new CertTemplateData(subject, publicKey, notBefore, notAfter, extensions, certprofileName, certReqId, caGenerateKeypair));
    }
    if (resps.size() == n) {
        // all error
        CertResponse[] certResps = new CertResponse[n];
        for (int i = 0; i < n; i++) {
            certResps[i] = resps.get(i);
        }
        event.setStatus(AuditStatus.FAILED);
        return new CertRepMessage(null, certResps);
    }
    if (cmpControl.isGroupEnroll() && certTemplateDatas.size() != n) {
        event.setStatus(AuditStatus.FAILED);
        // GroupEnroll and at least one certRequest cannot be used to enroll certificate
        int lastFailureIndex = certTemplateDatas.size();
        BigInteger failCertReqId = certReqMsgs[lastFailureIndex].getCertReq().getCertReqId().getValue();
        CertResponse failCertResp = resps.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;
            }
            PKIStatusInfo tmpStatus = generateRejectionStatus(failStatus, failureInfo.intValue(), "error in certReq " + failCertReqId);
            certResps[i] = new CertResponse(certResps[i].getCertReqId(), tmpStatus);
        }
        return new CertRepMessage(null, certResps);
    }
    List<CertResponse> generateCertResponses = generateCertificates(certTemplateDatas, requestor, tid, kup, request, cmpControl, msgId, event);
    CertResponse[] certResps = new CertResponse[n];
    int index = 0;
    for (CertResponse errorResp : resps) {
        // error single CertResponse
        certResps[index++] = errorResp;
    }
    for (CertResponse certResp : generateCertResponses) {
        certResps[index++] = certResp;
    }
    CMPCertificate[] caPubs = null;
    if (cmpControl.isSendCaCert() || cmpControl.isSendCertChain()) {
        boolean anyCertEnrolled = false;
        for (CertResponse certResp : generateCertResponses) {
            if (certResp.getCertifiedKeyPair() != null) {
                anyCertEnrolled = true;
                break;
            }
        }
        if (anyCertEnrolled) {
            List<CMPCertificate> certchain = new ArrayList<>(2);
            certchain.add(getCa().getCaInfo().getCertInCmpFormat());
            if (cmpControl.isSendCertChain()) {
                certchain.addAll(getCa().getCaInfo().getCertchainInCmpFormat());
            }
            caPubs = certchain.toArray(new CMPCertificate[0]);
        }
    }
    return new CertRepMessage(caPubs, certResps);
}
Also used : CmpUtf8Pairs(org.xipki.security.cmp.CmpUtf8Pairs) CertificateRequestMessage(org.bouncycastle.cert.crmf.CertificateRequestMessage) X500Name(org.bouncycastle.asn1.x500.X500Name) CertTemplateData(org.xipki.ca.server.CertTemplateData) IOException(java.io.IOException) PKIFailureInfo(org.bouncycastle.asn1.cmp.PKIFailureInfo) CaMgmtException(org.xipki.ca.api.mgmt.CaMgmtException) PKIStatus(org.bouncycastle.asn1.cmp.PKIStatus) BigInteger(java.math.BigInteger) CertWithRevocationInfo(org.xipki.ca.api.mgmt.CertWithRevocationInfo)

Example 2 with CmpUtf8Pairs

use of org.xipki.security.cmp.CmpUtf8Pairs in project xipki by xipki.

the class CmpResponder 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(String dfltCertprofileName, PKIMessage request, CmpRequestorInfo requestor, ASN1OctetString tid, PKIHeader reqHeader, CertificationRequest p10cr, CmpControl cmpControl, String msgId, AuditEvent event) {
    // verify the POP first
    CertResponse certResp = null;
    ASN1Integer certReqId = new ASN1Integer(-1);
    boolean certGenerated = false;
    X509Ca ca = getCa();
    if (!ca.verifyCsr(p10cr)) {
        LOG.warn("could not validate POP for the pkcs#10 requst");
        certResp = buildErrCertResp(certReqId, badPOP, "invalid POP");
    } else {
        CertificationRequestInfo certTemp = p10cr.getCertificationRequestInfo();
        Extensions extensions;
        try {
            extensions = CaUtil.getExtensions(certTemp);
        } catch (IllegalArgumentException ex) {
            extensions = null;
            LOG.warn("could not parse extensions of the pkcs#10 requst");
            certResp = buildErrCertResp(certReqId, badCertTemplate, "invalid extensions");
        }
        if (certResp == null) {
            X500Name subject = certTemp.getSubject();
            SubjectPublicKeyInfo publicKeyInfo = certTemp.getSubjectPublicKeyInfo();
            InfoTypeAndValue[] generalInfo = reqHeader.getGeneralInfo();
            CmpUtf8Pairs keyvalues = CmpUtil.extractUtf8Pairs(generalInfo);
            // CertProfile name
            String certprofileName = null;
            String[] list = CmpUtil.extractCertProfile(generalInfo);
            if (list != null && list.length > 0) {
                certprofileName = list[0];
            } else {
                if (keyvalues != null) {
                    certprofileName = keyvalues.value(KEY_CERTPROFILE);
                }
            }
            // NotBefore and NotAfter
            Date notBefore = null;
            Date notAfter = null;
            if (keyvalues != null) {
                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) {
                certprofileName = dfltCertprofileName;
            }
            if (certprofileName == null) {
                LOG.warn("no certprofile is specified");
                certResp = buildErrCertResp(certReqId, badCertTemplate, "badCertTemplate");
            } else {
                certprofileName = certprofileName.toLowerCase();
                if (!requestor.isCertprofilePermitted(certprofileName)) {
                    String msg = "certprofile " + certprofileName + " is not allowed";
                    certResp = buildErrCertResp(certReqId, notAuthorized, msg);
                } else {
                    CertTemplateData certTemplateData = new CertTemplateData(subject, publicKeyInfo, notBefore, notAfter, extensions, certprofileName, certReqId, false);
                    certResp = generateCertificates(Collections.singletonList(certTemplateData), requestor, tid, false, request, cmpControl, msgId, event).get(0);
                    certGenerated = true;
                }
            }
        }
    }
    CMPCertificate[] caPubs = null;
    if (certGenerated && (cmpControl.isSendCaCert() || cmpControl.isSendCertChain())) {
        List<CMPCertificate> certchain = new ArrayList<>(2);
        certchain.add(getCa().getCaInfo().getCertInCmpFormat());
        if (cmpControl.isSendCertChain()) {
            certchain.addAll(getCa().getCaInfo().getCertchainInCmpFormat());
        }
        caPubs = certchain.toArray(new CMPCertificate[0]);
    }
    if (event.getStatus() == null || event.getStatus() != AuditStatus.FAILED) {
        int status = certResp.getStatus().getStatus().intValue();
        if (status != GRANTED && status != GRANTED_WITH_MODS && status != WAITING) {
            event.setStatus(AuditStatus.FAILED);
            PKIFreeText statusStr = certResp.getStatus().getStatusString();
            if (statusStr != null) {
                event.addEventData(CaAuditConstants.NAME_message, statusStr.getStringAt(0).getString());
            }
        }
    }
    return new PKIBody(PKIBody.TYPE_CERT_REP, new CertRepMessage(caPubs, new CertResponse[] { certResp }));
}
Also used : CertificationRequestInfo(org.bouncycastle.asn1.pkcs.CertificationRequestInfo) CmpUtf8Pairs(org.xipki.security.cmp.CmpUtf8Pairs) X509Ca(org.xipki.ca.server.X509Ca) X500Name(org.bouncycastle.asn1.x500.X500Name) CertTemplateData(org.xipki.ca.server.CertTemplateData)

Example 3 with CmpUtf8Pairs

use of org.xipki.security.cmp.CmpUtf8Pairs in project xipki by xipki.

the class CmpUtf8PairsTest method test3.

@Test
public void test3() {
    CmpUtf8Pairs pairs = new CmpUtf8Pairs("key-a?value-a%");
    String expEncoded = "key-a?value-a%";
    Map<String, String> expNameValues = new HashMap<>();
    expNameValues.put("key-a", "value-a");
    check(pairs, expEncoded, expNameValues);
}
Also used : CmpUtf8Pairs(org.xipki.security.cmp.CmpUtf8Pairs) HashMap(java.util.HashMap) Test(org.junit.Test)

Example 4 with CmpUtf8Pairs

use of org.xipki.security.cmp.CmpUtf8Pairs in project xipki by xipki.

the class CmpUtf8PairsTest method test5.

@Test
public void test5() {
    CmpUtf8Pairs pairs = new CmpUtf8Pairs("key-a?value-a%3f%3f%25%");
    String expEncoded = "key-a?value-a%3f%3f%25%";
    Map<String, String> expNameValues = new HashMap<>();
    expNameValues.put("key-a", "value-a??%");
    check(pairs, expEncoded, expNameValues);
}
Also used : CmpUtf8Pairs(org.xipki.security.cmp.CmpUtf8Pairs) HashMap(java.util.HashMap) Test(org.junit.Test)

Example 5 with CmpUtf8Pairs

use of org.xipki.security.cmp.CmpUtf8Pairs in project xipki by xipki.

the class CmpUtf8PairsTest method test4.

@Test
public void test4() {
    CmpUtf8Pairs pairs = new CmpUtf8Pairs("key-a?value-a%3f%");
    String expEncoded = "key-a?value-a%3f%";
    Map<String, String> expNameValues = new HashMap<>();
    expNameValues.put("key-a", "value-a?");
    check(pairs, expEncoded, expNameValues);
}
Also used : CmpUtf8Pairs(org.xipki.security.cmp.CmpUtf8Pairs) HashMap(java.util.HashMap) Test(org.junit.Test)

Aggregations

CmpUtf8Pairs (org.xipki.security.cmp.CmpUtf8Pairs)7 HashMap (java.util.HashMap)5 Test (org.junit.Test)5 X500Name (org.bouncycastle.asn1.x500.X500Name)2 CertTemplateData (org.xipki.ca.server.CertTemplateData)2 IOException (java.io.IOException)1 BigInteger (java.math.BigInteger)1 PKIFailureInfo (org.bouncycastle.asn1.cmp.PKIFailureInfo)1 PKIStatus (org.bouncycastle.asn1.cmp.PKIStatus)1 CertificationRequestInfo (org.bouncycastle.asn1.pkcs.CertificationRequestInfo)1 CertificateRequestMessage (org.bouncycastle.cert.crmf.CertificateRequestMessage)1 CaMgmtException (org.xipki.ca.api.mgmt.CaMgmtException)1 CertWithRevocationInfo (org.xipki.ca.api.mgmt.CertWithRevocationInfo)1 X509Ca (org.xipki.ca.server.X509Ca)1