homed: AddSigningKey: only feed data to OpenSSL _after_ Polkit auth

As a hardening measure it makes sense not to process potentially crafted
data in `openssl_pubkey_to_pem()` before we know that the caller is
authorized to perform the action.
This commit is contained in:
Matthias Gerstner
2025-08-27 10:18:41 +02:00
committed by Yu Watanabe
parent a521e76dc8
commit 1158545ef7

View File

@@ -969,24 +969,9 @@ static int method_add_signing_key(sd_bus_message *message, void *userdata, sd_bu
if (streq(fn, "local.public"))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Refusing to write local public key.");
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
r = openssl_pubkey_from_pem(pem, /* pem_size= */ SIZE_MAX, &pkey);
if (r == -EIO)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Public key invalid: %s", fn);
if (r < 0)
return r;
if (hashmap_contains(m->public_keys, fn))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Public key name already exists: %s", fn);
/* Make sure the local key is loaded before can detect conflicts */
r = manager_acquire_key_pair(m);
if (r < 0)
return r;
if (manager_has_public_key(m, pkey))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Public key already exists: %s", fn);
r = bus_verify_polkit_async(
message,
"org.freedesktop.home1.manage-signing-keys",
@@ -998,6 +983,21 @@ static int method_add_signing_key(sd_bus_message *message, void *userdata, sd_bu
if (r == 0)
return 1; /* Will call us back */
_cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
r = openssl_pubkey_from_pem(pem, /* pem_size= */ SIZE_MAX, &pkey);
if (r == -EIO)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Public key invalid: %s", fn);
if (r < 0)
return r;
/* Make sure the local key is loaded before can detect conflicts */
r = manager_acquire_key_pair(m);
if (r < 0)
return r;
if (manager_has_public_key(m, pkey))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Public key already exists: %s", fn);
_cleanup_free_ char *pem_reformatted = NULL;
r = openssl_pubkey_to_pem(pkey, &pem_reformatted);
if (r < 0)