diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 23deeed272..801014af11 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -34,8 +34,12 @@ static int search_policy_hash( return log_error_errno(r, "Failed to read JSON token data off disk: %m"); keyslot = cryptsetup_get_keyslot_from_token(v); - if (keyslot < 0) - return log_error_errno(keyslot, "Failed to determine keyslot of JSON token: %m"); + if (keyslot < 0) { + /* Handle parsing errors of the keyslots field gracefully, since it's not 'owned' by + * us, but by the LUKS2 spec */ + log_warning_errno(keyslot, "Failed to determine keyslot of JSON token %i, skipping: %m", token); + continue; + } w = json_variant_by_key(v, "tpm2-policy-hash"); if (!w || !json_variant_is_string(w)) diff --git a/src/cryptsetup/cryptsetup-fido2.c b/src/cryptsetup/cryptsetup-fido2.c index 74b6bff1aa..3a870016d3 100644 --- a/src/cryptsetup/cryptsetup-fido2.c +++ b/src/cryptsetup/cryptsetup-fido2.c @@ -133,6 +133,7 @@ int find_fido2_auto_data( for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token ++) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; JsonVariant *w; + int ks; r = cryptsetup_get_token_as_json(cd, token, "systemd-fido2", &v); if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) @@ -140,10 +141,21 @@ int find_fido2_auto_data( if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); + ks = cryptsetup_get_keyslot_from_token(v); + if (ks < 0) { + /* Handle parsing errors of the keyslots field gracefully, since it's not 'owned' by + * us, but by the LUKS2 spec */ + log_warning_errno(ks, "Failed to extract keyslot index from FIDO2 JSON data token %i, skipping: %m", token); + continue; + } + if (cid) return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Multiple FIDO2 tokens enrolled, cannot automatically determine token."); + assert(keyslot < 0); + keyslot = ks; + w = json_variant_by_key(v, "fido2-credential"); if (!w || !json_variant_is_string(w)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -165,11 +177,6 @@ int find_fido2_auto_data( if (r < 0) return log_error_errno(r, "Failed to decode base64 encoded salt."); - assert(keyslot < 0); - keyslot = cryptsetup_get_keyslot_from_token(v); - if (keyslot < 0) - return log_error_errno(keyslot, "Failed to extract keyslot index from FIDO2 JSON data: %m"); - w = json_variant_by_key(v, "fido2-rp"); if (w) { /* The "rp" field is optional. */ diff --git a/src/cryptsetup/cryptsetup-pkcs11.c b/src/cryptsetup/cryptsetup-pkcs11.c index 31960de597..f991389aa5 100644 --- a/src/cryptsetup/cryptsetup-pkcs11.c +++ b/src/cryptsetup/cryptsetup-pkcs11.c @@ -111,6 +111,7 @@ int find_pkcs11_auto_data( for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; JsonVariant *w; + int ks; r = cryptsetup_get_token_as_json(cd, token, "systemd-pkcs11", &v); if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) @@ -118,10 +119,21 @@ int find_pkcs11_auto_data( if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); + ks = cryptsetup_get_keyslot_from_token(v); + if (ks < 0) { + /* Handle parsing errors of the keyslots field gracefully, since it's not 'owned' by + * us, but by the LUKS2 spec */ + log_warning_errno(ks, "Failed to extract keyslot index from PKCS#11 JSON data token %i, skipping: %m", token); + continue; + } + if (uri) return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Multiple PKCS#11 tokens enrolled, cannot automatically determine token."); + assert(keyslot < 0); + keyslot = ks; + w = json_variant_by_key(v, "pkcs11-uri"); if (!w || !json_variant_is_string(w)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -145,11 +157,6 @@ int find_pkcs11_auto_data( r = unbase64mem(json_variant_string(w), SIZE_MAX, &key, &key_size); if (r < 0) return log_error_errno(r, "Failed to decode base64 encoded key."); - - assert(keyslot < 0); - keyslot = cryptsetup_get_keyslot_from_token(v); - if (keyslot < 0) - return log_error_errno(keyslot, "Failed to extract keyslot index from PKCS#11 JSON data: %m"); } if (!uri) diff --git a/src/cryptsetup/cryptsetup-tpm2.c b/src/cryptsetup/cryptsetup-tpm2.c index 4d95dacca5..8757212969 100644 --- a/src/cryptsetup/cryptsetup-tpm2.c +++ b/src/cryptsetup/cryptsetup-tpm2.c @@ -93,6 +93,7 @@ int find_tpm2_auto_data( for (token = start_token; token < sym_crypt_token_max(CRYPT_LUKS2); token++) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; JsonVariant *w, *e; + int ks; r = cryptsetup_get_token_as_json(cd, token, "systemd-tpm2", &v); if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) @@ -100,6 +101,14 @@ int find_tpm2_auto_data( if (r < 0) return log_error_errno(r, "Failed to read JSON token data off disk: %m"); + ks = cryptsetup_get_keyslot_from_token(v); + if (ks < 0) { + /* Handle parsing errors of the keyslots field gracefully, since it's not 'owned' by + * us, but by the LUKS2 spec */ + log_warning_errno(ks, "Failed to extract keyslot index from TPM2 JSON data token %i, skipping: %m", token); + continue; + } + w = json_variant_by_key(v, "tpm2-pcrs"); if (!w || !json_variant_is_array(w)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -125,6 +134,9 @@ int find_tpm2_auto_data( search_pcr_mask != pcr_mask) /* PCR mask doesn't match what is configured, ignore this entry */ continue; + assert(keyslot < 0); + keyslot = ks; + assert(pcr_bank == UINT16_MAX); assert(primary_alg == TPM2_ALG_ECC); @@ -184,11 +196,6 @@ int find_tpm2_auto_data( return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid base64 data in 'tpm2-policy-hash' field."); - assert(keyslot < 0); - keyslot = cryptsetup_get_keyslot_from_token(v); - if (keyslot < 0) - return log_error_errno(keyslot, "Failed to extract keyslot index from TPM2 JSON data: %m"); - break; }