Cath
Cath

Reputation: 135

Self signed certificate "doesn' contain CN or DNS subjectAlt"

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

Answers (2)

david
david

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

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

Related Questions