From 45bb1bfa3c48e7f6a315c365884ce6d15bb31a23 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Sun, 3 Jan 2021 16:59:24 +0100 Subject: [PATCH] hsmd: cleanup encrypted hsm_secret detection This makes use of the constant defined in the previous commits to more accurately detect plaintext, encrypted, and invalid seeds. We now error on invalid seeds. Changelog-changed: hsmd: we now error at startup on invalid hsm_secret Changelog-changed: hsmtool: all commands now error on invalid hsm_secret Signed-off-by: Antoine Poinsot --- hsmd/hsmd.c | 14 ++++++++++---- lightningd/hsm_control.c | 4 +++- tools/hsmtool.c | 11 ++++++++--- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index f2d3cfbf6..2356945fc 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -666,7 +666,7 @@ static void load_hsm(const struct secret *encryption_key) "stating: %s", strerror(errno)); /* If the seed is stored in clear. */ - if (st.st_size <= 32) { + if (st.st_size == 32) { if (!read_all(fd, &secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret))) status_failed(STATUS_FAIL_INTERNAL_ERROR, "reading: %s", strerror(errno)); @@ -686,11 +686,14 @@ static void load_hsm(const struct secret *encryption_key) "opening: %s", strerror(errno)); } } - /*~ If an encryption key was passed and the `hsm_secret` is stored + /* If an encryption key was passed and the `hsm_secret` is stored * encrypted, recover the seed from the cipher. */ - if (encryption_key && st.st_size > 32) { + else if (st.st_size == ENCRYPTED_HSM_SECRET_LEN) { struct encrypted_hsm_secret encrypted_secret; + /* hsm_control must have checked it! */ + assert(encryption_key); + if (!read_all(fd, encrypted_secret.data, ENCRYPTED_HSM_SECRET_LEN)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Reading encrypted hsm_secret: %s", strerror(errno)); @@ -702,7 +705,10 @@ static void load_hsm(const struct secret *encryption_key) exit(1); } } - /* else { handled in hsm_control } */ + else + status_failed(STATUS_FAIL_INTERNAL_ERROR, "Invalid hsm_secret, " + "no plaintext nor encrypted" + " seed."); close(fd); populate_secretstuff(); diff --git a/lightningd/hsm_control.c b/lightningd/hsm_control.c index 15e5eb388..b05e5a219 100644 --- a/lightningd/hsm_control.c +++ b/lightningd/hsm_control.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -106,7 +107,8 @@ struct ext_key *hsm_init(struct lightningd *ld) * actual secret. */ if (!ld->config.keypass) { struct stat st; - if (stat("hsm_secret", &st) == 0 && st.st_size > 32) + if (stat("hsm_secret", &st) == 0 && + st.st_size == ENCRYPTED_HSM_SECRET_LEN) errx(1, "hsm_secret is encrypted, you need to pass the " "--encrypted-hsm startup option."); } diff --git a/tools/hsmtool.c b/tools/hsmtool.c index 28e072279..af8a73deb 100644 --- a/tools/hsmtool.c +++ b/tools/hsmtool.c @@ -145,14 +145,19 @@ static void get_channel_seed(struct secret *channel_seed, struct node_id *peer_i info, strlen(info)); } -/* We detect an encrypted hsm_secret as a hsm_secret which is larger than - * the plaintext seed. */ +/* We detect an encrypted hsm_secret as a hsm_secret which is 73-bytes long. */ static bool hsm_secret_is_encrypted(const char *hsm_secret_path) { struct stat st; + if (stat(hsm_secret_path, &st) != 0) errx(ERROR_HSM_FILE, "Could not stat hsm_secret"); - return st.st_size > 32; + + if (st.st_size != 32 && st.st_size != ENCRYPTED_HSM_SECRET_LEN) + errx(ERROR_HSM_FILE, "Invalid hsm_secret (neither plaintext " + "nor encrypted)."); + + return st.st_size == ENCRYPTED_HSM_SECRET_LEN; } static int decrypt_hsm(const char *hsm_secret_path)