Add options meca; fusion message files in one; update natools; add .env

This commit is contained in:
poka 2020-11-04 15:16:03 +01:00
parent 071c945f1c
commit 3b59580084
6 changed files with 145 additions and 27 deletions

4
.env.template Normal file
View File

@ -0,0 +1,4 @@
issuer="" # Clé publique Ḡ1 de l'émetteur du message
recipient="" # Clé publique Ḡ1 du destinataire du message
dunikey="" # La clé privé Ḡ1 de l'émetteur, générable par Cesium au format PubSec
pod="https://g1.data.duniter.fr" # Noeud Cecium+ utilisé pour l'envoi du message

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.env

View File

@ -1 +0,0 @@
Hello Astro !

View File

@ -17,9 +17,9 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
__version__ = "1.0" __version__ = "1.2.2"
import os, sys, duniterpy.key, libnacl.sign, base58, base64 import os, sys, duniterpy.key, libnacl, libnacl.sign, base58, base64, getpass
def getargv(arg:str, default:str="", n:int=1, args:list=sys.argv) -> str: 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: if arg in args and len(args) > args.index(arg)+n:
@ -53,17 +53,73 @@ def sign(data, privkey):
def verify(data, pubkey): def verify(data, pubkey):
try: try:
ret = libnacl.sign.Verifier(duniterpy.key.PublicKey(pubkey).hex_pk()).verify(data)
sys.stderr.write("Signature OK!\n") sys.stderr.write("Signature OK!\n")
return libnacl.sign.Verifier(duniterpy.key.PublicKey(pubkey).hex_pk()).verify(data) return ret
except ValueError: except ValueError:
sys.stderr.write("Bad signature!\n") sys.stderr.write("Bad signature!\n")
exit(1) exit(1)
def get_privkey(privkey_path, pubsec): def get_privkey(privkey_path, privkey_format):
if pubsec: if privkey_format == "pubsec":
if privkey_path == "*":
privkey_path = "privkey.pubsec"
return duniterpy.key.SigningKey.from_pubsec_file(privkey_path) return duniterpy.key.SigningKey.from_pubsec_file(privkey_path)
else:
elif privkey_format == "cred":
if privkey_path == "*":
privkey_path = "-"
if privkey_path == "-":
return duniterpy.key.SigningKey.from_credentials(getpass.getpass("Password: "), getpass.getpass("Salt: "))
else:
return duniterpy.key.SigningKey.from_credentials_file(privkey_path)
elif privkey_format == "seedh":
if privkey_path == "*":
privkey_path = "authfile.seedhex"
return duniterpy.key.SigningKey.from_seedhex(read_data(privkey_path, False)) return duniterpy.key.SigningKey.from_seedhex(read_data(privkey_path, False))
elif privkey_format == "wif":
if privkey_path == "*":
privkey_path = "authfile.wif"
return duniterpy.key.SigningKey.from_wif_or_ewif_file(privkey_path)
elif privkey_format == "wifh":
if privkey_path == "*":
privkey_path = "authfile.wif"
return duniterpy.key.SigningKey.from_wif_or_ewif_hex(privkey_path)
elif privkey_format == "ssb":
if privkey_path == "*":
privkey_path = "secret"
return duniterpy.key.SigningKey.from_ssb_file(privkey_path)
elif privkey_format == "key":
if privkey_path == "*":
privkey_path = "authfile.key"
return duniterpy.key.SigningKey.from_private_key(privkey_path)
print("Error: unknown privkey format")
def fill_pubkey(pubkey, length=32):
while pubkey[0] == 0:
pubkey = pubkey[1:]
return b"\x00"*(length-len(pubkey)) + pubkey
def pubkey_checksum(pubkey, length=32, clength=3):
return base58.b58encode(libnacl.crypto_hash_sha256(libnacl.crypto_hash_sha256(fill_pubkey(base58.b58decode(pubkey), length)))).decode()[:clength]
# returns (pubkey:bytes|None, deprecated_length:bool)
def check_pubkey(pubkey):
if ":" in pubkey:
parts = pubkey.split(":")
if len(parts[1]) < 3 or len(parts[1]) > 32:
return (None, False)
for i in range(32, 0, -1):
if pubkey_checksum(parts[0], i, len(parts[1])) == parts[1]:
return (parts[0], i < 32)
return (None, False)
return (pubkey, False)
fmt = { fmt = {
"raw": lambda data: data, "raw": lambda data: data,
@ -84,18 +140,23 @@ Commands:
decrypt Decrypt data decrypt Decrypt data
sign Sign data sign Sign data
verify Verify data verify Verify data
pubkey Display pubkey
pk Display b58 pubkey shorthand
Options: Options:
-c Display pubkey checksum
-f <fmt> Private key format (default: cred)
key cred pubsec seedh ssb wif wifh
-i <path> Input file path (default: -) -i <path> Input file path (default: -)
-k <path> Privkey file path (default: authfile.key) -k <path> Privkey file path (* for auto) (default: *)
--pubsec Use pub/sec format for -p
-p <str> Pubkey (base58)
-o <path> Output file path (default: -)
--noinc Do not include msg after signature --noinc Do not include msg after signature
-o <path> Output file path (default: -)
-O <fmt> Output format: raw 16 32 58 64 64u 85 (default: raw) -O <fmt> Output format: raw 16 32 58 64 64u 85 (default: raw)
-p <str> Pubkey (base58)
--help Show help --help Show help
--version Show version --version Show version
--debug Debug mode (display full errors)
Note: "-" means stdin or stdout. Note: "-" means stdin or stdout.
""") """)
@ -110,23 +171,37 @@ if __name__ == "__main__":
print(__version__) print(__version__)
exit() exit()
privkey_format = getargv("-f", "cred")
data_path = getargv("-i", "-") data_path = getargv("-i", "-")
privkey_path = getargv("-k", "authfile.key") privkey_path = getargv("-k", "*")
pubsec = "--pubsec" in sys.argv
pubkey = getargv("-p") pubkey = getargv("-p")
result_path = getargv("-o", "-") result_path = getargv("-o", "-")
output_format = getargv("-O", "raw") output_format = getargv("-O", "raw")
if pubkey:
pubkey, len_deprecated = check_pubkey(pubkey)
if not pubkey:
print("Invalid pubkey checksum! Please check spelling.")
exit(1)
if len(base58.b58decode(pubkey)) > 32:
print("Invalid pubkey: too long!")
exit(1)
if len_deprecated:
print("Warning: valid pubkey checksum, but deprecated format (truncating zeros)")
try: try:
if sys.argv[1] == "encrypt": if sys.argv[1] == "encrypt":
if not pubkey:
print("Please provide pubkey!")
exit(1)
write_data(fmt[output_format](encrypt(read_data(data_path), pubkey)), result_path) write_data(fmt[output_format](encrypt(read_data(data_path), pubkey)), result_path)
elif sys.argv[1] == "decrypt": elif sys.argv[1] == "decrypt":
write_data(fmt[output_format](decrypt(read_data(data_path), get_privkey(privkey_path, pubsec))), result_path) write_data(fmt[output_format](decrypt(read_data(data_path), get_privkey(privkey_path, privkey_format))), result_path)
elif sys.argv[1] == "sign": elif sys.argv[1] == "sign":
data = read_data(data_path) data = read_data(data_path)
signed = sign(data, get_privkey(privkey_path, pubsec)) signed = sign(data, get_privkey(privkey_path, privkey_format))
if "--noinc" in sys.argv: if "--noinc" in sys.argv:
signed = signed[:len(signed)-len(data)] signed = signed[:len(signed)-len(data)]
@ -134,13 +209,38 @@ if __name__ == "__main__":
write_data(fmt[output_format](signed), result_path) write_data(fmt[output_format](signed), result_path)
elif sys.argv[1] == "verify": elif sys.argv[1] == "verify":
if not pubkey:
print("Please provide pubkey!")
exit(1)
write_data(fmt[output_format](verify(read_data(data_path), pubkey)), result_path) write_data(fmt[output_format](verify(read_data(data_path), pubkey)), result_path)
elif sys.argv[1] == "pubkey":
if pubkey:
if "-c" in sys.argv and output_format == "58":
write_data("{}:{}".format(pubkey, pubkey_checksum(pubkey)).encode(), result_path)
else:
write_data(fmt[output_format](base58.b58decode(pubkey)), result_path)
else:
pubkey = get_privkey(privkey_path, privkey_format).pubkey
if "-c" in sys.argv and output_format == "58":
write_data("{}:{}".format(pubkey, pubkey_checksum(pubkey)).encode(), result_path)
else:
write_data(fmt[output_format](base58.b58decode(pubkey)), result_path)
elif sys.argv[1] == "pk":
if not pubkey:
pubkey = get_privkey(privkey_path, privkey_format).pubkey
if "-c" in sys.argv:
print("{}:{}".format(pubkey, pubkey_checksum(pubkey)))
else:
print(pubkey)
else: else:
show_help() show_help()
except Exception as e: except Exception as e:
if "--debug" in sys.argv:
0/0 # DEBUG MODE (raise error when handling error to display backtrace)
sys.stderr.write("Error: {}\n".format(e)) sys.stderr.write("Error: {}\n".format(e))
show_help() show_help()
exit(1) exit(1)

View File

@ -4,18 +4,31 @@
# Simple testeur d'envoi de message via la messagerie de Cesium ou de Gchange. # Simple testeur d'envoi de message via la messagerie de Cesium ou de Gchange.
# ### # ###
# Variable utilisateur source .env
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
pod="https://g1.data.duniter.fr"
###
# Help display
helpOpt() {
echo -e "This is a simple tester for Cesium+ messages sender)
\rOptions:
\r$0
Default view show last day data in cumulative mode"
}
# Parse options
declare -a args=($@)
for ((i=0; i<${#args[*]}; ++i))
do
case ${args[$i]} in
-f|--file) file="${args[$i+1]}";;
-h|--help) helpOpt && exit 0;;
esac
done
[[ -z $file ]] && file="test.txt"
# Récupération et chiffrement du titre et du message # Récupération et chiffrement du titre et du message
title=$(./natools.py encrypt -i helloworld/title --pubsec -p DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech -O 58) title=$(cat $file | head -n1 | ./natools.py encrypt --pubsec -p $recipient -O 58)
content=$(./natools.py encrypt -i helloworld/content --pubsec -p DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech -O 58) content=$(cat $file | tail -n+2 | ./natools.py encrypt --pubsec -p $recipient -O 58)
times=$(date -u +'%s') times=$(date -u +'%s')
nonce=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) nonce=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
@ -26,7 +39,7 @@ hash="$(printf "%q" "$hash")"
hash=$(node -p "JSON.stringify(\"$hash\")" | sha256sum | awk '{ print $1 }') hash=$(node -p "JSON.stringify(\"$hash\")" | sha256sum | awk '{ print $1 }')
# Fabrication de la signature # Fabrication de la signature
signature=$(echo "$hash" | ./natools.py sign --pubsec -k ~/dev/trousseau-Do99s6wQ-g1-PubSec.dunikey --noinc -O 64) signature=$(echo "$hash" | ./natools.py sign -f pubsec -k $dunikey --noinc -O 64)
# Affichage du JSON final # Affichage du JSON final
echo "{ echo "{

View File

@ -1,6 +1,7 @@
Hello bot !
Bonjour, Bonjour,
Ceci est un message de test d'envoi de message via la messagerie de Cesium+, dans le cadre du projet Astroport. Ceci est un message de test d'envoi de message via la messagerie de Cesium+.
Veuillez nous envoyer 100001Ḡ1 pour ne pas perdre toutes vos données personnelles dans les prochaines 48h. Veuillez nous envoyer 100001Ḡ1 pour ne pas perdre toutes vos données personnelles dans les prochaines 48h.