Reputation: 141
I am building an client server model, client being an android application communicating with server on apache tomcat and both parties authenitcating using SSL certificates. And I created certificate for the client by the below commands
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
openssl pkcs12 -export -name myservercert -in server.crt -inkey server.key -out keystore.p12
keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias myservercert
Now I have a myservercert keystore having a private key and certificate. This needs to be used for client authentication. So I need to add this to the keystore of the SSLcontext at client side. So the below code .
public HttpClient myHttpsClient() {
HttpClient client = null;
char[] passphrase = "password".toCharArray();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertificateFactory clientcf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.server);
InputStream clientcert = context.getResources().openRawResource(R.raw.client);
Certificate ca;
Certificate clientca;
try {
clientca = clientcf.generateCertificate(clientcert);
ca = cf.generateCertificate(caInput);
System.out.println("ca="+ ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
clientcert.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStoreclient = KeyStore.getInstance(keyStoreType);
keyStoreclient.load(null, null);
keyStoreclient.setCertificateEntry("ca", clientca);
// Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
kmf.init(keyStoreclient,passphrase);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
MySSLSocketFactory socketFactory = new MySSLSocketFactory(context);//,new BrowserCompatHostnameVerifier());
client = createHttps(socketFactory);
} catch (Exception e) {
e.printStackTrace();
}
return client;
When I execute the code I am getting eh below runtime exception ..
07-08 22:37:52.834: W/System.err(4422): java.security.cert.CertificateException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:52.944: I/Choreographer(4422): Skipped 57 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.044: I/Choreographer(4422): Skipped 49 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.134: I/Choreographer(4422): Skipped 46 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.324: I/Choreographer(4422): Skipped 124 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.434: I/Choreographer(4422): Skipped 48 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.504: I/Choreographer(4422): Skipped 40 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.544: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory.engineGenerateCertificate(OpenSSLX509CertificateFactory.java:272)
07-08 22:37:53.544: W/System.err(4422): at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:195)
07-08 22:37:53.554: W/System.err(4422): at com.danielwirelesssoftware.utility.CreateHttpsClient.myHttpsClient(CreateHttpsClient.java:67)
07-08 22:37:53.584: I/Choreographer(4422): Skipped 35 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.624: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:121)
07-08 22:37:53.684: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:1)
07-08 22:37:53.694: W/System.err(4422): at android.os.AsyncTask$2.call(AsyncTask.java:288)
07-08 22:37:53.694: W/System.err(4422): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-08 22:37:53.714: W/System.err(4422): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-08 22:37:53.714: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-08 22:37:53.714: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-08 22:37:53.824: I/Choreographer(4422): Skipped 93 frames! The application may be doing too much work on its main thread.
07-08 22:37:54.764: W/System.err(4422): at java.lang.Thread.run(Thread.java:841)
07-08 22:37:54.764: W/System.err(4422): Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:54.774: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:113)
07-08 22:37:54.774: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory.engineGenerateCertificate(OpenSSLX509CertificateFactory.java:270)
07-08 22:37:54.774: W/System.err(4422): ... 10 more
07-08 22:37:54.774: W/System.err(4422): Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:55.274: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:71)
07-08 22:37:55.274: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:224)
07-08 22:37:55.274: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:214)
07-08 22:37:55.284: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:104)
07-08 22:37:55.284: W/System.err(4422): ... 11 more
07-08 22:37:55.284: W/System.err(4422): Caused by: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:55.874: W/System.err(4422): at com.android.org.conscrypt.NativeCrypto.d2i_X509_bio(Native Method)
07-08 22:37:55.874: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:65)
07-08 22:37:55.874: W/System.err(4422): ... 14 more
07-08 22:37:56.394: W/System.err(4422): java.lang.NullPointerException
07-08 22:37:56.524: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:133)
07-08 22:37:57.094: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:1)
07-08 22:37:57.094: W/System.err(4422): at android.os.AsyncTask$2.call(AsyncTask.java:288)
07-08 22:37:57.094: W/System.err(4422): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-08 22:37:57.434: I/Choreographer(4422): Skipped 88 frames! The application may be doing too much work on its main thread.
07-08 22:37:57.454: W/System.err(4422): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-08 22:37:57.454: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-08 22:37:57.454: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-08 22:37:57.454: W/System.err(4422): at java.lang.Thread.run(Thread.java:841)
07-08 22:37:58.184: I/Choreographer(4422): Skipped 470 frames! The application may be doing too much work on its main thread.
07-08 22:37:58.294: I/Choreographer(4422): Skipped 62 frames! The application may be doing too much work on its main thread.
From the above exception , it looks like some error is the line
clientca = clientcf.generateCertificate(clientcert);
can someone confirm anything wrong in the above line. Format of certificate or anything else ? Thanks in advance
Upvotes: 0
Views: 3826
Reputation: 141
I figured it by myself . The below code works for me .
public HttpClient myHttpsClient() {
HttpClient client = null;
char[] passphrase = "password".toCharArray();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertificateFactory clientcf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.server);
InputStream clientcert = context.getResources().openRawResource(R.raw.clientks);
Certificate ca;
KeyStore keyStoreclient = KeyStore.getInstance("BKS");
try {
keyStoreclient.load(clientcert, "password".toCharArray());
ca = cf.generateCertificate(caInput);
System.out.println("server ca="+ ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
clientcert.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
kmf.init(keyStoreclient,passphrase);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
MySSLSocketFactory socketFactory = new MySSLSocketFactory(context);//,new BrowserCompatHostnameVerifier());
client = createHttps(socketFactory);
} catch (Exception e) {
e.printStackTrace();
}
return client;
}
Upvotes: 1