(node_factory)
| 1048 | |
| 1049 | @unittest.skipIf(VALGRIND, "It does not play well with prompt and key derivation.") |
| 1050 | def test_hsm_secret_encryption(node_factory): |
| 1051 | l1 = node_factory.get_node(may_fail=True) # May fail when started without key |
| 1052 | password = "reckful&é🍕\n" |
| 1053 | # We need to simulate a terminal to use termios in `lightningd`. |
| 1054 | master_fd, slave_fd = os.openpty() |
| 1055 | |
| 1056 | # Test we can encrypt an already-existing and not encrypted hsm_secret |
| 1057 | l1.stop() |
| 1058 | l1.daemon.opts.update({"encrypted-hsm": None}) |
| 1059 | l1.daemon.start(stdin=slave_fd, wait_for_initialized=False) |
| 1060 | l1.daemon.wait_for_log(r'Enter hsm_secret password') |
| 1061 | write_all(master_fd, password.encode("utf-8")) |
| 1062 | l1.daemon.wait_for_log(r'Confirm hsm_secret password') |
| 1063 | write_all(master_fd, password.encode("utf-8")) |
| 1064 | l1.daemon.wait_for_log("Server started with public key") |
| 1065 | id = l1.rpc.getinfo()["id"] |
| 1066 | l1.stop() |
| 1067 | |
| 1068 | # Test we cannot start the same wallet without specifying --encrypted-hsm |
| 1069 | l1.daemon.opts.pop("encrypted-hsm") |
| 1070 | with pytest.raises(subprocess.CalledProcessError, match=r'returned non-zero exit status {}'.format(HSM_ERROR_IS_ENCRYPT)): |
| 1071 | subprocess.check_call(l1.daemon.cmd_line) |
| 1072 | |
| 1073 | # Test we cannot restore the same wallet with another password |
| 1074 | l1.daemon.opts.update({"encrypted-hsm": None}) |
| 1075 | l1.daemon.start(stdin=slave_fd, wait_for_initialized=False, stderr_redir=True) |
| 1076 | l1.daemon.wait_for_log(r'Enter hsm_secret password') |
| 1077 | write_all(master_fd, password[2:].encode("utf-8")) |
| 1078 | assert(l1.daemon.proc.wait(WAIT_TIMEOUT) == HSM_BAD_PASSWORD) |
| 1079 | assert(l1.daemon.is_in_stderr("Wrong password for encrypted hsm_secret.")) |
| 1080 | |
| 1081 | # Not sure why this helps, but seems to reduce flakiness where |
| 1082 | # tail() thread in testing/utils.py gets 'ValueError: readline of |
| 1083 | # closed file' and we get `ValueError: Process died while waiting for logs` |
| 1084 | # when waiting for "Server started with public key" below. |
| 1085 | time.sleep(10) |
| 1086 | |
| 1087 | # Test we can restore the same wallet with the same password |
| 1088 | l1.daemon.start(stdin=slave_fd, wait_for_initialized=False) |
| 1089 | l1.daemon.wait_for_log(r'The hsm_secret is encrypted') |
| 1090 | write_all(master_fd, password.encode("utf-8")) |
| 1091 | l1.daemon.wait_for_log("Server started with public key") |
| 1092 | assert id == l1.rpc.getinfo()["id"] |
| 1093 | l1.stop() |
| 1094 | |
| 1095 | # We can restore the same wallet with the same password provided through stdin |
| 1096 | l1.daemon.start(stdin=subprocess.PIPE, wait_for_initialized=False) |
| 1097 | l1.daemon.proc.stdin.write(password.encode("utf-8")) |
| 1098 | l1.daemon.proc.stdin.flush() |
| 1099 | l1.daemon.wait_for_log("Server started with public key") |
| 1100 | assert id == l1.rpc.getinfo()["id"] |
| 1101 | |
| 1102 | |
| 1103 | class HsmTool(TailableProc): |
nothing calls this directly
no test coverage detected