Taking the TLS package for a spin ... and failing

Hi Haskellers, I am trying to connect a Java client to a Haskell server using the Haskell tls package, and things are not working out for me. There is a lot of steps involved and I do not know what I am doing wrong, so this is a long message. But first I create a private/public key-pair:
openssl genrsa -out privkey.pem 2048
then I make a self-signed certificate:
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:192.168.1.6 Email Address []:
then I convert the certificate to DER format and stuff it into a Java keystore:
openssl x509 -in cacert.pem -out cert.der -outform DER keytool -keystore myKeystore.store -importcert -storepass foobar -keypass foobar -file cert.der
now I start the Haskell server:
ghc -hide-package monads-tf Server.hs -e main
and then the Java client:
javac Client.java java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=myKeystore.store -Djavax.net.ssl.trustStorePassword=foobar Client >JavaClientOutput.txt 2>&1
The server output is:
<interactive>: user error (unexpected type received. expecting handshake ++ Left (Error_Packet "invalid type"))
and not "Hello world" as expected. The client output is very long, but the most interesting part is properly:
main, received EOFException: error main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake main, SEND TLSv1 ALERT: fatal, description = handshake_failure
I have attached the Haskell server, the Java client and the full java output. Hope somebody can help figure out what I do wrong. I am using the Haskell tsl package version 0.3.1. And I run Debian Linux. I also tried connecting a Java client to a Java server. First create server keystore:
openssl pkcs8 -topk8 -nocrypt -in privkey.pem -inform PEM -out privkey.der -outform DER java -Dkeystore=myServerKeystore.store ImportKey privkey.der cert.der
ImportKey.java can be found here http://www.agentbob.info/agentbob/79-AB.html . then start Java server:
javac JavaServer.java java -Djavax.net.ssl.keyStore=myServerKeystore.store -Djavax.net.ssl.keyStorePassword=importkey JavaServer
and run the client again:
java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=myKeystore.store -Djavax.net.ssl.trustStorePassword=foobar Client
and the server outputs:
Hello world
as expected. Thus I think the certificates are fine, and the Java client is fine. But what am I doing wrong in the Haskell server? I have attached JavaServer.java. Regards, Mads Lindstrøm

Hi again, I found a simpler way to test the server connection, but it is still not working. Namely,
penssl s_client -connect 192.168.1.6:8000
CONNECTED(00000003) 18683:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake > failure:s23_lib.c:188:
Regards, Mads Lindstrøm On Sun, 2010-12-12 at 20:14 +0100, Mads Lindstrøm wrote:
Hi Haskellers,
I am trying to connect a Java client to a Haskell server using the Haskell tls package, and things are not working out for me. There is a lot of steps involved and I do not know what I am doing wrong, so this is a long message. But first I create a private/public key-pair:
openssl genrsa -out privkey.pem 2048
then I make a self-signed certificate:
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:192.168.1.6 Email Address []:
then I convert the certificate to DER format and stuff it into a Java keystore:
openssl x509 -in cacert.pem -out cert.der -outform DER keytool -keystore myKeystore.store -importcert -storepass foobar -keypass foobar -file cert.der
now I start the Haskell server:
ghc -hide-package monads-tf Server.hs -e main
and then the Java client:
javac Client.java java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=myKeystore.store -Djavax.net.ssl.trustStorePassword=foobar Client >JavaClientOutput.txt 2>&1
The server output is:
<interactive>: user error (unexpected type received. expecting handshake ++ Left (Error_Packet "invalid type"))
and not "Hello world" as expected.
The client output is very long, but the most interesting part is properly:
main, received EOFException: error main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake main, SEND TLSv1 ALERT: fatal, description = handshake_failure
I have attached the Haskell server, the Java client and the full java output. Hope somebody can help figure out what I do wrong.
I am using the Haskell tsl package version 0.3.1. And I run Debian Linux.
I also tried connecting a Java client to a Java server. First create server keystore:
openssl pkcs8 -topk8 -nocrypt -in privkey.pem -inform PEM -out privkey.der -outform DER java -Dkeystore=myServerKeystore.store ImportKey privkey.der cert.der
ImportKey.java can be found here http://www.agentbob.info/agentbob/79-AB.html .
then start Java server:
javac JavaServer.java java -Djavax.net.ssl.keyStore=myServerKeystore.store -Djavax.net.ssl.keyStorePassword=importkey JavaServer
and run the client again:
java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=myKeystore.store -Djavax.net.ssl.trustStorePassword=foobar Client
and the server outputs:
Hello world
as expected. Thus I think the certificates are fine, and the Java client is fine. But what am I doing wrong in the Haskell server?
I have attached JavaServer.java.
Regards,
Mads Lindstrøm

