diff --git a/src/creds/creds.c b/src/creds/creds.c index 380fd316d4..ab3beabc02 100644 --- a/src/creds/creds.c +++ b/src/creds/creds.c @@ -1419,6 +1419,16 @@ static int vl_method_decrypt(sd_varlink *link, sd_json_variant *parameters, sd_v return sd_varlink_error(link, "io.systemd.Credentials.NoSuchUser", NULL); if (r == -EMEDIUMTYPE) return sd_varlink_error(link, "io.systemd.Credentials.BadScope", NULL); + if (r == -EHOSTDOWN) + return sd_varlink_error(link, "io.systemd.Credentials.CantFindPCRSignature", NULL); + if (r == -EHWPOISON) + return sd_varlink_error(link, "io.systemd.Credentials.NullKeyNotAllowed", NULL); + if (r == -EREMOTE) + return sd_varlink_error(link, "io.systemd.Credentials.KeyBelongsToOtherTPM", NULL); + if (r == -ENOLCK) + return sd_varlink_error(link, "io.systemd.Credentials.TPMInDictionaryLockout", NULL); + if (IN_SET(r, -EREMCHG, -ENOANO, -EUCLEAN, -EPERM)) + return sd_varlink_error(link, "io.systemd.Credentials.UnexpectedPCRState", NULL); if (r < 0) return r; diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c index 1e5cd937b4..c4762fe1e4 100644 --- a/src/shared/creds-util.c +++ b/src/shared/creds-util.c @@ -1652,16 +1652,26 @@ int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp, if (r < 0) return log_error_errno(r, "Failed to call Decrypt() varlink call."); if (!isempty(error_id)) { - if (streq(error_id, "io.systemd.Credentials.BadFormat")) - return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Bad credential format."); - if (streq(error_id, "io.systemd.Credentials.NameMismatch")) - return log_error_errno(SYNTHETIC_ERRNO(EDESTADDRREQ), "Name in credential doesn't match expectations."); - if (streq(error_id, "io.systemd.Credentials.TimeMismatch")) - return log_error_errno(SYNTHETIC_ERRNO(ESTALE), "Outside of credential validity time window."); - if (streq(error_id, "io.systemd.Credentials.NoSuchUser")) - return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "No such user."); - if (streq(error_id, "io.systemd.Credentials.BadScope")) - return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Scope mismtach."); + static struct { + const char *id; + int errnum; + const char *msg; + } table[] = { + { "io.systemd.Credentials.BadFormat", EBADMSG, "Bad credential format." }, + { "io.systemd.Credentials.NameMismatch", EDESTADDRREQ, "Name in credential doesn't match expectations." }, + { "io.systemd.Credentials.TimeMismatch", ESTALE, "Outside of credential validity time window." }, + { "io.systemd.Credentials.NoSuchUser", ESRCH, "No such user." }, + { "io.systemd.Credentials.BadScope", EMEDIUMTYPE, "Scope mismatch." }, + { "io.systemd.Credentials.CantFindPCRSignature", EHOSTDOWN, "PCR signature required for decryption, but could not be found." }, + { "io.systemd.Credentials.NullKeyNotAllowed", EHWPOISON, "The key was encrypted with a null key, but that's now allowed during decryption." }, + { "io.systemd.Credentials.KeyBelongsToOtherTPM", EREMOTE, "The TPM integrity check for this key failed, key probably belongs to another TPM, or was corrupted." }, + { "io.systemd.Credentials.TPMInDictionaryLockout", ENOLCK, "The TPM is in dictionary lockout mode, cannot operate." }, + { "io.systemd.Credentials.UnexpectedPCRState" , EUCLEAN, "Unexpected TPM PCR state of the system." }, + }; + + FOREACH_ELEMENT(i, table) + if (streq(i->id, error_id)) + return log_error_errno(SYNTHETIC_ERRNO(i->errnum), "%s", i->msg); return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id); } diff --git a/src/shared/varlink-io.systemd.Credentials.c b/src/shared/varlink-io.systemd.Credentials.c index 69e36cda91..ab99adefe5 100644 --- a/src/shared/varlink-io.systemd.Credentials.c +++ b/src/shared/varlink-io.systemd.Credentials.c @@ -44,6 +44,11 @@ static SD_VARLINK_DEFINE_ERROR(NameMismatch); static SD_VARLINK_DEFINE_ERROR(TimeMismatch); static SD_VARLINK_DEFINE_ERROR(NoSuchUser); static SD_VARLINK_DEFINE_ERROR(BadScope); +static SD_VARLINK_DEFINE_ERROR(CantFindPCRSignature); +static SD_VARLINK_DEFINE_ERROR(NullKeyNotAllowed); +static SD_VARLINK_DEFINE_ERROR(KeyBelongsToOtherTPM); +static SD_VARLINK_DEFINE_ERROR(TPMInDictionaryLockout); +static SD_VARLINK_DEFINE_ERROR(UnexpectedPCRState); SD_VARLINK_DEFINE_INTERFACE( io_systemd_Credentials, @@ -62,4 +67,14 @@ SD_VARLINK_DEFINE_INTERFACE( SD_VARLINK_SYMBOL_COMMENT("The specified user does not exist."), &vl_error_NoSuchUser, SD_VARLINK_SYMBOL_COMMENT("The credential does not match the selected scope."), - &vl_error_BadScope); + &vl_error_BadScope, + SD_VARLINK_SYMBOL_COMMENT("PCR signature required for decryption, but not found."), + &vl_error_CantFindPCRSignature, + SD_VARLINK_SYMBOL_COMMENT("The key was encrypted with a null key, but that's now allowed during decryption."), + &vl_error_NullKeyNotAllowed, + SD_VARLINK_SYMBOL_COMMENT("The TPM integrity check for this key failed, key probably belongs to another TPM, or was corrupted."), + &vl_error_KeyBelongsToOtherTPM, + SD_VARLINK_SYMBOL_COMMENT("The TPM is in dictionary lockout mode, cannot operate."), + &vl_error_TPMInDictionaryLockout, + SD_VARLINK_SYMBOL_COMMENT("Unexpected TPM PCR state of the system."), + &vl_error_UnexpectedPCRState);