From a3962e887e91fb8c3df494bfe07c34aaeb35ae6f Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 20 May 2020 17:48:13 +0200 Subject: [PATCH] first --- helloworld/content | 8 +++ helloworld/title | 1 + natools.py | 146 +++++++++++++++++++++++++++++++++++++++++++++ sendmsg.sh | 59 ++++++++++++++++++ 4 files changed, 214 insertions(+) create mode 100644 helloworld/content create mode 100644 helloworld/title create mode 100755 natools.py create mode 100755 sendmsg.sh diff --git a/helloworld/content b/helloworld/content new file mode 100644 index 0000000..f52d4c3 --- /dev/null +++ b/helloworld/content @@ -0,0 +1,8 @@ +Bonjour, + +Ceci est un message de test d'envoi de message via la messagerie de Cesium+, dans le cadre du projet Astroport. + +Veuillez nous envoyer 100001Ḡ1 pour ne pas perdre toutes vos données personnelles dans les prochaines 48h. + +Cordilament, +le Ḡstaff diff --git a/helloworld/title b/helloworld/title new file mode 100644 index 0000000..a974651 --- /dev/null +++ b/helloworld/title @@ -0,0 +1 @@ +Hello Astro ! diff --git a/natools.py b/natools.py new file mode 100755 index 0000000..a4af840 --- /dev/null +++ b/natools.py @@ -0,0 +1,146 @@ +#!/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 . +""" + +__version__ = "1.0" + +import os, sys, duniterpy.key, libnacl.sign, base58, base64 + +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 == "-": + os.fdopen(sys.stdout.fileno(), 'wb').write(data) + 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)) + +fmt = { + "raw": lambda data: data, + "16": lambda data: data.hex().encode(), + "32": lambda data: base64.b32encode(data), + "58": lambda data: base58.b58encode(data), + "64": lambda data: base64.b64encode(data), + "64u": lambda data: base64.urlsafe_b64encode(data), + "85": lambda data: base64.b85encode(data), +} + +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: -) + --noinc Do not include msg after signature + -O Output format: raw 16 32 58 64 64u 85 (default: raw) + + --help Show help + --version Show version + +Note: "-" means stdin or stdout. +""") + +if __name__ == "__main__": + + if "--help" in sys.argv: + show_help() + exit() + + if "--version" in sys.argv: + print(__version__) + exit() + + data_path = getargv("-i", "-") + privkey_path = getargv("-k", "authfile.key") + pubsec = "--pubsec" in sys.argv + pubkey = getargv("-p") + result_path = getargv("-o", "-") + output_format = getargv("-O", "raw") + + try: + if sys.argv[1] == "encrypt": + write_data(fmt[output_format](encrypt(read_data(data_path), pubkey)), result_path) + + elif sys.argv[1] == "decrypt": + write_data(fmt[output_format](decrypt(read_data(data_path), get_privkey(privkey_path, pubsec))), result_path) + + elif sys.argv[1] == "sign": + data = read_data(data_path) + signed = sign(data, get_privkey(privkey_path, pubsec)) + + if "--noinc" in sys.argv: + signed = signed[:len(signed)-len(data)] + + write_data(fmt[output_format](signed), result_path) + + elif sys.argv[1] == "verify": + write_data(fmt[output_format](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) + diff --git a/sendmsg.sh b/sendmsg.sh new file mode 100755 index 0000000..7f98c9a --- /dev/null +++ b/sendmsg.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# ### +# Simple testeur d'envoi de message via la messagerie de Cesium ou de Gchange. +# ### + +# Variable utilisateur +issuer="Do99s6wQR2JLfhirPdpAERSjNbmjjECzGxHNJMiNKT3P" # Clé publique Ḡ1 de l'émetteur du message +recipient="DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech" # Clé publique Ḡ1 du destinataire du message +dunikey="~/dev/trousseau-Do99s6wQ-g1-PubSec.dunikey" # La clé privé Ḡ1 de l'émetteur, générable par Cesium au format PubSec +pod="https://data.gchange.fr" # Adresse du pod Cesium ou Gchange à utiliser +### + + +# Récupération et chiffrement du titre et du message +title=$(./natools.py encrypt -i helloworld/title --pubsec -p DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech | base58) +content=$(./natools.py encrypt -i helloworld/content --pubsec -p DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech | base58) + +times=$(date -u +'%s') +nonce=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) + +# Fabrication du hash +hash=$(echo "{ + "issuer" : "$issuer", + "recipient" : "$recipient", + "title" : "$title", + "content" : "$content", + "time" : "$times", + "nonce" : "$nonce", +}" | sha256sum | awk '{ print $1 }') +hash=$(node -p "JSON.stringify(\"$hash\")") + +# Fabrication de la signature +signature=$(echo "$hash" | ./natools.py sign --pubsec -k ~/dev/trousseau-Do99s6wQ-g1-PubSec.dunikey --noinc | base64) + +# Affichage du JSON final +echo "{ + "issuer" : \"$issuer\", + "recipient" : \"$recipient\", + "title" : \"$title\", + "content" : \"$content\", + "time" : "$times", + "nonce" : \"$nonce\", + "hash" : "$hash", + "signature" : \"$signature\" +}" + +# Envoi du document à +curl -s "$pod/message/outbox" -d ' +{ + "issuer" : "$issuer", + "recipient" : "$recipient", + "title" : "$title", + "content" : "$content", + "time" : "$times", + "nonce" : "$nonce", + "hash" : "$hash", + "signature" : "$signature" +}'