mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Merge pull request #6727 from bigbrett/tls13-sniffer-keylogfile
TLS 1.3 sniffer keylog file support
This commit is contained in:
@ -42,7 +42,7 @@ run_test() { # Usage: run_test <cipher> [serverArgs [clientArgs]]
|
||||
}
|
||||
|
||||
run_sequence() {
|
||||
if [ "$1" == "tls13-dh" ] || [ "$1" == "tls13-ecc" ]; then # TLS v1.3
|
||||
if [ "$1" == "tls13-dh" ] || [ "$1" == "tls13-ecc" ] || [ "$1" == "tls13-keylog" ]; then # TLS v1.3
|
||||
run_test "TLS13-AES128-GCM-SHA256" "-v 4" "-v 4"
|
||||
run_test "TLS13-AES256-GCM-SHA384" "-v 4" "-v 4"
|
||||
run_test "TLS13-CHACHA20-POLY1305-SHA256" "-v 4" "-v 4"
|
||||
@ -86,6 +86,10 @@ run_capture() {
|
||||
./configure "${config_flags[@]}" 1>/dev/null || exit $?
|
||||
make 1>/dev/null || exit $?
|
||||
|
||||
if [[ "$1" == "tls12-keylog" || "$1" == "tls13-keylog" ]]; then
|
||||
rm -f ./sslkeylog.log
|
||||
fi
|
||||
|
||||
echo "starting capture"
|
||||
tcpdump -i lo -n port 11111 -w ./scripts/sniffer-${1}.pcap -U &
|
||||
tcpdump_pid=$!
|
||||
@ -93,13 +97,14 @@ run_capture() {
|
||||
sleep 1
|
||||
kill -15 $tcpdump_pid; tcpdump_pid=0
|
||||
|
||||
if [ "$1" == "tls12-keylog" ]; then
|
||||
if [[ "$1" == "tls12-keylog" || "$1" == "tls13-keylog" ]]; then
|
||||
cp ./sslkeylog.log ./scripts/sniffer-${1}.sslkeylog
|
||||
fi
|
||||
}
|
||||
|
||||
run_capture "tls12" ""
|
||||
run_capture "tls12-keylog" "--enable-enc-then-mac=no --enable-keylog-export CFLAGS='-Wno-cpp -DWOLFSSL_SNIFFER_KEYLOGFILE'"
|
||||
run_capture "tls13-keylog" "--enable-keylog-export CFLAGS='-Wno-cpp -DWOLFSSL_SNIFFER_KEYLOGFILE'"
|
||||
run_capture "tls13-ecc" ""
|
||||
run_capture "tls13-ecc-resume" "--enable-session-ticket"
|
||||
run_capture "tls13-dh" "--disable-ecc"
|
||||
|
@ -72,7 +72,7 @@ RESULT=0
|
||||
# TLS v1.2 Static RSA Test
|
||||
if test $RESULT -eq 0 && test $has_rsa == yes && test $has_tlsv12 == yes && test $has_static_rsa == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-static-rsa.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-static-rsa.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-static-rsa.pcap -key ./certs/server-key.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
@ -82,45 +82,53 @@ fi
|
||||
# TLS v1.2 Static RSA Test (IPv6)
|
||||
if test $RESULT -eq 0 && test $has_rsa == yes && test $has_tlsv12 == yes && test $has_static_rsa == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-ipv6.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-ipv6.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-ipv6.pcap -key ./certs/server-key.pem -server ::1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "\nsnifftest (ipv6) failed\n" && exit 1
|
||||
fi
|
||||
|
||||
# TLS v1.2 sniffer keylog file test: runs sniffer on pcap and associated keylog file and compares decrypted traffic with known good output.
|
||||
# TLS v1.2 and v1.3 sniffer keylog file test: runs sniffer on pcap and associated keylog file and compares decrypted traffic with known good output.
|
||||
# To regenerate the known good output, run `scripts/sniffer-gen.sh` to regenerate the pcap and keylog file, then run the sniffer on it
|
||||
# with the same arguments as in the test below, but redirect output to `./scripts/sniffer-tls12-keylog.out`.
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_keylog == yes
|
||||
if test $RESULT -eq 0 && test $has_keylog == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls12-keylog.pcap...\n"
|
||||
for tlsver in tls12 tls13
|
||||
do
|
||||
# skip tls versions we don't have compiled-in support for
|
||||
[[ $tlsver == "tls12" && $has_tlsv12 == "no" ]] && continue
|
||||
[[ $tlsver == "tls13" && $has_tlsv13 == "no" ]] && continue
|
||||
|
||||
TMPFILE=$(mktemp)
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "\nsnifftest keylog test failed: unable to create tmpfile\n" && rm $TMPFILE && exit 1
|
||||
echo -e "\nStarting snifftest on sniffer-$tlsver-keylog.pcap...\n"
|
||||
|
||||
./sslSniffer/sslSnifferTest/snifftest \
|
||||
-pcap scripts/sniffer-tls12-keylog.pcap \
|
||||
-keylogfile scripts/sniffer-tls12-keylog.sslkeylog \
|
||||
-server 127.0.0.1 -port 11111 > $TMPFILE
|
||||
TMPFILE=$(mktemp)
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "\n$tlsver snifftest keylog test failed: unable to create tmpfile\n" && rm $TMPFILE && exit 1
|
||||
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "\nsnifftest keylog test failed: snifftest returned $RESULT\n" && rm $TMPFILE && exit 1
|
||||
./sslSniffer/sslSnifferTest/snifftest \
|
||||
-pcap scripts/sniffer-$tlsver-keylog.pcap \
|
||||
-keylogfile scripts/sniffer-$tlsver-keylog.sslkeylog \
|
||||
-server 127.0.0.1 -port 11111 | tee $TMPFILE
|
||||
|
||||
# sed '1d' strips out first line, which contains wolfSSL version
|
||||
sed '1d' $TMPFILE | diff - <(sed '1d' scripts/sniffer-tls12-keylog.out)
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "\n$tlsver snifftest keylog test failed: snifftest returned $RESULT\n" && rm $TMPFILE && exit 1
|
||||
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "\nsnifftest keylog test failed: snifftest diff returned $RESULT\n" && rm $TMPFILE && exit 1
|
||||
# use grep to only compare against decrypted output
|
||||
SEARCH_STRING="SSL App Data"
|
||||
grep "$SEARCH_STRING" $TMPFILE | diff - <(grep "$SEARCH_STRING" scripts/sniffer-$tlsver-keylog.out)
|
||||
|
||||
rm $TMPFILE
|
||||
RESULT=$?
|
||||
[ $RESULT -ne 0 ] && echo -e "\n$tlsver snifftest keylog test failed: snifftest diff returned $RESULT\n" && rm $TMPFILE && exit 1
|
||||
|
||||
rm $TMPFILE
|
||||
done
|
||||
fi
|
||||
|
||||
# TLS v1.3 sniffer test ECC
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_ecc == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls13-ecc.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-tls13-ecc.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-tls13-ecc.pcap -key ./certs/statickeys/ecc-secp256r1.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
@ -130,7 +138,7 @@ fi
|
||||
# TLS v1.3 sniffer test DH
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_dh == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls13-dh.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-tls13-dh.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-tls13-dh.pcap -key ./certs/statickeys/dh-ffdhe2048.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
@ -140,7 +148,7 @@ fi
|
||||
# TLS v1.3 sniffer test X25519
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_x25519 == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls13-x25519.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-tls13-x25519.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-tls13-x25519.pcap -key ./certs/statickeys/x25519.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
@ -150,7 +158,7 @@ fi
|
||||
# TLS v1.3 sniffer test ECC resumption
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_ecc == yes && test $session_ticket == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls13-ecc-resume.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-tls13-ecc-resume.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-tls13-ecc-resume.pcap -key ./certs/statickeys/ecc-secp256r1.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
@ -160,7 +168,7 @@ fi
|
||||
# TLS v1.3 sniffer test DH
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_dh == yes && test $session_ticket == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls13-dh-resume.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-tls13-dh-resume.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-tls13-dh-resume.pcap -key ./certs/statickeys/dh-ffdhe2048.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
@ -170,7 +178,7 @@ fi
|
||||
# TLS v1.3 sniffer test X25519
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_x25519 == yes && test $session_ticket == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls13-x25519-resume.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-tls13-x25519-resume.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-tls13-x25519-resume.pcap -key ./certs/statickeys/x25519.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
@ -180,7 +188,7 @@ fi
|
||||
# TLS v1.3 sniffer test hello_retry_request (HRR) with ECDHE
|
||||
if test $RESULT -eq 0 && test $has_tlsv13 == yes && test $has_ecc == yes
|
||||
then
|
||||
echo -e "\nStaring snifftest on sniffer-tls13-hrr.pcap...\n"
|
||||
echo -e "\nStarting snifftest on sniffer-tls13-hrr.pcap...\n"
|
||||
./sslSniffer/sslSnifferTest/snifftest -pcap ./scripts/sniffer-tls13-hrr.pcap -key ./certs/statickeys/ecc-secp256r1.pem -server 127.0.0.1 -port 11111
|
||||
|
||||
RESULT=$?
|
||||
|
Binary file not shown.
@ -1,12 +1,4 @@
|
||||
CLIENT_RANDOM 3827fef5d4172f3753d81661dbc228b41adcb2357e04e493f8d9d4d4a85777d3 5240740265eaa6a8622805728bf53fd88b546b1523e4b9c3d4b6573471bc081ce9f074520df99873c0c447d3a37ebdc6
|
||||
CLIENT_RANDOM 3827fef5d4172f3753d81661dbc228b41adcb2357e04e493f8d9d4d4a85777d3 5240740265eaa6a8622805728bf53fd88b546b1523e4b9c3d4b6573471bc081ce9f074520df99873c0c447d3a37ebdc6
|
||||
CLIENT_RANDOM 8d793a1160661700dc686746be0e77a01dcf94472971bfbb517c6d7d179b7bcd ac612c7b9292ad6bc5304176b9dcde81ee488b6adb63bb6917cbf38a0775e9e334766839e091506972450e77ba6ce977
|
||||
CLIENT_RANDOM 8d793a1160661700dc686746be0e77a01dcf94472971bfbb517c6d7d179b7bcd ac612c7b9292ad6bc5304176b9dcde81ee488b6adb63bb6917cbf38a0775e9e334766839e091506972450e77ba6ce977
|
||||
CLIENT_RANDOM 4a1d3695145e5136a2914756962f848f033b62d3a9b714f7e659ae3f133d2527 118442e0edd05696d1566eb73693a9a1316d24ac62e024f92e685c540eaec31a463e19091d45b63cfc8539d3bd11915b
|
||||
CLIENT_RANDOM 4a1d3695145e5136a2914756962f848f033b62d3a9b714f7e659ae3f133d2527 118442e0edd05696d1566eb73693a9a1316d24ac62e024f92e685c540eaec31a463e19091d45b63cfc8539d3bd11915b
|
||||
CLIENT_RANDOM 307abe19ea84d9b45621df5b89fee8d2f9ac66eb4303cf9303cf6e957ad1d75d dfb9bb0d29579a0b2f35be65982954f33268c30ea8709985a45c95633c1c6e94cbfdebe625bda975572921b4462d5153
|
||||
CLIENT_RANDOM 307abe19ea84d9b45621df5b89fee8d2f9ac66eb4303cf9303cf6e957ad1d75d dfb9bb0d29579a0b2f35be65982954f33268c30ea8709985a45c95633c1c6e94cbfdebe625bda975572921b4462d5153
|
||||
CLIENT_RANDOM 41ad4bceb3b900ffbc77f9b0c67d69a62f2b1d490f91b2af496cf6e78371900d 9752ea66a193ac04e4a20aca3c7160faa2637efb927d00c2a2d90b77e2e7875a760ee76f9ce509e549f8303625a2fd59
|
||||
CLIENT_RANDOM 41ad4bceb3b900ffbc77f9b0c67d69a62f2b1d490f91b2af496cf6e78371900d 9752ea66a193ac04e4a20aca3c7160faa2637efb927d00c2a2d90b77e2e7875a760ee76f9ce509e549f8303625a2fd59
|
||||
CLIENT_RANDOM 596ffcdec477ac0b24e0958ecd7c1fc7cc5b37337bac90803b864e3edbad8780 2f86705d0c4fb7e92c7cb1ef2f104955724d5a0b5abd18478d39c1dd96222b4462e4382982bec26e9a231ec970c2d509
|
||||
CLIENT_RANDOM 596ffcdec477ac0b24e0958ecd7c1fc7cc5b37337bac90803b864e3edbad8780 2f86705d0c4fb7e92c7cb1ef2f104955724d5a0b5abd18478d39c1dd96222b4462e4382982bec26e9a231ec970c2d509
|
||||
CLIENT_RANDOM 10b90b535c84a76d92d655789c6ae562c02448f6b1ad95eecf2b619a61cdff32 dbb3e0d1968e59f16259f5c86f10df10156d2002277984c19fd6ef187a98534d01df0cc617f6e4fe644bf45bb5c371e8
|
||||
CLIENT_RANDOM 10b90b535c84a76d92d655789c6ae562c02448f6b1ad95eecf2b619a61cdff32 dbb3e0d1968e59f16259f5c86f10df10156d2002277984c19fd6ef187a98534d01df0cc617f6e4fe644bf45bb5c371e8
|
||||
CLIENT_RANDOM 0b524527d36bef5e8537e8a728ddea96b3587c84329c0f1ff524f20589e08ee4 05aae5a9ea9cc56f61801189e867a00ca780e578389ba79a287da9e7c86198061fbed81b325b754091b7b96c37182ee9
|
||||
CLIENT_RANDOM 0b524527d36bef5e8537e8a728ddea96b3587c84329c0f1ff524f20589e08ee4 05aae5a9ea9cc56f61801189e867a00ca780e578389ba79a287da9e7c86198061fbed81b325b754091b7b96c37182ee9
|
||||
|
9
scripts/sniffer-tls13-keylog.out
Normal file
9
scripts/sniffer-tls13-keylog.out
Normal file
@ -0,0 +1,9 @@
|
||||
snifftest 5.6.3
|
||||
sniffer features: key_callback tls_v13 tls_v12 static_ephemeral sni extended_master rsa dh ecc rsa_static dh_static ssl_keylog_file
|
||||
|
||||
SSL App Data(22:14):hello wolfssl!
|
||||
SSL App Data(24:22):I hear you fa shizzle!
|
||||
SSL App Data(50:14):hello wolfssl!
|
||||
SSL App Data(51:22):I hear you fa shizzle!
|
||||
SSL App Data(77:14):hello wolfssl!
|
||||
SSL App Data(78:22):I hear you fa shizzle!
|
BIN
scripts/sniffer-tls13-keylog.pcap
Normal file
BIN
scripts/sniffer-tls13-keylog.pcap
Normal file
Binary file not shown.
24
scripts/sniffer-tls13-keylog.sslkeylog
Normal file
24
scripts/sniffer-tls13-keylog.sslkeylog
Normal file
@ -0,0 +1,24 @@
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 d7e90625f07d9ca3c09862eb23badbcfeadee90341564f0e08ccb6dca4169fa0
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 d7e90625f07d9ca3c09862eb23badbcfeadee90341564f0e08ccb6dca4169fa0
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 6887aa8833f3c6e9b4d211e62f105100f1ec30a0e66e8bec08349388bbb1ea14
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 6887aa8833f3c6e9b4d211e62f105100f1ec30a0e66e8bec08349388bbb1ea14
|
||||
CLIENT_TRAFFIC_SECRET_0 d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 45d90c7debf4fa6123f86a229a6beacc3e4f6ccfa2fa9144f8822a31d1cd6887
|
||||
SERVER_TRAFFIC_SECRET_0 d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 5341d729eb66e2f098adc7b7fbf38efddf58cfd3946cfa45d5e43923d6d8d6e7
|
||||
CLIENT_TRAFFIC_SECRET_0 d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 45d90c7debf4fa6123f86a229a6beacc3e4f6ccfa2fa9144f8822a31d1cd6887
|
||||
SERVER_TRAFFIC_SECRET_0 d99819b631844f268f7179381e8003976d100e553ff7d55c4c79919d09231009 5341d729eb66e2f098adc7b7fbf38efddf58cfd3946cfa45d5e43923d6d8d6e7
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 363cd576478d733f04895c0aff54f9393d542485548f29be71e43ea89c7ebbc7c527735ca97500a9bcc975e78c9fb59e
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 217e25b3934b5fcb9d7f78c26c2a4a3de048d3bf6defed80901971c69c9cf805a71a3b916e8c0d1bfc274b7e45231f00
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 363cd576478d733f04895c0aff54f9393d542485548f29be71e43ea89c7ebbc7c527735ca97500a9bcc975e78c9fb59e
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 217e25b3934b5fcb9d7f78c26c2a4a3de048d3bf6defed80901971c69c9cf805a71a3b916e8c0d1bfc274b7e45231f00
|
||||
CLIENT_TRAFFIC_SECRET_0 f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 246b412ade0a21f52fd763996e07e55a12927bf342f00f26eea660803d79d31c9ccfbaca010ea2bae970cca15050af3a
|
||||
SERVER_TRAFFIC_SECRET_0 f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 19135dd5d1c271e50a7a1721a21258bfab412f2bd8d607397b09eca381785b77ec7e56b014c49776de76b6c9089a8ecc
|
||||
CLIENT_TRAFFIC_SECRET_0 f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 246b412ade0a21f52fd763996e07e55a12927bf342f00f26eea660803d79d31c9ccfbaca010ea2bae970cca15050af3a
|
||||
SERVER_TRAFFIC_SECRET_0 f894c097fd8487eb0814460a3cb087889dde2c9ffe1ecdbe38e61ceac549263f 19135dd5d1c271e50a7a1721a21258bfab412f2bd8d607397b09eca381785b77ec7e56b014c49776de76b6c9089a8ecc
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 8b105eb411a40a629cb1cfd3163066f9e31863b5a01226c16ecbf95274022b7c
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 532d887bc52a937c6101278100eda09542affd953151e7484ef12ce653cc3afb
|
||||
CLIENT_HANDSHAKE_TRAFFIC_SECRET b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 8b105eb411a40a629cb1cfd3163066f9e31863b5a01226c16ecbf95274022b7c
|
||||
SERVER_HANDSHAKE_TRAFFIC_SECRET b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 532d887bc52a937c6101278100eda09542affd953151e7484ef12ce653cc3afb
|
||||
CLIENT_TRAFFIC_SECRET_0 b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 76ebcabed6ecf6bc7cdcc65bb15dba6d530f204b13486e926bb81a139d267240
|
||||
SERVER_TRAFFIC_SECRET_0 b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 7371413fec66d8e960bb284295514716c14c7aa451fb63f9d17aaa0c0fa8daa2
|
||||
CLIENT_TRAFFIC_SECRET_0 b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 76ebcabed6ecf6bc7cdcc65bb15dba6d530f204b13486e926bb81a139d267240
|
||||
SERVER_TRAFFIC_SECRET_0 b72cb4fa8af218c7162d459673d577cc98110edf0460ce3d3d3366b40a4af5b0 7371413fec66d8e960bb284295514716c14c7aa451fb63f9d17aaa0c0fa8daa2
|
168
src/sniffer.c
168
src/sniffer.c
@ -662,13 +662,15 @@ static void UpdateMissedDataSessions(void)
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
static int addSecretNode(unsigned char* clientRandom,
|
||||
int type,
|
||||
unsigned char* masterSecret,
|
||||
char* error);
|
||||
static void hexToBin(const char* hex, unsigned char* bin, int binLength);
|
||||
static int parseKeyLogFile(const char* fileName, char* error);
|
||||
static unsigned char* findMasterSecret(unsigned char* clientRandom);
|
||||
static unsigned char* findSecret(unsigned char* clientRandom, int type);
|
||||
static void freeSecretList(void);
|
||||
static int snifferSecretCb(unsigned char* client_random,
|
||||
int type,
|
||||
unsigned char* output_secret);
|
||||
static void setSnifferSecretCb(SnifferSession* session);
|
||||
static int addKeyLogSnifferServerHelper(const char* address,
|
||||
@ -7207,15 +7209,18 @@ int ssl_PollSniffer(WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags,
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
|
||||
#define CLIENT_RANDOM_LABEL_LENGTH 13
|
||||
#define CLIENT_RANDOM_LENGTH 32
|
||||
#define MASTER_SECRET_LENGTH 48
|
||||
#define CLIENT_RANDOM_BITS ((CLIENT_RANDOM_LENGTH) * 8)
|
||||
|
||||
/* Maximum length of the NSS Keylog prefix string */
|
||||
#define MAX_PREFIX_LENGTH (31)
|
||||
/* Maximum length (in bytes) required to store the binary representation of
|
||||
* the "client random" value parsed from keylog file */
|
||||
#define CLIENT_RANDOM_LENGTH (32)
|
||||
/* Maximum length (in bytes) required to store the binary representation of the
|
||||
* "secret" value parsed from keylog file */
|
||||
#define SECRET_LENGTH (48)
|
||||
|
||||
typedef struct SecretNode {
|
||||
unsigned char clientRandom[CLIENT_RANDOM_LENGTH];
|
||||
unsigned char masterSecret[MASTER_SECRET_LENGTH];
|
||||
unsigned char secrets[SNIFFER_SECRET_NUM_SECRET_TYPES][SECRET_LENGTH];
|
||||
struct SecretNode* next;
|
||||
} SecretNode;
|
||||
|
||||
@ -7233,7 +7238,6 @@ secretHashTable[WOLFSSL_SNIFFER_KEYLOGFILE_HASH_TABLE_SIZE] = {NULL};
|
||||
static WOLFSSL_GLOBAL wolfSSL_Mutex secretListMutex;
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned int secretHashFunction(unsigned char* clientRandom);
|
||||
|
||||
#ifdef HAVE_C___ATOMIC
|
||||
@ -7253,9 +7257,10 @@ static unsigned int secretHashFunction(unsigned char* clientRandom)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int hash = 0;
|
||||
const int CLIENT_RANDOM_NUM_BITS = CLIENT_RANDOM_LENGTH * 8;
|
||||
|
||||
for (i = 0; i < CLIENT_RANDOM_LENGTH; i++) {
|
||||
hash = (hash * CLIENT_RANDOM_BITS + clientRandom[i])
|
||||
hash = (hash * CLIENT_RANDOM_NUM_BITS + clientRandom[i])
|
||||
% WOLFSSL_SNIFFER_KEYLOGFILE_HASH_TABLE_SIZE;
|
||||
}
|
||||
|
||||
@ -7263,62 +7268,67 @@ static unsigned int secretHashFunction(unsigned char* clientRandom)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adds a new secret to the secret table, creating a new node based on the
|
||||
* client random if necessary. If the client random is already present in the
|
||||
* list, the requested secret will be updated.
|
||||
*/
|
||||
static int addSecretNode(unsigned char* clientRandom,
|
||||
unsigned char* masterSecret,
|
||||
int type,
|
||||
unsigned char* secret,
|
||||
char* error)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
SecretNode* newSecretNode = NULL;
|
||||
int index = 0;
|
||||
int ret = 0;
|
||||
SecretNode* node = NULL;
|
||||
|
||||
newSecretNode = (SecretNode*)XMALLOC(sizeof(SecretNode),
|
||||
NULL,
|
||||
DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE);
|
||||
if (newSecretNode == NULL) {
|
||||
SetError(MEMORY_STR, error, NULL, 0);
|
||||
if (type >= SNIFFER_SECRET_NUM_SECRET_TYPES) {
|
||||
return WOLFSSL_SNIFFER_ERROR;
|
||||
}
|
||||
|
||||
XMEMCPY(newSecretNode->clientRandom, clientRandom, CLIENT_RANDOM_LENGTH);
|
||||
XMEMCPY(newSecretNode->masterSecret, masterSecret, MASTER_SECRET_LENGTH);
|
||||
|
||||
LOCK_SECRET_LIST();
|
||||
|
||||
index = secretHashFunction(clientRandom);
|
||||
newSecretNode->next = NULL;
|
||||
node = secretHashTable[index];
|
||||
|
||||
if (secretHashTable[index] == NULL) {
|
||||
secretHashTable[index] = newSecretNode;
|
||||
}
|
||||
else {
|
||||
SecretNode* current = secretHashTable[index];
|
||||
while (current != NULL) {
|
||||
if (memcmp(current->clientRandom,
|
||||
clientRandom,
|
||||
CLIENT_RANDOM_LENGTH) == 0) {
|
||||
/* No need for a new node, since it already exists */
|
||||
fprintf(stderr, "Found duplicate client random value in "
|
||||
"keylog file. Rejecting.\n");
|
||||
XFREE(newSecretNode, NULL, DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE);
|
||||
break;
|
||||
}
|
||||
if (current->next == NULL) {
|
||||
current->next = newSecretNode;
|
||||
break;
|
||||
}
|
||||
current = current->next;
|
||||
while(node) {
|
||||
/* Node already exists, so just add the requested secret */
|
||||
if (XMEMCMP(node->clientRandom, clientRandom, CLIENT_RANDOM_LENGTH)
|
||||
== 0)
|
||||
{
|
||||
XMEMCPY(node->secrets[type], secret, SECRET_LENGTH);
|
||||
ret = 0;
|
||||
goto unlockReturn;
|
||||
}
|
||||
node = node ->next;
|
||||
}
|
||||
|
||||
node = (SecretNode*)XMALLOC(sizeof(SecretNode),
|
||||
NULL,
|
||||
DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE);
|
||||
if (node == NULL) {
|
||||
SetError(MEMORY_STR, error, NULL, 0);
|
||||
ret = WOLFSSL_SNIFFER_ERROR;
|
||||
goto unlockReturn;
|
||||
}
|
||||
|
||||
XMEMCPY(node->clientRandom, clientRandom, CLIENT_RANDOM_LENGTH);
|
||||
XMEMCPY(node->secrets[type], secret, SECRET_LENGTH);
|
||||
node->next = secretHashTable[index];
|
||||
secretHashTable[index] = node;
|
||||
|
||||
unlockReturn:
|
||||
|
||||
UNLOCK_SECRET_LIST();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Looks up a master secret for a given client random from the keylog file
|
||||
*/
|
||||
static unsigned char* findMasterSecret(unsigned char* clientRandom)
|
||||
static unsigned char* findSecret(unsigned char* clientRandom, int type)
|
||||
{
|
||||
unsigned char* secret = NULL;
|
||||
SecretNode* node = NULL;
|
||||
@ -7332,7 +7342,7 @@ static unsigned char* findMasterSecret(unsigned char* clientRandom)
|
||||
while (node != NULL) {
|
||||
if (XMEMCMP(node->clientRandom,
|
||||
clientRandom, CLIENT_RANDOM_LENGTH) == 0) {
|
||||
secret = node->masterSecret;
|
||||
secret = node->secrets[type];
|
||||
break;
|
||||
}
|
||||
node = node->next;
|
||||
@ -7348,23 +7358,25 @@ static void hexToBin(const char* hex, unsigned char* bin, int binLength)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < binLength; i++) {
|
||||
sscanf(hex + 2 * i, "%02hhx", &bin[i]);
|
||||
sscanf(hex + 2*i, "%02hhx", &bin[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Helper function to parse secrets from the keylog file into the secret table
|
||||
*/
|
||||
static int parseKeyLogFile(const char* fileName, char* error)
|
||||
{
|
||||
const char CLIENT_RANDOM_LABEL_STR[] = "CLIENT_RANDOM";
|
||||
unsigned char clientRandom[CLIENT_RANDOM_LENGTH];
|
||||
unsigned char masterSecret[MASTER_SECRET_LENGTH];
|
||||
unsigned char secret[SECRET_LENGTH];
|
||||
FILE* file = NULL;
|
||||
int ret = 0;
|
||||
int type = 0;
|
||||
/* +1 for null terminator */
|
||||
char clientRandomLabel[CLIENT_RANDOM_LABEL_LENGTH + 1] = {0};
|
||||
char prefix[MAX_PREFIX_LENGTH + 1] = {0};
|
||||
/* 2 chars for Hexadecimal representation, plus null terminator */
|
||||
char clientRandomHex[2 * CLIENT_RANDOM_LENGTH + 1] = {0};
|
||||
char masterSecretHex[2 * MASTER_SECRET_LENGTH + 1] = {0};
|
||||
char secretHex[2 * SECRET_LENGTH + 1] = {0};
|
||||
|
||||
|
||||
file = fopen(fileName, "r");
|
||||
@ -7374,16 +7386,43 @@ static int parseKeyLogFile(const char* fileName, char* error)
|
||||
return WOLFSSL_SNIFFER_ERROR;
|
||||
}
|
||||
|
||||
while (fscanf(file, "%13s %64s %96s",
|
||||
clientRandomLabel, clientRandomHex, masterSecretHex) == 3) {
|
||||
if (XSTRCMP(clientRandomLabel, CLIENT_RANDOM_LABEL_STR) == 0) {
|
||||
hexToBin(clientRandomHex, clientRandom, CLIENT_RANDOM_LENGTH);
|
||||
hexToBin(masterSecretHex, masterSecret, MASTER_SECRET_LENGTH);
|
||||
ret = addSecretNode(clientRandom, masterSecret, error);
|
||||
if (ret != 0) {
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
/* Format specifiers for each column should be:
|
||||
* MAX_PREFIX_LENGTH, 2*CLIENT_RANDOM_LENGTH, and 2*SECRET_LENGTH */
|
||||
while (fscanf(file, "%31s %64s %96s", prefix, clientRandomHex, secretHex)
|
||||
== 3) {
|
||||
|
||||
if (XSTRCMP(prefix, "CLIENT_RANDOM") == 0) {
|
||||
type = SNIFFER_SECRET_TLS12_MASTER_SECRET;
|
||||
}
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
else if (XSTRCMP(prefix, "CLIENT_EARLY_TRAFFIC_SECRET") == 0) {
|
||||
type = SNIFFER_SECRET_CLIENT_EARLY_TRAFFIC_SECRET;
|
||||
}
|
||||
else if (XSTRCMP(prefix, "CLIENT_HANDSHAKE_TRAFFIC_SECRET") == 0) {
|
||||
type = SNIFFER_SECRET_CLIENT_HANDSHAKE_TRAFFIC_SECRET;
|
||||
}
|
||||
else if (XSTRCMP(prefix, "SERVER_HANDSHAKE_TRAFFIC_SECRET") == 0) {
|
||||
type = SNIFFER_SECRET_SERVER_HANDSHAKE_TRAFFIC_SECRET;
|
||||
}
|
||||
else if (XSTRCMP(prefix, "CLIENT_TRAFFIC_SECRET_0") == 0) {
|
||||
type = SNIFFER_SECRET_CLIENT_TRAFFIC_SECRET;
|
||||
}
|
||||
else if (XSTRCMP(prefix, "SERVER_TRAFFIC_SECRET_0") == 0) {
|
||||
type = SNIFFER_SECRET_SERVER_TRAFFIC_SECRET;
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13 */
|
||||
else {
|
||||
fprintf(stderr, "unrecognized prefix: %s\n", prefix);
|
||||
continue;
|
||||
}
|
||||
|
||||
hexToBin(clientRandomHex, clientRandom, CLIENT_RANDOM_LENGTH);
|
||||
hexToBin(secretHex, secret, SECRET_LENGTH);
|
||||
ret = addSecretNode(clientRandom, type, secret, error);
|
||||
|
||||
if (ret != 0) {
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
@ -7418,6 +7457,7 @@ static void freeSecretList(void)
|
||||
* Looks up secret based on client random and copies it to output_secret
|
||||
*/
|
||||
static int snifferSecretCb(unsigned char* client_random,
|
||||
int type,
|
||||
unsigned char* output_secret)
|
||||
{
|
||||
unsigned char* secret = NULL;
|
||||
@ -7426,10 +7466,14 @@ static int snifferSecretCb(unsigned char* client_random,
|
||||
return WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (type >= SNIFFER_SECRET_NUM_SECRET_TYPES) {
|
||||
return WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* get secret from secret table based on client random */
|
||||
secret = findMasterSecret(client_random);
|
||||
secret = findSecret(client_random, type);
|
||||
if (secret != NULL) {
|
||||
XMEMCPY(output_secret, secret, MASTER_SECRET_LENGTH);
|
||||
XMEMCPY(output_secret, secret, SECRET_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -520,7 +520,9 @@ int MakeTlsMasterSecret(WOLFSSL* ssl)
|
||||
/* If this is called from a sniffer session with keylog file support, obtain
|
||||
* the master secret from the callback */
|
||||
if (ssl->snifferSecretCb != NULL) {
|
||||
ret = ssl->snifferSecretCb(ssl->arrays->clientRandom, ssl->arrays->masterSecret);
|
||||
ret = ssl->snifferSecretCb(ssl->arrays->clientRandom,
|
||||
SNIFFER_SECRET_TLS12_MASTER_SECRET,
|
||||
ssl->arrays->masterSecret);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -15227,4 +15229,5 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
||||
#endif /* NO_WOLFSSL_SERVER */
|
||||
|
||||
#endif /* NO_TLS */
|
||||
|
||||
#endif /* WOLFCRYPT_ONLY */
|
||||
|
58
src/tls13.c
58
src/tls13.c
@ -414,6 +414,7 @@ int Tls13DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
|
||||
word32 protocolLen;
|
||||
int digestAlg = 0;
|
||||
|
||||
|
||||
switch (hashAlgo) {
|
||||
#ifndef NO_SHA256
|
||||
case sha256_mac:
|
||||
@ -610,6 +611,17 @@ static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key, int side)
|
||||
if (ssl == NULL || ssl->arrays == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
/* If this is called from a sniffer session with keylog file support,
|
||||
* obtain the appropriate secret from the callback */
|
||||
if (ssl->snifferSecretCb != NULL) {
|
||||
return ssl->snifferSecretCb(ssl->arrays->clientRandom,
|
||||
SNIFFER_SECRET_CLIENT_EARLY_TRAFFIC_SECRET,
|
||||
key);
|
||||
}
|
||||
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->secret,
|
||||
earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1, side);
|
||||
@ -658,6 +670,16 @@ static int DeriveClientHandshakeSecret(WOLFSSL* ssl, byte* key)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
/* If this is called from a sniffer session with keylog file support,
|
||||
* obtain the appropriate secret from the callback */
|
||||
if (ssl->snifferSecretCb != NULL) {
|
||||
return ssl->snifferSecretCb(ssl->arrays->clientRandom,
|
||||
SNIFFER_SECRET_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
|
||||
key);
|
||||
}
|
||||
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
|
||||
clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_CLIENT_END);
|
||||
@ -703,9 +725,21 @@ static int DeriveServerHandshakeSecret(WOLFSSL* ssl, byte* key)
|
||||
if (ssl == NULL || ssl->arrays == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
/* If this is called from a sniffer session with keylog file support,
|
||||
* obtain the appropriate secret from the callback */
|
||||
if (ssl->snifferSecretCb != NULL) {
|
||||
return ssl->snifferSecretCb(ssl->arrays->clientRandom,
|
||||
SNIFFER_SECRET_SERVER_HANDSHAKE_TRAFFIC_SECRET,
|
||||
key);
|
||||
}
|
||||
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
|
||||
serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_SERVER_END);
|
||||
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, SERVER_HANDSHAKE_TRAFFIC_SECRET, key,
|
||||
@ -748,9 +782,21 @@ static int DeriveClientTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
if (ssl == NULL || ssl->arrays == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
/* If this is called from a sniffer session with keylog file support,
|
||||
* obtain the appropriate secret from the callback */
|
||||
if (ssl->snifferSecretCb != NULL) {
|
||||
return ssl->snifferSecretCb(ssl->arrays->clientRandom,
|
||||
SNIFFER_SECRET_CLIENT_TRAFFIC_SECRET,
|
||||
key);
|
||||
}
|
||||
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
|
||||
clientAppLabel, CLIENT_APP_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_CLIENT_END);
|
||||
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, CLIENT_TRAFFIC_SECRET, key,
|
||||
@ -793,9 +839,21 @@ static int DeriveServerTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
if (ssl == NULL || ssl->arrays == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
/* If this is called from a sniffer session with keylog file support,
|
||||
* obtain the appropriate secret from the callback */
|
||||
if (ssl->snifferSecretCb != NULL) {
|
||||
return ssl->snifferSecretCb(ssl->arrays->clientRandom,
|
||||
SNIFFER_SECRET_SERVER_TRAFFIC_SECRET,
|
||||
key);
|
||||
}
|
||||
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
|
||||
ret = Tls13DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
|
||||
serverAppLabel, SERVER_APP_LABEL_SZ,
|
||||
ssl->specs.mac_algorithm, 1, WOLFSSL_SERVER_END);
|
||||
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
if (ret == 0 && ssl->tls13SecretCb != NULL) {
|
||||
ret = ssl->tls13SecretCb(ssl, SERVER_TRAFFIC_SECRET, key,
|
||||
|
@ -39,8 +39,7 @@ The STARTTLS option allows the sniffer to receive and ignore plaintext before re
|
||||
|
||||
`./configure --enable-sniffer CPPFLAGS=-DSTARTTLS_ALLOWED`
|
||||
|
||||
The SSL KeyLog file option enables the sniffer to decrypt TLS traffic using the master secret obtained from a [NSS keylog file](https://web.archive.org/web/20220531072242/https://firefox-source-docs.mozilla.org/security/nss/legacy/key_log_format/index.html). This allows the sniffer to decrypt all TLS traffic, even for TLS connections using ephemeral cipher suites. Currently, sniffer keylog file support is limited to TLSv1.2 traffic. WolfSSL can be configured to export a keylog file using the `-DSHOW_SECRETS -DHAVE_SECRET_CALLBACK -DWOLFSSL_SSLKEYLOGFILE` macros, independently from the sniffer feature (NOTE: never do this in a production environment, as it is inherently insecure). To enable sniffer support for keylog files,
|
||||
use the following configure command line and build as before:
|
||||
The SSL Keylog file option enables the sniffer to decrypt TLS traffic using the master secret obtained from a [NSS keylog file](https://web.archive.org/web/20220531072242/https://firefox-source-docs.mozilla.org/security/nss/legacy/key_log_format/index.html). This allows the sniffer to decrypt all TLS traffic, even for TLS connections using ephemeral cipher suites. Keylog file sniffing is supported for TLS versions 1.2 and 1.3. WolfSSL can be configured to export a keylog file using the `--enable-keylog-export` configure option, independently from the sniffer feature (NOTE: never do this in a production environment, as it is inherently insecure). To enable sniffer support for keylog files, use the following configure command line and build as before:
|
||||
|
||||
`./configure --enable-sniffer CPPFLAGS=-DWOLFSSL_SNIFFER_KEYLOGFILE`
|
||||
|
||||
@ -326,7 +325,7 @@ int ssl_LoadSecretsFromKeyLogFile(const char* keylogfile, char* error)
|
||||
|
||||
Loads secrets to decrypt TLS traffic from a keylog file. Only sniffer servers registered with `ssl_createKeyLogSnifferServer()` will be able to decrypt using these secrets
|
||||
|
||||
This function requires that sniffer keylog file support (`WOLFSSL_SNIFFER_KEYLOGFILE`) is enabled in the build. Keylog file sniffing is only supported for TLS 1.2 traffic.
|
||||
This function requires that sniffer keylog file support (`WOLFSSL_SNIFFER_KEYLOGFILE`) is enabled in the build. Keylog file sniffing is supported for TLS versions 1.2 and 1.3.
|
||||
|
||||
Return Values:
|
||||
* 0 on success
|
||||
@ -340,7 +339,7 @@ int ssl_CreateKeyLogSnifferServer(const char* address, int port, char* error)
|
||||
|
||||
Creates a sniffer session based on `serverAddress` and `port`, and uses secrets obtained from a keylog file to decrypt traffic. Keylog files should be loaded using `ssl_LoadSecretsFromKeyLogFile()`.
|
||||
|
||||
This function requires that sniffer keylog file support (`WOLFSSL_SNIFFER_KEYLOGFILE`) is enabled in the build. Keylog file sniffing is only supported for TLS 1.2 traffic.
|
||||
This function requires that sniffer keylog file support (`WOLFSSL_SNIFFER_KEYLOGFILE`) is enabled in the build. Keylog file sniffing is supported for TLS versions 1.2 and 1.3.
|
||||
|
||||
Return Values:
|
||||
* 0 on success
|
||||
@ -680,7 +679,7 @@ Remember to always start the sniffing application before the server. This is im
|
||||
|
||||
### Cipher Suite Limitations
|
||||
|
||||
As a passive sniffer the wolfSSL sniffer will not be able to decode any SSL session that uses DHE (Ephemeral Diffie-Hellman) because it will not have access to the temporary key that the server generates. You may need to disable DHE cipher suites on the server and/or client to prevent these cipher suites from being used.
|
||||
As a passive sniffer the wolfSSL sniffer will not be able to decode any SSL session that uses DHE (Ephemeral Diffie-Hellman) because it will not have access to the temporary key that the server generates. You may need to disable DHE cipher suites on the server and/or client to prevent these cipher suites from being used. The notable exception to this is if the sniffer session uses the keylog file feature, in which case any session using TLS 1.2 or 1.3 can be decoded.
|
||||
|
||||
### Thread Safety
|
||||
|
||||
|
@ -315,6 +315,19 @@ SSL_SNIFFER_API int ssl_PollSniffer(WOLF_EVENT** events, int maxEvents,
|
||||
|
||||
#ifdef WOLFSSL_SNIFFER_KEYLOGFILE
|
||||
|
||||
typedef enum {
|
||||
SNIFFER_SECRET_TLS12_MASTER_SECRET,
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
SNIFFER_SECRET_CLIENT_EARLY_TRAFFIC_SECRET,
|
||||
SNIFFER_SECRET_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
|
||||
SNIFFER_SECRET_SERVER_HANDSHAKE_TRAFFIC_SECRET,
|
||||
SNIFFER_SECRET_CLIENT_TRAFFIC_SECRET,
|
||||
SNIFFER_SECRET_SERVER_TRAFFIC_SECRET,
|
||||
#endif /* WOLFSSL_TLS13 */
|
||||
SNIFFER_SECRET_NUM_SECRET_TYPES
|
||||
} SnifferSecretType;
|
||||
|
||||
|
||||
WOLFSSL_API
|
||||
SSL_SNIFFER_API int ssl_CreateKeyLogSnifferServer(const char* address,
|
||||
int port,
|
||||
@ -325,6 +338,7 @@ SSL_SNIFFER_API int ssl_LoadSecretsFromKeyLogFile(const char* keylogfile,
|
||||
char* error);
|
||||
|
||||
typedef int (*SSLSnifferSecretCb)(unsigned char* client_random,
|
||||
int type,
|
||||
unsigned char* output_secret);
|
||||
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
|
Reference in New Issue
Block a user