简体   繁体   中英

Websocket (spring) ssl connection (empty chain)

Good day! I have a simple chat application with websocket (STOMP). I have configured ssl connection with mutal auth.

Server side:

server.port=8443
server.ssl.key-store=path/to/server.jks
server.ssl.trust-store=path/to/trusted.jks
server.ssl.key-store-password=22222222
server.ssl.trust-store-password=22222222
server.ssl.client-auth=need

client :

System.setProperty("javax.net.ssl.keyStore","path/to/client.jks");
System.setProperty("javax.net.ssl.keyStorePassword","22222222");
System.setProperty("javax.net.ssl.trustStore","path/to/trusted.jks");  
System.setProperty("javax.net.ssl.trustStorePassword","22222222");

server trusted.jks and client trusted.jks are the same.

so when I try to connect with

-Djavax.net.debug=ssl

I get lots of output and some strange situation - I can see two(?) key-agreements. The first one goes ok -

  trustStore is: /path/to/trusted.jks

adding as trusted cert:
  Subject: EMAILADDRESS=ca@ca.com, CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU
  Issuer:  EMAILADDRESS=ca@ca.com, CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU
  Algorithm: RSA; Serial number: 0x9952f188496b2545
  Valid from Wed Jun 28 15:39:04 MSK 2017 until Sat Jun 26 15:39:04 MSK 2027

So my CA cert is added as trusted. Then

*** ClientHello, TLSv1.2
//ok
*** ServerHello, TLSv1.2
//ok
*** Certificate chain
//my localhost server cert
***
Found trusted certificate:

 Version: V3
 Subject: EMAILADDRESS=ca@ca.com, CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU
 Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

So my client found trusted certificate for this server certificate.

*** ECDH ServerKeyExchange
//ok
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Cert Authorities:

*** ServerHelloDone

And I can find my CHAIN -

*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: EMAILADDRESS=client3@mail.ru, CN=client3, OU=client3, O=client3, L=client3, ST=client3, C=RU
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

chain [1] = [
[
  Version: V3
  Subject: EMAILADDRESS=ca@ca.com, CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
*** ECDHClientKeyExchange
*** CertificateVerify
*** Finished

As far as I know - this is ok. Then I can see:

DEBUG org.springframework.web.client.RestTemplate - GET request for "https://localhost:8443/chat/info" resulted in 200 (null)
DEBUG org.springframework.web.socket.sockjs.client.WebSocketTransport - Starting WebSocket session on wss://localhost:8443/chat/437/f6158d1ee84b4c53ba55a6810b2f92a8/websocket
DEBUG org.springframework.web.socket.client.standard.StandardWebSocketClient - 
Connecting to wss://localhost:8443/chat/437/f6158d1ee84b4c53ba55a6810b2f92a8/websocket

Again adding trust store certificate and so on, all is the same, but

*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Cert Authorities:
<EMAILADDRESS=ca@ca.com, CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU>
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***

So the server says to me

ttps-jsse-nio-8443-exec-9, fatal error: 42: null cert chain
javax.net.ssl.SSLHandshakeException: null cert chain

Any thoughts about problem? If it is needed I can post my keystores and client implementation here. Thank you for help!

UPDATE with curl output

 env -i curl -E ./chain.pem --key ./client.key --cacert ca.crt --verbose --user test:test  https://localhost:8443/

*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8443 (#0)
* found 1 certificates in ca.crt
* found 704 certificates in /etc/ssl/certs 
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
*    server certificate verification OK
*    server certificate status verification SKIPPED
*    common name: localhost (matched)
*    server certificate expiration date OK
*    server certificate activation date OK
*    certificate public key: RSA
*    certificate version: #3
*    subject: 

C=RU,ST=localhost, 
L=localhost,O=localhost,OU=localhost, 
CN=localhost,EMAIL=localhost@mail.com
*    start date: Wed, 28 Jun 2017 13:07:14 GMT
*    expire date: Thu, 28 Jun 2018 13:07:14 GMT
*    issuer: C=RU,ST=ca,L=ca,O=ca,OU=ca,CN=ca,EMAIL=ca@ca.com
*    compression: NULL
* ALPN, server did not agree to a protocol
* Server auth using Basic with user 'kitcpp'
> GET / HTTP/1.1
> Host: localhost:8443
> Authorization: Basic a2l0Y3BwOmtpdGNwcA==
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=67BACDE78AF68627516075B29C987C86; Path=/; Secure; HttpOnly
< Last-Modified: Wed, 28 Jun 2017 16:29:53 GMT
 < Accept-Ranges: bytes
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-US
< Content-Length: 6935
< Date: Fri, 30 Jun 2017 09:30:02 GMT
< 
<!DOCTYPE html>
<html>
<head>
//and so on (my web chat page)

You are using Tomcat's WebSocket client. Its documentation describes how it should be configured to use SSL:

When using the WebSocket client to connect to secure server endpoints, the client SSL configuration is controlled by the userProperties of the provided javax.websocket.ClientEndpointConfig . The following user properties are supported:

  • org.apache.tomcat.websocket.SSL_CONTEXT
  • org.apache.tomcat.websocket.SSL_PROTOCOLS
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD

If the org.apache.tomcat.websocket.SSL_CONTEXT property is set then the org.apache.tomcat.websocket.SSL_TRUSTSTORE and org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD properties will be ignored.

You're using Spring's WebSocket and it is creating the ClientEndpointConfig for you. To configure its user properties you set them on the StandardWebSocketClient and it will then use them when it creates the ClientEndpointConfig . For example, assuming that the default SSL context is sufficient:

StandardWebSocketClient simpleWebSocketClient =
        new StandardWebSocketClient();
Map<String, Object> userProperties = new HashMap<>();
userProperties.put("org.apache.tomcat.websocket.SSL_CONTEXT", SSLContext.getDefault());
simpleWebSocketClient.setUserProperties(userProperties);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM