We're going to have a bumper crop of revoked SSL certificates, courtesy of heartbleed. When I saw that Chrome on Android apparently ignores revoked SSL certificates, I wondered what the behavior would be when requesting in Java a Web resource from a server, where we get a revoked SSL certificate.
What I hoped for was a crash with some sort of SSLHandshakeException
.
What I am seeing is a successful connection, but downloading no data -- reading from getInputStream()
returns a length of -1. This is tested using https://revoked.grc.com/ as my test site, which will return an explanatory page if you download it ignoring certificate errors (e.g., via wget -no-check-certificate
). I have tried 4.4, 4.3, and 2.3 emulators, with the same results.
Is there a specified behavior for the Java VM? I doubt that there is an Android-specific specification, but if Android's actual behavior differs from a Java specification, I can work to get the differences clarified as either being bugs or missing documentation.
Revoking your SSL certificate cancels it and immediately removes HTTPS from the website. Depending on your Web host, your website might display errors or become temporarily inaccessible. The process cannot be reversed.
The browser contacts a server called an OCSP responder to find out the revocation status of a particular certificate. The OCSP responder replies with the revocation status and the Certificate Authority's private signing key, which the browser then verifies.
To check the revocation status of an SSL Certificate, the client connects to the URLs and downloads the CA's CRLs. Then, the client searches through the CRL for the serial number of the certificate to make sure that it hasn't been revoked.
The expected behavior would be for X509TrustManager
to catch a CertPathValidatorException
from CertPathValidator
and re-throw it as a CertificateException
(a CertificateRevokedException
when available in Android).
CRL checking is disabled here, on line 362. Note that its not as easy as removing that line, since if a cert has no CRL, a CertPathValidatorException
is also thrown.
CertPathValidator is implemented here and as far as I can tell, by wandering through the source, it doesn't download the CRL's.
This is based on a cursory reading of the javadocs and the JSSE Reference Guide for Java.
The javadoc does not say what happens in the way of SSL certificate verification. On the contrary, the APIs make it clear that the whole process is highly customizable, starting with a SSL socket factory and/or a HostnameVerifier
. The javadocs do not say anything about the behaviour of the defaults.
The JSSE reference goes into a lot more detail, but it is also very complicated ... and clearly JSSE implementation specific. But I think it says that this stuff is handled by the trustmanager, and the default trustmanager is PXIX. Then it says the following:
"If the init(KeyStore ks) method is used, default PKIXParameters are used with the exception that revocation checking is disabled. It can be enabled by setting the system property com.sun.net.ssl.checkRevocation to true. Note that this setting requires that the CertPath implementation can locate revocation information by itself. The PKIX implementation in the SUN provider can do this in many cases but requires that the system property com.sun.security.enableCRLDP be set to true."
In short, certificate revocation checking is disabled by default.
I haven't researched the Android case, and I would not expect the Android implementation to be the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With