1

I need to verify a detached PKCS#7 Signature in Scala using BouncyCastle (version 1.54). The signed data are not enveloped in the PKCS#7 signature.

The PKCS#7 signature is performed using a single certificate.

I wrote a simple function based on the Javadoc of BouncyCastle to verify the signature:

      def verify(data: File): Boolean = {
        val signedData = new CMSSignedData(new CMSProcessableFile(data), Base64.decode(this.value))
        val certStore = signedData.getCertificates
        val signers = signedData.getSignerInfos.getSigners
        val signer = signers.iterator.next
        val certs = certStore.getMatches(signer.getSID)
        val cert = certs.iterator.next.asInstanceOf[X509CertificateHolder]
        signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))
      }

When I compile the code , I obtain the following error:

[error] LogVerifier.scala:26: type mismatch;
[error]  found   : org.bouncycastle.cms.SignerId
[error]  required: org.bouncycastle.util.Selector[?0]
[error]     val certs = certStore.getMatches(signer.getSID)

Could you please help me solve this compilation issue?

Thanks in advance!

  • In fact, I think that my problem is related to the fact that I am using a Java type implementing a Java Interface with generic type. I m probably going to reformulate my question in that direction cause it as nothing to do with PKCS#7 Signature (even if this is what I am trying to do). – Jean-Julien Alvado Aug 06 '16 at 08:09

1 Answers1

1

The problem is that CMSSignedData.getCertificates returns an untyped Store:

https://www.bouncycastle.org/docs/pkixdocs1.5on/org/bouncycastle/cms/CMSSignedData.html#getCertificates()

public org.bouncycastle.util.Store getCertificates()

The Scala compiler interprets this is Store[_], which is shorthand for the existential type Store[?0] forSome { type ?0 } (see the answer to this question), i.e. the Store is parameterized with some specific, arbitrary type and not with Any.

Additionally, SignerId extends an untyped Selector.

Now, the following code causes a type mismatch since the type parameter values for certStore (Store[_]) and signer.getSID (Selector[_]) are not compatible.

val certs = certStore.getMatches(signer.getSID)

To resolve the problem, it should help to explicitly cast certStore to Store[X509CertificateHolder] and signerId to Selector[X509CertificateHolder] (not tested):

val certStore = signedData.getCertificates.
  asInstanceOf[Store[X509CertificateHolder]]

val certs = certStore.getMatches(
  signer.getSID.asInstanceOf[Selector[X509CertificateHolder]])
Community
  • 1
  • 1
devkat
  • 1,624
  • 14
  • 15