[Android Q&A, Help & Troubleshooting] HellPrye:
Hi,

I've been developing a rss reader which needs to make a mutal ssl authentication. Ive managed to get the user certificate using the Keychain API and have got what seems to a mostly working SSLSocketFactory. But whenever i try to make a connection to the server i get a 401 Unauthorized error, i feel its probably something to do with the way i am setting up my SSL Connection and my general code. If anyone can help point out what im doing wrong and what i need to do i would be very appreciative.

Main Activity:

public class AliasLoader extends AsyncTask<Void, Void, X509Certificate[]>

{

X509Certificate[] chain = null;

@Override protected X509Certificate[] doInBackground(Void... params) {

android.os.Debug.waitForDebugger();

if(!SavedAlias.isEmpty())

{

try {

PrivateKey key2 = KeyChain.getPrivateKey(getApplicationContext(), SavedAlias);

setPrivateKey(key2);

chain = KeyChain.getCertificateChain(getApplicationContext(),SavedAlias);

setCertificate(chain);

} catch (Exception e) {

Log.e(TAG, e.getMessage());

}

}

else

{

this.cancel(true);

}

return chain;

}

@Override

protected void onPostExecute(X509Certificate[] chain)

{

if(chain != null)

{

HttpClient client = CustomSSLSocketFactory.getNewHttpClient(context, getAlias(), chain, key);

String formDataServiceUrl = "https://android.diif.r.mil.uk";

WebView wv = (WebView) findViewById(R.id.rssFeedItemView);

HttpPost post = new HttpPost(formDataServiceUrl);

final HttpGet request = new HttpGet(formDataServiceUrl);

HttpResponse result = null;

try {

result = client.execute(post);

} catch (ClientProtocolException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

wv.loadUrl(formDataServiceUrl);

}

else

{

Toast.makeText(getApplicationContext(), "Certificate is Empty", Toast.LENGTH_LONG).show();

}

}

}

CustomSSLSocketFactory:

public class CustomSSLSocketFactory extends SSLSocketFactory {

public static KeyStore rootCAtrustStore = null;

public static KeyStore clientKeyStore = null;

SSLContext sslContext = SSLContext.getInstance("TLS");

Context context;

/**

* Constructor.

*/

public CustomSSLSocketFactory(Context context, KeyStore keystore, String keyStorePassword, KeyStore truststore)

throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {

super(keystore, keyStorePassword, truststore);

this.context = context;

// custom TrustManager,trusts all servers

X509TrustManager tm = new X509TrustManager() {

public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {

}

public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {

}

public X509Certificate[] getAcceptedIssuers() {

return null;

}

};

Log.i("CLIENT CERTIFICATES", "Loaded client certificates: " + keystore.size());

// initialize key manager factory with the client certificate

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

keyManagerFactory.init(keystore,null);

sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { tm }, null);

//sslContext.init(null, new TrustManager[]{tm}, null);

}

@Override

public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {

return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);

}

@Override

public Socket createSocket() throws IOException {

return sslContext.getSocketFactory().createSocket();

}

/**

* Create new HttpClient with CustomSSLSocketFactory.

*/

public static HttpClient getNewHttpClient(Context context, String alias, X509Certificate[] chain, PrivateKey key) {

try {

// This is method from tutorial ----------------------------------------------------

//The root CA Trust Store

rootCAtrustStore = KeyStore.getInstance("BKS");

rootCAtrustStore.load(null);

//InputStream in = context.getResources().openRawResource(com.DII.RSS_Viewer.R.raw.rootca);

//rootCAtrustStore.load(in, "PASSWORD".toCharArray());

//The Keystore with client certificates.

//clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());

clientKeyStore = KeyStore.getInstance("pkcs12");

clientKeyStore.load(null);

// client certificate is stored in android's keystore

if((alias != null) && (chain != null))

{

Key pKey = key;

clientKeyStore.setKeyEntry(alias, pKey, "password".toCharArray(), chain);

}

//SSLSocketFactory sf = new CustomSSLSocketFactory(context, clientKeyStore, "password", rootCAtrustStore);

SSLSocketFactory sf = new SSLSocketFactory(clientKeyStore, "password");

sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

HttpParams params = new BasicHttpParams();

HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

SchemeRegistry registry = new SchemeRegistry();

registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

registry.register(new Scheme("https", (SocketFactory) sf, 443));

ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

return new DefaultHttpClient(ccm, params);

}

catch (Exception e)

{

return new DefaultHttpClient();

}

}

}