On Sun, Dec 12, 2010 at 08:13:59PM +0100, Mads Lindstrøm wrote:
Hi Haskellers,
I am trying to connect a Java client to a Haskell server using the Haskell tls package, and things are not working out for me. There is a lot of steps involved and I do not know what I am doing wrong, so this is a long message. But first I create a private/public key-pair:
On Mon, Dec 13, 2010 at 01:22:17AM +0100, Mads Lindstrøm wrote:
Hi again,
I found a simpler way to test the server connection, but it is still not working. Namely,
openssl s_client -connect 192.168.1.6:8000
Hi Mads, This one has to do with the fact that openssl try to send a SSLv2 hello message, which is not yet supported by TLS (and not in the supported Version list in the params if it was). unfortunately lots of clients still do that for compatibility; even though that doesn't buy much since nobody should connect to a pure SSLv2 server. For the openssl cmdline, you can add a simple -ssl3 flag or -tls1 flag to start negociating at the right version straight away.
[snip] main, WRITE: SSLv2 client hello message, length = 101 [snip]
This lines appears suspicious; I think that's exactly the same problem. I suppose there's a way to instanciate your java SSL connection to SSL3 or TLS1 It would be nice to add support to the SSLv2 hello message directly though, but I don't have any timeline for that to happens. -- Vincent

Hi Vincent, On Mon, 2010-12-13 at 08:51 +0000, Vincent Hanquez wrote:
that doesn't buy much since nobody should connect to a pure SSLv2 server.
For the openssl cmdline, you can add a simple -ssl3 flag or -tls1 flag to start negociating at the right version straight away.
Yes, that worked :)
[snip] main, WRITE: SSLv2 client hello message, length = 101 [snip]
This lines appears suspicious; I think that's exactly the same problem. I suppose there's a way to instanciate your java SSL connection to SSL3 or TLS1
I have tried a little, and it is not easy at least. But I will try some more. Thank you for answering, Mads

