title: Validate TLS server certificate with BouncyCastle's "lightweight" API
body: <p>I'm using Java BouncyCastle so-called "lightweight" API to establish a TLS connection over a TCP socket.</p>
  
  <p>I want to verify server-provided certificate chain being signed by one of trusted CAs. Sounds like a reasonably common task that every sane TLS client implementation out there does by default, so I expect this should be simple.</p>
  
  <p>For a sake of simplifying the question, I don't ask about verifying anything other than the sign/trust chain, like matching hostname or checking expiration date. Such checks seem trivial to implement.</p>
  
  <p>If I understand the documentation correctly, there's a <a href="http://www.bouncycastle.org/docs/docs1.5on/org/bouncycastle/crypto/tls/TlsAuthentication.html" rel="nofollow"><code>TlsAuthentication</code></a> interface, that users are supposed to implement. The sole provided implementation is <code>LegacyTlsAuthentication</code>, which adapts upon now-deprecated <a href="http://www.bouncycastle.org/docs/docs1.5on/org/bouncycastle/crypto/tls/CertificateVerifyer.html" rel="nofollow"><code>CertificateVerifyer</code></a> interface, which has only <a href="http://www.bouncycastle.org/docs/docs1.5on/org/bouncycastle/crypto/tls/AlwaysValidVerifyer.html" rel="nofollow"><code>AlwaysValidVerifyer</code></a> implementation (that's just dummy "<code>return true;</code>" under the hood).</p>
  
  <p>So, this is what I have for now:</p>
  
  <pre><code>DefaultTlsClient tlsClient = new DefaultTlsClient() {
      @Override
      public TlsAuthentication getAuthentication() throws IOException {
          TlsAuthentication auth = new TlsAuthentication() {
              @Override
              public void notifyServerCertificate(Certificate serverCertificate) {
                  // Here I should validate certificate chain, but this far
                  // I only managed to print subjects for debugging purposes.
                  for (org.bouncycastle.asn1.x509.Certificate c : serverCertificate.getCerts()) {
                      System.out.println("Certificate: " + c.getSubject().toString());
                  }
              }
  
              @Override
              public TlsCredentials getClientCredentials(CertificateRequest cr) throws IOException {
                  return null;
              }
          };
          return auth;
      }
  };
  
  socket = new Socket(hostname, port);
  tlsHandler = new TlsProtocolHandler(socket.getInputStream(), socket.getOutputStream());
  tlsHandler.connect(tlsClient);
  </code></pre>
  
  <p>However, I fail to understand or find any existing example that would check one <code>org.bouncycastle.asn1.x509.Certificate</code> for being correctly signed by another one. Could someone provide some pointers to me, please?</p>
  
  <p>I'm using BounceCastle's proprietary API due to need to use ciphersuites that default Java installations do not allow due to being subject to US cryptographic policy jurisdiction restrictions. For example, AES256 encryption requires installing unlimited strength policy files, and I'd really like to avoid additional end-user installation steps, if possible.</p>