diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 29115bc60..a4a647eee 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -4908,6 +4908,76 @@ static int ocsp_status_cb(SSL *s, void *arg) #endif /* HAVE_OCSP */ +static size_t max_str_len(const char **lines) +{ + const char **p; + size_t max_len = 0; + + for (p = lines; *p; p++) { + size_t len = os_strlen(*p); + + if (len > max_len) + max_len = len; + } + + return max_len; +} + + +static int match_lines_in_file(const char *path, const char **lines) +{ + FILE *f; + char *buf; + size_t bufsize; + int found = 0, is_linestart = 1; + + bufsize = max_str_len(lines) + sizeof("\r\n"); + buf = os_malloc(bufsize); + if (!buf) + return 0; + + f = fopen(path, "r"); + if (!f) { + os_free(buf); + return 0; + } + + while (!found && fgets(buf, bufsize, f)) { + int is_lineend; + size_t len; + const char **p; + + len = strcspn(buf, "\r\n"); + is_lineend = buf[len] != '\0'; + buf[len] = '\0'; + + if (is_linestart && is_lineend) { + for (p = lines; !found && *p; p++) + found = os_strcmp(buf, *p) == 0; + } + is_linestart = is_lineend; + } + + fclose(f); + bin_clear_free(buf, bufsize); + + return found; +} + + +static int is_tpm2_key(const char *path) +{ + /* Check both new and old format of TPM2 PEM guard tag */ + static 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) { @@ -4960,6 +5030,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 (params->private_key && + (!engine_id || os_strcmp(engine_id, "tpm2") == 0) && + 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) { @@ -4991,7 +5072,8 @@ 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)