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;
}
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;
}
Aggregations