title: Public Key pinning with X509TrustManagerExtensions checkServerTrusted
body: <p><strong>Public key pinning in for a HTTPS TLS connection.</strong></p>
  
  <p>There is an issue with Android API, below 17, that enables MITM (Man in the Middle) attack incase of public key pinning. This has been explained in the link below.</p>
  
  <p><a href="https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/" rel="nofollow">https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/</a></p>
  
  <p>So in Android minimum sdk below 17, ie, below Android version 4.2, we need to initialise the <strong>X509TrustManager</strong> with Android Keystore which has only the server root certificates (<em>instead of the default keystore; which would have all certificates installed in the device</em>). This helps in cleaning the leaf certificates received from the server before performing public key pinning.</p>
  
  <p>From Android API 17 onwards, Android has introduced <strong>X509TrustManagerExtensions</strong> which performs this root cleaning at OS level.</p>
  
  <p><a href="https://developer.android.com/reference/android/net/http/X509TrustManagerExtensions.html" rel="nofollow">https://developer.android.com/reference/android/net/http/X509TrustManagerExtensions.html</a></p>
  
  <p><strong>My question:</strong></p>
  
  <p>I would be glad if anyone could please provide an example on how to implement the following method provided by the X509TrustManagerExtensions for root cleaning.</p>
  
  <pre><code>List&lt;X509Certificate&gt; checkServerTrusted (X509Certificate[] chain, 
                  String authType, 
                  String host)
  </code></pre>
  
  <p>I am confused with the following.</p>
  
  <ol>
  <li><p><code>host</code>; should it be the domain URL? with https or without? or should it be the full url (domain + relative path)</p></li>
  <li><p>How to create instant of a <code>X509TrustManagerExtensions</code>?
  The constructor for X509TrustManagerExtensions takes <code>X509TrustManager</code> as input. Do we create this X509TrustManager with the android default keystore?</p></li>
  </ol>
  
  <p><strong>Code snippet (Not working):</strong></p>
  
  <pre><code>   TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
     tmf.init(KeyStore.getInstance(KeyStore.getDefaultType()));
  
     for (TrustManager trustManager : tmf.getTrustManagers()) {
         X509TrustManagerExtensions tme = new X509TrustManagerExtensions((X509TrustManager) trustManager);
         tme.checkServerTrusted(chain, authType, &lt;&lt;String https://www.example.com&gt;&gt;);
     }
  </code></pre>
  
  <p><strong>Exception:</strong>
  Trust anchor for certification path not found</p>
  
  <p><strong>Possible security risk:</strong>
  Using <code>KeyStore.getDefaultType()</code></p>
  
  <p>Any help would be greatly appreciated.</p>