title: trustManager.checkServerTrusted(...) never throws CertificateException
body: <p>I'm working on a custom TrustManager implementation that uses an X509TrustManager and I encountered the following problem:</p>
  
  <p>According to the Javadocs, a X509TrustManager is expected to throw a CertificateException:</p>
  
  <pre><code>void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException;
  </code></pre>
  
  <p>The CertificateException is an class that got a number of sub-classes:</p>
  
  <pre><code>java.security.cert.CertificateException 
  
  CertificateEncodingException
  CertificateExpiredException
  CertificateNotYetValidException
  CertificateParsingException
  CertificateRevokedException 
  </code></pre>
  
  <p>Unfortunately, these exceptions are never thrown (at least not from sun.security.ssl.X509TrustManagerImpl that got returned from the factory). Instead I get a sun.security.validator.ValidatoreException with different causes:</p>
  
  <pre><code>sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path...
  </code></pre>
  
  <p>when the CA is not in the trust-store or the cert is self-signed</p>
  
  <pre><code>java.security.cert.CertPathValidatorException: Certificate has been revoked...
  </code></pre>
  
  <p>when the cert has been revoked</p>
  
  <p>So, my question is: what is the best way to get to the real cause of certificate verification problems, especially considering the fact that we should not use from sun packages?</p>
  
  <p>Cheers,
  Andreas</p>
  
  <p>@rxg</p>
  
  <p>That's exactly my problem - I'm catching the CertificateException. However the actual type is always a ValidatorException and not one of the documented exceptions (CertificateEncodingException, CertificateExpiredException, CertificateNotYetValidException, CertificateParsingException, CertificateRevokedException). To figure out what the real cause of a validation exception was, I have to analyse the class causing the exception and to read the message, like this:</p>
  
  <pre><code>} catch (CertificateException e) {
  
  if (e.getCause() instanceof java.security.cert.CertPathValidatorException ) {
  
      if (e.getCause().getMessage().startsWith("Certificate has been revoked")) {
          // ...
      } else if (e.getCause().getMessage().startsWith("timestamp check failed")) {
          // ...
      }
  
  
  } ... more ifs following ...
  </code></pre>
  
  <p>Evaluating the exception message is really bad style and definitely not reliable. Therefore my question: is there any other way to do this?</p>