use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.
the class OcspStatusCmd method processResponse.
@Override
protected Object processResponse(OCSPResp response, X509Certificate respIssuer, IssuerHash issuerHash, List<BigInteger> serialNumbers, Map<BigInteger, byte[]> encodedCerts) throws Exception {
ParamUtil.requireNonNull("response", response);
ParamUtil.requireNonNull("issuerHash", issuerHash);
ParamUtil.requireNonNull("serialNumbers", serialNumbers);
BasicOCSPResp basicResp = OcspUtils.extractBasicOcspResp(response);
boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null;
SingleResp[] singleResponses = basicResp.getResponses();
if (singleResponses == null || singleResponses.length == 0) {
throw new CmdFailure("received no status from server");
}
final int n = singleResponses.length;
if (n != serialNumbers.size()) {
throw new CmdFailure("received status with " + n + " single responses from server, but " + serialNumbers.size() + " were requested");
}
Date[] thisUpdates = new Date[n];
for (int i = 0; i < n; i++) {
thisUpdates[i] = singleResponses[i].getThisUpdate();
}
// check the signature if available
if (null == basicResp.getSignature()) {
println("response is not signed");
} else {
X509CertificateHolder[] responderCerts = basicResp.getCerts();
if (responderCerts == null || responderCerts.length < 1) {
throw new CmdFailure("no responder certificate is contained in the response");
}
ResponderID respId = basicResp.getResponderId().toASN1Primitive();
X500Name respIdByName = respId.getName();
byte[] respIdByKey = respId.getKeyHash();
X509CertificateHolder respSigner = null;
for (X509CertificateHolder cert : responderCerts) {
if (respIdByName != null) {
if (cert.getSubject().equals(respIdByName)) {
respSigner = cert;
}
} else {
byte[] spkiSha1 = HashAlgo.SHA1.hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes());
if (Arrays.equals(respIdByKey, spkiSha1)) {
respSigner = cert;
}
}
if (respSigner != null) {
break;
}
}
if (respSigner == null) {
throw new CmdFailure("no responder certificate match the ResponderId");
}
boolean validOn = true;
for (Date thisUpdate : thisUpdates) {
validOn = respSigner.isValidOn(thisUpdate);
if (!validOn) {
throw new CmdFailure("responder certificate is not valid on " + thisUpdate);
}
}
if (validOn) {
PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey);
boolean sigValid = basicResp.isSignatureValid(cvp);
if (!sigValid) {
throw new CmdFailure("response is equipped with invalid signature");
}
// verify the OCSPResponse signer
if (respIssuer != null) {
boolean certValid = true;
X509Certificate jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure());
if (X509Util.issues(respIssuer, jceRespSigner)) {
try {
jceRespSigner.verify(respIssuer.getPublicKey());
} catch (SignatureException ex) {
certValid = false;
}
}
if (!certValid) {
throw new CmdFailure("response is equipped with valid signature but the" + " OCSP signer is not trusted");
}
} else {
println("response is equipped with valid signature");
}
// end if(respIssuer)
}
if (verbose.booleanValue()) {
println("responder is " + X509Util.getRfc4519Name(responderCerts[0].getSubject()));
}
}
for (int i = 0; i < n; i++) {
if (n > 1) {
println("---------------------------- " + i + "----------------------------");
}
SingleResp singleResp = singleResponses[i];
CertificateStatus singleCertStatus = singleResp.getCertStatus();
String status;
if (singleCertStatus == null) {
status = "good";
} else if (singleCertStatus instanceof RevokedStatus) {
RevokedStatus revStatus = (RevokedStatus) singleCertStatus;
Date revTime = revStatus.getRevocationTime();
Date invTime = null;
Extension ext = singleResp.getExtension(Extension.invalidityDate);
if (ext != null) {
invTime = ASN1GeneralizedTime.getInstance(ext.getParsedValue()).getDate();
}
if (revStatus.hasRevocationReason()) {
int reason = revStatus.getRevocationReason();
if (extendedRevoke && reason == CrlReason.CERTIFICATE_HOLD.getCode() && revTime.getTime() == 0) {
status = "unknown (RFC6960)";
} else {
status = StringUtil.concatObjects("revoked, reason = ", CrlReason.forReasonCode(reason).getDescription(), ", revocationTime = ", revTime, (invTime == null ? "" : ", invalidityTime = " + invTime));
}
} else {
status = "revoked, no reason, revocationTime = " + revTime;
}
} else if (singleCertStatus instanceof UnknownStatus) {
status = "unknown (RFC2560)";
} else {
status = "ERROR";
}
StringBuilder msg = new StringBuilder();
CertificateID certId = singleResp.getCertID();
HashAlgo hashAlgo = HashAlgo.getNonNullInstance(certId.getHashAlgOID());
boolean issuerMatch = issuerHash.match(hashAlgo, certId.getIssuerNameHash(), certId.getIssuerKeyHash());
BigInteger serialNumber = certId.getSerialNumber();
msg.append("issuer matched: ").append(issuerMatch);
msg.append("\nserialNumber: ").append(LogUtil.formatCsn(serialNumber));
msg.append("\nCertificate status: ").append(status);
if (verbose.booleanValue()) {
msg.append("\nthisUpdate: ").append(singleResp.getThisUpdate());
msg.append("\nnextUpdate: ").append(singleResp.getNextUpdate());
Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash);
if (extension != null) {
msg.append("\nCertHash is provided:\n");
ASN1Encodable extensionValue = extension.getParsedValue();
CertHash certHash = CertHash.getInstance(extensionValue);
ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm();
byte[] hashValue = certHash.getCertificateHash();
msg.append("\tHash algo : ").append(hashAlgOid.getId()).append("\n");
msg.append("\tHash value: ").append(Hex.encode(hashValue)).append("\n");
if (encodedCerts != null) {
byte[] encodedCert = encodedCerts.get(serialNumber);
MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId());
byte[] expectedHashValue = md.digest(encodedCert);
if (Arrays.equals(expectedHashValue, hashValue)) {
msg.append("\tThis matches the requested certificate");
} else {
msg.append("\tThis differs from the requested certificate");
}
}
}
// end if (extension != null)
extension = singleResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff);
if (extension != null) {
ASN1Encodable extensionValue = extension.getParsedValue();
ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(extensionValue);
msg.append("\nArchive-CutOff: ");
msg.append(time.getTimeString());
}
AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
if (sigAlg == null) {
msg.append(("\nresponse is not signed"));
} else {
String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
if (sigAlgName == null) {
sigAlgName = "unknown";
}
msg.append("\nresponse is signed with ").append(sigAlgName);
}
// extensions
msg.append("\nExtensions: ");
List<?> extensionOids = basicResp.getExtensionOIDs();
if (extensionOids == null || extensionOids.size() == 0) {
msg.append("-");
} else {
int size = extensionOids.size();
for (int j = 0; j < size; j++) {
ASN1ObjectIdentifier extensionOid = (ASN1ObjectIdentifier) extensionOids.get(j);
String name = EXTENSION_OIDNAME_MAP.get(extensionOid);
if (name == null) {
msg.append(extensionOid.getId());
} else {
msg.append(name);
}
if (j != size - 1) {
msg.append(", ");
}
}
}
}
// end if (verbose.booleanValue())
println(msg.toString());
}
// end for
println("");
return null;
}
use of org.bouncycastle.operator.ContentVerifierProvider in project keystore-explorer by kaikramer.
the class Pkcs10Util method verifyCsr.
/**
* Verify a PKCS #10 certificate signing request (CSR).
*
* @param csr The certificate signing request
* @return True if successfully verified
* @throws CryptoException If there was a problem verifying the CSR
*/
public static boolean verifyCsr(PKCS10CertificationRequest csr) throws CryptoException {
try {
PublicKey pubKey = new JcaPKCS10CertificationRequest(csr).getPublicKey();
ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder().setProvider("BC").build(pubKey);
return csr.isSignatureValid(contentVerifierProvider);
} catch (InvalidKeyException | OperatorCreationException | NoSuchAlgorithmException | PKCSException e) {
throw new CryptoException(res.getString("NoVerifyPkcs10Csr.exception.message"), e);
}
}
use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.
the class CmpAgent method verifyProtection.
private ProtectionVerificationResult verifyProtection(String tid, GeneralPKIMessage pkiMessage) throws CMPException, InvalidKeyException {
ProtectedPKIMessage protectedMsg = new ProtectedPKIMessage(pkiMessage);
PKIHeader header = protectedMsg.getHeader();
if (requestor instanceof Requestor.PbmMacCmpRequestor) {
if (!protectedMsg.hasPasswordBasedMacProtection()) {
LOG.warn("NOT_MAC_BASED: {}", pkiMessage.getHeader().getProtectionAlg().getAlgorithm().getId());
return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
Responder.PbmMacCmpResponder macResponder = (Responder.PbmMacCmpResponder) responder;
PBMParameter parameter = PBMParameter.getInstance(pkiMessage.getHeader().getProtectionAlg().getParameters());
HashAlgo owf;
try {
owf = HashAlgo.getInstance(parameter.getOwf());
} catch (NoSuchAlgorithmException ex) {
LOG.warn("MAC_ALGO_FORBIDDEN (PBMParameter.owf)", ex);
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
if (!macResponder.isPbmOwfPermitted(owf)) {
LOG.warn("MAC_ALGO_FORBIDDEN (PBMParameter.owf: {})", owf);
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
SignAlgo mac;
try {
mac = SignAlgo.getInstance(parameter.getMac());
} catch (NoSuchAlgorithmException ex) {
LOG.warn("MAC_ALGO_FORBIDDEN (PBMParameter.mac)", ex);
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
if (!macResponder.isPbmMacPermitted(mac)) {
LOG.warn("MAC_ALGO_FORBIDDEN (PBMParameter.mac: {})", mac);
return new ProtectionVerificationResult(null, ProtectionResult.MAC_ALGO_FORBIDDEN);
}
Requestor.PbmMacCmpRequestor macRequestor = (Requestor.PbmMacCmpRequestor) requestor;
PKMACBuilder pkMacBuilder = new PKMACBuilder(new JcePKMACValuesCalculator());
boolean macValid = protectedMsg.verify(pkMacBuilder, macRequestor.getPassword());
return new ProtectionVerificationResult(requestor, macValid ? ProtectionResult.MAC_VALID : ProtectionResult.MAC_INVALID);
} else {
if (protectedMsg.hasPasswordBasedMacProtection()) {
LOG.warn("NOT_SIGNATURE_BASED: {}", pkiMessage.getHeader().getProtectionAlg().getAlgorithm().getId());
return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
if (recipientName != null) {
boolean authorizedResponder;
if (header.getSender().getTagNo() != GeneralName.directoryName) {
authorizedResponder = false;
} else {
X500Name msgSender = X500Name.getInstance(header.getSender().getName());
authorizedResponder = recipientName.equals(msgSender);
}
if (!authorizedResponder) {
LOG.warn("tid={}: not authorized responder '{}'", tid, header.getSender());
return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
}
Responder.SignatureCmpResponder sigResponder = (Responder.SignatureCmpResponder) responder;
SignAlgo protectionAlgo;
try {
protectionAlgo = SignAlgo.getInstance(protectedMsg.getHeader().getProtectionAlg());
} catch (NoSuchAlgorithmException ex) {
LOG.warn("tid={}: unknown response protection algorithm: {}", tid, ex.getMessage());
return new ProtectionVerificationResult(null, ProtectionResult.SIGNATURE_INVALID);
}
if (!sigResponder.getSigAlgoValidator().isAlgorithmPermitted(protectionAlgo)) {
LOG.warn("tid={}: response protected by untrusted protection algorithm '{}'", tid, protectionAlgo.getJceName());
return new ProtectionVerificationResult(null, ProtectionResult.SIGNATURE_INVALID);
}
X509Cert cert = sigResponder.getCert();
ContentVerifierProvider verifierProvider = securityFactory.getContentVerifierProvider(cert);
if (verifierProvider == null) {
LOG.warn("tid={}: not authorized responder '{}'", tid, header.getSender());
return new ProtectionVerificationResult(cert, ProtectionResult.SENDER_NOT_AUTHORIZED);
}
boolean signatureValid = protectedMsg.verify(verifierProvider);
return new ProtectionVerificationResult(cert, signatureValid ? ProtectionResult.SIGNATURE_VALID : ProtectionResult.SIGNATURE_INVALID);
}
}
use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.
the class CrlStreamParser method verifySignature.
public boolean verifySignature(PublicKey publicKey) throws IOException {
try {
ContentVerifierProvider cvp = SignerUtil.getContentVerifierProvider(publicKey, null);
ContentVerifier verifier = cvp.get(algorithmIdentifier);
OutputStream sigOut = verifier.getOutputStream();
try (InputStream crlStream = new FileInputStream(crlFile)) {
skip(crlStream, tbsCertListOffset);
int remainingLength = tbsCertListEndIndex - tbsCertListOffset;
byte[] buffer = new byte[1024];
while (true) {
int count = crlStream.read(buffer);
if (count == -1) {
break;
} else if (count > 0) {
if (count <= remainingLength) {
sigOut.write(buffer, 0, count);
remainingLength -= count;
} else {
sigOut.write(buffer, 0, remainingLength);
remainingLength = 0;
}
}
if (remainingLength == 0) {
break;
}
}
if (remainingLength != 0) {
throw new IOException("could reading all tbsCertList");
}
}
sigOut.close();
return verifier.verify(this.getSignature());
} catch (InvalidKeyException | OperatorCreationException ex) {
LogUtil.error(LOG, ex, "could not validate POPO of CSR");
return false;
}
}
use of org.bouncycastle.operator.ContentVerifierProvider 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