Search in sources :

Example 1 with PkiResponse

use of org.xipki.cmp.PkiResponse in project xipki by xipki.

the class CmpRequestor method signAndSend.

protected PkiResponse signAndSend(PKIMessage request, RequestResponseDebug debug) throws CmpRequestorException {
    ParamUtil.requireNonNull("request", request);
    PKIMessage tmpRequest = (signRequest) ? sign(request) : request;
    byte[] encodedRequest;
    try {
        encodedRequest = tmpRequest.getEncoded();
    } catch (IOException ex) {
        LOG.error("could not encode the PKI request {}", tmpRequest);
        throw new CmpRequestorException(ex.getMessage(), ex);
    }
    RequestResponsePair reqResp = null;
    if (debug != null) {
        reqResp = new RequestResponsePair();
        debug.add(reqResp);
        if (debug.saveRequest()) {
            reqResp.setRequest(encodedRequest);
        }
    }
    byte[] encodedResponse;
    try {
        encodedResponse = send(encodedRequest);
    } catch (IOException ex) {
        LOG.error("could not send the PKI request {} to server", tmpRequest);
        throw new CmpRequestorException("TRANSPORT_ERROR", ex);
    }
    if (reqResp != null && debug.saveResponse()) {
        reqResp.setResponse(encodedResponse);
    }
    GeneralPKIMessage response;
    try {
        response = new GeneralPKIMessage(encodedResponse);
    } catch (IOException ex) {
        LOG.error("could not decode the received PKI message: {}", Hex.encode(encodedResponse));
        throw new CmpRequestorException(ex.getMessage(), ex);
    }
    PKIHeader reqHeader = request.getHeader();
    PKIHeader respHeader = response.getHeader();
    ASN1OctetString tid = reqHeader.getTransactionID();
    ASN1OctetString respTid = respHeader.getTransactionID();
    if (!tid.equals(respTid)) {
        LOG.warn("Response contains different tid ({}) than requested {}", respTid, tid);
        throw new CmpRequestorException("Response contains differnt tid than the request");
    }
    ASN1OctetString senderNonce = reqHeader.getSenderNonce();
    ASN1OctetString respRecipientNonce = respHeader.getRecipNonce();
    if (!senderNonce.equals(respRecipientNonce)) {
        LOG.warn("tid {}: response.recipientNonce ({}) != request.senderNonce ({})", tid, respRecipientNonce, senderNonce);
        throw new CmpRequestorException("Response contains differnt tid than the request");
    }
    GeneralName rec = respHeader.getRecipient();
    if (!sender.equals(rec)) {
        LOG.warn("tid={}: unknown CMP requestor '{}'", tid, rec);
    }
    PkiResponse ret = new PkiResponse(response);
    if (response.hasProtection()) {
        try {
            ProtectionVerificationResult verifyProtection = verifyProtection(Hex.encode(tid.getOctets()), response);
            ret.setProtectionVerificationResult(verifyProtection);
        } catch (InvalidKeyException | OperatorCreationException | CMPException ex) {
            throw new CmpRequestorException(ex.getMessage(), ex);
        }
    } else if (signRequest) {
        PKIBody respBody = response.getBody();
        int bodyType = respBody.getType();
        if (bodyType != PKIBody.TYPE_ERROR) {
            throw new CmpRequestorException("response is not signed");
        }
    }
    return ret;
}
Also used : ProtectedPKIMessage(org.bouncycastle.cert.cmp.ProtectedPKIMessage) PKIMessage(org.bouncycastle.asn1.cmp.PKIMessage) GeneralPKIMessage(org.bouncycastle.cert.cmp.GeneralPKIMessage) RequestResponsePair(org.xipki.common.RequestResponsePair) PKIHeader(org.bouncycastle.asn1.cmp.PKIHeader) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) PkiResponse(org.xipki.cmp.PkiResponse) PKIBody(org.bouncycastle.asn1.cmp.PKIBody) ProtectionVerificationResult(org.xipki.cmp.ProtectionVerificationResult) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) GeneralPKIMessage(org.bouncycastle.cert.cmp.GeneralPKIMessage) CMPException(org.bouncycastle.cert.cmp.CMPException) GeneralName(org.bouncycastle.asn1.x509.GeneralName) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException)

Example 2 with PkiResponse

use of org.xipki.cmp.PkiResponse in project xipki by xipki.

the class X509CmpRequestor method unrevokeCertificate.

public RevokeCertResultType unrevokeCertificate(UnrevokeOrRemoveCertRequest request, RequestResponseDebug debug) throws CmpRequestorException, PkiErrorException {
    ParamUtil.requireNonNull("request", request);
    PKIMessage reqMessage = buildUnrevokeOrRemoveCertRequest(request, CrlReason.REMOVE_FROM_CRL.getCode());
    PkiResponse response = signAndSend(reqMessage, debug);
    return parse(response, request.getRequestEntries());
}
Also used : PKIMessage(org.bouncycastle.asn1.cmp.PKIMessage) PkiResponse(org.xipki.cmp.PkiResponse)

Example 3 with PkiResponse

use of org.xipki.cmp.PkiResponse in project xipki by xipki.

the class X509CmpRequestor method generateCrl.

public X509CRL generateCrl(RequestResponseDebug debug) throws CmpRequestorException, PkiErrorException {
    int action = XiSecurityConstants.CMP_ACTION_GEN_CRL;
    PKIMessage request = buildMessageWithXipkAction(action, null);
    PkiResponse response = signAndSend(request, debug);
    return evaluateCrlResponse(response, action);
}
Also used : PKIMessage(org.bouncycastle.asn1.cmp.PKIMessage) PkiResponse(org.xipki.cmp.PkiResponse)

