summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)AuthorFilesLines
2019-11-20sslkeylog: add macOS supportPeter Wu3-8/+82
Tested with macOS 10.15.1 (Catalina). Works with python3 3.7.5 (requests library) and openssl 1.1.1d (s_client) from Homebrew. Does not work with curl 7.64.1 in /usr/bin/curl because it is signed and does not allow DYLD environment variables to be passed when SIP is enabled.
2018-10-23sslkeylog.c: fix OpenSSL 1.1.1 support when library is not loadedPeter Wu1-17/+21
When libssl.so.1.1.1 was not yet loaded, it would assume that an older library was already loaded and avoid the new API. That assumption is not correct, it is also possible that no library was loaded at all as is the case with Python. Test: ./sslkeylog.sh python -c \ 'import requests;print(requests.head("https://wireshark.org"))' Before this fix it would output all zeroes as secret (a sign that something is wrong).
2018-10-23sslkeylog.c: support TLS 1.3 and OpenSSL 1.1.1Peter Wu1-4/+99
OpenSSL 1.1.1 adds TLS 1.3 support which uses a new secrets format. Previously it resulted in garbage keylog files, this has been fixed now. OpenSSL 1.1.1 also introduces a new API for secrets extraction. Consumers can use it like this (curl uses this code for example): static void keylog_callback(const SSL *ssl, const char *line) { /* write line and terminating '\n' */ } { SSL_CTX *ctx; ... SSL_CTX_set_keylog_callback(ctx, keylog_callback); SSL *ssl = SSL_new(ctx); } In case you cannot change the source code for an application, you can use sslkeylog.c again. This will basically perform the above step, set the key log callback before calling SSL_new. Since the new OpenSSL 1.1.1 API requires no further interception of SSL_read and other functions, a new NO_OPENSSL_110_SUPPORT macro was to avoid intercepting these. Additionally, a NO_OPENSSL_102_SUPPORT macro avoids the need for OpenSSL development headers. Caveat: when building with OpenSSL <= 1.0.2, libsslkeylog.so will not be compatible with runtime OpenSSL 1.1.0. OpenSSL 1.1.1 still works though. Use of SSL_new and interception via SSL_CTX_set_keylog_callback was initially proposed by Derick Rethans, thanks for the suggestion!
2017-02-25src/sslkeylog.c: fix post-interception tapping for OpenSSL 1.1.0Peter Wu1-27/+40
Lookup SSL_SESSION_get_master_key and SSL_get_client_random at runtime too after intercepting a call instead of a link-time dependency.
2017-02-24src/sslkeylog.c: avoid linker errorsPeter Wu1-25/+42
Since the previous OpenSSL 1.1.0 compatibility patch, addition of the SSL_get_session and SSL_SESSION_get_master_key required them to be available at load time. Since applications are not necessarily linked with -lssl, this can fail. Avoid this dependency by looking up the symbols at runtime. Tested with OpenSSL 1.0.2.k (using python+requests) and OpenSSL_1_1_0-pre6-1439-g0e2c7b3ee (openssl s_client).
2016-08-16src/sslkeylog.c: OpenSSL 1.1.0 compatibilityPeter Wu1-18/+48
OpenSSL 1.1.0 makes some structures opaque, but luckily it provides new functions to extract the client random and master secret which is all we need from the structures. Tested with OpenSSL 1.1.0-pre6 using openssl s_client and OpenSSL 1.0.2.h using curl.
2015-07-16sslkeylog.py: fix writing headerPeter Wu1-1/+1
2015-07-10sslkeylog.py: document batch modePeter Wu1-1/+16
Found in gdb source code that 'all' implies everything except SIGTRAP and SIGINT. SIGINT is normally used for interactive debugging (so can be disabled) but SIGTRAP is used for breakpoints (and can therefore not be disabled without killing the program on such signals).
2015-07-10sslkeylog.py: fix older gdb and python compatPeter Wu1-5/+14
Older gdb is upset by appending to a pipe, so fallback to writing instead in such cases. Older python do not allow interpolation in bytes, so use strings and encode it to bytes before writing. Previously tested with GDB 7.9.1 and Python 2.7.10. Now tested with GDB 7.7.1 and Python 2.7.6 on Ubuntu 14.04.
2015-07-10sslkeylog.py: initial check-inPeter Wu1-0/+198
Tool to extract SSL keys on-the-fly from existing OpenSSL programs. Servers included!
2015-03-27sslkeylog.sh: allow it to be sourcedPeter Wu1-4/+6
Switch to bash as there is no readable / easy way to make it compatible for all shells in the world.
2015-01-30Add sslkeylog.sh wrapper scriptPeter Wu1-0/+22
2015-01-30sslkeylog: load libssl.so if not alreadyPeter Wu1-5/+35
This solves a null deref in python ssl module in SSL_do_handshake.
2015-01-29sslkeylog: interpose SSL_read and SSL_writePeter Wu1-0/+24
These functions can trigger a renegotiation which changes the key material (detected by using `curl` and `openssl s_server` and pressing `R` in `openssl s_server`).
2015-01-29sslkeylog: skip writing duplicate entriesPeter Wu1-4/+35
SSL_connect is somehow called multiple times on the same connection by curl, this may result in duplicate keylog file entries. Detect when the state changes, and only print the keys if it has changed.
2015-01-29sslkeylog: intercept server functionsPeter Wu1-6/+33
Also intercept SSL_do_handshake (nginx) and SSL_accept (s_server).
2015-01-29sslkeylog: continue after failed handshake, reject SSLv2Peter Wu1-1/+4
Try to dump as many keys as possible, even if a fatal alert occurred. Wireshark does not support SSLv2, so check that a successful connection does not use SSLv2 before dumping keys (this fixes a crash).
2015-01-28sslkeylog: rename key_logfile to keylog_filePeter Wu1-9/+9
This follows the preference name ssl.keylog_file.
2015-01-28sslkeylog.c: utility to intercept OpenSSL keysPeter Wu2-0/+94
For a gdb function, see http://security.stackexchange.com/a/80174/2630 To generate the line assuming you have a context with a SSL structure (named "s") run this: python def read_as_hex(name, size): addr = gdb.parse_and_eval(name).address data = gdb.selected_inferior().read_memory(addr, size) return ''.join('%02X' % ord(x) for x in data) def pm(ssl='s'): mk = read_as_hex('%s->session->master_key' % ssl, 48) cr = read_as_hex('%s->s3->client_random' % ssl, 32) print('CLIENT_RANDOM %s %s' % (cr, mk)) end python pm()