[PATCH] OpenSSL: add support for TPM2-wrapped keys

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If the header of a PEM-formatted cert or key indicates that it is
wrapped with a TPM2 key, try to autoload the appropriate OpenSSL engine
that can transparently unwrap the key. This enables systems to use
TPM2-wrapped keys as drop-in replacements to ordinary SSL keys.

Signed-off-by: Daniel Kobras <kobras@xxxxxxxxxxxxx>
---
Hi!

This patch adds support for TPM2-wrapped keys, similar to what David
Woodhouse did in openconnect, and suggested earlier on this list for
wpa_supplicant as well. It requires
https://git.kernel.org/pub/scm/linux/kernel/git/jejb/openssl_tpm2_engine.git/
to be installed as an openssl engine.

The match_line_in_file() helper function is rather generic. If there's a
better place to put it, please let me know.

Kind regards,

Daniel
---
 src/crypto/tls_openssl.c | 74 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 1073f6450..7f61f7560 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -4819,6 +4819,67 @@ static int ocsp_status_cb(SSL *s, void *arg)

 #endif /* HAVE_OCSP */

+static int match_lines_in_file(const char *path, const char **lines)
+{
+	FILE *f = NULL;
+	const char **p;
+	char *buf;
+	size_t bufsize = 0;
+	int found, is_linestart;
+
+	if (!path || !lines || !*lines)
+		return 0;
+
+	for (p = lines; *p; p++) {
+		size_t size = strlen(*p) + sizeof("\r\n");
+		bufsize = (size > bufsize) ? size : bufsize;
+	}
+
+	buf = os_malloc(bufsize);
+	if (!buf)
+		return 0;
+
+	f = fopen(path, "r");
+	if (!f) {
+		os_free(buf);
+		return 0;
+	}
+
+	found = 0;
+	is_linestart = 1;
+
+	while (!found && fgets(buf, bufsize, f)) {
+		int is_lineend;
+		size_t buflen = strlen(buf);
+
+		buf[strcspn(buf, "\r\n")] = '\0';
+		is_lineend = strlen(buf) < buflen;
+
+		if (is_linestart && is_lineend) {
+			for (p = lines; !found && *p; p++) {
+				found = !os_strcmp(buf, *p);
+			}
+		}
+		is_linestart = is_lineend;
+	}
+
+	fclose(f);
+	os_free(buf);
+
+	return found;
+}
+
+static int is_tpm2_key(const char *path)
+{
+	/* Check both new and old format of TPM2 PEM guard tag */
+	const char *tpm2_tags[] = {
+		"-----BEGIN TSS2 PRIVATE KEY-----",
+		"-----BEGIN TSS2 KEY BLOB-----",
+		NULL
+	};
+
+	return match_lines_in_file(path, tpm2_tags);
+}

 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
 			      const struct tls_connection_params *params)
@@ -4872,6 +4933,17 @@ int tls_connection_set_params(void *tls_ctx,
struct tls_connection *conn,
 	if (can_pkcs11 == 2 && !engine_id)
 		engine_id = "pkcs11";

+	/* If private_key points to a TPM2-wrapped key, automatically enable
+	 * tpm2 engine and use it to unwrap the key. */
+	if (!engine_id || os_strcmp(engine_id, "tpm2")) {
+		if (is_tpm2_key(params->private_key)) {
+			wpa_printf(MSG_DEBUG, "OpenSSL: Found TPM2 wrapped key %s",
+			           params->private_key);
+			key_id = key_id ? key_id : params->private_key;
+			engine_id = engine_id ? engine_id : "tpm2";
+		}
+	}
+
 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) ||
defined(EAP_SERVER_FAST)
 #if OPENSSL_VERSION_NUMBER < 0x10100000L ||
defined(LIBRESSL_VERSION_NUMBER)
 	if (params->flags & TLS_CONN_EAP_FAST) {
@@ -4903,7 +4975,7 @@ int tls_connection_set_params(void *tls_ctx,
struct tls_connection *conn,
 	}

 	if (engine_id) {
-		wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
+		wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine %s", engine_id);
 		ret = tls_engine_init(conn, engine_id, params->pin,
 				      key_id, cert_id, ca_cert_id);
 		if (ret)
-- 
2.20.1

-- 
Daniel Kobras
Principal Architect
Puzzle ITC Deutschland
+49 7071 14316 0
www.puzzle-itc.de

-- 
Puzzle ITC Deutschland GmbH
Sitz der Gesellschaft: Jurastr. 27/1, 72072 
Tübingen

Eingetragen am Amtsgericht Stuttgart HRB 765802
Geschäftsführer: 
Lukas Kallies, Daniel Kobras, Mark Pröhl


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap




[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux