Home Books Training Newsletter Resources
Sign up Log in
book cover

OpenSSL Cookbook  3rd Edition

The definitive guide to using the OpenSSL command line for configuration and testing. Topics covered in this book include key and certificate management, server configuration, a step by step guide to creating a private CA, and testing of online services. Written by Ivan Ristić.


2.2 Connecting to TLS Services

OpenSSL comes with a client tool that you can use to connect to a secure server. The tool is similar to telnet or nc in the sense that it handles the encryption aspect but allows you to fully control the layer that comes next.

To connect to a server, you need to supply a hostname and a port. For example:

$ openssl s_client -crlf \
-connect www.feistyduck.com:443 \
-servername www.feistyduck.com

Notice that you had to supply the hostname twice. The -connect switch is used to establish the TCP connection, but -servername is used to specify the hostname sent at the TLS level. Starting with OpenSSL 1.1.1, the s_client tool automatically configures the latter. You’ll still need to use the -servername switch if (1) you’re using an earlier version of OpenSSL, (2) you’re connecting to an IP address, or (3) the TLS host needs to be different. Use the -noservername switch to avoid sending hostname information in the TLS handshake.

Once you type the command, you’re going to see a lot of diagnostic output (more about that in a moment) followed by an opportunity to type whatever you want. Because we’re talking to an HTTP server, the most sensible thing to do is to submit an HTTP request. In the following example, I use a HEAD request because it instructs the server not to send the response body:

HEAD / HTTP/1.0
Host: www.feistyduck.com

HTTP/1.1 200 OK
Date: Mon, 24 Aug 2020 16:38:02 GMT
Server: Apache
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Cache-control: no-cache, must-revalidate
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Set-Cookie: JSESSIONID=882D48C8842EA82E3F3AFACC4425A695; Path=/; Secure; HttpOnly
Connection: close

read:errno=0
🛈︎
Note

If, when connecting to a remote server in this way, the TLS handshake completes but you’re getting disconnected after the first HTTP request line, check that you’ve specified the -crlf switch on the command line. This switch ensures that the newlines you type are translated to a carriage return plus line feed combo to ensure string HTTP compliance.

Now we know that the TLS communication layer is working: we got through to the HTTP server, submitted a request, and received a response back. Let’s go back to the diagnostic output. The first couple of lines will show the information about the server certificate:

CONNECTED(00000003)
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = www.feistyduck.com
verify return:1

The next section in the output lists all the certificates presented by the server in the order in which they were delivered:

Certificate chain
 0 s:OU = Domain Control Validated, OU = PositiveSSL, CN = www.feistyduck.com
   i:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
 1 s:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
   i:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority

For each certificate, the first line shows the subject and the second line shows the issuer information.

This part is very useful when you need to see exactly what certificates are sent; browser certificate viewers typically display reconstructed certificate chains that can be almost completely different from the presented ones. To determine if the chain is nominally correct, you might wish to verify that the subjects and issuers match. You start with the leaf (web server) certificate at the top, and then you go down the list, matching the issuer of the current certificate to the subject of the next. The last issuer you see can point to some root certificate that is not in the chain, or—if the self-signed root is included—it can point to itself.

The next item in the output is the server certificate; it’s a lot of text, but I’m going to remove most of it for brevity:

Server certificate
-----BEGIN CERTIFICATE-----
MIIFUzCCBDugAwIBAgIRAPR/CbWZEksfCIRqxNcesPIwDQYJKoZIhvcNAQELBQAw
gZAxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTYwNAYD
[...]
L1MPjFiB5pyvf9jDBxv8TmG4Q6TnDDhw2t2Qil6lhsPAMZ9odP22W3uaLE1y7aB6
zbQXjVsc3E1THfFZWRzDPsU4fN/1iGlbrcAWa2sFfhJXrCDfAowFJ8A1n9jMiNEG
WfQfGgA2ar2xUtsqA7Re6XlXOlwBPuQ=
-----END CERTIFICATE-----
subject=OU = Domain Control Validated, OU = PositiveSSL, CN = www.feistyduck.com
issuer=C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
🛈︎
Note

