summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2017-02-24 18:43:21 +0100
committerPeter Wu <peter@lekensteyn.nl>2017-02-24 18:43:21 +0100
commitba5d37b60e00154517984a17ce22585e51ac37d6 (patch)
tree6c69b69c16f62f91f243e12e6c21d340d26ea556 /src
parent9680a664e1594692bbbf2040a3a79bed0b45f2f2 (diff)
downloadwireshark-notes-ba5d37b60e00154517984a17ce22585e51ac37d6.tar.gz
src/sslkeylog.c: avoid linker errors
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).
Diffstat (limited to 'src')
-rw-r--r--src/sslkeylog.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/src/sslkeylog.c b/src/sslkeylog.c
index 6a42510..6cc91c9 100644
--- a/src/sslkeylog.c
+++ b/src/sslkeylog.c
@@ -80,21 +80,60 @@ static void init_keylog_file(void)
}
}
+static inline void *lookup_symbol(const char *sym)
+{
+ void *func = dlsym(RTLD_NEXT, sym);
+ /* Symbol not found, OpenSSL is not loaded (linked) so try to load it
+ * manually. This is error-prone as it depends on a fixed library name.
+ * Perhaps it should be an env name? */
+ if (!func) {
+ void *handle = dlopen(OPENSSL_SONAME, RTLD_LAZY);
+ if (!handle) {
+ fprintf(stderr, "Lookup error for %s: %s", sym, dlerror());
+ abort();
+ }
+ func = dlsym(handle, sym);
+ if (!func) {
+ fprintf(stderr, "Cannot lookup %s", sym);
+ abort();
+ }
+ dlclose(handle);
+ }
+ return func;
+}
+
typedef struct ssl_tap_state {
int master_key_length;
unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
} ssl_tap_state_t;
+static inline SSL_SESSION *ssl_get_session(const SSL *ssl)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ static SSL_SESSION *(*func)();
+ if (!func) {
+ func = lookup_symbol("SSL_get_session");
+ }
+ return func(ssl);
+#else
+ return ssl->session;
+#endif
+}
+
/* Copies SSL state for later comparison in tap_ssl_key. */
static void ssl_tap_state_init(ssl_tap_state_t *state, const SSL *ssl)
{
- const SSL_SESSION *session = SSL_get_session(ssl);
+ const SSL_SESSION *session = ssl_get_session(ssl);
memset(state, 0, sizeof(ssl_tap_state_t));
if (session) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
- state->master_key_length = SSL_SESSION_get_master_key(session,
+ static size_t (*func)();
+ if (!func) {
+ func = lookup_symbol("SSL_SESSION_get_master_key");
+ }
+ state->master_key_length = func(session,
state->master_key, SSL_MAX_MASTER_KEY_LENGTH);
#else
if (session->master_key_length > 0) {
@@ -112,7 +151,7 @@ static void ssl_tap_state_init(ssl_tap_state_t *state, const SSL *ssl)
static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state)
{
- const SSL_SESSION *session = SSL_get_session(ssl);
+ const SSL_SESSION *session = ssl_get_session(ssl);
unsigned char client_random[SSL3_RANDOM_SIZE];
unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
int master_key_length = 0;
@@ -150,28 +189,6 @@ static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state)
}
}
-static inline void *lookup_symbol(const char *sym)
-{
- void *func = dlsym(RTLD_NEXT, sym);
- /* Symbol not found, OpenSSL is not loaded (linked) so try to load it
- * manually. This is error-prone as it depends on a fixed library name.
- * Perhaps it should be an env name? */
- if (!func) {
- void *handle = dlopen(OPENSSL_SONAME, RTLD_LAZY);
- if (!handle) {
- fprintf(stderr, "Lookup error for %s: %s", sym, dlerror());
- abort();
- }
- func = dlsym(handle, sym);
- if (!func) {
- fprintf(stderr, "Cannot lookup %s", sym);
- abort();
- }
- dlclose(handle);
- }
- return func;
-}
-
int SSL_connect(SSL *ssl)
{
static int (*func)();