Example 4 with PkiResponse

use of org.xipki.cmp.PkiResponse 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)

Example 5 with PkiResponse

use of org.xipki.cmp.PkiResponse in project xipki by xipki.

the class X509CmpRequestor method retrieveCaInfo.

public CaInfo retrieveCaInfo(String caName, RequestResponseDebug debug) throws CmpRequestorException, PkiErrorException {
    ParamUtil.requireNonBlank("caName", caName);
    ASN1EncodableVector vec = new ASN1EncodableVector();
    vec.add(new ASN1Integer(2));
    ASN1Sequence acceptVersions = new DERSequence(vec);
    int action = XiSecurityConstants.CMP_ACTION_GET_CAINFO;
    PKIMessage request = buildMessageWithXipkAction(action, acceptVersions);
    PkiResponse response = signAndSend(request, debug);
    ASN1Encodable itvValue = extractXipkiActionRepContent(response, action);
    DERUTF8String utf8Str = DERUTF8String.getInstance(itvValue);
    String systemInfoStr = utf8Str.getString();
    LOG.debug("CAInfo for CA {}: {}", caName, systemInfoStr);
    Document doc;
    try {
        doc = xmlDocBuilder.parse(new ByteArrayInputStream(systemInfoStr.getBytes("UTF-8")));
    } catch (SAXException | IOException ex) {
        throw new CmpRequestorException("could not parse the returned systemInfo for CA " + caName + ": " + ex.getMessage(), ex);
    }
    final String namespace = null;
    Element root = doc.getDocumentElement();
    String str = root.getAttribute("version");
    if (StringUtil.isBlank(str)) {
        str = root.getAttributeNS(namespace, "version");
    }
    int version = StringUtil.isBlank(str) ? 1 : Integer.parseInt(str);
    if (version == 2) {
        // CACert
        X509Certificate caCert;
        String b64CaCert = XmlUtil.getValueOfFirstElementChild(root, namespace, "CACert");
        try {
            caCert = X509Util.parseBase64EncodedCert(b64CaCert);
        } catch (CertificateException ex) {
            throw new CmpRequestorException("could no parse the CA certificate", ex);
        }
        // CmpControl
        ClientCmpControl cmpControl = null;
        Element cmpCtrlElement = XmlUtil.getFirstElementChild(root, namespace, "cmpControl");
        if (cmpCtrlElement != null) {
            String tmpStr = XmlUtil.getValueOfFirstElementChild(cmpCtrlElement, namespace, "rrAkiRequired");
            boolean required = (tmpStr == null) ? false : Boolean.parseBoolean(tmpStr);
            cmpControl = new ClientCmpControl(required);
        }
        // certprofiles
        Set<String> profileNames = new HashSet<>();
        Element profilesElement = XmlUtil.getFirstElementChild(root, namespace, "certprofiles");
        Set<CertprofileInfo> profiles = new HashSet<>();
        if (profilesElement != null) {
            List<Element> profileElements = XmlUtil.getElementChilden(profilesElement, namespace, "certprofile");
            for (Element element : profileElements) {
                String name = XmlUtil.getValueOfFirstElementChild(element, namespace, "name");
                String type = XmlUtil.getValueOfFirstElementChild(element, namespace, "type");
                String conf = XmlUtil.getValueOfFirstElementChild(element, namespace, "conf");
                CertprofileInfo profile = new CertprofileInfo(name, type, conf);
                profiles.add(profile);
                profileNames.add(name);
                LOG.debug("configured for CA {} certprofile (name={}, type={}, conf={})", caName, name, type, conf);
            }
        }
        LOG.info("CA {} supports profiles {}", caName, profileNames);
        return new CaInfo(caCert, cmpControl, profiles);
    } else {
        throw new CmpRequestorException("unknown CAInfo version " + version);
    }
}
Also used : PkiResponse(org.xipki.cmp.PkiResponse) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) Element(org.w3c.dom.Element) CertificateException(java.security.cert.CertificateException) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) DEROctetString(org.bouncycastle.asn1.DEROctetString) Document(org.w3c.dom.Document) SAXException(org.xml.sax.SAXException) DERSequence(org.bouncycastle.asn1.DERSequence) ASN1EncodableVector(org.bouncycastle.asn1.ASN1EncodableVector) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) HashSet(java.util.HashSet) PKIMessage(org.bouncycastle.asn1.cmp.PKIMessage) CertprofileInfo(org.xipki.ca.client.api.CertprofileInfo) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) ByteArrayInputStream(java.io.ByteArrayInputStream)

Aggregations

PKIMessage (org.bouncycastle.asn1.cmp.PKIMessage)8 PkiResponse (org.xipki.cmp.PkiResponse)8 IOException (java.io.IOException)3 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)3 BigInteger (java.math.BigInteger)2 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)2 DEROctetString (org.bouncycastle.asn1.DEROctetString)2 DERUTF8String (org.bouncycastle.asn1.DERUTF8String)2 PKIBody (org.bouncycastle.asn1.cmp.PKIBody)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InvalidKeyException (java.security.InvalidKeyException)1 CertificateException (java.security.cert.CertificateException)1 X509Certificate (java.security.cert.X509Certificate)1 HashSet (java.util.HashSet)1 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)1 ASN1EncodableVector (org.bouncycastle.asn1.ASN1EncodableVector)1 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)1 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)1 DERSequence (org.bouncycastle.asn1.DERSequence)1 CMPCertificate (org.bouncycastle.asn1.cmp.CMPCertificate)1