Problem sending data with HTTPS using client authentication.
Hi,
I磎 tryingto send a message to a secure server using for this client certificate, apparently if I make a GET of "/" (server root) , everything works fine (authentication, and data received), from the moment that I try to ways send data to the "/pvtn " directory i obtain the following error.
This is a sample of the code i磎 using:
import com.sun.net.ssl.KeyManagerFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.security.*;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.security.PublicKey;
import java.util.Collection;
import java.util.Date;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.security.cert.*;
import javax.security.cert.X509Certificate;
public class Test
{
public static final String TARGET_HTTPS_SERVER = "mymachine.mydomain.pt";
public static final intTARGET_HTTPS_PORT= 443;
public static void main(String[] args) throws Exception
{
System.setProperty("javax.net.ssl.trustStore","/certificados/truststore.txt");
System.setProperty("javax.net.ssl.trustStorePassword","trustpwd");
System.setProperty("javax.net.ssl.keyStore","/certificados/truststore.txt");
System.setProperty("javax.net.ssl.keyStorePassword","trustpwd");
java.security.Security.removeProvider("SunJSSE");
java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(),2);
KeyManagerFactory kmf= KeyManagerFactory.getInstance("SunX509", "SunJSSE") ;
//Socket
SSLSocket jsslSoc = (SSLSocket) SSLSocketFactory.getDefault().createSocket(TARGET_HTTPS_SERVER, TARGET_HTTPS_PORT);
////////////////////////////////////////////////////////////////////////////////////
String [] ciphers = jsslSoc.getSupportedCipherSuites() ;
//// Select the ciphers you want and put them.
//// Here we will put all availabel ciphers
jsslSoc.setEnabledCipherSuites(ciphers);
//// We are creating socket in client mode
jsslSoc.setUseClientMode(true);
//// Do SSL handshake
jsslSoc.startHandshake();
// Print negotiated cipher
System.out.println("Negotiated Cipher Suite: " + jsslSoc.getSession().getCipherSuite());
System.out.println("");
X509Certificate[] peerCerts = ((javax.net.ssl.SSLSocket)jsslSoc).getSession().getPeerCertificateChain();
if (peerCerts != null)
{
System.out.println("Printing server information:");
for(int i =0; i < peerCerts.length; i++)
{
System.out.println("Peer Certificate ["+i+"] Information:");
System.out.println("- Subject: " + peerCerts.getSubjectDN().getName());
System.out.println("- Issuer: " + peerCerts.getIssuerDN().getName());
System.out.println("- Version: " + peerCerts.getVersion());
System.out.println("- Start Time: " + peerCerts.getNotBefore().toString());
System.out.println("- End Time: " + peerCerts.getNotAfter().toString());
System.out.println("- Signature Algorithm: " + peerCerts.getSigAlgName());
System.out.println("- Serial Number: " + peerCerts.getSerialNumber());
}
}
else
{
System.out.println("Failed to get peer certificates");
}
///////////////////////////////////////////////////////////////////////////////////
try
{
Writer out = new OutputStreamWriter(jsslSoc.getOutputStream(), "ISO-8859-1");
//THIS WAY WORKS FINE
out.write("GET / HTTP/1.1\r\n");
// HERE COMES THE TROUBLES
//out.write("GET /pvtn?someparameter=paramvalue HTTP/1.1\r\n");
out.write("Host: " + TARGET_HTTPS_SERVER + ":" + TARGET_HTTPS_PORT + "\r\n");
out.write("Proxy-Connection: Keep-Alive\r\n");
out.write("User-Agent: SSL-TEST \r\n");
out.write("\r\n");
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(jsslSoc.getInputStream(), "ISO-8859-1"));
String line = null;
while ((line = in.readLine()) != null)
{
System.out.println(line);
}
}
finally
{
jsslSoc.close();
}
}
}
the ssl log until sending the GET is
.
.
.
.
main, WRITE: SSL v3.1 Handshake, length = 36
main, READ: SSL v3.1 Change Cipher Spec, length = 1
main, READ: SSL v3.1 Handshake, length = 36
Plaintext after DECRYPTION: len = 36
0000: 14 00 00 0C 71 AB 40 CC6C 33 92 05 E9 69 4B 8F ....q.@.l3...iK.
0010: D1 77 3F 6E 3C DB F0 A0B7 9C CF 49 B6 6D C8 17 .w?n<......I.m..
0020: 7E 03 52 14..R.
*** Finished, v3.1
verify_data: { 113, 171, 64, 204, 108, 51, 146, 5, 233, 105, 75, 143 }
***
%% Cached client session: [Session-1, SSL_RSA_WITH_RC4_128_SHA]
[read] MD5 and SHA1 hashes: len = 16
0000: 14 00 00 0C 71 AB 40 CC6C 33 92 05 E9 69 4B 8F ....q.@.l3...iK.
Negotiated Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
When i send the GET
.
.
.
Plaintext before ENCRYPTION: len = 247
0000: 47 45 54 20 2F 70 76 746E 3F 41 30 33 30 3D 4D GET /pvtn?A030=M
.
.
.
.
.
main, WRITE: SSL v3.1 Application Data, length = 247
main, READ: SSL v3.1 Handshake, length = 24
Plaintext after DECRYPTION: len = 24
.
.
*** HelloRequest (empty)
%% Client cached [Session-1, SSL_RSA_WITH_RC4_128_SHA]
%% Try resuming [Session-1, SSL_RSA_WITH_RC4_128_SHA] from port 3535
*** ClientHello, v3.1
RandomCookie: GMT: 1131988975 bytes = { 45, 113, 241, 212, 81, 255, 244, 169, 74, 41, 160, 227, 197, 210, 155, 211, 47, 237, 18, 179, 238, 47, 28, 86, 30, 253, 157, 253 }
Session ID: {208, 18, 243, 174, 216, 156, 80, 201, 121, 136, 63, 162, 31, 196, 186, 95, 193, 143, 238, 172, 173, 79, 64, 219, 17, 149, 14, 138, 53, 95, 18, 96}
Cipher Suites: { 0, 5, 0, 4, 0, 9, 0, 10, 0, 18, 0, 19, 0, 3, 0, 17, 0, 2, 0, 1, 0, 24, 0, 26, 0, 27, 0, 23, 0, 25 }
Compression Methods: { 0 }
***
[write] MD5 and SHA1 hashes: len = 105
.
.
Plaintext before ENCRYPTION: len = 125
.
.
main, WRITE: SSL v3.1 Handshake, length = 125
main, READ: SSL v3.1 Handshake, length = 94
Plaintext after DECRYPTION: len = 94
.
.
.
*** ServerHello, v3.1
RandomCookie: GMT: 1131991620 bytes = { 205, 194, 212, 113, 37, 213, 41, 13, 60, 142, 135, 68, 17, 78, 227, 251, 176, 211, 133, 203, 153, 173, 153, 195, 93, 7, 87, 123 }
Session ID: {108, 85, 45, 208, 104, 124, 209, 24, 247, 113, 156, 134, 28, 154, 75, 198, 64, 181, 167, 9, 149, 223, 162, 21, 225, 32, 168, 31, 190, 48, 241, 195}
Cipher Suite: { 0, 5 }
Compression Method: 0
***
%% Created: [Session-2, SSL_RSA_WITH_RC4_128_SHA]
** SSL_RSA_WITH_RC4_128_SHA
[read] MD5 and SHA1 hashes: len = 74
.
.
main, READ: SSL v3.1 Handshake, length = 3154
Plaintext after DECRYPTION: len = 3154
.
.
*** Certificate chain
.
.
.
***
stop on trusted cert: [
[
Version: V1
Subject: CN=GTE CyberTrust Global Root, OU="GTE CyberTrust Solutions, Inc.", O=GTE Corporation, C=US
.
.
]
Algorithm: [MD5withRSA]
Signature:
.
.
]
[read] MD5 and SHA1 hashes: len = 3134
.
.
main, READ: SSL v3.1 Handshake, length = 479
Plaintext after DECRYPTION: len = 479
.
.
*** CertificateRequest
Cert Types: RSA, DSS,
Cert Authorities:
.
.
.
[read] MD5 and SHA1 hashes: len = 455
.
.
.
*** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00....
*** Certificate chain
***
*** ClientKeyExchange, RSA PreMasterSecret, v3.1
Random Secret: { 3, 1, 19, 223, 230, 65, 59, 210, 10, 69, 239, 178, 185, 5, 52, 57, 44, 160, 163, 239, 85, 64, 173, 16, 132, 234, 33, 228, 0, 8, 134, 52, 20, 190, 196, 15, 205, 35, 169, 39, 14, 160, 143, 74, 210, 74, 43, 181 }
[write] MD5 and SHA1 hashes: len = 141
.
.
.
Plaintext before ENCRYPTION: len = 161
.
.
.
main, WRITE: SSL v3.1 Handshake, length = 161
SESSION KEYGEN:
PreMaster Secret:
.
.
.CONNECTION KEYGEN:
Client Nonce:
.
.
.
Server Nonce:
.
.
.
Master Secret:
.
.
Client MAC write Secret:
.
.
Server MAC write Secret:
.
.
Client write key:
.
.
Server write key:
0000: FE 94 DF 4C 1A 9F FA CE0C E9 A6 DB 31 53 E5 FD ...L........1S..
... no IV for cipher
Plaintext before ENCRYPTION: len = 21
0000: 01 0D 16 E6 49 18 36 AFE1 52 9C 2F 72 EE CA DF ....I.6..R./r...
0010: 41 71 68 30 06 Aqh0.
main, WRITE: SSL v3.1 Change Cipher Spec, length = 21
*** Finished, v3.1
verify_data: { 243, 49, 247, 150, 113, 86, 182, 125, 244, 163, 245, 243 }
***
[write] MD5 and SHA1 hashes: len = 16
0000: 14 00 00 0C F3 31 F7 9671 56 B6 7D F4 A3 F5 F3 .....1..qV......
Plaintext before ENCRYPTION: len = 36
0000: 14 00 00 0C F3 31 F7 9671 56 B6 7D F4 A3 F5 F3 .....1..qV......
0010: 1A 7C 8F D9 51 CB 6F 472A 7C 90 81 20 EE 97 64 ....Q.oG*... ..d
0020: FF 47 35 CA.G5.
main, WRITE: SSL v3.1 Handshake, length = 36
main, SEND SSL v3.1 ALERT: warning, description = close_notify
Plaintext before ENCRYPTION: len = 22
0000: 01 00 F0 F4 AC 3C B2 DE95 98 0E B4 ED B1 24 3B .....<........$;
0010: 54 6C 8B DC F3 1F Tl....
main, WRITE: SSL v3.1 Alert, length = 22
java.net.SocketException: Connection aborted by peer: socket write error
void java.net.SocketOutputStream.socketWrite(java.io.FileDescriptor, byte[], int, int)
native code
void java.net.SocketOutputStream.write(byte[], int, int)
SocketOutputStream.java:96
void com.sun.net.ssl.internal.ssl.OutputRecord.a(java.io.OutputStream)
void com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(com.sun.net.ssl.internal.ssl.OutputRecord)
void com.sun.net.ssl.internal.ssl.HandshakeOutStream.flush()
void com.sun.net.ssl.internal.ssl.Handshaker.sendChangeCipherSpec(com.sun.net.ssl.internal.ssl.HandshakeMessage$Finished)
void com.sun.net.ssl.internal.ssl.ClientHandshaker.c()
void com.sun.net.ssl.internal.ssl.ClientHandshaker.a(com.sun.net.ssl.internal.ssl.SunJSSE_o)
void com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(byte, int)
void com.sun.net.ssl.internal.ssl.Handshaker.process_record(com.sun.net.ssl.internal.ssl.InputRecord)
void com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(com.sun.net.ssl.internal.ssl.InputRecord, boolean)
void com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(com.sun.net.ssl.internal.ssl.InputRecord)
int com.sun.net.ssl.internal.ssl.AppInputStream.read(byte[], int, int)
int java.io.InputStream.read(byte[])
InputStream.java:91
int java.io.InputStreamReader.fill(char[], int, int)
InputStreamReader.java:173
int java.io.InputStreamReader.read(char[], int, int)
InputStreamReader.java:249
void java.io.BufferedReader.fill()
BufferedReader.java:139
java.lang.String java.io.BufferedReader.readLine(boolean)
BufferedReader.java:299
java.lang.String java.io.BufferedReader.readLine()
BufferedReader.java:362
void Teste3.main(java.lang.String[])
Teste3.java:109
Exception in thread main
Debugger disconnected from local process.
Process exited with exit code 1.
One more thing if if make the same thing via browser (https://mymachine.mydomain.pt/pvtn?someparameter=somevalue) and works fine too (obviously i pre installed the client certificate in the browser and choose the certificate when the pop up show up)
It seems like the handshaking fails when i send data to /pvtn...
Regards,
Paulo.

