Search in sources :

Example 1 with ReqRespPair

use of org.xipki.util.ReqRespDebug.ReqRespPair in project xipki by xipki.

the class CmpAgent method signAndSend.

// method sign
private VerifiedPkiMessage signAndSend(PKIMessage request, ReqRespDebug debug) throws CmpClientException {
    notNull(request, "request");
    PKIMessage tmpRequest = requestor.signRequest() ? sign(request) : request;
    byte[] encodedRequest;
    try {
        encodedRequest = tmpRequest.getEncoded();
    } catch (IOException ex) {
        LOG.error("could not encode the PKI request {}", tmpRequest);
        throw new CmpClientException(ex.getMessage(), ex);
    }
    ReqRespPair reqResp = null;
    if (debug != null) {
        reqResp = new ReqRespPair();
        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 CmpClientException("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 CmpClientException(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 CmpClientException("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 CmpClientException("Response contains differnt tid than the request");
    }
    GeneralName rec = respHeader.getRecipient();
    if (!requestor.getName().equals(rec)) {
        LOG.warn("tid={}: unknown CMP requestor '{}'", tid, rec);
    }
    VerifiedPkiMessage ret = new VerifiedPkiMessage(response);
    if (response.hasProtection()) {
        try {
            ProtectionVerificationResult verifyProtection = verifyProtection(Hex.encode(tid.getOctets()), response);
            ret.setProtectionVerificationResult(verifyProtection);
        } catch (InvalidKeyException | CMPException ex) {
            throw new CmpClientException(ex.getMessage(), ex);
        }
    } else if (requestor.signRequest()) {
        PKIBody respBody = response.getBody();
        int bodyType = respBody.getType();
        if (bodyType != PKIBody.TYPE_ERROR) {
            throw new CmpClientException("response is not signed");
        }
    }
    return ret;
}
Also used : IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) ReqRespPair(org.xipki.util.ReqRespDebug.ReqRespPair) GeneralName(org.bouncycastle.asn1.x509.GeneralName)

Example 2 with ReqRespPair

use of org.xipki.util.ReqRespDebug.ReqRespPair in project xipki by xipki.

the class AbstractOcspRequestor method ask.

