I am working with iText 8.0.4 (GitHub Repository) and trying to cast IBasicOCSPResponse (from com.itextpdf.signatures) to IBasicOCSPResp (from com.itextpdf.commons.bouncycastle.cert.ocsp).
This is needed to use OCSPVerifier as follows:
List<IBasicOCSPResp> ocsps = new ArrayList<>();
if (pkcs7.getOcsp() != null) {
ocsps.add((IBasicOCSPResp) pkcs7.getOcsp()); // Causes ClassCastException
}
// Checking if the OCSP responses in the list were valid for the certificate on a specific date.
OCSPVerifier ocspVerifier = new OCSPVerifier(null, ocsps);
However, this results in the following ClassCastException:
java.lang.ClassCastException: class com.itextpdf.bouncycastle.asn1.ocsp.BasicOCSPResponseBC cannot be cast to class com.itextpdf.commons.bouncycastle.cert.ocsp.IBasicOCSPResp (com.itextpdf.bouncycastle.asn1.ocsp.BasicOCSPResponseBC and com.itextpdf.commons.bouncycastle.cert.ocsp.IBasicOCSPResp are in unnamed module of loader 'app')
Here is the relevant function:
public VerifResult checkRevocation(PdfPKCS7 pkcs7, X509Certificate signCert,
X509Certificate issuerCert, Date date, Signature signature)
throws GeneralSecurityException {
List<IBasicOCSPResp> ocsps = new ArrayList<>();
if (pkcs7.getOcsp() != null) {
ocsps.add((IBasicOCSPResp) pkcs7.getOcsp()); // Causes ClassCastException
}
// Check OCSP response validity
OCSPVerifier ocspVerifier = new OCSPVerifier(null, ocsps);
List<VerificationOK> verification = ocspVerifier.verify(signCert, issuerCert, date);
// If OCSP verification fails, fall back to CRL verification
if (verification.isEmpty()) {
List<X509CRL> crls = new ArrayList<>();
if (pkcs7.getCRLs() != null) {
for (CRL crl : pkcs7.getCRLs()) {
crls.add((X509CRL) crl);
}
}
CRLVerifier crlVerifier = new CRLVerifier(null, crls);
verification.addAll(crlVerifier.verify(signCert, issuerCert, date));
}
boolean ok = false;
if (verification.isEmpty()) {
logger.info("[{}] The signing certificate couldn't be verified", this.traceid);
signature.setNotRevokedWhenSigned(false);
return new VerifResult(false, false);
} else {
for (VerificationOK v : verification) {
logger.info(v);
signature.setNotRevokedWhenSigned(true);
ok = true;
}
}
signature.setNotRevokedWhenSigned(false);
return new VerifResult(false, ok);
}
Dependencies used:
<dependencies>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>bouncy-castle-adapter</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-core</artifactId>
<version>${itext.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>${itext.version}</version>
</dependency>
</dependencies>
What I Have Tried:
Checking for duplicate dependency versions
Using Dependency Management (caused more errors)
Converting pkcs7.getOcsp().toASN1Primitive().getEncoded() into IBasicOCSPResp (resulted in malformed response: illegal object in getInstance: org.bouncycastle.asn1.DLSequence)
How can I properly convert IBasicOCSPResponse (from com.itextpdf.signatures) into IBasicOCSPResp (from com.itextpdf.commons.bouncycastle.cert.ocsp) to use it in OCSPVerifier?
Is there a workaround to avoid the ClassCastException issue?
Any guidance would be greatly appreciated. Thanks in advance!
PdfPKCS7.getOcsp returns an IBasicOCSPResponse. IBasicOCSPResponse and IBasicOCSPResp are two different interfaces, so there is no reason these should be castable.
These are wrappers for BouncyCastles BasicOCSPResponse and BasicOCSPResp classes. They do represent the same thing, but differently.
A IBasicOCSPResp can be created from a IBasicOCSPResponse with the IBouncyCastleFactory.createBasicOCSPResp(IBasicOCSPResponse response) method.
Something like:
BouncyCastleFactoryCreator.getFactory().createBasicOCSPResp(pkcs7.getOcsp())