Reputation: 135
I am working on a project in which my colleague implemented an https server, which uses a self signed server, and I am designing an android app which sends httpposts to it. He has tested it using curl and has no problems. I am using Android 3.2, if it's relevant.
Following this tutorial here, I generated a keystore and added it to the app, also creating a custom httpClient. I replaced the get request with post using the following code:
private InputStream postHttpConnection(String urlValue,
JSONObject jsonPost, Context context) {
InputStream inStream = null;
URL url;
try {
url = new URL(urlValue);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
Log.e("postHttpConnection", "Fail: " + "Not an HTTP connection");
} catch (MalformedURLException e) {
Log.e("postHttpConnection", "Fail: " + e);
} catch (IOException e) {
Log.e("postHttpConnection", "Fail: " + e);
}
try {
DefaultHttpClient client = new MyHttpClient(context);
HttpConnectionParams
.setConnectionTimeout(client.getParams(), 10000);
HttpResponse postResponse;
HttpPost post = new HttpPost(urlValue);
StringEntity se = new StringEntity(jsonPost.toString());
post.setEntity(se);
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
postResponse = client.execute(post);
inStream = postResponse.getEntity().getContent();
} catch (ClientProtocolException e) {
Log.e("postHttpConnection", "Fail: " + e);
} catch (IOException e) {
Log.e("postHttpConnection", "Fail: " + e);
}
return inStream;
}
When I use this function, with an appropriate JSONObject, I get the following error:
E/postHttpConnection(9236): Fail: javax.net.ssl.SSLException: Certificate for <address> doesn't contain CN or DNS subjectAlt
Can you tell me what this is related to? Thank you.
Upvotes: 2
Views: 2631
Reputation: 1057
private HttpClient getHttpClient(){
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory> create();
ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
registryBuilder.register("http", plainSF);
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
TrustStrategy anyTrustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, anyTrustStrategy)
.build();
LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
registryBuilder.register("https", sslSF);
} catch (Exception e) {
throw new RuntimeException(e);
}
Registry<ConnectionSocketFactory> registry = registryBuilder.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
HttpClient httpclient = HttpClientBuilder.create().setConnectionManager(connManager).build();
return httpclient;
}
it's maybe help you. ps. httpclient version is 4.3.1
Upvotes: 0
Reputation: 46050
The problem is not in your code but in the certificate. You need to have your domain name (the one the client is connecting to) specified either in SubjectName.CommonName field of the certificate or in Subject Alternative Name extension of the certificate. You need to re-create the certificate and when doing this, check manuals regarding how to specify CommonName (you'd need to set it to something like "www.mydomain.com").
Upvotes: 4