title: Fine grain X509 certificate checks and TrustManagerFactory initialization
body: <p>I am trying to configure a https client in my android application that would perform fine grain checking on the certificate chain received from server.</p>
  
  <p>More precisely I would like to check :</p>
  
  <ul>
  <li>if the chain contains a given CA certificate (custom CA) </li>
  <li>the value of the common name and the organization name of the end-of-chain certificate </li>
  </ul>
  
  <p>I though this could be done by initializing a TrustManagerFactory with properly constructed CertPathTrustManagerParameters but the 2nd line of this code snippet:</p>
  
  <pre><code>TrustManagerFactory tmf = 
  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
  
  tmf.init(new CertPathTrustManagerParameters(pkixBuilderParameters));
  </code></pre>
  
  <p>throws the following Exception :</p>
  
  <pre><code> Unsupported spec: javax.net.ssl.CertPathTrustManagerParameters@634b748. 
   Only android.security.net.config.RootTrustManagerFactorySpi$ApplicationConfigParameters supported.
  </code></pre>
  
  <p>From this post : <a href="https://security.stackexchange.com/questions/83372/what-is-the-difference-of-trustmanager-pkix-and-sunx509">https://security.stackexchange.com/questions/83372/what-is-the-difference-of-trustmanager-pkix-and-sunx509</a>
  I understand that Android JSSE provider may not support TrustManagerFactory initialization with CertPathTrustManagerParameters. </p>
  
  <p>I would like to know if it is possible to initialize TrustManagerFactory with CertPathTrustManagerParameters on Android.</p>
  
  <p>A back up solution for my problem is to initialize TrustManagerFactory with a KeyStore containing my CA certificate and to override <em>checkServerTrusted(X509Certificate[] chain, String authType)</em> function of the generated TrustManager adding checks on organization and common name.</p>
  
  <p><strong>Note :</strong></p>
  
  <p>Regardless of the algorithm specified when calling </p>
  
  <pre><code> TrustManagerFactory tmf = TrustManagerFactory.getInstance(String algorithm)
  </code></pre>
  
  <p>the TrustManagerFactory object returned is always set with a <strong>RootTrustManagerFactorySpi</strong> as TrustManagerFactorySpi. </p>
  
  <p>Then, the function </p>
  
  <pre><code>tmf.init(new CertPathTrustManagerParameters(pkixBuilderParameters))
  </code></pre>
  
  <p>calls the following function in RootTrustManagerFactorySpi:</p>
  
  <pre><code>@Override
  public void engineInit(ManagerFactoryParameters spec)
          throws InvalidAlgorithmParameterException {
      if (!(spec instanceof ApplicationConfigParameters)) {
          throw new InvalidAlgorithmParameterException("Unsupported spec: " +  spec + ". Only "
                  + ApplicationConfigParameters.class.getName() + " supported");
  
      }
      mApplicationConfig = ((ApplicationConfigParameters) spec).config;
  }
  </code></pre>
  
  <p>This shows that, when initalized with <strong>ManagerFactoryParameters</strong>, the TrustManagerFactory only accepts <strong>ApplicationConfigParameters</strong> to be provided and rejects <strong>CertPathTrustManagerParameters</strong> (both are child class of ManagerFactoryParameters)</p>