inital
This commit is contained in:
119
ob_save.py
Normal file
119
ob_save.py
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import gnupg
|
||||
|
||||
""" Now rewrite all this doodoo into a proper class """
|
||||
|
||||
gnupg_homedir = "./gnupg_home/"
|
||||
keyring_file = "pubring.kbx"
|
||||
json_filename = 'json_stuff.txt'
|
||||
|
||||
gpg = gnupg.GPG(gnupghome=gnupg_homedir, keyring=gnupg_homedir+keyring_file)
|
||||
|
||||
|
||||
def get_fingerprint_by_email(email):
|
||||
for key in gpg.list_keys():
|
||||
if email in key["uids"][0]:
|
||||
return key["fingerprint"]
|
||||
return None
|
||||
|
||||
|
||||
def get_keyid_by_email(email):
|
||||
for key in gpg.list_keys():
|
||||
if email in key["uids"][0]:
|
||||
return key["keyid"]
|
||||
return None
|
||||
|
||||
|
||||
def read_gpg_file(filename: str, verify: bool = None) -> dict:
|
||||
"""
|
||||
Opposite function of write_gpg_file()
|
||||
splits message, signature and hash from input file.
|
||||
reads file line by line and uses a nasty state machine looking for magic strings to determine what goes where.
|
||||
|
||||
:param filename: path to file to be read, usually ends with .pgp
|
||||
:param verify: Should
|
||||
:return: dict -> {"json": str, "pgp_signature": str, "hash": str, "verified": bool}
|
||||
|
||||
json = json payload form file as string, can be loaded to dict with json.loads(read_gpg_file(filename)["json"])
|
||||
pgp_signature = string representation of signature, use this to verify signature.
|
||||
hash = hash function used. Might be useful, might not.
|
||||
verified = Whenever signature verification was successful
|
||||
"""
|
||||
# Magic strings to look for
|
||||
gpg_msg_start = "-----BEGIN PGP SIGNED MESSAGE-----\n"
|
||||
gpg_sig_start = "-----BEGIN PGP SIGNATURE-----\n"
|
||||
gpg_sig_end = "-----END PGP SIGNATURE-----\n"
|
||||
|
||||
# Empty strings to prepare return.
|
||||
complete_msg = ""
|
||||
out_string = ""
|
||||
hash = ""
|
||||
out_signature = ""
|
||||
verified = None
|
||||
|
||||
# Behold... the mighty state machine
|
||||
msg_start_found = False
|
||||
sig_start_found = False
|
||||
with open(filename, "r") as f:
|
||||
for line in f.readlines():
|
||||
complete_msg += line
|
||||
if not msg_start_found:
|
||||
if line == gpg_msg_start:
|
||||
msg_start_found = True
|
||||
continue
|
||||
if line.startswith("Hash"):
|
||||
hash += line.split(" ")[1].rstrip() # Remove unused whitespace
|
||||
continue
|
||||
if line == gpg_sig_start:
|
||||
sig_start_found = True
|
||||
continue
|
||||
if not sig_start_found:
|
||||
out_string += line.lstrip().rstrip() # Remove unused whitespace
|
||||
if sig_start_found and msg_start_found and line != gpg_sig_end:
|
||||
out_signature += line.lstrip().rstrip() # Remove unused whitespace
|
||||
if line == gpg_sig_end:
|
||||
break
|
||||
if verify:
|
||||
verified = gpg.verify(complete_msg).status
|
||||
else:
|
||||
verified = None
|
||||
return {"json": out_string, "pgp_signature": out_signature, "hash": hash, "verified": verified}
|
||||
|
||||
|
||||
def write_gpg_file(payload_to_sign: dict, filename: str, fingerprint=None) -> bool:
|
||||
"""
|
||||
:param payload_to_sign: dictonary that should be signed and written to disk.
|
||||
:param filename: target filename WITHOUT .gpg extention!
|
||||
:param fingerprint: OPTIONAL fingerprint (string) (Not yet implemented)
|
||||
:return: True if any data was written, else prints error message and returns False
|
||||
"""
|
||||
if type(payload_to_sign) != dict:
|
||||
print("Could not write {}, invalid payload. \n"
|
||||
"Ensure to only pass object type: \"dict\"".format(filename))
|
||||
return False
|
||||
|
||||
with open(filename+".gpg", "w") as f:
|
||||
json.dump(payload_to_sign, f)
|
||||
with open(filename+".gpg", "rb") as f:
|
||||
signed_string = gpg.sign_file(f, keyid=fingerprint)
|
||||
print("Signing with {}".format(fingerprint))
|
||||
with open(filename+".gpg", "w") as f:
|
||||
if f.write(str(signed_string)):
|
||||
return True
|
||||
else:
|
||||
print("Could not write {}, 0 bytes written!\n"
|
||||
"This message should be impossible to reach, well done.".format(filename))
|
||||
return False
|
||||
|
||||
|
||||
def verify_gpg_json(payload: str, signature: str) -> bool:
|
||||
"""
|
||||
Placeholder function to verify if pgp signed json is valid.
|
||||
:param payload: Complete pgp message with headers and signature
|
||||
:param signature:
|
||||
:return:
|
||||
"""
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user