I'm working on a Java app - to be run on App Engine - which routinely checks the SSL certificates used by our web apps and gives us a warning if they're about to expire.
I was hoping to use the following code, which throws an exception if the certificate expires in less than 2 weeks (I've simplified it a little by removing some error checking).
GregorianCalendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_YEAR, 14);
Date twoWeeksInTheFuture = cal.getTime();
URL url = new URL(https_url);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
// Need the following line in order to establish a connection with the server
con.getResponseCode();
Certificate[] certs = con.getServerCertificates();
Certificate certificate = certs[0];
X509Certificate x509Certificate = (X509Certificate) certificate;
x509Certificate.checkValidity(twoWeeksInTheFuture);
That code works fine outside of App Engine (e.g. in the main method of a Java class). However, when run in App Engine the following exception is thrown:
java.lang.ClassCastException: com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection cannot be cast to javax.net.ssl.HttpsURLConnection
at com.bronzelabs.httpschecker.servlets.cron.HttpsChecker.doGet(HttpsChecker.java:101)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
HttpsURLConnection is in the whitelist of allowed classes so there must be a way to use this class on App Engine (well, you'd assume). It just seems like you can't use URL.openConnection().
Does anyone know of a way to establish an HTTPS Connection (using Java on App Engine) and view details on the SSL certificates?
Note: I've looked at Google's URLFetchService. There doesn't appear to be any way to access the certificates (only the contents of the HTTP request).
There's no way to do this with the built-in URLFetchService in the Standard Environment, as you've (correctly) observed. For details about what you can do with URLFetchService and HTTPS, see here. You may be able use a third-party library to do this; also, you could try using the flexible environment instead depending on your use case.
There's no way to do this with the built-in URLFetchService in the Standard Environment, as you've (correctly) observed. For details about what you can do with URLFetchService and HTTPS, see here. You may be able use a third-party library to do this, but request proxying could also prove a roadblock; you could try using the flexible environment instead depending on your use case.