Showing posts with label ssl. Show all posts
Showing posts with label ssl. Show all posts

Monday, July 22, 2019

No suitable client certificate could be found - continuing without client authentication

"No suitable client certificate could be found - continuing without client authentication"

1) are you specifying the password for the keystore?

2) are you providing a full certificate chain ? ( chain [0] , chain [1], chain [2] until the Root CA)

3) server specified issuers different from the one of the client certificate?

4) server specified ciphers not matching the one of the certificate?

5) (this is same as 2) whole certificate chain not in keystore (see https://stackoverflow.com/questions/9299133/why-doesnt-java-send-the-client-certificate-during-ssl-handshake )



Here the code https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/security/ssl/ClientHandshaker.java , as you see it's totally pathetic and at the same message correspond completely different scenarios.

Thursday, July 11, 2019

Java JSSE SSL flags

-Djavax.net.debug=help

all turn on all debugging
ssl turn on ssl debugging

The following can be used with ssl:

record enable per-record tracing
handshake print each handshake message
keygen print key generation data
session print session activity
defaultctx print default SSL initialization
sslctx print SSLContext tracing
sessioncache print session cache tracing
keymanager print key manager tracing
trustmanager print trust manager tracing
pluggability print pluggability tracing
handshake debugging can be widened with:
data hex dump of each handshake message
verbose verbose handshake message printing


record debugging can be widened with:

plaintext hex dump of record plaintext
packet print raw SSL/TLS packets


Other non-so-famous properties:


https://www.oracle.com/technetwork/java/javase/overview/tlsreadme2-176330.html

-Dsun.security.ssl.allowUnsafeRenegotiation=true

-Dsun.security.ssl.allowLegacyHelloMessages=true

https://www.oracle.com/technetwork/java/javase/8u161-relnotes-4021379.html

-Djdk.tls.allowLegacyResumption=true

-Djdk.tls.allowLegacyMasterSecret=true

-Djdk.tls.traceHandshakeException=true

-Djdk.tls.useExtendedMasterSecret=true

-Djdk.tls.legacyAlgorithms=???

-Djdk.tls.ephemeralDHKeySize=???

https://docs.oracle.com/javase/10/security/java-secure-socket-extension-jsse-reference-guide.htm


jdk.tls.client.cipherSuites

jdk.tls.server.cipherSuites






Tuesday, June 11, 2019

Java SSL server and client

https://www.baeldung.com/java-ssl-handshake-failures

this article is inspiring but it contains several errors/omissions.

The actually working code with detailed keytool commands is here https://github.com/vernetto/ssltests



Ultimate resource to learn SSL handshake is https://tls.ulfheim.net/

Thursday, June 6, 2019

SSL renegotiation and resumption

"Resumption and renegotiation are rather opposites. Resumption restarts a previous TLS session in a new TCP connection, using the same TLS parameters. Renegotiation continues an existing TLS session in the same TCP connection, but changes some of the parameters.
"


in Fiddler, check for the renegotiation_info field in the CONNECT requestsmethods


https://www.ssllabs.com/ssltest/


Secure Renegotiation Supported
Secure Client-Initiated Renegotiation Yes
Insecure Client-Initiated Renegotiation No

Session resumption (caching) Yes
Session resumption (tickets) No


check DisableRenegoOnClient link


https://www.salt.ky/disabling-tlsssl-renegotiation-in-configuration-manager-2012/ and https://support.microsoft.com/en-us/help/977377/microsoft-security-advisory-vulnerability-in-tls-ssl-could-allow-spoof

"Modify the key to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\DisableRenegoOnClient | DWORD=0"



https://backstage.forgerock.com/knowledge/kb/article/a28022128 -Djdk.tls.rejectClientInitiatedRenegotiation=true


-Dsun.security.ssl.allowUnsafeRenegotiation=true ( see https://www.oracle.com/technetwork/java/javase/tlsreadme2-176330.html on why this is a bad idea)

Doc on Session Resumption https://spacehost.de/tls-session-resumption-caching-tickets/

jdk.tls.useExtendedMasterSecret=false
jdk.tls.allowLegacyResumption=true
jdk.tls.allowLegacyMasterSecret=true


Here more explanation on Resumption and Renegotiation



To understand JSSE in general read this guide https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html



Monday, May 6, 2019

JDK maven Nexus and HTTPS

If your Nexus repository uses certificates signed by your own Root CA, chances are that a JDK doesn't trust them.

Then when you run

mvn package

you get


sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target


Go to your JAVA_HOME\jre\lib\security folder, where the cacerts file is located, and issue

keytool -list -v -keystore cacerts

enter "changeit" as password

this shold tell you all your trusted CAs

You should import your own CA certificate to into this keystore.


I have tried also setting:


set MAVEN_OPTS="-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true"

but it disn't work for me.




Friday, April 27, 2018

Nexus 3.10 Docker hosted repository on HTTPS

https://support.sonatype.com/hc/en-us/articles/213465098-How-to-Configure-HTTPS-Protocols-Used-By-Nexus

https://support.sonatype.com/hc/en-us/articles/213465768-SSL-Certificate-Guide

https://hub.docker.com/r/bradbeck/nexus-https/


https://hub.docker.com/r/bradbeck/nexus-https/~/dockerfile/

FROM sonatype/nexus3 
MAINTAINER Brad Beck <bradley.beck+docker@gmail.com> 
ENV NEXUS_SSL=${NEXUS_HOME}/etc/ssl 
ENV PUBLIC_CERT=${NEXUS_SSL}/cacert.pem \ 
    PUBLIC_CERT_SUBJ=/CN=localhost \ 
    PRIVATE_KEY=${NEXUS_SSL}/cakey.pem \ 
    PRIVATE_KEY_PASSWORD=password ARG GOSU_VERSION=1.10 

USER root 
RUN yum -y update && yum install -y openssl libxml2 libxslt && yum clean all
RUN gpg --keyserver pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
 && curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-amd64" \
 && curl -o /usr/local/bin/gosu.asc -SL "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-amd64.asc" \
 && gpg --verify /usr/local/bin/gosu.asc \
 && rm /usr/local/bin/gosu.asc \
 && rm -r /root/.gnupg/ \
 && chmod +x /usr/local/bin/gosu

RUN sed \
    -e '/^nexus-args/ s:$:,${jetty.etc}/jetty-https.xml:' \
    -e '/^application-port/a \
application-port-ssl=8443\
' \
    -i ${NEXUS_HOME}/etc/nexus-default.properties
COPY entrypoint.sh ${NEXUS_HOME}/entrypoint.sh
RUN chown nexus:nexus ${NEXUS_HOME}/entrypoint.sh && chmod a+x ${NEXUS_HOME}/entrypoint.sh
VOLUME [ "${NEXUS_SSL}" ]
EXPOSE 8443 WORKDIR ${NEXUS_HOME}
ENTRYPOINT [ "./entrypoint.sh" ]
CMD [ "bin/nexus", "run"]




[root@9118f1784d46 ssl]# more /opt/sonatype/nexus/entrypoint.sh
#!/usr/bin/env bash

set -x
set -eo pipefail

if [ "$1" == 'bin/nexus' ]; then
  if [ ! -f "$NEXUS_SSL/keystore.jks" ]; then
    mkdir -p $NEXUS_SSL
    if [ ! -f $PUBLIC_CERT ] && [ ! -f $PRIVATE_KEY ]; then
      openssl req -nodes -new -x509 -keyout $PRIVATE_KEY -out $PUBLIC_CERT -subj
 "${PUBLIC_CERT_SUBJ}"
    fi
    if [ ! -f $NEXUS_SSL/jetty.key ]; then
      openssl pkcs12 -export -in $PUBLIC_CERT -inkey $PRIVATE_KEY -out $NEXUS_SS
L/jetty.key -passout pass:$PRIVATE_KEY_PASSWORD
    fi
    $JAVA_HOME/bin/keytool -importkeystore -noprompt -deststorepass $PRIVATE_KEY
_PASSWORD -destkeypass $PRIVATE_KEY_PASSWORD -destkeystore $NEXUS_SSL/keystore.j
ks -srckeystore $NEXUS_SSL/jetty.key -srcstoretype PKCS12 -srcstorepass $PRIVATE
_KEY_PASSWORD
    sed -r '/<Set name="(KeyStore|KeyManager|TrustStore)Password">/ s:>.*$:>'$PR
IVATE_KEY_PASSWORD'</Set>:' -i $NEXUS_HOME/etc/jetty/jetty-https.xml
  fi

  mkdir -p "$NEXUS_DATA"
  chown -R nexus:nexus "$NEXUS_DATA"

  exec gosu nexus "$@"
fi

exec "$@"








create a Docker hosted repo on HTTPS port 8282

no need for insecure registry:

[centos@localhost ~]$ docker run -d -p 127.0.0.1:8081:8081 -p 127.0.0.1:8443:8443 -p 127.0.0.1:8482:8482 -v ~/nexus-data:/nexus-data -v ~/nexus-ssl:/opt/sonatype/nexus/etc/ssl --name nexus bradbeck/nexus-https
4b4e525ee28d5f10a26c4667065f15a7e9f308412bbcc6ebab18e2a030c042dd
[centos@localhost ~]$ netstat -an | grep 8482
tcp 0 0 127.0.0.1:8482 0.0.0.0:* LISTEN
[centos@localhost ~]$ docker login https://localhost:8482
Username: admin
Password:
Login Succeeded

this is the image https://hub.docker.com/r/bradbeck/nexus-https/~/dockerfile/




How to create the .cer, .key and jks files....

this will create a wildfly.keystore:
keytool -genkeypair -keystore wildfly.keystore -storepass mypassword -keypass mypassword -keyalg RSA -validity 180 -alias wildfly -dname "cn=packtpub,o=PackPub,c=GB"






Friday, June 30, 2017

System property jdk.tls.namedGroups(null) contains no supported elliptic curves

We get this using java version "1.6.0_141" Java(TM) SE Runtime Environment (build 1.6.0_141-b12) Java HotSpot(TM) 64-Bit Server VM (build 20.141-b12, mixed mode) :


java.lang.IllegalArgumentException: System property jdk.tls.namedGroups(null) contains no supported elliptic curves
 at com.sun.net.ssl.internal.ssl.SupportedEllipticCurvesExtension.<clinit>(HelloExtensions.java:567)

<Jun 29, 2017 11:16:07 AM CEST> <Error> <Socket> <BEA-000421> <Uncaught Throwable in processSockets
 java.lang.ExceptionInInitializerError.
 java.lang.ExceptionInInitializerError
 at com.sun.net.ssl.internal.ssl.HelloExtensions.<init>(HelloExtensions.java:73)
 at com.sun.net.ssl.internal.ssl.HandshakeMessage$ClientHello.<init>(HandshakeMessage.java:223)
 at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:204)
 at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:945)
 at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Handshaker.java:885)
 Truncated. see log file for complete stacktrace
 Caused By: java.lang.IllegalArgumentException: System property jdk.tls.namedGroups(null) contains no supported elliptic curves
 at com.sun.net.ssl.internal.ssl.SupportedEllipticCurvesExtension.<clinit>(HelloExtensions.java:567)
 at com.sun.net.ssl.internal.ssl.HelloExtensions.<init>(HelloExtensions.java:73)
 at com.sun.net.ssl.internal.ssl.HandshakeMessage$ClientHello.<init>(HandshakeMessage.java:223)
 at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:204)
 at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:945)
 Truncated. see log file for complete stacktrace
 >
 <Jun 29, 2017 11:16:07 AM CEST> <Error> <Socket> <BEA-000421> <Uncaught Throwable in processSockets
 java.lang.NoClassDefFoundError: Could not initialize class com.sun.net.ssl.internal.ssl.SupportedEllipticCurvesExtension.
 java.lang.NoClassDefFoundError: Could not initialize class com.sun.net.ssl.internal.ssl.SupportedEllipticCurvesExtension
 at com.sun.net.ssl.internal.ssl.HelloExtensions.<init>(HelloExtensions.java:73)
 at com.sun.net.ssl.internal.ssl.HandshakeMessage$ClientHello.<init>(HandshakeMessage.java:223)
 at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:204)
 at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:945)
 at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Handshaker.java:885)
 Truncated. see log file for complete stacktrace



