SSL client authenticatio

by mastergap » Fri, 03 Sep 2010 20:10:11 GMT


Sponsored Links
 i, i'm developing a simple app that is an android client that
communicates with a server on a ssl socket. Everything works fine,
but when i add to the ServerSocket running on my server pc the option
setNeedClientAuth the client can't authenticate...in particular i get
this exception on the server...
[CODE]
javax.net.ssl.SSLHandshakeException: null cert chain
[/CODE]

The same code executed in a normal app in Java on a pc works fine!

Here i post the code of the server:

[CODE]
* SslReverseEchoerRevised.java
* Copyright (c) 2005 by Dr. Herong Yang
*/
import java.io.*;
import java.net.*;
import java.security.*;
import javax.net.ssl.*;
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class SslReverseEchoer {
public static void main(String[] args) {
//if (args.length<3) {
// System.out.println("Usage:");
//System.out.println(
// " java SslReverseEchoerRevised ksName ksPass ctPass");
//return;
//}
//String ksName = args[0];
//char[] ksPass = args[1].toCharArray();
//char[] ctPass = args[2].toCharArray();
//System.setProperty("javax.net.ssl.trustStore", "servertrust");
//System.setProperty("javax.net.ssl.trustStorePassword",
"password");

try {
System.out.println("-----
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(new FileInputStream("serverkeys2.bks"),
"password".toCharArray());
KeyManagerFactory kmf =
KeyManagerFactory.getInstance("sunX509");
kmf.init(ks, "password".toCharArray());
//KeyStore ts = KeyStore.getInstance("BKS");
//ts.load(new FileInputStream("servertrust.bks"),
"password".toCharArray());
TrustManagerFactory tmf =
TrustManagerFactory.getInstance("X509");
tmf.init(ks);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s
= (SSLServerSocket) ssf.createServerSocket(8888);
s.setNeedClientAuth(true);
printServerSocketInfo(s);
SSLSocket c = (SSLSocket) s.accept();
//c.setNeedClientAuth(true);
printSocketInfo(c);
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(
c.getOutputStream()));
BufferedReader r = new BufferedReader(new InputStreamReader(
c.getInputStream()));
String m = "Welcome to SSL Reverse Echo Server."+
" Please type in some words.";
w.write(m,0,m.length());
w.newLine();
w.flush();
while ((m=r.readLine())!= null) {
if (m.equals(".")) break;
char[] a = m.toCharArray();
int n = a.length;
for (int i=0; i<n/2; i++) {
char t = a[i];
a[i] = a[n-1-i];
a[n-i-1] = t;
}
w.write(a,0,n);
w.newLine();
w.flush();
}
w.close();
r.close();
c.close();
s.close();
} catch (Exception e) {
System.err.println(e.toString());
}



SSL client authenticatio

by mastergap » Sat, 04 Sep 2010 12:02:41 GMT


 No, i didn't. I'm new on SSL programming. I say to you what i've done
exactly. I made two keystores clientkeys.bks and serverkeys with
keytool respectively with a certificate for the client and on e for
the server. After i extract certificates from keystores just created
and i have imported them respectively in two new keystores
(servertrust and clienttrust.bks) that i use as truststores. If i do
this procedure, using keystores and trustores on a java server app and
a java client app on two different computers everything is OK, but if
the client is an Andorid system (an emulator on another pc or a phone)
i get the SSLHandshakeException.






--


Sponsored Links


SSL client authenticatio

by Brian Carlstrom » Sat, 04 Sep 2010 18:14:08 GMT


 






the problem doesn't seem to be that the device does not trust the server
root (although the client code is making its own trust manager which is
presumably to trust the server cert chain, which presumably would be to
address this)

the problem is curious since it is the server complaining about the client
and the code apparently worked okay with a host client, so that is why I was
focusing on the contents of the client key store as seen in the program and
what is sent on the wire.

I think there might be some know issues on older releases abut only sending
the cert with its chain. if its signed by an intermediate it, you'd have to
workaround on the server by trusting the intermediate.

-bri

--



SSL client authenticatio

