I don't know if this is related to having updated Android Build Tools since I didn't try right after but I can't seem to get Charles to work propery with SSL Proxying on Android (it was working fine before).
In a nutshell, if I enable ssl proxying on my api endpoint on Charles I get:
Caused by: java.security.cert.CertificateException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at Wed Aug 31 10:09:00 GMT+02:00 2016 (compared to Thu Sep 01 15:18:53 GMT+02:00 2016)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:344)
at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:219)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:556)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
Of course I've checked our servers certificates (they didn't expire). I've checked the setup many times, I've tried deleting emulators (API 23 & 24) and reinstalling fresh ones, I've even tried upgrading build tools and compile sdk version to 24 and using Java 8. And I've also tried upgrading to Charles 4 and reinstalling the root certificate.
The keytool -list -keystore
/usr/libexec/java_home/jre/lib/security/cacerts -storepass changeit
does list the Charles Certificate. (for both the 1.7 and 1.8 jdks)
Charles Root certificate is properly installed on the emulator and expires in 2044
If I disable SSL Proxying on Charles, everything works just fine again with our without Charles running.
Also, when using an emulator running API 24, the exception is slightly different:
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:563)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:444)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:508)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:401)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:375)
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:304)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
On more important thing to note, the same setup works just fine on the iOS Simulators using the same api endpoint. So this definitely has to do with Java/Android configuration.
Any help is appreciated.