The issue can be solved by removing -Dweblogic.ssl.JSSEEnabled=true

According to the Oracle website this issue was introduced with 141-b12 - http://www.oracle.com/technetwork/java/javase/overview-156328.html#R160_141 and is fixed in JDK 141-b32



Tuesday, June 13, 2017

Java: debugging HttpsClient connections

Recently we had this case:


 java.io.EOFException: SSL peer shut down incorrectly    SSL peer shut down incorrectly
 at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:462)
 at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
 at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1323)
 at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1350)
 at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1334)
 at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:569)
 at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
 at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1075)
 at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
 at com.sun.xml.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:129)
 at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:187)
 at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:124)
 at com.sun.xml.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:118)
 at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:866)
 at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:815)
 at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:778)
 at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:680)
 at com.sun.xml.ws.client.Stub.process(Stub.java:272)
 at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:153)
 at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:115)
 at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:95)
 at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:136)
 at com.sun.proxy.$Proxy225.getInstruments30(Unknown Source)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:84)
 at com.sun.proxy.$Proxy227.getInstruments30(Unknown Source)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)



Problem is, there is no way to trace the host, port, proxy parameters, protocols being used etc.

The classes involved are in jsse.jar and rt.jar (this is java 6!).

The other issue is that most attributes in those classes (HttpsClient, HttpClient...) have protected attributes, so you can't even access them easily with btrace or the like.

