summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2019-04-11 14:35:32 +0200
committerDaiki Ueno <dueno@redhat.com>2019-04-19 08:56:54 +0200
commit96a5dd4fa8e9c7b1d45fe934ec7829d494dbd372 (patch)
tree7538ef2dfeebced514c85893a5339a27265b13d6
parent89c975cc25d4e7c5040a3f657b732dd1704bfb2b (diff)
downloadgnutls-96a5dd4fa8e9c7b1d45fe934ec7829d494dbd372.tar.gz
serv, cli: add --keymatexport option
This adds --keymatexport and --keymatexportsize options to both gnutls-serv and gnutls-cli. Those would be useful for testing interoperability with other implementations. Signed-off-by: Daiki Ueno <dueno@redhat.com>
-rw-r--r--src/cli-args.def14
-rw-r--r--src/cli.c5
-rw-r--r--src/common.c37
-rw-r--r--src/common.h1
-rw-r--r--src/serv-args.def14
-rw-r--r--src/serv.c7
-rw-r--r--tests/scripts/common.sh4
-rwxr-xr-xtests/suite/testcompat-tls13-openssl.sh22
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
diff --git a/src/cli.c b/src/cli.c
index a770c74bcc..691eb98c54 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -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}"
}