diff options
Diffstat (limited to 'libnm-core/nm-crypto.c')
| -rw-r--r-- | libnm-core/nm-crypto.c | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/libnm-core/nm-crypto.c b/libnm-core/nm-crypto.c index c7142216..e0c3b7fd 100644 --- a/libnm-core/nm-crypto.c +++ b/libnm-core/nm-crypto.c @@ -1,5 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - /* * Dan Williams <dcbw@redhat.com> * @@ -51,6 +49,12 @@ #define PEM_PKCS8_DEC_KEY_BEGIN "-----BEGIN PRIVATE KEY-----" #define PEM_PKCS8_DEC_KEY_END "-----END PRIVATE KEY-----" +#define PEM_TPM2_WRAPPED_KEY_BEGIN "-----BEGIN TSS2 PRIVATE KEY-----" +#define PEM_TPM2_WRAPPED_KEY_END "-----END TSS2 PRIVATE KEY-----" + +#define PEM_TPM2_OLD_WRAPPED_KEY_BEGIN "-----BEGIN TSS2 KEY BLOB-----" +#define PEM_TPM2_OLD_WRAPPED_KEY_END "-----END TSS2 KEY BLOB-----" + /*****************************************************************************/ static const NMCryptoCipherInfo cipher_infos[] = { @@ -118,21 +122,23 @@ find_tag (const char *tag, gsize start_at, gsize *out_pos) { - gsize i, taglen; - gsize len = data_len - start_at; + const guint8 *p; + gsize taglen; - g_return_val_if_fail (out_pos != NULL, FALSE); + nm_assert (out_pos); + nm_assert (start_at <= data_len); taglen = strlen (tag); - if (len >= taglen) { - for (i = 0; i < len - taglen + 1; i++) { - if (memcmp (data + start_at + i, tag, taglen) == 0) { - *out_pos = start_at + i; - return TRUE; - } - } - } - return FALSE; + + p = memmem (&data[start_at], data_len - start_at, tag, taglen); + if (!p) + return FALSE; + + *out_pos = p - data; + + nm_assert (memcmp (&data[*out_pos], tag, taglen) == 0); + + return TRUE; } #define DEK_INFO_TAG "DEK-Info: " @@ -387,6 +393,43 @@ parse_pkcs8_key_file (const guint8 *data, } static gboolean +parse_tpm2_wrapped_key_file (const guint8 *data, + gsize data_len, + gboolean *out_encrypted, + GError **error) +{ + gsize start = 0, end = 0; + const char *start_tag = NULL, *end_tag = NULL; + + nm_assert (out_encrypted); + + if (find_tag (PEM_TPM2_WRAPPED_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_TPM2_WRAPPED_KEY_BEGIN; + end_tag = PEM_TPM2_WRAPPED_KEY_END; + } else if (find_tag (PEM_TPM2_OLD_WRAPPED_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_TPM2_OLD_WRAPPED_KEY_BEGIN; + end_tag = PEM_TPM2_OLD_WRAPPED_KEY_END; + } else { + g_set_error_literal (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected TSS start tag.")); + return FALSE; + } + + start += strlen (start_tag); + if (!find_tag (end_tag, data, data_len, start, &end)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected TSS end tag '%s'."), + end_tag); + return FALSE; + } + + *out_encrypted = FALSE; + return TRUE; +} + +static gboolean file_read_contents (const char *filename, NMSecretPtr *out_contents, GError **error) @@ -824,6 +867,8 @@ nm_crypto_verify_private_key_data (const guint8 *data, if ( !password || _nm_crypto_verify_pkcs8 (parsed.bin, parsed.len, is_encrypted, password, error)) format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + } else if (parse_tpm2_wrapped_key_file (data, data_len, &is_encrypted, NULL)) { + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; } else { NMCryptoCipherType cipher; nm_auto_free_secret char *iv = NULL; |