Untrusted certificate error and httpclient on android

11,677

I believe your certificate doesn't contain all intermediate certificates necessary to validate path to a system trusted root certificate. It can be reported as incomplete certificate chain by some SSL config validation tools.

A certificate can contain a special Authority Information Access extension (RFC-3280) with URL to issuer's certificate. Most browsers can use the AIA extension to download missing intermediate certificate to complete the certificate chain. But some clients (mobile browsers, OpenSSL) don't support this extension, so they report such certificate as untrusted.

You can solve the incomplete certificate chain issue manually by concatenating all certificates from the certificate to the trusted root certificate (exclusive, in this order), to prevent such issues. Note, the trusted root certificate should not be there, as it is already included in the system’s root certificate store.

You should be able to fetch intermediate certificates from the issuer and concat them together by yourself. I have written a script to automate the procedure, it loops over the AIA extension to produce output of correctly chained certificates. https://github.com/zakjan/cert-chain-resolver

Share:
11,677
Ivo
Author by

Ivo

Updated on June 04, 2022

Comments

  • Ivo
    Ivo almost 2 years

    I'm using the Apache HttpClient library to setup a https connection. Unfortunately Android gives me a "Not trusted server certificate" error. If I browse to the site with the phone's browser it validates the certificate correctly, which leads me to believe that I need to make the HttpClient 'aware' of the root certificates on the phone. This is my HttpClient setup code:

    HttpParams params = new BasicHttpParams();
    
    HttpConnectionParams.setConnectionTimeout( params, 20000 );
    HttpConnectionParams.setSoTimeout( params, 20000 );
    
    HttpProtocolParams.setVersion( params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset( params, HTTP.DEFAULT_CONTENT_CHARSET);
    HttpProtocolParams.setUseExpectContinue( params, false);
    
    SchemeRegistry schReg = new SchemeRegistry();
    schReg.register( new Scheme( "http", PlainSocketFactory.getSocketFactory(), 80 ) );
    schReg.register( new Scheme( "https", SSLSocketFactory.getSocketFactory(), 443 ) );
    
    ClientConnectionManager conMgr = new ThreadSafeClientConnManager( params, schReg );
    
    DefaultHttpClient defaultHttpClient = new DefaultHttpClient( conMgr, params );
    
    return ( defaultHttpClient );
    

    As you can see I do nothing special with the SSLSocketFactory. How can I make the HttpClient library validate my site without adding a custom certificate in the keystore?. Should I create a custom SSLSocketFactory and load the cacerts.bks from the Android phone? In that case I might get problems with different passwords for the keystore on different phones?

    Please let me know if you need further information. This SSL stuff is pretty difficult for me.