From 96a5dd4fa8e9c7b1d45fe934ec7829d494dbd372 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Thu, 11 Apr 2019 14:35:32 +0200 Subject: 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 --- src/cli-args.def | 14 ++++++++++++++ src/cli.c | 5 +++++ src/common.c | 37 +++++++++++++++++++++++++++++++++++++ src/common.h | 1 + src/serv-args.def | 14 ++++++++++++++ src/serv.c | 7 +++++++ 6 files changed, 78 insertions(+) (limited to 'src') 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; -- cgit v1.2.1