diff --git a/duniterpy/key/signing_key.py b/duniterpy/key/signing_key.py index 4d33d19e20d0f70319f4ae06d94280f61f7645cb..f825164ee2aaa9f7ef0ea388b90e8ae11f94d5d6 100644 --- a/duniterpy/key/signing_key.py +++ b/duniterpy/key/signing_key.py @@ -14,6 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import base64 +import os import re from hashlib import scrypt, sha256 from pathlib import Path @@ -36,6 +37,10 @@ from .scrypt_params import ScryptParams SigningKeyType = TypeVar("SigningKeyType", bound="SigningKey") +def opener_user_rw(path, flags): + return os.open(path, flags, 0o600) + + class SigningKey(libnacl.sign.Signer): def __init__(self, seed: bytes) -> None: """ @@ -92,7 +97,7 @@ class SigningKey(libnacl.sign.Signer): :return: """ # capture credentials from file - with open(path, encoding="utf-8") as fh: + with open(path, encoding="utf-8", opener=opener_user_rw) as fh: lines = fh.readlines() assert len(lines) > 1 salt = lines[0].strip() @@ -107,7 +112,7 @@ class SigningKey(libnacl.sign.Signer): :param path: Authentication file path """ seedhex = convert_seed_to_seedhex(self.seed) - with open(path, "w", encoding="utf-8") as fh: + with open(path, "w", encoding="utf-8", opener=opener_user_rw) as fh: fh.write(seedhex) @staticmethod @@ -179,7 +184,7 @@ class SigningKey(libnacl.sign.Signer): :param path: Path to WIF file """ - with open(path, encoding="utf-8") as fh: + with open(path, encoding="utf-8", opener=opener_user_rw) as fh: pubsec_content = fh.read() # line patterns @@ -221,7 +226,7 @@ class SigningKey(libnacl.sign.Signer): Version: {version}\n\ pub: {self.pubkey}\n\ sec: {base58_signing_key}" - with open(path, "w", encoding="utf-8") as fh: + with open(path, "w", encoding="utf-8", opener=opener_user_rw) as fh: fh.write(content) @staticmethod @@ -341,7 +346,7 @@ sec: {base58_signing_key}" content = f"Type: WIF\n\ Version: {version}\n\ Data: {wif_key}" - with open(path, "w", encoding="utf-8") as fh: + with open(path, "w", encoding="utf-8", opener=opener_user_rw) as fh: fh.write(content) @staticmethod @@ -471,7 +476,7 @@ Data: {wif_key}" content = f"Type: EWIF\n\ Version: {version}\n\ Data: {ewif_key}" - with open(path, "w", encoding="utf-8") as fh: + with open(path, "w", encoding="utf-8", opener=opener_user_rw) as fh: fh.write(content) @classmethod diff --git a/tests/key/test_signing_key.py b/tests/key/test_signing_key.py index 26ee0fcad6c93e42ee6c6258889416432710defb..b2589b33498f8baa8a95782f2bb24b2b8454d5cf 100644 --- a/tests/key/test_signing_key.py +++ b/tests/key/test_signing_key.py @@ -52,6 +52,13 @@ class TestSigningKey(unittest.TestCase): sign_key_load = SigningKey.from_seedhex_file(TEST_FILE_PATH) self.assertEqual(sign_key_save.sk, sign_key_load.sk) + def test_permissions_save_seedhex_file(self): + sign_key_save = SigningKey.from_credentials("alice", "password", ScryptParams()) + sign_key_save.save_seedhex_file(TEST_FILE_PATH) + + # https://www.geeksforgeeks.org/how-to-get-the-permission-mask-of-a-file-in-python/ + assert oct(os.stat(TEST_FILE_PATH).st_mode)[-3:] == "600" + def test_save_and_load_from_pubsec_file(self): sign_key_save = SigningKey.from_credentials("alice", "password", ScryptParams()) sign_key_save.save_pubsec_file(TEST_FILE_PATH)