Hi Vincent, I got it to work :) But there seems to be some bugs in the Haskell server certificate handling. It seems that TLS do not transfer the ST (state, as in California) parameter in the X509 subject field. It also seems that the Haskell server do not send the email-address. The reason for my suspicion is that when I connect my Java client to the Haskell server, the client sees this certificate: *** Certificate chain chain [0] = [ [ Version: V3 Subject: OU=Head office, O=Mads Inc., C=DK, CN=192.168.1.6 Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 Key: Sun RSA public key, 2048 bits modulus: 2222747914719126678758768988 (the modulus is longer, but I cut it down). public exponent: 65537 Validity: [From: Tue Dec 14 11:07:05 CET 2010, To: Fri Dec 13 11:07:05 CET 2013] Issuer: OU=Head office, O=Mads Inc., C=DK, CN=192.168.1.6 SerialNumber: [ e11f077d a534af39] ] Whereas, if I connect the Java client to the Java server I get this certificate: chain [0] = [ [ Version: V3 Subject: EMAILADDRESS=mads.lindstroem@gmail.com, CN=192.168.1.6, OU=Head office, O=Mads Inc., L=Copenhagen, ST=Denmark, C=DK Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 Key: Sun RSA public key, 2048 bits modulus: 2222747914719126678758768988 (the modulus is longer, but I cut it down) public exponent: 65537 Validity: [From: Tue Dec 14 11:07:05 CET 2010, To: Fri Dec 13 11:07:05 CET 2013] Issuer: EMAILADDRESS=mads.lindstroem@gmail.com, CN=192.168.1.6, OU=Head office, O=Mads Inc., L=Copenhagen, ST=Denmark, C=DK SerialNumber: [ e11f077d a534af39] Certificate Extensions: 3 [1]: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: B3 F9 87 37 7D 80 53 2C F4 B1 B2 05 43 24 21 51 ...7..S,....C$!Q 0010: FD 37 4C C8 .7L. ] ] And without ST and/or email-address the Java client will not recognize the certificate. To avoid these problems I created a new certificate, using:
openssl req -new -x509 -key privkey.pem -subj "/OU=Head office, O=Mads Inc., C=DK, CN=192.168.1.6" -out cacert.pem -days 1095
That is, without email and without ST parameter. I then recreated the Java keystore. And now it works. Woohooo! I have attached the modified Java client, if anybody is interested in how to force SSL3 from Java. /Mads On Mon, 2010-12-13 at 08:51 +0000, Vincent Hanquez wrote:
On Sun, Dec 12, 2010 at 08:13:59PM +0100, Mads Lindstrøm wrote:
Hi Haskellers,
I am trying to connect a Java client to a Haskell server using the Haskell tls package, and things are not working out for me. There is a lot of steps involved and I do not know what I am doing wrong, so this is a long message. But first I create a private/public key-pair:
On Mon, Dec 13, 2010 at 01:22:17AM +0100, Mads Lindstrøm wrote:
Hi again,
I found a simpler way to test the server connection, but it is still not working. Namely,
openssl s_client -connect 192.168.1.6:8000
Hi Mads,
This one has to do with the fact that openssl try to send a SSLv2 hello message, which is not yet supported by TLS (and not in the supported Version list in the params if it was).
unfortunately lots of clients still do that for compatibility; even though that doesn't buy much since nobody should connect to a pure SSLv2 server.
For the openssl cmdline, you can add a simple -ssl3 flag or -tls1 flag to start negociating at the right version straight away.
[snip] main, WRITE: SSLv2 client hello message, length = 101 [snip]
This lines appears suspicious; I think that's exactly the same problem. I suppose there's a way to instanciate your java SSL connection to SSL3 or TLS1
It would be nice to add support to the SSLv2 hello message directly though, but I don't have any timeline for that to happens.

* Mads Lindstrøm:
I got it to work :) But there seems to be some bugs in the Haskell server certificate handling. It seems that TLS do not transfer the ST (state, as in California) parameter in the X509 subject field. It also seems that the Haskell server do not send the email-address.
And in reality, DER encoding isn't reversible, so you better serve the exact certificate blob which was passed to the server. Decoding and reencoding does not work reliably because sometimes, a non-DER version of the certificate has been signed.

On Tue, Dec 14, 2010 at 10:24:29PM +0100, Florian Weimer wrote:
* Mads Lindstrøm:
I got it to work :) But there seems to be some bugs in the Haskell server certificate handling. It seems that TLS do not transfer the ST (state, as in California) parameter in the X509 subject field. It also seems that the Haskell server do not send the email-address.
And in reality, DER encoding isn't reversible, so you better serve the exact certificate blob which was passed to the server. Decoding and reencoding does not work reliably because sometimes, a non-DER version of the certificate has been signed.
DER encoding IS fully reversible. However you're right about some certificate, that have been improperly signed when they were not valid DER. Hopefully this is a thing of the past, and I do intent to keep re-encoding the certificate instead of passing a binary blob (as i used to do at first, with some vestigial code still present). It gives a good workout to the certificate and asn1 DER modules as well, which isn't all that bad. -- Vincent

On Tue, Dec 14, 2010 at 11:41:29AM +0100, Mads Lindstrøm wrote:
Hi Vincent,
I got it to work :) But there seems to be some bugs in the Haskell server certificate handling. It seems that TLS do not transfer the ST (state, as in California) parameter in the X509 subject field. It also seems that the Haskell server do not send the email-address.
The reason for my suspicion is that when I connect my Java client to the Haskell server, the client sees this certificate:
Hi Mads, That's great you got it to work. The certificate fields missing is indeed a bug in the certificate package, which I just fixed in certificate-0.4 (mainly I forgot to write all the "others" fields in the Distinguish Name structure). I reuploaded a new tls 0.3.2 as well for convenience, and couple of others minor fixes. -- Vincent
participants (3)
-
Florian Weimer
-
Mads Lindstrøm
-
Vincent Hanquez