I ended up decompiling sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection from jsse.jar and changing the code to:

  public void connect()
    throws IOException
  {
    if (this.connected) {
      return;
    }
    plainConnect();
    if (this.cachedResponse != null) {
      return;
    }
    if ((!this.http.isCachedConnection()) && (this.http.needsTunneling())) {
      doTunneling();
    }
    try {
     java.lang.reflect.Field phost = HttpClient.class.getDeclaredField("host");
     phost.setAccessible(true);
     java.lang.reflect.Field pport = HttpClient.class.getDeclaredField("port");
     pport.setAccessible(true);
     System.out.println("PV host = " + phost.get(this.http) + " port = " + pport.get(this.http) + " usingProxy=" + this.http.usingProxy + " getProxyHostUsed=" + this.http.getProxyHostUsed() + " getProxyPortUsed=" + this.http.getProxyPortUsed());
    }
    catch (Throwable t) {
     System.out.println("PV an error occurred in AbstractDelegateHttpsURLConnection : ");
     t.printStackTrace();
    }
    ((HttpsClient)this.http).afterConnect();
  }

packaging the compiled class in pvjsse.jar and adding -Xbootclasspath/p:pvjsse.jar to the JVM parameters. It works !



Saturday, June 10, 2017

WebLogic 2 Way SSL