By default, the s_client tool shows just the leaf certificate. If you wish to obtain the entire chain, use the -showcerts switch.

If you want to have a better look at the certificate, you’ll first need to copy it from the output and store it in a separate file. I’ll discuss how to do that in the next section.

The following is a lot of information about the TLS connection, most of which is self-explanatory:

---
No client certificate CA names sent
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3624 bytes and written 446 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 73FC4831AF053C46291C2D8CC90BF7F1D5B12178E488FBB4DC49A302B870E8DE
    Session-ID-ctx: 
    Master-Key: E60DA9C6669C2C7DFFD8A3AD2CD17405CC0B9B69C4184469D779A9BA19A6FD4B3D602A023BD8B23F8D9A9FF2CBB5DDF7
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 31 95 ff d0 4c 42 dd d0-24 64 03 5c fc 55 1d 17   1...LB..$d.\.U..
    0010 - 05 c4 61 1f b8 ba fd fe-f7 6c 6c e9 ae a2 49 3f   ..a......ll...I?
    0020 - c5 19 d4 e9 69 a5 79 d5-af 13 26 c8 2c e7 f0 01   ....i.y...&.,...
    0030 - 3b 42 d8 c0 29 4c fa 7e-88 aa 8d c8 0b 30 96 ce   ;B..)L.~.....0..
    0040 - 43 40 2c 09 0b aa 2e d5-61 e3 34 7a a3 78 2f 93   C@,.....a.4z.x/.
    0050 - 67 5a b9 96 78 f5 e7 69-b7 b6 2d 8c 00 8f 04 ab   gZ..x..i..-.....
    0060 - 42 1d 26 db 92 ec 2d 2f-ba 1c c6 61 87 64 0e d5   B.&...-/...a.d..
    0070 - f2 ce 20 d0 07 a5 e2 6d-c6 45 50 c2 45 14 a8 ee   .. ....m.EP.E...
    0080 - 59 7c 63 e1 d7 d8 b0 b6-76 21 d2 13 97 eb bd 97   Y|c.....v!......
    0090 - a1 d3 e8 5c 61 da da 2d-85 80 db ae de 56 97 e1   ...\a..-.....V..
    00a0 - e8 7a 25 f9 bf cf b6 18-48 5b b0 03 a5 e6 ec 0a   .z%.....H[......
    00b0 - bf 2f 0d 1a 6b ae 79 10-80 9c cf 4d 66 8f 90 43   ./..k.y....Mf..C
    00c0 - 69 54 32 be 0c 89 57 e8-6d 81 b5 3e 5b cb 5e 8e   iT2...W.m..>[.^.

    Start Time: 1598288068
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no

The most important information here is the protocol version (TLS 1.2) and cipher suite used (ECDHE-RSA-AES128-GCM-SHA256). Do note that protocol information appears in two locations, which is potentially confusing when different versions are shown. The first location describes the minimum protocol requirement with the negotiated cipher suite, while the second location points to the actual protocol version currently being negotiated. You will see a difference in protocol versions with some older cipher suites—for example:

New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA

The selected suite could be used with SSL 3.0, but it’s used with TLS 1.2 on this connection:

    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES128-SHAs

You can also determine that the server has issued to you a session ID and a TLS session ticket (a way of resuming sessions without having the server maintain state) and that secure renegotiation is supported.

🛈︎
Note

If you’re connecting to a TLS 1.3 server, the output may be different. Sometimes you will observe less information initially, with additional information arriving later in bursts. This behavior depends on the implementation and reflects the changes in TLS 1.3, which transmits session tickets as separate protocol messages that are sent only after the handshake is complete. Additionally, multiple session tickets are usually sent on the same connection.

< Prev
^ Table of Contents
Next >
@feistyduck

Books

  • Bulletproof TLS and PKI
  • ModSecurity Handbook
  • OpenSSL Cookbook

Training

  • Practical TLS and PKI

Resources

  • Newsletter
  • SSL/TLS and PKI History
  • Archived Books
  • Bulletproof TLS Guide

Company

  • Support
  • Website Terms of Use
  • Terms and Conditions
  • Privacy Policy
  • About Us