ignore ssl errors in DefaultHttpClient

10,073

I solved the problem. It works if you use the above request, but instead of the DefaultHttpClient, use your own version:

public class MyHttpClient extends DefaultHttpClient {
final Context context;
TrustManager easyTrustManager = new X509TrustManager() {
    @Override
    public void checkClientTrusted(
            X509Certificate[] chain,
            String authType) throws CertificateException {
    }

    @Override
    public void checkServerTrusted(
            X509Certificate[] chain,
            String authType) throws CertificateException {
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }    
};
  public MyHttpClient(Context context) {
    this.context = context;
  }

  @Override protected ClientConnectionManager createClientConnectionManager() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(
        new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(new Scheme("https", newSslSocketFactory(), 443));
    return new SingleClientConnManager(getParams(), registry);
  }


  private MySSLSocketFactory newSslSocketFactory() {
    try {
      KeyStore trusted = KeyStore.getInstance("BKS");      
      try {
         trusted.load(null, null);

      } finally {
      }

      MySSLSocketFactory sslfactory =  new MySSLSocketFactory(trusted);
        sslfactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        return sslfactory;
    } catch (Exception e) {
      throw new AssertionError(e);
    }

  }
  public class MySSLSocketFactory extends SSLSocketFactory {
        SSLContext sslContext = SSLContext.getInstance("TLS");

        public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
            super(truststore);

            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();
        }
    }
   }
Share:
10,073
2red13
Author by

2red13

Updated on June 14, 2022

Comments

  • 2red13
    2red13 about 2 years

    Im searching for a possibility to ignore all ssl errors (eg. not trusted) in a default httpclient. I've seen lots of solutions here, but i alwas have to import a specific certificate an add it to the trustmanager or it is for HttpsUrlConnection instad of DefaultHttpClient. My used webrequests are:

        public static String makeGETRequest(String s,String encoding)
    {
        DefaultHttpClient http = new DefaultHttpClient();
        final String username = "USERNAME";
        final String password = "PASSWORD";
        UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password);
        BasicCredentialsProvider cP = new BasicCredentialsProvider(); 
        cP.setCredentials(AuthScope.ANY, c); 
        http.setCredentialsProvider(cP);
        HttpResponse res;
        try {
    
            res = http.execute(new HttpGet(s));
            InputStream is = res.getEntity().getContent();
            BufferedInputStream bis = new BufferedInputStream(is);
            ByteArrayBuffer baf = new ByteArrayBuffer(50);
            int current = 0;
            while((current = bis.read()) != -1){
                  baf.append((byte)current);
             }
    
            return  new String(baf.toByteArray(),encoding);
           } 
        catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            return "error: " + e.getMessage();
        } 
        catch (IOException e) {
            // TODO Auto-generated catch block
            return "error: " + e.getMessage();
        } 
    
    }
    

    And:

    public static String makePOSTRequest(String s, List <NameValuePair> nvps,String encoding)
    {
        DefaultHttpClient http = new DefaultHttpClient();
        final String username = "USERNAME";
        final String password = "PASSWORD";
        UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password);
        BasicCredentialsProvider cP = new BasicCredentialsProvider(); 
        cP.setCredentials(AuthScope.ANY, c); 
        http.setCredentialsProvider(cP);
        HttpResponse res;
        try {
            HttpPost httpost = new HttpPost(s);
            httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.DEFAULT_CONTENT_CHARSET));
            res = http.execute(httpost);
            InputStream is = res.getEntity().getContent();
            BufferedInputStream bis = new BufferedInputStream(is);
            ByteArrayBuffer baf = new ByteArrayBuffer(50);
            int current = 0;
            while((current = bis.read()) != -1){
                  baf.append((byte)current);
             }
            res = null;
            httpost = null;
            String ret = new String(baf.toByteArray(),encoding);
            return  ret;
           } 
        catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            return e.getMessage();
        } 
        catch (IOException e) {
            // TODO Auto-generated catch block
            return e.getMessage();
        } 
    
    }
    

    Did anyone know how to ignore ssl errors in this code?

    edit: because I have to trust only one specific (expired) certificate, I try to overwrite the DefaultHttpClient in the following way:

    public class MyHttpClient extends DefaultHttpClient {
    final Context context;
    
      public MyHttpClient(Context context) {
        this.context = context;
      }
    
      @Override protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(
            new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
      }
    
      private SSLSocketFactory newSslSocketFactory() {
        try {
          KeyStore trusted = KeyStore.getInstance("BKS");
          InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
          try {
            trusted.load(in, "mypassword".toCharArray());
          } finally {
            in.close();
          }
          return new SSLSocketFactory(trusted);
        } catch (Exception e) {
          throw new AssertionError(e);
        }
      }
    

    }

    The file in R.raw.mykeystore is a .bks file, which I created with Portecle, I make a new bks and imported the stored pem of the expired certificate, it seemes to work and the keystored is loaded without errors, but if I perform the request, i get a IO Exception with the message "no peer certificate", what might be the problem?

  • 2red13
    2red13 almost 13 years
    this code will peoduce an broken pipe error in os version 2.2, fixed in 2.3.3 +
  • Pointer Null
    Pointer Null almost 12 years
    Unused field easyTrustManager!