on the server tab, enable SSL

on the SSL tab, enable "client certificate requested and enforced"

then enter https url in Firefox:

https://192.168.56.1:7002/SnoopServlet/SnoopServlet.jsp

Your connection is not secure

The owner of 192.168.56.1 has configured their website improperly. To protect your information from being stolen, Firefox has not connected to this website.


click on "advanced"

192.168.56.1:7002 uses an invalid security certificate. The certificate is not trusted because the issuer certificate is unknown. The server might not be sending the appropriate intermediate certificates. An additional root certificate may need to be imported. The certificate is not valid for the name 192.168.56.1. Error code: SEC_ERROR_UNKNOWN_ISSUER





Secure Connection Failed

An error occurred during a connection to 192.168.56.1:7002. SSL peer cannot verify your certificate. Error code: SSL_ERROR_BAD_CERT_ALERT

    The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
    Please contact the website owners to inform them of this problem.


See https://support.mozilla.org/en-US/kb/what-does-your-connection-is-not-secure-mean

In Firefox: Tools / Options / Advanced / Certificates / View certificates / Your Certificates

Run keystore explorer (it needs unlimited cryptography strength), create new pkcs12 keystore, Tools/generate key pair, rsa 2048 key length, sha-256 with RSA,

please enter the password that was used to encrypt this certificate backup

In Chrome:
This site can’t provide a secure connection

192.168.56.1 didn’t accept your login certificate, or one may not have been provided.
Try contacting the system admin.


I add set JAVA_OPTIONS="-Djavax.net.debug=all" to startWebLogic.cmd

javax.net.ssl.SSLHandshakeException: null cert chain



Friday, January 20, 2017

javax.net.ssl.SSLHandshakeException: null cert chain

Some HtTP 500 was being generated in a webapp.
by enabling these flags
-Djavax.net.debug=ssl:handshake
-Dssl.debug=true
-Dweblogic.log.StdoutSeverity=Debug
-Dweblogic.StdoutDebugEnabled=true
-Dwls.debug.https=true


we discovered this error:

