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