by Brian Carlstrom » Sat, 04 Sep 2010 18:14:08 GMT


 >

Is the PC version using BKS or JKS keystore? Perhaps there is a problem with
the BKS file? It might be worth just iterating through the entries and
printing them out, including the certificate chain of the private key entry.


It's two days that i break my head on this thing...i hope that someone


I would use wireshark to look and see what is in the Certificate message
from the client to the server.

-bri

--



SSL client authenticatio

by mastergap » Sun, 05 Sep 2010 14:10:16 GMT


 Thank you. The pc version uses jks keystore, so to check if the
problem is rekative to bks keystores i will try to use bks also in the
pc version. Anyway, i didn't understand if there is a way to solve my
problem, or if you have tried to reproduce my code and you if you've
found a solution. Thanks a lot. Tomorrow i will post the logcat output
if you want, because the problem is on the client side during the
handshake, in fact if i take off the needClientAuth option the client
receives the server's certificate and i can see server identity
information on the client's output.






--



SSL client authenticatio

by Brian Carlstrom » Mon, 06 Sep 2010 04:39:16 GMT


 




I believe there is a way to solve your problem. I know
people successfully use client certificates on Android such as in the
Nitrodesk Touchdown app for exchange server authentication in Eclair and
possibly earlier. There were some bugs in early versions of Froyo. I don't
think you mentioned what version you are using.

but no, I haven't tried to reproduce anything with your code, just giving
suggestions on how to debug.

-bri

--



SSL client authenticatio

by mastergap » Mon, 06 Sep 2010 06:48:35 GMT


 > There were some bugs in early versions of Froyo. I don't

You're right,i'm using 2.1-update1 version. Another simple question,
us it right to create client certificates with keytool with the
command:
"Keytool -genkey -keystore clientkeys -alias  client -storetype BKS -
provider org.bouncy... -providerpath ..."?

--



SSL client authenticatio

by Brian Carlstrom » Mon, 06 Sep 2010 07:00:18 GMT


 Here are some notes I had for a self signed client cert on Ubuntu for
debugging:

# For device client certificate (doesn't seem to work on 64-bit):


/usr/lib/jvm/java-6-openjdk/bin/keytool -genkey -keyalg RSA -provider
org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath
/usr/share/java/bcprov.jar -storetype BKS -keystore client.bks -storepass
password -keypass password -dname 'CN=Unknown, OU=Unknown, O=Unknown,
L=Unknown, ST=Unknown, C=Unknown' && /usr/lib/jvm/java-6-openjdk/bin/keytool
-selfcert -provider org.bouncycastle.jce.provider.BouncyCastleProvider
-providerpath /usr/share/java/bcprov.jar -storetype BKS -keystore client.bks
-storepass password -keypass password


I'm guessing you are on Windows from the "Keytool" capitalization, but the
arguments should be the same even if the path names are not.



for more serious testing I have some Java code that generates a longer test
keychain with root ca, intermediate ca, and client cert that is not
generated with the command line but instead with X509V3CertificateGenerator,
which is why I don't have an example command line for that handy. There is
some discussion of using X509V3CertificateGenerator here:
 http://www.bouncycastle.org/wiki/display/JA1/X.509 +Public+Key+Certificate+and+Certification+Request+Generation

-bri




>



SSL client authenticatio

by mastergap » Mon, 06 Sep 2010 09:44:02 GMT


 Ok, thanks a lot! I solved my problem, I made some mistakes creating
certificates. I followed a guide on an IBM tutorial and i was deceived
by the fact that that code worked fine on a standard java client app.
I didn't run the keytool -selfcert command on the client keystore
previously made. Executing this command i generate a correct
selfsigned certificate and all works fine. When i will finish to write
my test code i will post a small step-by-step guide to work with ssl
sockets with client-server applications in android, considering that
there's nothing clear on the web about this, and many of my problems
were caused by picking fragmentary informations from different places
and joining them together. Thanks a lot again, your help was crucial
for me, thanks and thanks again.

--



SSL client authenticatio

by mastergap » Mon, 06 Sep 2010 15:13:49 GMT


 I made a lot of tests and i understand what is the problem: the key