weblogic.socket.Muxer']]weblogic.security.SSL.jsseadapter: SSLENGINE: SSLEngine.unwrap(ByteBuffer,ByteBuffer[]) called: result=Status = OK HandshakeStatus = NEED_TASK
bytesConsumed = 12 bytesProduced = 0.> 
*** Certificate chain
***
ExecuteThread: '1' for queue: 'weblogic.socket.Muxer', fatal error: 42: null cert chain
javax.net.ssl.SSLHandshakeException: null cert chain
ExecuteThread: '1' for queue: 'weblogic.socket.Muxer', SEND TLSv1 ALERT:  fatal, description = bad_certificate
ExecuteThread: '1' for queue: 'weblogic.socket.Muxer', WRITE: TLSv1 Alert, length = 2
ExecuteThread: '1' for queue: 'weblogic.socket.Muxer', fatal: engine already closed.  Rethrowing javax.net.ssl.SSLHandshakeException: null cert chain
 
 
 
 
 
<Jan 18, 2017 4:39:09 PM CET> <Debug> <SecuritySSL> <BEA-000000> <[Thread[ExecuteThread: '1' for queue: 'weblogic.socket.Muxer',5,Thread Group for Queue: 'weblogic.socket.Muxer']]weblogic.security.SSL.jsseadapter: SSLENGINE: Exception occurred during SSLEngine.wrap(ByteBuffer,ByteBuffer).
javax.net.ssl.SSLHandshakeException: null cert chain
               at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Handshaker.java:1227)
               at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:489)
               at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1165)
               at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1137)
               at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:450)
               at weblogic.security.SSL.jsseadapter.JaSSLEngine$1.run(JaSSLEngine.java:68)
               at weblogic.security.SSL.jsseadapter.JaSSLEngine.doAction(JaSSLEngine.java:732)
               at weblogic.security.SSL.jsseadapter.JaSSLEngine.wrap(JaSSLEngine.java:66)
               at weblogic.socket.JSSEFilterImpl.wrapAndWrite(JSSEFilterImpl.java:625)
               at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:93)
               at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:66)
               at weblogic.socket.JSSEFilterImpl.isMessageComplete(JSSEFilterImpl.java:288)
               at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:955)
               at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:897)
               at weblogic.socket.PosixSocketMuxer.processSockets(PosixSocketMuxer.java:130)
               at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29)
               at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:42)
               at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145)
               at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117)
Caused By: javax.net.ssl.SSLHandshakeException: null cert chain
               at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:172)
               at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1599)
               at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:269)
               at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:257)
               at com.sun.net.ssl.internal.ssl.ServerHandshaker.clientCertificate(ServerHandshaker.java:1512)
               at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:212)
               at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:817)
               at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Handshaker.java:757)
               at java.security.AccessController.doPrivileged(Native Method)
               at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1164)
               at weblogic.socket.JSSEFilterImpl.doTasks(JSSEFilterImpl.java:191)
               at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:97)
               at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:66)
               at weblogic.socket.JSSEFilterImpl.isMessageComplete(JSSEFilterImpl.java:288)
               at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:955)
               at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:897)
               at weblogic.socket.PosixSocketMuxer.processSockets(PosixSocketMuxer.java:130)
               at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29)
               at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:42)
               at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145)
               at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117)



Examining WebLogic config.xml we notice that
<ssl>
      <client-certificate-enforced>false</client-certificate-enforced>
      <listen-port>32008</listen-port>
      <two-way-ssl-enabled>true</two-way-ssl-enabled>
</ssl>
and this also appears in the logs:
<Jan 20, 2017 3:07:23 PM CET> <Debug> <SecuritySSL> <BEA-000000> <[Thread[DynamicJSSEListenThread[DefaultSecure],9,WebLogicServer]]weblogic.security.SSL.jsseadapter: SSLENGINE: SSLEngine.setNeedClientAuth(boolean): value=false.>

(setNeedClientAuth should have value=true ! )
Setting the client-certificate-enforced to true fixed the issue.


Friday, October 7, 2016

java.net.SocketException: Software caused connection abort: recv failed

if you see crap like this:

Caused by: java.net.SocketException: Software caused connection abort: recv failed
            at java.net.SocketInputStream.socketRead0(Native Method)
            at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
            at java.net.SocketInputStream.read(SocketInputStream.java:170)
            at java.net.SocketInputStream.read(SocketInputStream.java:141)
            at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
            at sun.security.ssl.InputRecord.read(InputRecord.java:503)
            at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
            at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1769)
            at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:124)
            at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1083)
            at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1222)
            at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1134)
            at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)
            at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
            at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
            at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
            at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
            at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
            at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
            at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1283)
            at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1258)
            at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)


it means that the web service consumer doesn't send the certificate
In reality the client should send a different (more meaningful) error, related to SSL handshake, that in reality it catched and ignores....then he tries to read the data, which never arrive, then he complains that the server closed the socket.
You discover what really happened by setting the debug flags for jsse and you see that the server requests the client certificate, receives nothing and then sends the client to hell - which is the expected behaviour.


