Trust anchor for certification path not found - Android - Volley

606 views Asked by At

I am using Volley for api call in my android java application, and recently I am getting SSLHandshakeException - java.security.cert.CertPathValidatorException: Trust anchor for certification path not found

I have used X509 Trust Manager and it works, but when I send my app on Google Play for review, it is rejected. Below is my code

/**
 * Enables https connections
 */
@SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                try {
                    certs[0].checkValidity();
                } catch (CertificateExpiredException | CertificateNotYetValidException e) {
                    throw new RuntimeException(e);
                }
            }
        }};

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception ignored) {
    }
}

Is this the correct way to handle this type of exception? If no then what needs to be corrected in above code so that the implementation will pass the Google Review

1

There are 1 answers

0
Maarten Bodewes On

First of all, I see that the Volley library allows for specific stacks to be configured to execute the "volleys". Those can be based on HttpsURLConnection, but there also seems to be an option for Apache HttpClient, which - as far as I know - doesn't use HttpsURLConnection.

So you may configure your HttpsURLConnection to use your specific TrustManager but that doesn't mean that it gets used for Volley. To me it doesn't make sense to presume any kind of way that Volley sends requests / receives responses. That said, the Apache HttpClient implementation does seem deprecated.


The problem why your code is rejected is probably not the exception. It is the absence of any kind of verification, which allows man-in-the-middle attacks to be performed. You accept any certificate that is valid without checking that it was signed by a trusted source leading back to a trust anchor.

Furthermore, you allow any hostname to be accepted. This would mean that literally anybody with a certificate & private key may act as an endpoint, e.g. by rerouting the internet packets. This is a huge problem, especially in the face of e.g. rogue Wifi access points. Basically you are completely circumventing any security that TLS offers for the HTTPS protocol.


Presuming that you are not just connecting to any server: I'd make sure that the root certificate of the endpoint that you connect to is in a trust store or indicated as trust anchor directly to the TLS implementation, rather than just letting any HTTP request within the application have zero trust.

You can get free, generally accepted certificates from e.g. Let's Encrypt. Such services are generally considered secure. They are definitely more secure than allowing anybody to act as a TLS endpoint, for all parts of your application that uses HttpsURLConnection.