WildFly Elytron

SSLv2Hello with WildFly

It is now possible to use SSLv2Hello with WildFly. This blog post will give an introduction to this new feature, but it will assume previous knowledge on how to configure SSL in Elytron. For more information on how to configure SSL, refer to the elytron documentation.

An Overview of SSLv2Hello

Older JDK versions use SSLv2Hello during the initial handshake message where the SSL version that will be used for the rest of the handshake is negotiated.

The use of this protocol is discouraged. As a result, newer JDK versions disable this protocol by default for clients, but do provide the ability to re-enable it if needed.

By adding SSLv2Hello as a supported protocol in WildFly, we are ensuring older clients are still able to communicate to servers guaranteeing parity with legacy security.

Enabling SSLv2Hello on the Server Side

SSLv2Hello can be enabled by configuring it in the protocols attribute in the SSL context definition in the Elytron subsystem. Let’s take a look at an example configuring one way SSL using SSLv2Hello in the server and client. The example application is available here.

Back Up Your Standalone Server Configuration

Prior to starting, back up your standalone server configuration by making a copy of your WILDFLY_HOME/standalone/configuration/standalone.xml file. You will need it in the end to restore your server’s configuration.

Pre-requisite Server Configuration

As a first step, we’re going to enable one-way SSL for applications deployed to WildFly using the security enable-ssl-http-server CLI command.

First, make sure you have an instance of your WildFly server running. Then, run the following commands:

WILDFLY_HOME/bin/jboss-cli.sh --connect

Then run the security enable-ssl-http-server command as follows:

security enable-ssl-http-server --interactive
Please provide required pieces of information to enable SSL:

Certificate info:
Key-store file name (default default-server.keystore): server.keystore
Password (blank generated): secret
What is your first and last name? [Unknown]: localhost
What is the name of your organizational unit? [Unknown]: wildfly
What is the name of your organization? [Unknown]: jboss
What is the name of your City or Locality? [Unknown]: Raleigh
What is the name of your State or Province? [Unknown]: North Carolina
What is the two-letter country code for this unit? [Unknown]: US
Is CN=localhost, OU=jboss, O=wildfly, L=Raleigh, ST=North Carolina, C=US correct y/n [y]?y
Validity (in days, blank default): 365
Alias (blank generated): localhost
Enable SSL Mutual Authentication y/n (blank n):n

SSL options:
key store file: server.keystore
distinguished name: CN=localhost, OU=wildfly, O=jboss, L=Raleigh, ST=North Caro
lina, C=US
password: secret
validity: 365
alias: localhost
Server keystore file server.keystore, certificate file server.pem and server.csr file will be generated in server configuration directory.

Do you confirm y/n :y
Server reloaded.
SSL enabled for default-server
ssl-context is ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884
key-manager is key-manager-aaad4a67-14f1-4869-a01c-9fc56c3ff884
key-store   is key-store-aaad4a67-14f1-4869-a01c-9fc56c3ff884
Make sure you enter your desired "hostname" for the first and last name field, otherwise you might run into issues while permanently accepting this certificate as an exception to some browsers. Chrome does not currently exhibit this behaviour.

As we can see from the output, the above command automatically generated a self-signed certificate, added it to a newly created keystore and added a new ssl-context resource, ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884 to the Elytron subsystem in order to enable one-way SSL for applications deployed to WildFly.

Test the Server SSL Configuration

To test the connection to the SSL port of your server instance, open a browser and navigate to https://localhost:8443/.

You get the privacy error because the server certificate is self-signed. If you need to use a fully signed certificate, you must get a PEM file from the Certificate Authority and then import the PEM into the keystore.

Configuring SSLv2Hello in the Server

At this point in time, your server has not yet been configured to accept SSLv2Hello messages. Since, we used the security enable-ssl-http-server CLI command, this configures our SSL context to accept TLSv1.2 only. To enable SSLv2Hello, we need to update our ssl-context configuration in the Elytron subsystem to modify the attribute protocols to include SSLv2Hello as follows:

/subsystem=elytron/server-ssl-context=ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884:write-attribute(name=protocols,value=[TLSv1,SSLv2Hello])

reload
When configuring any SSL context to enable SSLv2Hello (client or server), you always need to specify an additional SSL/TLS protocol. SSLv2Hello cannot be specified by itself, as it is a pseudo protocol which is only used to negotiate another SSL/TLS version to be used throughout the rest of the communication.

A Note On Enabling SSLv2Hello In Newer JDK Versions

Newer JDK versions have disabled TLSv1. Since we need the TLSv1 protocol to make use of SSLv2Hello, we will walk you through how to re-enable it on the server side.

  • Access the following file: WILDFLY_HOME/bin/standalone.conf.

  • Look for the following line

# JAVA_OPTS="$JAVA_OPTS -Djava.security.properties==/path/to/custom/java.security"
  • Make sure to uncomment it and edit the path to the file enabled_tlsv1.properties in this example application. Additionally, make sure you use one = as opposed to two. That way you will not completely override the java.security file.

Note, you might have to reload your server for these changes to take effect.

Configure the Client’s Trust Store

Export the server’s certificate to a file by navigating to WILDFLY_HOME/standalone/configuration and running the following command:

keytool -export -alias localhost -keystore server.keystore -file myCert.cer -storepass secret

Import the certificate into the client’s trust store. Note the following command will create a trust store if it does not exist at the location specified.

keytool -import -file myCert.cer -alias localhost -keystore client.keystore -storepass secret

You should see the following output next:

Owner: CN=localhost, OU=wildfly, O=jboss, L=Raleigh, ST=North Carolina, C=US
Issuer: CN=localhost, OU=wildfly, O=jboss, L=Raleigh, ST=North Carolina, C=US
Serial number: 7af5ad9991816bbc
Valid from: Wed Nov 04 16:15:09 EST 2020 until: Thu Nov 04 16:15:09 EDT 2021
Certificate fingerprints:
	 SHA1: 24:6E:96:9A:8B:D2:FF:2B:7B:58:87:84:03:F3:ED:C6:56:8B:96:5B
	 SHA256: 27:51:F6:7A:F8:51:7D:6E:CB:DA:4A:9A:75:E5:9A:AD:06:88:1B:AE:40:73:7D:D8:E4:4F:22:CA:8E:03:94:37
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: FF BA 34 E8 94 94 BE EB   25 B5 C5 4E B3 B2 A4 34  ..4.....%..N...4
0010: 97 EE A2 24                                        ...$
]
]

Trust this certificate? [no]: y
Certificate was added to keystore

You have now created the client’s trustore and imported the server’s certificate.

Configure a Client that sends SSLv2Hello messages

The example application presents a simple client Client.java which checks the connection to the server is successful. To ensure the client uses SSLv2Hello in its initial handshake, we have provided a common configuration framework in wildfly-config.xml.

Review this file to see how SSLv2Hello is enabled in the client SSL context along with TLSv1.

As a final step in configuring the client, update the path to the client’s trust store to /PATH/TO/client.keystore.

Build and Deploy the Application

Ensure you have a running instance of your server. Then, navigate to the root directory of the example application and run the following commands:

cd server
mvn clean package wildfly:deploy

This deploys the server-sslv2hello.war to the running instance of the server. You should see a message in the server log indicating that the archive deployed successfully.

Run the Client

Navigate to the root directory of the example application and run the following commands:

cd client
mvn clean install -Dtest=Client

The test verifies a successful connection using SSLv2Hello.

Verifying the Client Sends SSLv2Hello Messages

In the following section, we will be inspecting the SSL debug logs to ensure the Client Hello messages make use of SSLv2Hello. You will need to enable SSL debug logs in your client and server using the javax.net.debug system property as follows:

  1. To run your client with SSL debug logs:

mvn clean install -Dtest=Client -Djavax.net.debug=ssl,handshake
  1. To run your server with SSL debug logs:

WILDFLY_HOME/bin/standalone.sh -Djavax.net.debug=ssl,handshake

Verifying SSLv2Hello Messages Succeed When SSLv2Hello is Configured on the Server

Run your client.

In your client SSL logs, you should see a ClientHello message similar to the following:

"ClientHello": {
  "client version"      : "TLSv1",
  "random"              : "28 D9 B0 EB 0E A1 5B 07 B6 0D 21 B1 87 F8 42 14 EE 11 6A 11 8B B6 19 7D 2B CF DB B5 B1 A1 43 01",
  "session id"          : "",
  "cipher suites"       : "[TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(0xC00A), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(0xC009), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033)]",
  "compression methods" : "00",
  "extensions"          : [
    "status_request (5)": {
      "certificate status type": ocsp
      "OCSP status request": {
        "responder_id": <empty>
        "request extensions": {
          <empty>
        }
      }
    },
    "supported_groups (10)": {
      "versions": [secp256r1, secp384r1, secp521r1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
    },
    "ec_point_formats (11)": {
      "formats": [uncompressed]
    },
    "status_request_v2 (17)": {
      "cert status request": {
        "certificate status type": ocsp_multi
        "OCSP status request": {
          "responder_id": <empty>
          "request extensions": {
            <empty>
          }
        }
      }
    },
    "extended_master_secret (23)": {
      <empty>
    },
    "supported_versions (43)": {
      "versions": [TLSv1, SSLv2Hello]
    },
    "renegotiation_info (65,281)": {
      "renegotiated connection": [<no renegotiated connection>]
    }
  ]
}

Notice how TLSv1 and SSLv2Hello are specified under supported_versions. This triggers an SSLv2Hello ClientHello. Your tests should succeed, and you should be able to see the negotiated protocol is TLSv1 in both your client and server logs.

Verifying SSLv2Hello messages fail when SSLv2Hello is not configured on the server

You can modify your server-ssl-context resource again to only accept TLSv1 as follows:

/subsystem=elytron/server-ssl-context=ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884:write-attribute(name=protocols,value=[TLSv1])

Now, run your client. You should be able to see a similar ClientHello as the one in the section above, but you should also see a handshake_failure in the log.

Upon reviewing your server log, it should provide more details as to what causes the failure. You should see a message similar to the following:

ERROR [stderr] (default I/O-2) javax.net.ssl|ERROR|01 14|default I/O-2|2020-11-05
14:29:27.677 EST|TransportContext.java:318|Fatal (HANDSHAKE_FAILURE): SSLv2Hello is not enabled (
14:29:27,678 ERROR [stderr] (default I/O-2) "throwable" : {
14:29:27,678 ERROR [stderr] (default I/O-2)   javax.net.ssl.SSLHandshakeException: SSLv2Hello is not enabled

Now, you have verified that enabling SSLv2Hello on the client side triggers an SSLv2Hello message, which if not supported by the server, causes a handshake exception.

Undeploy the Application

When you are finished testing the application, follow these steps to undeploy the archive:

  1. Make sure you start the WildFly server.

  2. Open a terminal and navigate to the root directory of this example.

  3. Type the following commands to undeploy the archive:

cd server
mvn wildfly:undeploy

Restore the WildFly Standalone Server Configuration

You can restore your WildFly Standalone Server Configuration by replacing your WILDFLY_HOME/standalone/configuration/standalone.xml file with your backed up copy.

Summary

This blog post has given an overview on how SSLv2Hello can be used with WildFly on both the server and client side. For more details, take a look at the Elytron documentation.