Monday, October 3, 2016

java.io.EOFException: SSL peer shut down incorrectly

This error:


Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:899)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1218)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1245)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1229)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:476)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1033)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler$1$1.getOutputStream(URLConnectionClientHandler.java:202)
    at com.sun.jersey.api.client.CommittingOutputStream.commitWrite(CommittingOutputStream.java:117)
    at com.sun.jersey.api.client.CommittingOutputStream.write(CommittingOutputStream.java:89)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
    at java.io.BufferedWriter.flush(BufferedWriter.java:236)
    at com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191)
    at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128)
    at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88)
    at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58)
    at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:311)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:181)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:129)
    ... 7 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:462)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:880)
    ... 30 more


Unexpected error occured!
com.sun.jersey.api.client.ClientHandlerException: java.net.SocketException: Connection reset
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:131)
    at com.csg.cs.batch.launch.client.util.JerseyClientWrapper$1.handle(JerseyClientWrapper.java:67)
    at com.sun.jersey.api.client.Client.handle(Client.java:629)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:601)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:507)
    at com.csg.cs.batch.launch.client.util.JerseyClientWrapper.postOverHTTPS(JerseyClientWrapper.java:87)
    at com.csg.cs.batch.launch.client.JobClient.main(JobClient.java:86)
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:168)
    at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:422)
    at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:460)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:880)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1218)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1245)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1229)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:476)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1033)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler$1$1.getOutputStream(URLConnectionClientHandler.java:202)
    at com.sun.jersey.api.client.CommittingOutputStream.commitWrite(CommittingOutputStream.java:117)
    at com.sun.jersey.api.client.CommittingOutputStream.write(CommittingOutputStream.java:89)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
    at java.io.BufferedWriter.flush(BufferedWriter.java:236)
    at com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191)
    at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128)
    at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88)
    at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58)
    at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:311)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:181)
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:129)



according to Oracle Support KB documents:

SSL-Encrypted JDBC Connections Fail With "Remote host closed connection during handshake" (Doc ID 2149709.1)

Getting "javax.net.ssl.SSLHandshakeException: Remote Host Closed Connection During Handshake" Error (Doc ID 1572454.1)

it could be because of unsupported cypher suites (not in our case, this is a WLS to WLS communication, a DB listener is not involved) , or a proxy or a firewall in between that mangles the data transfer or closes the connection (mmmm this also is unsure)



Thursday, August 18, 2016

ClientHello and ServerHello

When you enable -Dssl.debug=true -Djavax.net.debug=ssl -Dweblogic.log.StdoutSeverity=Debug you get a lot of cryptic information in the logs
This document http://www.cisco.com/c/en/us/support/docs/security-vpn/secure-socket-layer-ssl/116181-technote-product-00.html explains quite well the SSL exchange protocol.


http://security.stackexchange.com/questions/19473/understanding-2048-bit-ssl-and-256-bit-encryption

this is a sample ClientHello:

*** ClientHello, TLSv1
RandomCookie:  GMT: 1454428615 bytes = { 69, 83, 231, 161, 89, 17, 57, 52, 161, 204, 30, 120, 164, 155, 109, 48, 216, 11, 123, 111, 55, 22, 86, 64, 123, 128, 64, 180 }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension server_name, server_name: [host_name: ldap.pippo.net]
***
[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)', WRITE: TLSv1 Handshake, length = 94
[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)', READ: TLSv1 Handshake, length = 3726


this is a sample ServerHello:

*** ServerHello, TLSv1
RandomCookie:  GMT: 1454428615 bytes = { 173, 6, 9, 133, 26, 24, 40, 154, 88, 2, 88, 175, 59, 169, 225, 31, 240, 132, 194, 100, 230, 48, 159, 177, 56, 91, 246, 67 }
Session ID:  {49, 77, 200, 173, 221, 205, 188, 24, 24, 109, 151, 39, 90, 35, 26, 224, 39, 31, 102, 10, 125, 130, 207, 170, 124, 33, 67, 152, 53, 80, 6, 204}
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: 
***
%% Initialized:  [Session-1, TLS_RSA_WITH_AES_256_CBC_SHA]
** TLS_RSA_WITH_AES_256_CBC_SHA
*** Certificate chain
chain [0] = [
[
  Version: V3

...... details about certificate chain


]
***
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Cert Authorities:


*** ServerHelloDone









Monday, July 25, 2016

which Cipher Suites your JVM supports

"SunJSSE supports a large number of ciphersuites" http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider
1) WLS 11g (WLS 10.3.6) uses JSSE and runs on Java SE 6
2) JSSE java 6  http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider
3) WLS 10.3.6 ciphers: http://docs.oracle.com/cd/E28280_01/web.1111/e13707/ssl.htm#BABBDACC

The classification of the different bits (TLS_DHE_RSA_WITH_AES_128_CBC_SHA) is as follows:
TLS vs SSL
RSA vs ECDH vs ECDHE vs DHE vs KRB5
ECDSA vs RSA
RC4 vs 3DES vs DES vs AES
EDE vs CBC
SHA vs MD5

Set "-Dssl.debug=true -Djavax.net.debug=ssl -Dweblogic.log.StdoutSeverity=Debug" then search for the statement
SSLEngine.setEnabledCipherSuites
to see which Ciphers are actually ENABLED (not only supported).
See also http://stackoverflow.com/questions/10487962/java-cipher-suites
There is a property https.cipherSuites , and a SSLSocket.setEnabledCipherSuites()/SSLEngine.setEnabledCipherSuites() method.
See also MOS document "How to Verify the Sun JSSE Cipher Suites Available to WebLogic Server (11g/12c) (Doc ID 2052237.1)"
suggesting to enable these flags
 -Dweblogic.debug.DebugSecuritySSL=true
 -Djavax.net.SSL=true
 -Djava.debug=SSL
 -Djavax.net.debug=all
 -Dssl.debug=true
 -Dweblogic.StdoutDebugEnabled=true
 -Dweblogic.log.LogSeverity=Debug
 -Dweblogic.log.LoggerSeverity=Debug


Sunday, July 24, 2016

SSL TLS renegotiation, RFC 5746

Generalities:
https://devcentral.f5.com/articles/ssl-profiles-part-6-ssl-renegotiation

Oracle technical details on the famous RFC 5746, here the mythical JSEE Ref Guide (something every human should read) :
http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#tlsRenegotiation

More explanations
http://security.stackexchange.com/a/24569/118343



Other tags: no_renegotiation handshake_failure

Sunday, June 5, 2016

BEA-090171 and BEA-090169

in WebLogic there are 2 messages helping us identify the identity and trust store used :
BEA-090171 Loading the identity certificate and private key stored under the alias client ....

BEA-090169 Loading trusted certificates from the JKS file store

This flag is useful to trace: -Dweblogic.security.SSL.verbose=true -Djavax.net.debug=all
Check also the "ssl" element in config.xml:
    <ssl>
      <use-java>true</use-java>
      <enabled>true</enabled>
      <ciphersuite>TLS_RSA_WITH_AES_256_CBC_SHA</ciphersuite>
      <ciphersuite>TLS_RSA_WITH_AES_128_CBC_SHA</ciphersuite>
      <ciphersuite>TLS_RSA_WITH_RC4_128_SHA</ciphersuite>
      <ciphersuite>TLS_RSA_WITH_3DES_EDE_CBC_SHA</ciphersuite>
      <hostname-verifier>com.pierre.HostNameVerifier</hostname-verifier>
      <hostname-verification-ignored>false</hostname-verification-ignored>
      <export-key-lifespan>500</export-key-lifespan>
      <client-certificate-enforced>true</client-certificate-enforced>
      <listen-port>33641</listen-port>
      <two-way-ssl-enabled>true</two-way-ssl-enabled>
      <server-private-key-alias>some.certificate.alias</server-private-key-alias>
      <server-private-key-pass-phrase-encrypted>{AES}blablabla=</server-private-key-pass-phrase-encrypted>
      <ssl-rejection-logging-enabled>true</ssl-rejection-logging-enabled>
      <inbound-certificate-validation>BuiltinSSLValidationAndCertPathValidators</inbound-certificate-validation>
      <outbound-certificate-validation>BuiltinSSLValidationOnly</outbound-certificate-validation>
      <jsse-enabled>true</jsse-enabled>
    </ssl>




SSLMBean.ServerPrivateKeyAlias https://docs.oracle.com/cd/E13222_01/wls/docs100/schemaref/security/http.www.bea.com.ns.weblogic.920.domain/types/ssltype.server-private-key-alias.html



Tuesday, May 24, 2016

Apache http-client, customizing SSLSocketFactory

Here the general documentation on Apache HTTP client https://hc.apache.org/httpcomponents-client-ga/

https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/scheme/SchemeSocketFactory.html

    HttpContext context...
    SchemeRegistry registry = getSchemeRegistry(context);
    Scheme schm = registry.getScheme(target.getSchemeName());
    SchemeSocketFactory sf = schm.getSchemeSocketFactory();


This example https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java shows

Specifically, it's interesting to look at their default implementation of https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/HostnameVerifier.html which is the org.apache.http.conn.ssl.BrowserCompatHostnameVerifier ( extends org.apache.http.conn.ssl.AbstractVerifier implements org.apache.http.conn.ssl.X509HostnameVerifier extends javax.net.ssl.HostnameVerifier )

The extra methods added by org.apache.http.conn.ssl.X509HostnameVerifier are:

  public abstract void verify(String host, SSLSocket ssl)
    throws IOException;
  
  public abstract void verify(String host, X509Certificate cert)
    throws SSLException;
  
  public abstract void verify(String host, String[] cns, String[] subjectAlts)
    throws SSLException;

while the basic javax.net.ssl.HostnameVerifier contains only
verify(String hostname, SSLSession session)


Remember! javax.net.ssl.SSLSocketFactory is an ABSTRACT class.

For use within WebLogic, see http://docs.oracle.com/cd/E12839_01/core.1111/e10043/ohttps.htm#JISEC2046, but the property HTTPClient.defaultHostnameVerifier doesn't seem to work with Apache HTTPClient.

Also another interface exists weblogic.security.SSL.HostnameVerifier



Thursday, December 31, 2015

javax.net.ssl.SSLHandshakeException: Server chose unsupported or disabled protocol: SSLv3

If you get this error message "javax.net.ssl.SSLHandshakeException: Server chose unsupported or disabled protocol: SSLv3",
chances are that your JVM, for vulnerability issues connected to SSLv3, is configured to disable this protocol.
If you REALLY need to support SSLv3, check which file you are using for -Djava.security.properties=/path/to/yourfile, then edit yourfile and make sure your property:
jdk.tls.disabledAlgorithms=SSLv3, DH keySize < 768
doesn't contain SSLv3 (make it jdk.tls.disabledAlgorithms=DH keySize < 768)


Sunday, December 6, 2015

Debugging SSL with javax.net.debug=all

This is a guide to interpreting the output of -Djavax.net.debug=all:
https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html
and this is what I get
https://gist.github.com/vernetto/4b5c1e5b9562143998e0
by running this code with args[0]=www.usps.com (code courtesy of the excellent book "Java Network Programming, 4th Edition" that I highly recommend reading)



import java.io.*;
import javax.net.ssl.*;

public class HTTPSClient {

  public static void main(String[] args) {

    if (args.length == 0) {
      System.out.println("Usage: java HTTPSClient2 host");
      return;
    }

    int port = 443; // default https port
    String host = args[0];

    SSLSocketFactory factory
        = (SSLSocketFactory) SSLSocketFactory.getDefault();
    SSLSocket socket = null;
    try {
      socket = (SSLSocket) factory.createSocket(host, port);

      // enable all the suites
      String[] supported = socket.getSupportedCipherSuites();
      socket.setEnabledCipherSuites(supported);

      Writer out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
      // https requires the full URL in the GET line
      out.write("GET http://" + host + "/ HTTP/1.1\r\n");
      out.write("Host: " + host + "\r\n");
      out.write("\r\n");
      out.flush();

      // read response
      BufferedReader in = new BufferedReader(
          new InputStreamReader(socket.getInputStream()));

      // read the header
      String s;
      while (!(s = in.readLine()).equals("")) {
        System.out.println(s);
      }
      System.out.println();

      // read the length
      String contentLength = in.readLine();
      int length = Integer.MAX_VALUE;
      try {
        length = Integer.parseInt(contentLength.trim(), 16);
      } catch (NumberFormatException ex) {
        // This server doesn't send the content-length
        // in the first line of the response body
      }
      System.out.println(contentLength);

      int c;
      int i = 0;
      while ((c = in.read()) != -1 && i++ < length) {
        System.out.write(c);
      }

      System.out.println();
    } catch (IOException ex) {
      System.err.println(ex);
    } finally {
        try {
          if (socket != null) socket.close();
        } catch (IOException e) {}
    }
  }
}