Message ID | 8fd6383f-74f5-64d0-c023-e59823a4d138@puzzle-itc.de |
---|---|
State | Accepted |
Headers | show |
Series | OpenSSL: add support for TPM2-wrapped keys | expand |
Hi! Am 02.07.19 um 16:19 schrieb Daniel Kobras: > 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@puzzle-itc.de> > --- Any thoughts on the TPM2 below? NetworkManager has just release version 1.20 that includes a patch to pass through TPM2-wrapped PEM key files. Corresponding support in wpa_supplicant now is the missing piece of the puzzle to enable transparent support for TPM2-pinned keys with 802.1x for desktop users. If there's anything else you want me to provide regarding this patch, please let me know. Kind regards, Daniel > 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) >
On Tue, Jul 02, 2019 at 04:19:38PM +0200, Daniel Kobras wrote: > 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. Thanks, applied.
On 29 December 2019 09:55:41 GMT, Jouni Malinen <j@w1.fi> wrote: >On Tue, Jul 02, 2019 at 04:19:38PM +0200, Daniel Kobras wrote: >> 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. > >Thanks, applied. > cf. https://github.com/tpm2-software/tpm2-tss-engine/issues/28
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 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@puzzle-itc.de> --- 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(-) #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)