Use OpenSSL to simulate TLS 1.3 “Session Resumption”

Thanks the great help from OpenSSL community, I finally can simulate an TLS 1.3 “Session Resumption”. The Operation System I used is OmniOS, and OpenSSL version is 1.1.1k, but I think the methods here can also be applied to other platforms:

(1) Open one terminal to launch tcpdump to capture TLS packets:

$ pfexec /opt/ooce/sbin/tcpdump -w tls.pcap port 443

(2) Open another terminal to initiate the first TLS 1.3 session:

$ openssl s_client -connect cloudflare.com:443 -tls1_3 -sess_out sess.pem -keylogfile keys1.txt
......

Once the connection is established, input “GET /” to trigger TLS 1.3 Server to send “New Session Ticket” message, and this will be saved in sess.pem file.

(3) Initiate another TLS 1.3 session to reuse the saved “Session Ticket“:

$ echo | openssl s_client -connect cloudflare.com:443 -tls1_3 -sess_in sess.pem -keylogfile keys2.txt

(4) Stop the tcpdump process.

(5) Combine two keys file into one:

$ cat keys1.txt keys2.txt > keys.txt

Then the keys.txt can be used to decrypt the two TLS 1.3 sessions (refer Use Wireshark to decrypt TLS flows).

tshark can’t process macOS’s pcapng file well

Wireshark‘s tshark program can’t process macOS‘s pcapng file well. E.g.:

$ sudo tcpdump -w foo.pcapng
Password:
tcpdump: data link type PKTAP
tcpdump: listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
^C24 packets captured
27 packets received by filter
0 packets dropped by kernel

Use tshark to read and write the generated foo.pcapng:

$ tshark -r foo.pcapng -w bar.pcapng
tshark: An error occurred while writing to the file "bar.pcapng": Internal error.

I also met following error before:

$ tshark -r apsd-107.pcapng -w foo.pcapng
tshark: The capture file being read can't be written as a "pcapng" file.

macOS has its own bespoke libpcap and tcpdump, so if the pcapng file is generated by tcpdump, using tcpdump itself to process pcapng file seems the only choice.

A workaround is if you don’t care about losing information, you can use wireshark to convert the pcapng file to pcap first:

Process large pcap file

To process large pcap file, usually it is better to split it into small chunks first, then process every chunk in parallel. I implement a simple shell script to do it:

#!/bin/sh

input_pcap=input.pcap
output_pcap=./pcap/frag.pcap
spilt_size=1000
output_index=1
loop_count=10
exit_flag=0

command() {
    echo "$1" "$2" > log"$2"
}

tcpdump -r ${input_pcap} -w ${output_pcap} -C ${spilt_size}

command ${output_pcap}

while :
do
    loop_index=0
    while test ${loop_index} -lt ${loop_count}
    do
        if test -e ${output_pcap}${output_index}
        then
            command ${output_pcap} ${output_index} &
            output_index=$((output_index + 1))
            loop_index=$((loop_index + 1))
        else
            exit_flag=1
            break
        fi
    done
    wait

    if test ${exit_flag} -eq 1
    then
        exit 0
    fi
done

First of all, split input pcap file into 1GB chunks. Then launch 10 processes to crunch data (in above example, just simple output). Definitely you can customize it.

BTW, the code can be downloaded here.

Pcap develop package is needed in compiling tcpdump

On a fresh VoidLinux, I compiled tcpdump source code and met following errors during configuration:

# ../configure CFLAGS='-g -O0'
......
checking for local pcap library... not found
checking for pkg-config... no
checking for pcap-config... no
checking for main in -lpcap... no
configure: error: see the INSTALL doc for more info

I was sure libpcap was already installed. After some investigating, I found the root cause was libpcap-devel was needed:

# xbps-install -Suv libpcap-devel
......

Then the issue was fixed.

The difference of loopback packets on Linux and OpenBSD

Capture the packets on loopback network card on Linux:

# tcpdump -i lo -w lo.pcap port 33333
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
......

Download it onto Windows and use wireshark to analyze it:

1

We can see every packet conforms to standard ethernet format.

Capture lookback packets on OpenBSD:

# tcpdump -i lo0 -w lo.pcap port 33333
tcpdump: listening on lo0, link-type LOOP
......

Also download it onto Windows and open it with wireshark:

2

The wireshark just recognizes the packet as “Raw IP” format, but can’t show details.

After referring discussion in Wireshark mailing list, I know it is related to network link-layer header type0x0C stands for “Raw IP”:

3

I modified the 0x0C to 0x6C, which means “OpenBSD loopback”:

4

Now the packets can be decoded successfully:

5

P.S., I also started a discussion about this issue in mailing list.

Update: I write a script to do this conversion.