title: Verifying PKCS#7 certificates in Java
body: <p>Need some help with crypto routines in Java.</p>
  
  <p>Given a PKCS#7 signature, I want to verify all certificates it contains against a trusted store. I assume that all certificates contained in signature are in the correct order to form a valid certificate path (or chain, whatever), so that</p>
  
  <ul>
  <li>topmost (#0) is a signing certificate;</li>
  <li>next one (#1) is an intermediate certificate, used to sign #0;</li>
  <li>next one (#2) is another intermediate certificate, used to sign #1;</li>
  <li>and so on.</li>
  </ul>
  
  <p>The last certificate (#N) is signed by CA.</p>
  
  <p>That's what I've managed to hack so far:</p>
  
  <pre><code>// Exception handling skipped for readability
  
  //byte[] signature = ...
  pkcs7 = new PKCS7(signature); // `sun.security.pkcs.PKCS7;`
  
  // *** Checking some PKCS#7 parameters here
  
  X509Certificate prevCert = null; // Previous certificate we've found
  X509Certificate[] certs = pkcs7.getCertificates(); // `java.security.cert.X509Certificate`
  for (int i = 0; i &lt; certs.length; i++) {
      // *** Checking certificate validity period here
  
      if (cert != null) {
          // Verify previous certificate in chain against this one
          prevCert.verify(certs[i].getPublicKey());
      }
      prevCert = certs[i];
  }
  
  //String keyStorePath = ...
  KeyStore keyStore = KeyStore.getInstance("JKS"); // `java.security.KeyStore`
  keyStore.load(new FileInputStream(keyStorePath), null);
  
  // Get trusted VeriSign class 1 certificate
  Certificate caCert = keyStore.getCertificate("verisignclass1ca"); // `java.security.cert.Certificate`
  
  // Verify last certificate against trusted certificate
  cert.verify(caCert.getPublicKey());
  </code></pre>
  
  <p>So the question is -- how can this be done using standard Java classes like <code>CertPath</code> and friends? I have a strong feeling I'm re-inventing a bicycle. Or, if someone has an example with BouncyCastle library, that would also be fine.</p>
  
  <p>Bonus question: how to verify a certificate against a trusted store so that root certificate is selected automatically?</p>