title: an unsafe implementation of the interface X509TrustManager from google
body: <p>I hava an app in Google Play, I received a mail from Google saying that:</p>
  
  <blockquote>
    <p>Your app(s) listed at the end of this email use an unsafe implementation of the interface X509TrustManager. Specifically, the implementation ignores all SSL certificate validation errors when establishing an HTTPS connection to a remote host, thereby making your app vulnerable to man-in-the-middle attacks.</p>
    
    <p>To properly handle SSL certificate validation, change your code in the checkServerTrusted method of your custom X509TrustManager interface to raise either CertificateException or IllegalArgumentException whenever the certificate presented by the server does not meet your expectations.</p>
  </blockquote>
  
  <p>My app uses "https", my <code>checkServerTrusted()</code> is the following:</p>
  
  <pre><code> TrustManager tm = new X509TrustManager() {
          public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
          }
  
          public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  
          }
  
          public X509Certificate[] getAcceptedIssuers() {
              return null;
          }
      };
  </code></pre>
  
  <p>Then I modify this function:</p>
  
  <pre><code> TrustManager tm = new X509TrustManager() {
          public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
          }
  
          public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
              if (chain == null) {
                  throw new IllegalArgumentException("checkServerTrusted: X509Certificate array is null");
              }
  
              if (!(chain.length &gt; 0)) {
                  throw new IllegalArgumentException("checkServerTrusted: X509Certificate is empty");
              }
  
              if (!(null != authType &amp;&amp; authType.equalsIgnoreCase("RSA"))) {
  
                  throw new CertificateException("checkServerTrusted: AuthType is not RSA");
              }
          }
  
          public X509Certificate[] getAcceptedIssuers() {
              return null;
          }
  </code></pre>
  
  <p>the custom SSLSocketFactory:</p>
  
  <pre><code>public class MySSLSocketFactory extends SSLSocketFactory {
  SSLContext sslContext = SSLContext.getInstance("TLS");
  
  public MySSLSocketFactory(KeyStore ctx) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
      super(ctx);
  
      TrustManager tm = new X509TrustManager() {
          public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
          }
  
          public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
          }
  
          public X509Certificate[] getAcceptedIssuers() {
              return null;
          }
      };
  
      sslContext.init(null, new TrustManager[]{tm}, null);
  }
  
  @Override
  public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
      return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
  }
  
  @Override
  public Socket createSocket() throws IOException {
      return sslContext.getSocketFactory().createSocket();
  }
  </code></pre>
  
  <p>}</p>
  
  <p>the HttpClient function：</p>
  
  <pre><code>private static HttpClient getHttpClient(int timeout) {
      if (null == mHttpClient) {
  
          try {
              KeyStore trustStore = KeyStore.getInstance(KeyStore
                      .getDefaultType());
              trustStore.load(null, null);
              SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
              sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
  
              HttpParams params = new BasicHttpParams();
  
              HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
              HttpProtocolParams.setContentCharset(params,
                      HTTP.DEFAULT_CONTENT_CHARSET);
              HttpProtocolParams.setUseExpectContinue(params, true);
  
  
              ConnManagerParams.setTimeout(params, timeout);
  
              HttpConnectionParams.setConnectionTimeout(params, timeout);
  
              HttpConnectionParams.setSoTimeout(params, timeout);
  
  
              SchemeRegistry schReg = new SchemeRegistry();
              schReg.register(new Scheme("http", PlainSocketFactory
                      .getSocketFactory(), 80));
              schReg.register(new Scheme("https", sf, 443));
  
              ClientConnectionManager conManager = new ThreadSafeClientConnManager(
                      params, schReg);
  
              mHttpClient = new DefaultHttpClient(conManager, params);
          } catch (Exception e) {
              e.printStackTrace();
              return new DefaultHttpClient();
          }
      }
      return mHttpClient;
  }
  </code></pre>
  
  <p>But I do not know well about this,I just modify my code by what the email said,I think I have not sloved this problem.What is this warning all about? How to solve it?</p>