There are many tools available to test TLS servers, but sometimes you may need to test a TLS client, just to see what ciphers and algorithms it supports. This article explains how to use OpenSSL to create a TLS server that you can modify and have clients connect to.
Create some certificates
If you don’t already have a server key and certificate bundle then you can follow these steps to create a CA, a CSR and a server certificate bundle for your OpenSSL server to use.
Creating the Certificate Authority’s Certificate and Keys
- Generate a private key for the CA:
$ openssl genrsa 2048 > ca-key.pem
- Generate the X509 certificate for the CA: (In the next sections you must provide some basic info and not just hit enter when prompted. Just supply generic test made-up info)
$ openssl req -new -x509 -nodes -days 365000 \
-key ca-key.pem \
-out ca-cert.pem
Creating the Server’s Certificate and Keys
- Generate the private key and certificate request:
$ openssl req -newkey rsa:2048 -nodes -days 365 \
-keyout server-key.pem \
-out server-req.pem
- Generate the X509 certificate for the server:
$ openssl x509 -req -days 365 -set_serial 01 \
-in server-req.pem \
-out server-cert.pem \
-CA ca-cert.pem \
-CAkey ca-key.pem
Creating the Client’s Certificate and Keys (optional)
- Generate the private key and certificate request:
$ openssl req -newkey rsa:2048 -nodes -days 365 \
-keyout client-key.pem \
-out client-req.pem
- Generate the X509 certificate for the client:
$ openssl x509 -req -days 365 -set_serial 01 \
-in client-req.pem \
-out client-cert.pem \
-CA ca-cert.pem \
-CAkey ca-key.pem
Verifying the Certificates (optional)
- Verify the server certificate:
$ openssl verify -CAfile ca-cert.pem \
ca-cert.pem \
server-cert.pem
- Verify the client certificate:
$ openssl verify -CAfile ca-cert.pem \
ca-cert.pem \
client-cert.pem
Start your OpenSSL server
To get started without customizing your OpenSSL server simply use the following command to start the server listening on port 8443:
$ openssl s_server -key server-key.pem -cert server-cert.pem -accept 8443 -www
Now you can point your client to the OpenSSL server, for example assuming you have started the OpenSSL server on your local host, for a web browser client visit https://localhost:8443. You will receive the following level of information in the browser window.
$ openssl s_server -key server-key.pem -cert server-cert.pem -accept 8443 -www
Secure Renegotiation IS NOT supported
Ciphers supported in s_server binary
TLSv1.3 :TLS_AES_256_GCM_SHA384 TLSv1.3 :TLS_CHACHA20_POLY1305_SHA256
TLSv1.3 :TLS_AES_128_GCM_SHA256 TLSv1.2 :ECDHE-ECDSA-AES256-GCM-SHA384
TLSv1.2 :ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 :DHE-RSA-AES256-GCM-SHA384
TLSv1.2 :ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 :ECDHE-RSA-CHACHA20-POLY1305
TLSv1.2 :DHE-RSA-CHACHA20-POLY1305 TLSv1.2 :ECDHE-ECDSA-AES128-GCM-SHA256
TLSv1.2 :ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 :DHE-RSA-AES128-GCM-SHA256
TLSv1.2 :ECDHE-ECDSA-AES256-SHA384 TLSv1.2 :ECDHE-RSA-AES256-SHA384
TLSv1.2 :DHE-RSA-AES256-SHA256 TLSv1.2 :ECDHE-ECDSA-AES128-SHA256
TLSv1.2 :ECDHE-RSA-AES128-SHA256 TLSv1.2 :DHE-RSA-AES128-SHA256
TLSv1.0 :ECDHE-ECDSA-AES256-SHA TLSv1.0 :ECDHE-RSA-AES256-SHA
SSLv3 :DHE-RSA-AES256-SHA TLSv1.0 :ECDHE-ECDSA-AES128-SHA
TLSv1.0 :ECDHE-RSA-AES128-SHA SSLv3 :DHE-RSA-AES128-SHA
TLSv1.2 :RSA-PSK-AES256-GCM-SHA384 TLSv1.2 :DHE-PSK-AES256-GCM-SHA384
TLSv1.2 :RSA-PSK-CHACHA20-POLY1305 TLSv1.2 :DHE-PSK-CHACHA20-POLY1305
TLSv1.2 :ECDHE-PSK-CHACHA20-POLY1305 TLSv1.2 :AES256-GCM-SHA384
TLSv1.2 :PSK-AES256-GCM-SHA384 TLSv1.2 :PSK-CHACHA20-POLY1305
TLSv1.2 :RSA-PSK-AES128-GCM-SHA256 TLSv1.2 :DHE-PSK-AES128-GCM-SHA256
TLSv1.2 :AES128-GCM-SHA256 TLSv1.2 :PSK-AES128-GCM-SHA256
TLSv1.2 :AES256-SHA256 TLSv1.2 :AES128-SHA256
TLSv1.0 :ECDHE-PSK-AES256-CBC-SHA384 TLSv1.0 :ECDHE-PSK-AES256-CBC-SHA
SSLv3 :SRP-RSA-AES-256-CBC-SHA SSLv3 :SRP-AES-256-CBC-SHA
TLSv1.0 :RSA-PSK-AES256-CBC-SHA384 TLSv1.0 :DHE-PSK-AES256-CBC-SHA384
SSLv3 :RSA-PSK-AES256-CBC-SHA SSLv3 :DHE-PSK-AES256-CBC-SHA
SSLv3 :AES256-SHA TLSv1.0 :PSK-AES256-CBC-SHA384
SSLv3 :PSK-AES256-CBC-SHA TLSv1.0 :ECDHE-PSK-AES128-CBC-SHA256
TLSv1.0 :ECDHE-PSK-AES128-CBC-SHA SSLv3 :SRP-RSA-AES-128-CBC-SHA
SSLv3 :SRP-AES-128-CBC-SHA TLSv1.0 :RSA-PSK-AES128-CBC-SHA256
TLSv1.0 :DHE-PSK-AES128-CBC-SHA256 SSLv3 :RSA-PSK-AES128-CBC-SHA
SSLv3 :DHE-PSK-AES128-CBC-SHA SSLv3 :AES128-SHA
TLSv1.0 :PSK-AES128-CBC-SHA256 SSLv3 :PSK-AES128-CBC-SHA
---
Ciphers common between both SSL end points:
TLS_AES_128_GCM_SHA256 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_256_GCM_SHA384
ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA
ECDHE-RSA-AES256-SHA AES128-GCM-SHA256 AES256-GCM-SHA384
AES128-SHA AES256-SHA
Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA1:RSA+SHA1
Shared Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA1:RSA+SHA1
Supported Elliptic Groups: X25519:P-256:P-384:P-521:0x0100:0x0101
Shared Elliptic groups: X25519:P-256:P-384:P-521
---
No server certificate CA names sent
---
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_128_GCM_SHA256
Session-ID: 72E92F6C4FC712CE8436BC8807DAFC66F92CD68672AFEE9D6D0175EFAB91973D
Session-ID-ctx: 01000000
Resumption PSK: 7315D438FDD4B2767FE0644C96542F0D4483D38BAEEDB9C3F20104B32C0BE8B0
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1616599192
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
0 items in the session cache
0 client connects (SSL_connect())
0 client renegotiates (SSL_connect())
0 client connects that finished
1 server accepts (SSL_accept())
0 server renegotiates (SSL_accept())
1 server accepts that finished
0 session cache hits
0 session cache misses
0 session cache timeouts
0 callback cache hits
0 cache full overflows (128 allowed)
---
no client certificate available
To customize the OpenSSL server to use specific ciphers and algorithms you can add some of these command line arguments:
-ssl2, -ssl3, -tls1, -tls1_1, -tls1_2, -no_ssl2, -no_ssl3, -no_tls1, -no_tls1_1, -no_tls1_2
These options require or disable the use of the specified SSL or TLS protocols. By default the initial handshake uses a version-flexible method which will negotiate the highest mutually supported protocol version.
-named_curve curve
Specifies the elliptic curve to use. NOTE: this is single curve, not a list. For a list of all possible curves, use:
$ openssl ecparam -list_curves
-cipher cipherlist
This allows the cipher list used by the server to be modified. When the client sends a list of supported ciphers the first client cipher also included in the server list is used. Because the client specifies the preference order, the order of the server cipherlist irrelevant. To see the full list of supported ciphers use this command:
$ openssl ciphers