encryption algorithm. It must be RSA, i made all certificates with
keytool without specifying the algorithm with the -keyalg option, and
by the default keytool uses SHA1withDSA, and on android this causes
the fact that the client can't authenticate itself, i don't know why.
Maybe it's the BKS keystore format, i don't know.
So the step-by-step guide to work with SSL socket in android is very
simple:
-the keytool -selfcert command is useless, this fact is reported also
in the keytool usage guide
-keystore and truststore properties must be declared programmatically
(information on how to do this can be found on an IBM tutorial on
custom sockets)
-the keystore on android must be in BKS format. To make it you have to
download the bouncycastle jar on the bouncycastle site and use it as a
provider in keytool:
    keytool -provider org.bouncycastle.jce.BouncyCastleProvider -
providerpath bcprov-jdk16-145.jar ..." and after the usual options of
keytool (note that, this way, you         have to launch keytool in
the same directory of bcprov-jdk16-145.jar).
-this way you can create BKS keystores using keytool (there are a lot
of guides on the web) remembering that you have to use the option -
keyalg RSA when generating certificate's keys: keytool -genkey -keyalg
RSA.

--



SSL client authenticatio

by Brian Carlstrom » Tue, 07 Sep 2010 16:41:13 GMT


 



I'm not aware of any old issues with DSA certs inherently not working, but
most people use RSA.



I know in my later work that DSA's work fine with BKS.



can you give some doc to support this? I thought it was how to turn a
unsigned cert + key into a self signed cert.

-keystore and truststore properties must be declared programmatically

you can provide these via the SSLContext.init like your code showed.




I know third party tools using PKCS12 keystore format or most any KeyStore
implementation supported by Android, not just BKS. JKS is not supported.




I've make and used pkcs12 keystores with the "openssl pkcs12" command.
others using PKCS12 have used PFX files generated by Microsoft tools

-bri

--



SSL client authenticatio

by Chris Palmer » Tue, 07 Sep 2010 17:20:51 GMT


 



This sounds like a great idea! Thanks. Please post a link to your docs
when you finish. :)

--



SSL client authenticatio

by Brian Carlstrom » Tue, 07 Sep 2010 17:37:04 GMT


 I have a simple example of SSL client certificates in the Issue9623.zip
attachment to this issue:
 http://code.google.com/p/android/issues/detail?id=9623 It was a simple 
Exchange Active Sync test, but it shows the basics of
KeyStore/KeyManager/TrustManager/SSLContext

-bri






>



SSL client authenticatio

by mastergap » Tue, 07 Sep 2010 20:24:45 GMT


 > > -the keytool -selfcert command is useless, this fact is reported also


I read this thing on the usage guide of keytool. man keytool in ubuntu
10.04


Yes, sorry i made a mistake. And i made some other tests on the keyalg
option generting certificate with keytool and if i don't specify this
option with RSA parameter the server authentication works but the
client authetication fails, but i didn't try specifying the -keyalg
option with parameters different from RSA, i tried just not specifying
the -keyalg option and i saw that DSA is used by default.

--



SSL client authenticatio

by Brian Carlstrom » Tue, 07 Sep 2010 21:06:52 GMT


 




I see, thanks. I ran my stuff on 10.04 and didn't notice that the docs were
installed as a man page and that it says that genkeypair "[w]raps the public
key into an X.509 v3 self-signed certificate"

-bri

--



Other Threads

1. New site offering free android apps

check out http://www.androidapps.org/ for free app downloads.  pretty
nice selection of apps..

--~--~---------~--~----~------------~-------~--~----~

2. problem downloading source

Is anyone else seeing this problem:

$ repo sync
fatal: read error (Connection reset by peer)
error: Cannot fetch platform/external/webkit
$

-- 
Al Hopper

--~--~---------~--~----~------------~-------~--~----~

3. Is BrowserCallback missing in my SDK or does it not exist?

4. mime handler with inline content disposition

5. how to read the trace file

6. Somehow get RandomAccessFile from getAsset

7. MediaPlayer video playback problem