@Override
public OCSPResp ask(X509Cert issuerCert, BigInteger[] serialNumbers, URL responderUrl, RequestOptions requestOptions, ReqRespDebug debug) throws OcspResponseException, OcspRequestorException {
    notNull(issuerCert, "issuerCert");
    notNull(requestOptions, "requestOptions");
    notNull(responderUrl, "responderUrl");
    byte[] nonce = null;
    if (requestOptions.isUseNonce()) {
        nonce = nextNonce(requestOptions.getNonceLen());
    }
    OCSPRequest ocspReq = buildRequest(issuerCert, serialNumbers, nonce, requestOptions);
    byte[] encodedReq;
    try {
        encodedReq = ocspReq.getEncoded();
    } catch (IOException ex) {
        throw new OcspRequestorException("could not encode OCSP request: " + ex.getMessage(), ex);
    }
    ReqRespPair msgPair = null;
    if (debug != null) {
        msgPair = new ReqRespPair();
        debug.add(msgPair);
        if (debug.saveRequest()) {
            msgPair.setRequest(encodedReq);
        }
    }
    byte[] encodedResp;
    try {
        encodedResp = send(encodedReq, responderUrl, requestOptions);
    } catch (IOException ex) {
        throw new OcspResponseException.ResponderUnreachable("IOException: " + ex.getMessage(), ex);
    }
    if (msgPair != null && debug.saveResponse()) {
        msgPair.setResponse(encodedResp);
    }
    OCSPResp ocspResp;
    try {
        ocspResp = new OCSPResp(encodedResp);
    } catch (IOException ex) {
        throw new OcspResponseException.InvalidResponse("IOException: " + ex.getMessage(), ex);
    }
    Object respObject;
    try {
        respObject = ocspResp.getResponseObject();
    } catch (OCSPException ex) {
        throw new OcspResponseException.InvalidResponse("responseObject is invalid");
    }
    if (ocspResp.getStatus() != 0) {
        return ocspResp;
    }
    if (!(respObject instanceof BasicOCSPResp)) {
        return ocspResp;
    }
    BasicOCSPResp basicOcspResp = (BasicOCSPResp) respObject;
    if (nonce != null) {
        Extension nonceExtn = basicOcspResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
        if (nonceExtn == null) {
            if (!requestOptions.isAllowNoNonceInResponse()) {
                throw new OcspResponseException.OcspNonceUnmatched(nonce, null);
            }
        } else {
            byte[] receivedNonce = nonceExtn.getExtnValue().getOctets();
            if (!Arrays.equals(nonce, receivedNonce)) {
                throw new OcspResponseException.OcspNonceUnmatched(nonce, receivedNonce);
            }
        }
    }
    SingleResp[] singleResponses = basicOcspResp.getResponses();
    if (singleResponses == null || singleResponses.length == 0) {
        String msg = StringUtil.concat("response with no singleResponse is returned, expected is ", Integer.toString(serialNumbers.length));
        throw new OcspResponseException.OcspTargetUnmatched(msg);
    }
    final int countSingleResponses = singleResponses.length;
    if (countSingleResponses != serialNumbers.length) {
        String msg = StringUtil.concat("response with ", Integer.toString(countSingleResponses), " singleResponse", (countSingleResponses > 1 ? "s" : ""), " is returned, expected is ", Integer.toString(serialNumbers.length));
        throw new OcspResponseException.OcspTargetUnmatched(msg);
    }
    Request reqAt0 = Request.getInstance(ocspReq.getTbsRequest().getRequestList().getObjectAt(0));
    CertID certId = reqAt0.getReqCert();
    ASN1ObjectIdentifier issuerHashAlg = certId.getHashAlgorithm().getAlgorithm();
    byte[] issuerKeyHash = certId.getIssuerKeyHash().getOctets();
    byte[] issuerNameHash = certId.getIssuerNameHash().getOctets();
    if (serialNumbers.length == 1) {
        SingleResp singleResp = singleResponses[0];
        CertificateID cid = singleResp.getCertID();
        boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
        if (!issuerMatch) {
            throw new OcspResponseException.OcspTargetUnmatched("the issuer is not requested");
        }
        BigInteger serialNumber = cid.getSerialNumber();
        if (!serialNumbers[0].equals(serialNumber)) {
            throw new OcspResponseException.OcspTargetUnmatched("the serialNumber is not requested");
        }
    } else {
        List<BigInteger> tmpSerials1 = Arrays.asList(serialNumbers);
        List<BigInteger> tmpSerials2 = new ArrayList<>(tmpSerials1);
        for (int i = 0; i < countSingleResponses; i++) {
            SingleResp singleResp = singleResponses[i];
            CertificateID cid = singleResp.getCertID();
            boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
            if (!issuerMatch) {
                throw new OcspResponseException.OcspTargetUnmatched("the issuer specified in singleResponse[" + i + "] is not requested");
            }
            BigInteger serialNumber = cid.getSerialNumber();
            if (!tmpSerials2.remove(serialNumber)) {
                if (tmpSerials1.contains(serialNumber)) {
                    throw new OcspResponseException.OcspTargetUnmatched("serialNumber " + LogUtil.formatCsn(serialNumber) + "is contained in at least two singleResponses");
                } else {
                    throw new OcspResponseException.OcspTargetUnmatched("serialNumber " + LogUtil.formatCsn(serialNumber) + " specified in singleResponse[" + i + "] is not requested");
                }
            }
        }
    // end for
    }
    return ocspResp;
}
Also used : CertID(org.bouncycastle.asn1.ocsp.CertID) ArrayList(java.util.ArrayList) ReqRespPair(org.xipki.util.ReqRespDebug.ReqRespPair) OCSPRequest(org.bouncycastle.asn1.ocsp.OCSPRequest) Request(org.bouncycastle.asn1.ocsp.Request) IOException(java.io.IOException) Extension(org.bouncycastle.asn1.x509.Extension) BigInteger(java.math.BigInteger) OCSPRequest(org.bouncycastle.asn1.ocsp.OCSPRequest)

Aggregations

IOException (java.io.IOException)2 ReqRespPair (org.xipki.util.ReqRespDebug.ReqRespPair)2 BigInteger (java.math.BigInteger)1 InvalidKeyException (java.security.InvalidKeyException)1 ArrayList (java.util.ArrayList)1 CertID (org.bouncycastle.asn1.ocsp.CertID)1 OCSPRequest (org.bouncycastle.asn1.ocsp.OCSPRequest)1 Request (org.bouncycastle.asn1.ocsp.Request)1 Extension (org.bouncycastle.asn1.x509.Extension)1 GeneralName (org.bouncycastle.asn1.x509.GeneralName)1