javapdfitextbouncycastle

ClassCastException when casting IBasicOCSPResponse to IBasicOCSPResp in iText 8.0.4


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:

Any guidance would be greatly appreciated. Thanks in advance!


Solution

  • 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())