|
22 | 22 | #include <ctype.h> |
23 | 23 | #include <errno.h> |
24 | 24 | #include <poll.h> |
| 25 | +#include <pthread.h> |
25 | 26 | #include <stdint.h> |
26 | 27 | #include <stdio.h> |
27 | 28 | #include <stdlib.h> |
@@ -1923,3 +1924,91 @@ nc_tls_get_cert_exp_time_wrap(void *cert) |
1923 | 1924 |
|
1924 | 1925 | return timegm(&t); |
1925 | 1926 | } |
| 1927 | + |
| 1928 | +/** |
| 1929 | + * @brief Convert the MbedTLS key export type to a label for the keylog file. |
| 1930 | + * |
| 1931 | + * @param[in] type MbedTLS key export type. |
| 1932 | + * @return Label for the keylog file or NULL if the type is not supported. |
| 1933 | + */ |
| 1934 | +static const char * |
| 1935 | +nc_tls_keylog_type2label(mbedtls_ssl_key_export_type type) |
| 1936 | +{ |
| 1937 | + switch (type) { |
| 1938 | + case MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET: |
| 1939 | + return "CLIENT_RANDOM"; |
| 1940 | +#ifdef MBEDTLS_SSL_PROTO_TLS1_3 |
| 1941 | + case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET: |
| 1942 | + return "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; |
| 1943 | + case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET: |
| 1944 | + return "SERVER_HANDSHAKE_TRAFFIC_SECRET"; |
| 1945 | + case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET: |
| 1946 | + return "CLIENT_TRAFFIC_SECRET_0"; |
| 1947 | + case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET: |
| 1948 | + return "SERVER_TRAFFIC_SECRET_0"; |
| 1949 | +#endif |
| 1950 | + default: |
| 1951 | + return NULL; |
| 1952 | + } |
| 1953 | +} |
| 1954 | + |
| 1955 | +/** |
| 1956 | + * @brief Callback for writing a line in the keylog file. |
| 1957 | + */ |
| 1958 | +static void |
| 1959 | +nc_tls_keylog_write_line(void *UNUSED(p_expkey), mbedtls_ssl_key_export_type type, const unsigned char *secret, |
| 1960 | + size_t secret_len, const unsigned char client_random[32], |
| 1961 | + const unsigned char UNUSED(server_random[32]), mbedtls_tls_prf_types UNUSED(tls_prf_type)) |
| 1962 | +{ |
| 1963 | + size_t linelen, len = 0, i, client_random_len; |
| 1964 | + char buf[256]; |
| 1965 | + const char *label; |
| 1966 | + |
| 1967 | + if (!server_opts.tls_keylog_file) { |
| 1968 | + return; |
| 1969 | + } |
| 1970 | + |
| 1971 | + label = nc_tls_keylog_type2label(type); |
| 1972 | + if (!label) { |
| 1973 | + /* type not supported */ |
| 1974 | + return; |
| 1975 | + } |
| 1976 | + |
| 1977 | + /* <Label> <space> 0x<ClientRandom> <space> 0x<Secret> */ |
| 1978 | + linelen = strlen(label) + 1 + 2 * 32 + 1 + 2 * secret_len + 1; |
| 1979 | + if (linelen > sizeof(buf)) { |
| 1980 | + /* sanity check, should not happen since the max len should be 196 bytes */ |
| 1981 | + return; |
| 1982 | + } |
| 1983 | + |
| 1984 | + /* write the label */ |
| 1985 | + len += sprintf(buf + len, "%s ", label); |
| 1986 | + |
| 1987 | + /* write the client random */ |
| 1988 | + client_random_len = 32; |
| 1989 | + for (i = 0; i < client_random_len; i++) { |
| 1990 | + len += sprintf(buf + len, "%02x", client_random[i]); |
| 1991 | + } |
| 1992 | + len += sprintf(buf + len, " "); |
| 1993 | + |
| 1994 | + /* write the secret */ |
| 1995 | + for (i = 0; i < secret_len; i++) { |
| 1996 | + len += sprintf(buf + len, "%02x", secret[i]); |
| 1997 | + } |
| 1998 | + |
| 1999 | + len += sprintf(buf + len, "\n"); |
| 2000 | + buf[len] = '\0'; |
| 2001 | + |
| 2002 | + if (len != linelen) { |
| 2003 | + return; |
| 2004 | + } |
| 2005 | + |
| 2006 | + fputs(buf, server_opts.tls_keylog_file); |
| 2007 | + fflush(server_opts.tls_keylog_file); |
| 2008 | +} |
| 2009 | + |
| 2010 | +void |
| 2011 | +nc_tls_keylog_session_wrap(void *session) |
| 2012 | +{ |
| 2013 | + mbedtls_ssl_set_export_keys_cb(session, nc_tls_keylog_write_line, NULL); |
| 2014 | +} |
0 commit comments