Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I solved my problem - I needed to use a certificate with 10.0.2.2 as the common name (CN) so it matched Android localhost ip address of 10.0.2.2 instead of 'localhost' or '127.0.0.1'. </p> <p>Edit: you could probably create a certificate with localhost as the CN and '127.0.0.1' and '10.0.2.2' as Subject Alternative Names (SAN).</p> <p>Once I created 10.0.2.2 cert and private key pem files, I was able to hit my server running with the following command:</p> <pre><code>openssl s_server -accept 8888 -cert 10.0.2.2-cert.pem -key 10.0.2.2-key.pem -state -www </code></pre> <p>If you want to force the client to provide a certificate (though it won't be checked), add the flag <code>-Verify 1</code> to the command above.</p> <p>To test the server at the command line you can use the following (note openssl is able to connect via 127.0.0.1):</p> <pre><code>openssl s_client -connect 127.0.0.1:8888 </code></pre> <p>And to add a client cert if the server requires it, add the flags <code>-cert client-cert.pem -key client-key.pem</code></p> <p>In my Android client I used the following code to connect (error checking removed):</p> <pre><code>// use local trust store (CA) TrustManagerFactory tmf; KeyStore trustedStore = null; InputStream in = context.getResources().openRawResource(R.raw.mycatruststore); // BKS in res/raw trustedStore = KeyStore.getInstance("BKS"); trustedStore.load(in, "insertBksPasswordHere".toCharArray()); tmf = TrustManagerFactory.getInstance("X509"); tmf.init(trustedStore); // load client certificate KeyStore clientKeyStore = loadClientKeyStore(getApplicationContext()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); kmf.init(clientKeyStore, "insertPasswordHere".toCharArray()); SSLContext context = SSLContext.getInstance("TLS"); // provide client cert - if server requires client cert this will pass context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER; // connect to url URL u = new URL("https://10.0.2.2:8888/"); HttpsURLConnection urlConnection = (HttpsURLConnection) u.openConnection(); urlConnection.setSSLSocketFactory(context.getSocketFactory()); urlConnection.setHostnameVerifier(hostnameVerifier); urlConnection.connect(); System.out.println("Response Code: " + urlConnection.getResponseCode()); </code></pre> <p>You should get a response code of 200, and can dissect the response from there.</p> <p>Here's the code to load the client credentials, which is identical to loading the server key store but with a different resource filename and password:</p> <pre><code>private KeyStore loadClientKeyStore(Context context) { InputStream in = context.getResources().openRawResource(R.yourKeyStoreFile); KeyStore trusted = null; trusted = KeyStore.getInstance("BKS"); trusted.load(in, "yourClientPassword".toCharArray()); in.close(); return trusted; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload