diff options
-rw-r--r-- | src/cli-args.def | 14 | ||||
-rw-r--r-- | src/cli.c | 5 | ||||
-rw-r--r-- | src/common.c | 37 | ||||
-rw-r--r-- | src/common.h | 1 | ||||
-rw-r--r-- | src/serv-args.def | 14 | ||||
-rw-r--r-- | src/serv.c | 7 | ||||
-rw-r--r-- | tests/scripts/common.sh | 4 | ||||
-rwxr-xr-x | tests/suite/testcompat-tls13-openssl.sh | 22 |
8 files changed, 102 insertions, 2 deletions
diff --git a/src/cli-args.def b/src/cli-args.def index 518a97466e..621de61f3c 100644 --- a/src/cli-args.def +++ b/src/cli-args.def @@ -423,6 +423,20 @@ flag = { doc = ""; }; +flag = { + name = keymatexport; + arg-type = string; + descrip = "Label used for exporting keying material"; + doc = ""; +}; + +flag = { + name = keymatexportsize; + arg-type = number; + descrip = "Size of the exported keying material"; + doc = ""; +}; + doc-section = { ds-type = 'SEE ALSO'; // or anything else ds-format = 'texi'; // or texi or mdoc format @@ -1659,6 +1659,11 @@ int do_handshake(socket_st * socket) if (ret == 0) { /* print some information */ print_info(socket->session, verbose, HAVE_OPT(X509CERTFILE)?P_WAIT_FOR_CERT:0); + if (HAVE_OPT(KEYMATEXPORT)) + print_key_material(socket->session, + OPT_ARG(KEYMATEXPORT), + HAVE_OPT(KEYMATEXPORTSIZE) ? + OPT_VALUE_KEYMATEXPORTSIZE : 20); socket->secure = 1; } else { gnutls_alert_send_appropriate(socket->session, ret); diff --git a/src/common.c b/src/common.c index 28452fd589..664513c9ad 100644 --- a/src/common.c +++ b/src/common.c @@ -876,6 +876,43 @@ void print_list(const char *priorities, int verbose) } } +void +print_key_material(gnutls_session_t session, const char *label, size_t size) +{ + gnutls_datum_t bin = { NULL, 0 }, hex = { NULL, 0 }; + int ret; + + bin.data = gnutls_malloc(size); + if (!bin.data) { + fprintf(stderr, "Error in gnutls_malloc: %s\n", + gnutls_strerror(GNUTLS_E_MEMORY_ERROR)); + goto out; + } + + bin.size = size; + + ret = gnutls_prf_rfc5705(session, strlen(label), label, + 0, NULL, size, (char *)bin.data); + if (ret < 0) { + fprintf(stderr, "Error in gnutls_prf_rfc5705: %s\n", + gnutls_strerror(ret)); + goto out; + } + + ret = gnutls_hex_encode2(&bin, &hex); + if (ret < 0) { + fprintf(stderr, "Error in hex encoding: %s\n", + gnutls_strerror(ret)); + goto out; + } + log_msg(stdout, "- Key material: %s\n", hex.data); + fflush(stdout); + + out: + gnutls_free(bin.data); + gnutls_free(hex.data); +} + int check_command(gnutls_session_t session, const char *str, unsigned no_cli_cert) { size_t len = strnlen(str, 128); diff --git a/src/common.h b/src/common.h index 588ee82bf1..91b9ed04f2 100644 --- a/src/common.h +++ b/src/common.h @@ -61,6 +61,7 @@ extern const char str_unknown[]; #define P_WAIT_FOR_CERT (1<<1) int print_info(gnutls_session_t state, int verbose, int flags); void print_cert_info(gnutls_session_t, int flag, int print_cert); +void print_key_material(gnutls_session_t, const char *label, size_t size); int log_msg(FILE *file, const char *message, ...) __attribute__((format(printf, 2, 3))); void log_set(FILE *file); diff --git a/src/serv-args.def b/src/serv-args.def index ac056f37dc..4be3d9f298 100644 --- a/src/serv-args.def +++ b/src/serv-args.def @@ -318,6 +318,20 @@ flag = { doc = "This will override the default options in /etc/gnutls/pkcs11.conf"; }; +flag = { + name = keymatexport; + arg-type = string; + descrip = "Label used for exporting keying material"; + doc = ""; +}; + +flag = { + name = keymatexportsize; + arg-type = number; + descrip = "Size of the exported keying material"; + doc = ""; +}; + doc-section = { ds-type = 'SEE ALSO'; // or anything else ds-format = 'texi'; // or texi or mdoc format diff --git a/src/serv.c b/src/serv.c index bc490ee7da..0866bff903 100644 --- a/src/serv.c +++ b/src/serv.c @@ -1331,6 +1331,13 @@ static void retry_handshake(listener_item *j) #endif print_info(j->tls_session, verbose, verbose); + + if (HAVE_OPT(KEYMATEXPORT)) + print_key_material(j->tls_session, + OPT_ARG(KEYMATEXPORT), + HAVE_OPT(KEYMATEXPORTSIZE) ? + OPT_VALUE_KEYMATEXPORTSIZE : + 20); } j->close_ok = 1; diff --git a/tests/scripts/common.sh b/tests/scripts/common.sh index 1cce09d04e..a714bcd608 100644 --- a/tests/scripts/common.sh +++ b/tests/scripts/common.sh @@ -158,7 +158,7 @@ launch_server() { shift wait_for_free_port ${PORT} - ${SERV} ${DEBUG} -p "${PORT}" $* >/dev/null & + ${SERV} ${DEBUG} -p "${PORT}" $* >${LOGFILE-/dev/null} & } launch_pkcs11_server() { @@ -177,7 +177,7 @@ launch_bare_server() { shift wait_for_free_port ${PORT} - ${SERV} $* >/dev/null & + ${SERV} $* >${LOGFILE-/dev/null} & } wait_server() { diff --git a/tests/suite/testcompat-tls13-openssl.sh b/tests/suite/testcompat-tls13-openssl.sh index 27ca3826e3..6d17941b8e 100755 --- a/tests/suite/testcompat-tls13-openssl.sh +++ b/tests/suite/testcompat-tls13-openssl.sh @@ -264,6 +264,28 @@ run_client_suite() { kill ${PID} wait + # Try exporting keying material + echo_cmd "${PREFIX}Checking TLS 1.3 to export keying material..." + testdir=`create_testdir tls13-openssl-keymatexport` + eval "${GETPORT}" + LOGFILE="${testdir}/server.out" + launch_bare_server $$ s_server -accept "${PORT}" -keyform pem -certform pem ${OPENSSL_DH_PARAMS_OPT} -key "${RSA_KEY}" -cert "${RSA_CERT}" -CAfile "${CA_CERT}" -keymatexport label -keymatexportlen 20 + unset LOGFILE + PID=$! + wait_server ${PID} + + ${VALGRIND} "${CLI}" ${DEBUG} -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL${ADD}" --keymatexport label --keymatexportsize 20| tee "${testdir}/client.out" >> ${OUTPUT} + grep '^- Key material: ' "${testdir}/client.out" | \ + sed -e 's/^.*: //' -e 'y/abcdef/ABCDEF/' > "${testdir}/client.key" || \ + fail ${PID} "Failed" + grep '^ Keying material: ' "${testdir}/server.out" | \ + sed -e 's/^.*: //' -e 'y/abcdef/ABCDEF/' > "${testdir}/server.key" || \ + fail ${PID} "Failed" + diff "${testdir}/client.key" "${testdir}/server.key" || \ + fail ${PID} "Failed" + kill ${PID} + wait + rm -rf "${testdir}" } |