I want to open a HTTPS connection in a Google App Engine app using the URLFetch service. To be able to verify the SSL certificate of the server my app is talking to, I am using my own keystore file. I want to read this file in a warmup request when my app is loaded i.e. before any HTTPS requests are performed. The keystore file is part of my WAR file.
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(ClassLoader.getSystemResourceAsStream("myKeystoreFile"), "password".toCharArray());
trustManagerFactory.init(keystore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
I cannot use this approach, however, because while HttpURLConnection is on the GAE's JRE whitelist, HttpsUrlConnection is not.
Is there another way to use a custom keystore in GAE? I did not find any information on this in the GAE docs. It looks like while Google's URLFetch service supports HTTPS, the keystore cannot be customized. Is this correct?
If this isn't possible, is the approach still valid in general? Or is there a different approach that does still allow me to verify the SSL certificate?
UPDATE
In 2009, App Engine developer Nick Johnson from Google said on https://groups.google.com/d/topic/google-appengine-python/C9RSDGeIraE/discussion:
The urlfetch API doesn't allow you to specify your own client certificates, so unfortunately what you want to achieve is not currently possible.
Is this still correct? If every HTTP(s) request in App Engine relies on URLFetch this would mean that custom certificates just cannot be used at all in GAE.
I am using Appengine API 1.9.56 and what Dima suggested with
is not working anymore. Therefore I do not need the
appengine-api-stubs
library, either.However,
HttpsURLConnection.setDefaultSSLSocketFactory
just works fine.Here is my complete solution which solved my problem:
Luckily
HttpsURLConnection
is not blacklisted anymore, as it was in the time the question was made.I was recently facing the same issue and using the HttpClient implementation packaged with appengine-api-stubs worked for me.
Maven Dependency:
Code:
This does essentially the same thing as
But for one reason or another app engine doesn't block it.
You should sign up as a trusted tester for Outbound sockets support. Under Desired Features they enlist SSL. If more parts of the JDK SSL API would be supported building something like this would be simple.
I have had a similar problem... I needed a
keystore.p12
to call a foreign web service but had no chance loading it from the classpath. The only way I was able to use it was to put it in e.g./WEB-INF/keystore.p12
and load it from there.