TLS experiments with openssl-s_client – TLS Handshake Protocol Revisited
13.6.3 TLS experiments with openssl-s_client
So, what kind of experiments can we do using openssl-s˙client to better understand how TLS works under the hood? Well, we could start by looking into the protocol messages of an actual TLS session. As an example, we could perform a TLS handshake with the Packt web server:
# openssl s_client -connect packtpub.com:443 -msg
The output corresponding to the preceding command gives a detailed view of the TLS handshake, including all TLS messages, their length in bytes, and their hex dumps:
>>> TLS 1.0, RecordHeader [length 0005]
16 03 01 01 35
>>> TLS 1.3, Handshake [length 0135], ClientHello
01 00 01 31 03 03 1c 29 cd 91 3f dc 5e 9e 6b 4f
— snip —
<<< TLS 1.2, RecordHeader [length 0005]
16 03 03 00 7a
<<< TLS 1.3, Handshake [length 007a], ServerHello
02 00 00 76 03 03 5f f0 44 0e 05 69 25 78 14 cb
— snip —
<<< TLS 1.2, RecordHeader [length 0005]
14 03 03 00 01
<<< TLS 1.2, RecordHeader [length 0005]
17 03 03 09 f4
<<< TLS 1.3, InnerContent [length 0001]
16
<<< TLS 1.3, Handshake [length 000a], EncryptedExtensions
08 00 00 06 00 04 00 00 00 00
<<< TLS 1.3, Handshake [length 0956], Certificate
0b 00 09 52 00 00 09 4e 00 05 73 30 82 05 6f 30
— snip —
depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
verify return:1
depth=1 C = US, O = “Cloudflare, Inc.”, CN = Cloudflare Inc ECC CA-3
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = “Cloudflare, Inc.”, CN = packtpub.com
verify return:1
<<< TLS 1.3, \index{OpenSSL client!TLS experiments}Handshake [length 004f], CertificateVerify
0f 00 00 4b 04 03 00 47 30 45 02 20 7f f9 da ed
— snip —
<<< TLS 1.3, Handshake [length 0034], Finished
14 00 00 30 2a 64 1c 8f e0 f9 f1 ab 2b 3d 7b e8
— snip —
>>> TLS 1.2, RecordHeader [length 0005]
14 03 03 00 01
>>> TLS 1.3, ChangeCipherSpec [length 0001]
01
>>> TLS 1.2, RecordHeader [length 0005]
17 03 03 00 45
>>> TLS 1.2, InnerContent [length 0001]
16
>>> TLS 1.3, Handshake [length 0034], Finished
14 00 00 30 c1 23 05 61 7b 03 8e c9 d9 b5 1e de
— snip —
Note that the TLS messages sent by the client are denoted by ¿¿¿ and the TLS messages sent by the server by ¡¡¡. In addition, the command’s output includes the certificate presented by the server and the cryptographic settings of the TLS session:
Certificate chain
0 s:C = US, ST = California, L = San Francisco, O = “Cloudflare, Inc.”, CN = packtpub.com
i:C = US, O = “Cloudflare, Inc.”, CN = Cloudflare Inc ECC CA-3
a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA256
v:NotBefore: Apr 7 00:00:00 2023 GMT; NotAfter: Apr 6 23:59:59 2024 GMT
1 s:C = US, O = “Cloudflare, Inc.”, CN = Cloudflare Inc ECC CA-3
i:C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
a:PKEY: id-ecPublicKey, 256 (bit); sigalg: RSA-SHA256
v:NotBefore: Jan 27 12:48:08 2020 GMT; NotAfter: Dec 31 23:59:59 2024 GMT
—
Server certificate
—–BEGIN CERTIFICATE—–
MIIFbzCCBRWgAwIBAgIQCjUceIvorTtWOHsotymexDAKBggqhkjOPQQDAjBKMQsw
— snip —
—–END CERTIFICATE—–
subject=C = US, ST = California, L = San Francisco, O = “Cloudflare, Inc.”,
CN = packtpub.com
issuer=C = US, O = “Cloudflare, Inc.”, CN = Cloudflare Inc ECC CA-3
—
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
—
SSL handshake has read 2686 bytes and written 394 bytes
Verification: OK
—
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
— snip —
Next, we might want to know what the ClientHello message sent by openssl-s˙client to the Packt web server actually looks like. This can be done using the -trace option:
# openssl s_client -connect packtpub.com:443 -trace
The corresponding output contains detailed information about ClientHello and the values of its parameters:
Sent Record
Header:
Version = TLS 1.0 (0x301)
Content Type = Handshake (22)
Length = 309
ClientHello, Length=305
client_version=0x303 (TLS 1.2)
Random:
gmt_unix_time=0xF96120B2
random_bytes (len=28): 2C2985BC3763DE — snip —
session_id (len=32): 16BB585F1BAA7C — snip —
cipher_suites (len=62)
{0x13, 0x02} TLS_AES_256_GCM_SHA384
{0x13, 0x03} TLS_CHACHA20_POLY1305_SHA256
{0x13, 0x01} TLS_AES_128_GCM_SHA256
— snip —
compression_methods (len=1)
No Compression (0x00)
extensions, length = 170
extension_type=server_name(0), length=17
0000 – 00 0f 00 00 0c 70 61 63-6b 74 70 75 62 2e 63 …..packtpub.c
000f – 6f 6d om
extension_type=ec_point_formats(11), length=4
uncompressed (0)
ansiX962_compressed_prime (1)
ansiX962_compressed_char2 (2)
extension_type=supported_groups(10), length=22
ecdh_x25519 (29)
secp256r1 (P-256) (23)
ecdh_x448 (30)
— snip —
extension_type=session_ticket(35), length=0
extension_type=encrypt_then_mac(22), length=0
extension_type=extended_master_secret(23), length=0
extension_type=signature_algorithms(13), length=42
ecdsa_secp256r1_sha256 (0x0403)
ecdsa_secp384r1_sha384 (0x0503)
ecdsa_secp521r1_sha512 (0x0603)
— snip —
\index{OpenSSL client!TLS experiments}extension_type=supported_versions(43), length=5
TLS 1.3 (772)
TLS 1.2 (771)
extension_type=psk_key_exchange_modes(45), length=2
psk_dhe_ke (1)
extension_type=key_share(51), length=38
NamedGroup: ecdh_x25519 (29)
key_exchange: (len=32): F00D50A5796047 — snip —
Now let’s take a look at the states of the OpenSSL client state machine as the TLS connection to the Packt web server is being established. We can do this by executing the following command:
# openssl s_client -connect packtpub.com:443 -state
In the corresponding output, we can see that openssl-s˙client starts by sending ClientHello. After that, it transitions through a sequence of states where it receives the ServerHello, EncryptedExtensions, Certificate, CertificateVerify, and Finished messages from the TLS server. As a final step, the client sends its Finished message, thereby completing the TLS handshake:
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
SSL_connect:TLSv1.3 read encrypted extensions
— snip —
SSL_connect:SSLv3/TLS read server certificate
SSL_connect:TLSv1.3 read server certificate verify
SSL_connect:SSLv3/TLS read finished
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
Moreover, we can examine the details of TLS extensions that the Packt web server transmitted using the following command:
# openssl s_client -connect packtpub.com:443 -tlsextdebug
The corresponding output lists all TLS extensions sent by the server as well as their values in hexadecimal representation:
TLS server extension “key share” (id=51), len=36
0000 – 00 1d 00 20 08 3c 18 21-98 94 30 17 a1 37 00 8f …
.<.!..0..7..
0010 – c4 07 6f 93 69 46 3a 94-bc 08 f3 82 61 82 ac a7 ..o.iF:…..a…
0020 – 73 bb 1e 3f s..?
TLS server extension “supported versions” (id=43), len=2
0000 – 03 04 ..
TLS server extension “server name” (id=0), len=0
— snip —
Finally, let’s examine the OCSP response for the digital certificate that the Packt web server has presented to openssl-s˙client. We can do this using the following command:
# openssl s_client -connect packtpub.com:443 -status
The corresponding output shows the OCSP response status, the status of the certificate when the response was generated, and other details:
— snip —
OCSP response:
======================================
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
Version: 1 (0x0)
Responder Id: A5CE37EAEBB0750E946788B445FAD9241087961F
Produced At: Apr 29 20:42:45 2023 GMT
Responses:
Certificate ID:
Hash Algorithm: sha1
Issuer Name Hash: 12D78B402C356206FA827F8ED8922411B4ACF504
Issuer Key Hash: A5CE37EAEBB0750E946788B445FAD9241087961F
Serial Number: 0A351C788BE8AD3B56387B28B7299EC4
Cert Status: good
This Update: Apr 29 20:27:01 2023 GMT
Next Update: May 6 19:42:01 2023 GMT
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:44:02:20:17:4b:4e:d7:99:e4:ec:b3:ea:75:5a:33:bc:7b:
c7:da:69:30:03:20:99:48:b5:f6:e3:78:a4:dd:ff:78:04:3a:
02:20:6f:0a:b8:07:b0:40:9e:2c:16:96:6f:de:11:73:1a:fb:
3d:74:d4:9a:77:61:ae:8e:ac:8d:42:fb:f1:d4:e5:d7
======================================
— snip —
We encourage you to explore further options of the openssl-s˙client tool and experiment with other hosts. You can also adjust the list of signature algorithms or curves that the openssl-s˙client supports and observe how the TLS server responds, especially if it does not support any of the algorithms from that list.