use of org.xipki.security.cmp.ProtectionVerificationResult in project xipki by xipki.
the class CmpAgentUtil method checkProtection.
// method extractXiActionContent
static void checkProtection(VerifiedPkiMessage response) throws PkiErrorException {
notNull(response, "response");
if (!response.hasProtection()) {
return;
}
ProtectionVerificationResult protectionVerificationResult = response.getProtectionVerificationResult();
boolean valid;
if (protectionVerificationResult == null) {
valid = false;
} else {
ProtectionResult protectionResult = protectionVerificationResult.getProtectionResult();
valid = protectionResult == ProtectionResult.MAC_VALID || protectionResult == ProtectionResult.SIGNATURE_VALID;
}
if (!valid) {
throw new PkiErrorException(PKISTATUS_RESPONSE_ERROR, PKIFailureInfo.badMessageCheck, "message check of the response failed");
}
}
use of org.xipki.security.cmp.ProtectionVerificationResult in project xipki by xipki.
the class BaseCmpResponder method processPkiMessage.
// method processPKIMessage0
public PKIMessage processPkiMessage(PKIMessage pkiMessage, X509Cert tlsClientCert, Map<String, String> parameters, AuditEvent event) {
notNull(pkiMessage, "pkiMessage");
notNull(event, "event");
GeneralPKIMessage message = new GeneralPKIMessage(pkiMessage);
PKIHeader reqHeader = message.getHeader();
ASN1OctetString tid = reqHeader.getTransactionID();
String msgId = RandomUtil.nextHexLong();
event.addEventData(NAME_mid, msgId);
if (tid == null) {
byte[] randomBytes = randomTransactionId();
tid = new DEROctetString(randomBytes);
}
String tidStr = Base64.encodeToString(tid.getOctets());
event.addEventData(NAME_tid, tidStr);
int reqPvno = reqHeader.getPvno().getValue().intValue();
if (reqPvno < PVNO_CMP2000) {
event.update(AuditLevel.INFO, AuditStatus.FAILED);
event.addEventData(NAME_message, "unsupported version " + reqPvno);
return buildErrorPkiMessage(tid, reqHeader, PKIFailureInfo.unsupportedVersion, null);
}
CmpControl cmpControl = getCmpControl();
Integer failureCode = null;
String statusText = null;
Date messageTime = null;
if (reqHeader.getMessageTime() != null) {
try {
messageTime = reqHeader.getMessageTime().getDate();
} catch (ParseException ex) {
LogUtil.error(LOG, ex, "tid=" + tidStr + ": could not parse messageTime");
}
}
GeneralName recipient = reqHeader.getRecipient();
boolean intentMe = recipient == null || intendsMe(recipient);
if (!intentMe) {
LOG.warn("tid={}: I am not the intended recipient, but '{}'", tid, reqHeader.getRecipient());
failureCode = PKIFailureInfo.badRequest;
statusText = "I am not the intended recipient";
} else if (messageTime == null) {
if (cmpControl.isMessageTimeRequired()) {
failureCode = PKIFailureInfo.missingTimeStamp;
statusText = "missing time-stamp";
}
} else {
long messageTimeBias = cmpControl.getMessageTimeBias();
if (messageTimeBias < 0) {
messageTimeBias *= -1;
}
long msgTimeMs = messageTime.getTime();
long currentTimeMs = System.currentTimeMillis();
long bias = (msgTimeMs - currentTimeMs) / 1000L;
if (bias > messageTimeBias) {
failureCode = PKIFailureInfo.badTime;
statusText = "message time is in the future";
} else if (bias * -1 > messageTimeBias) {
failureCode = PKIFailureInfo.badTime;
statusText = "message too old";
}
}
if (failureCode != null) {
event.update(AuditLevel.INFO, AuditStatus.FAILED);
event.addEventData(NAME_message, statusText);
return buildErrorPkiMessage(tid, reqHeader, failureCode, statusText);
}
boolean isProtected = message.hasProtection();
CmpRequestorInfo requestor;
String errorStatus;
if (isProtected) {
try {
ProtectionVerificationResult verificationResult = verifyProtection(tidStr, message, cmpControl);
ProtectionResult pr = verificationResult.getProtectionResult();
if (pr == ProtectionResult.SIGNATURE_VALID || pr == ProtectionResult.MAC_VALID) {
errorStatus = null;
} else if (pr == ProtectionResult.SIGNATURE_INVALID) {
errorStatus = "request is protected by signature but invalid";
} else if (pr == ProtectionResult.MAC_INVALID) {
errorStatus = "request is protected by MAC but invalid";
} else if (pr == ProtectionResult.SENDER_NOT_AUTHORIZED) {
errorStatus = "request is protected but the requestor is not authorized";
} else if (pr == ProtectionResult.SIGNATURE_ALGO_FORBIDDEN) {
errorStatus = "request is protected by signature but the algorithm is forbidden";
} else if (pr == ProtectionResult.MAC_ALGO_FORBIDDEN) {
errorStatus = "request is protected by MAC but the algorithm is forbidden";
} else {
throw new IllegalStateException("should not reach here, unknown ProtectionResult " + pr);
}
requestor = (CmpRequestorInfo) verificationResult.getRequestor();
} catch (Exception ex) {
LogUtil.error(LOG, ex, "tid=" + tidStr + ": could not verify the signature");
errorStatus = "request has invalid signature based protection";
requestor = null;
}
} else if (tlsClientCert != null) {
boolean authorized = false;
X500Name x500Sender = getX500Sender(reqHeader);
requestor = (x500Sender == null) ? null : getRequestor(x500Sender);
if (requestor != null) {
if (tlsClientCert.equals(requestor.getCert().getCert())) {
authorized = true;
}
}
if (authorized) {
errorStatus = null;
} else {
LOG.warn("tid={}: not authorized requestor (TLS client '{}')", tid, tlsClientCert.getSubjectRfc4519Text());
errorStatus = "requestor (TLS client certificate) is not authorized";
}
} else {
errorStatus = "request has no protection";
requestor = null;
}
if (errorStatus != null) {
event.update(AuditLevel.INFO, AuditStatus.FAILED);
event.addEventData(NAME_message, errorStatus);
return buildErrorPkiMessage(tid, reqHeader, PKIFailureInfo.badMessageCheck, errorStatus);
}
PKIMessage resp = processPkiMessage0(pkiMessage, requestor, tid, message, msgId, parameters, event);
if (isProtected) {
resp = addProtection(resp, event, requestor);
}
return resp;
}
use of org.xipki.security.cmp.ProtectionVerificationResult in project xipki by xipki.
the class BaseCmpResponder method verifyProtection.
// method randomBytes
private ProtectionVerificationResult verifyProtection(String tid, GeneralPKIMessage pkiMessage, CmpControl cmpControl) throws CMPException, InvalidKeyException {
ProtectedPKIMessage protectedMsg = new ProtectedPKIMessage(pkiMessage);
PKIHeader header = protectedMsg.getHeader();
X500Name sender = getX500Sender(header);
if (sender == null) {
LOG.warn("tid={}: not authorized requestor 'null'", tid);
return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
AlgorithmIdentifier protectionAlg = header.getProtectionAlg();
if (protectedMsg.hasPasswordBasedMacProtection()) {
PBMParameter parameter = PBMParameter.getInstance(pkiMessage.getHeader().getProtectionAlg().getParameters());
HashAlgo owfAlg;
try {
owfAlg = HashAlgo.getInstance(parameter.getOwf());
} catch (NoSuchAlgorithmException ex) {
LogUtil.warn(LOG, ex);
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
if (!cmpControl.isRequestPbmOwfPermitted(owfAlg)) {
LOG.warn("MAC_ALGO_FORBIDDEN (PBMParameter.owf: {})", owfAlg.getJceName());
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
SignAlgo macAlg;
try {
macAlg = SignAlgo.getInstance(parameter.getMac());
} catch (NoSuchAlgorithmException ex) {
LogUtil.warn(LOG, ex);
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
if (!cmpControl.isRequestPbmMacPermitted(macAlg)) {
LOG.warn("MAC_ALGO_FORBIDDEN (PBMParameter.mac: {})", macAlg.getJceName());
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
int iterationCount = parameter.getIterationCount().getValue().intValue();
if (iterationCount < 1000) {
LOG.warn("MAC_ALGO_FORBIDDEN (PBMParameter.iterationCount: {} < 1000)", iterationCount);
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
ASN1OctetString asn1 = header.getSenderKID();
// CHECKSTYLE:SKIP
byte[] senderKID = (asn1 == null) ? null : asn1.getOctets();
PKMACBuilder pkMacBuilder = new PKMACBuilder(new JcePKMACValuesCalculator());
CmpRequestorInfo requestor = getMacRequestor(senderKID);
if (requestor == null) {
LOG.warn("tid={}: not authorized requestor with senderKID '{}", tid, (senderKID == null) ? "null" : Hex.toHexString(senderKID));
return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
boolean macValid = protectedMsg.verify(pkMacBuilder, requestor.getPassword());
return new ProtectionVerificationResult(requestor, macValid ? ProtectionResult.MAC_VALID : ProtectionResult.MAC_INVALID);
} else {
if (!cmpControl.getSigAlgoValidator().isAlgorithmPermitted(protectionAlg)) {
LOG.warn("SIG_ALGO_FORBIDDEN: {}", pkiMessage.getHeader().getProtectionAlg().getAlgorithm().getId());
return new ProtectionVerificationResult(null, ProtectionResult.SIGNATURE_ALGO_FORBIDDEN);
}
X500Name x500Sender = getX500Sender(header);
CmpRequestorInfo requestor = (x500Sender == null) ? null : getRequestor(x500Sender);
if (requestor == null) {
LOG.warn("tid={}: not authorized requestor '{}'", tid, header.getSender());
return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
ContentVerifierProvider verifierProvider = securityFactory.getContentVerifierProvider(requestor.getCert().getCert());
if (verifierProvider == null) {
LOG.warn("tid={}: not authorized requestor '{}'", tid, sender);
return new ProtectionVerificationResult(requestor, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
boolean signatureValid = protectedMsg.verify(verifierProvider);
return new ProtectionVerificationResult(requestor, signatureValid ? ProtectionResult.SIGNATURE_VALID : ProtectionResult.SIGNATURE_INVALID);
}
}
Aggregations