#!/usr/bin/env python3 """ CopyLeft 2020 Pascal Engélibert This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . """ import os, sys, duniterpy.key, libnacl.sign def getargv(arg:str, default:str="", n:int=1, args:list=sys.argv) -> str: if arg in args and len(args) > args.index(arg)+n: return args[args.index(arg)+n] else: return default def read_data(data_path, b=True): if data_path == "-": if b: return sys.stdin.read().encode() else: return sys.stdin.read() else: return open(os.path.expanduser(data_path), "rb" if b else "r").read() def write_data(data, result_path): if result_path == "-": sys.stdout.write(data.decode()) else: open(os.path.expanduser(result_path), "wb").write(data) def encrypt(data, pubkey): return duniterpy.key.PublicKey(pubkey).encrypt_seal(data) def decrypt(data, privkey): return privkey.decrypt_seal(data) def sign(data, privkey): return privkey.sign(data) def verify(data, pubkey): try: sys.stderr.write("Signature OK!\n") return libnacl.sign.Verifier(duniterpy.key.PublicKey(pubkey).hex_pk()).verify(data) except ValueError: sys.stderr.write("Bad signature!\n") exit(1) def get_privkey(privkey_path, pubsec): if pubsec: return duniterpy.key.SigningKey.from_pubsec_file(privkey_path) else: return duniterpy.key.SigningKey.from_seedhex(read_data(privkey_path, False)) def show_help(): print("""Usage: python3 natools.py [options] Commands: encrypt Encrypt data decrypt Decrypt data sign Sign data verify Verify data Options: -i Input file path (default: -) -k Privkey file path (default: authfile.key) --pubsec Use pub/sec format for -p -p Pubkey (base58) -o Output file path (default: -) Note: "-" means stdin or stdout. """) if __name__ == "__main__": if "--help" in sys.argv: show_help() exit() data_path = getargv("-i", "-") privkey_path = getargv("-k", "authfile.key") pubsec = "--pubsec" in sys.argv pubkey = getargv("-p") result_path = getargv("-o", "-") try: if sys.argv[1] == "encrypt": write_data(encrypt(read_data(data_path), pubkey), result_path) elif sys.argv[1] == "decrypt": write_data(decrypt(read_data(data_path), get_privkey(privkey_path, pubsec)), result_path) elif sys.argv[1] == "sign": write_data(sign(read_data(data_path), get_privkey(privkey_path, pubsec)), result_path) elif sys.argv[1] == "verify": write_data(verify(read_data(data_path), pubkey), result_path) else: show_help() except Exception as e: sys.stderr.write("Error: {}\n".format(e)) show_help() exit(1)