Remove the old Python code.
I'm liking Rust, it's working.
This commit is contained in:
parent
d296f40eae
commit
9b66d1ee98
148
gongor/aegis.py
148
gongor/aegis.py
|
@ -1,148 +0,0 @@
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
from pathlib import Path
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from cryptography import x509
|
|
||||||
from cryptography.hazmat.primitives import hashes, serialization
|
|
||||||
from cryptography.hazmat.primitives.ciphers import aead
|
|
||||||
from cryptography.hazmat.primitives.serialization import pkcs12
|
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec, ed25519, padding
|
|
||||||
|
|
||||||
MAX_HUMAN_AGE = 365 * 200
|
|
||||||
def box():
|
|
||||||
"Take a message, put it in a box, encrypt the contents using a public key."
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("aegis_cert_pem", type=Path, help="The file for the PEM-encoded aegis public cert.")
|
|
||||||
parser.add_argument("message", type=Path, help="The file containing the message to box.")
|
|
||||||
parser.add_argument("output", type=Path, help="The path to the file where the output will go.")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
with open(args.aegis_cert_pem, "rb") as f:
|
|
||||||
certificate = x509.load_pem_x509_certificate(
|
|
||||||
data=f.read(),
|
|
||||||
)
|
|
||||||
with open(args.message, "rb") as f:
|
|
||||||
data = f.read()
|
|
||||||
|
|
||||||
shared_ecc_key, ciphered_public_key = _generate_encryption_key(certificate.public_key())
|
|
||||||
aad = b"authenticated but unencrypted data"
|
|
||||||
key = aead.ChaCha20Poly1305.generate_key()
|
|
||||||
with open("encryption.key", "wb") as f:
|
|
||||||
f.write(key)
|
|
||||||
print("Wrote encryption key to 'encryption.key'")
|
|
||||||
chacha = aead.ChaCha20Poly1305(key)
|
|
||||||
nonce = os.urandom(12)
|
|
||||||
with open("nonce", "wb") as f:
|
|
||||||
f.write(nonce)
|
|
||||||
print("Wrote nonce to 'nonce'")
|
|
||||||
ct = chacha.encrypt(nonce, data, aad)
|
|
||||||
with open(args.output, "wb") as f:
|
|
||||||
f.write(ct)
|
|
||||||
print(f"Wrote encrypted message to '{args.output}'")
|
|
||||||
|
|
||||||
|
|
||||||
def ecc_calc_encryption_keys(pubKey):
|
|
||||||
ciphertextPrivKey = secrets.randbelow(curve.field.n)
|
|
||||||
ciphertextPubKey = ciphertextPrivKey * curve.g
|
|
||||||
sharedECCKey = pubKey * ciphertextPrivKey
|
|
||||||
return (sharedECCKey, ciphertextPubKey)
|
|
||||||
|
|
||||||
def ecc_calc_decryption_key(privKey, ciphertextPubKey):
|
|
||||||
sharedECCKey = ciphertextPubKey * privKey
|
|
||||||
return sharedECCKey
|
|
||||||
|
|
||||||
def generate():
|
|
||||||
print("Please name this aegis. You can call it anything. Frequently people use their legal name.")
|
|
||||||
name = input("Name? ")
|
|
||||||
print("Generating aegis.")
|
|
||||||
subprocess.run([
|
|
||||||
"openssl", "req", # PKCS#10 certificate generation utility
|
|
||||||
"-new", # Generate a new certificate
|
|
||||||
"-newkey", "ec", # Generate a new private key using elliptic-curve (ECDSA or ECDH compatible)
|
|
||||||
"-pkeyopt", "ec_paramgen_curve:prime256v1", # Use the prime256v1 CE curve from NIST (P-256)
|
|
||||||
"-x509", # Create a self-signed certificate instead of a certificate request.
|
|
||||||
"-days", str(MAX_HUMAN_AGE), # Set the validity period to the expected max age of a human
|
|
||||||
"-subj", f"/CN={name}", # Add the common name for the persona tied to this aegis
|
|
||||||
"-out", "cert.pem", # Generate a self-signed certificate file with a .pem extension
|
|
||||||
"-keyout", "key.pem", # Generate an encrypted private key file with a .pem extension
|
|
||||||
],
|
|
||||||
check=True,)
|
|
||||||
|
|
||||||
def sign():
|
|
||||||
"Sign some arbitrary data."
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("aegis_key_pem", type=Path, help="The file for the PEM-encoded aegis private key.")
|
|
||||||
parser.add_argument("message", type=Path, help="The file containing the message to sign.")
|
|
||||||
parser.add_argument("-p", "--password", help="The password to use to open the key file.")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
with open(args.aegis_key_pem, "rb") as f:
|
|
||||||
private_key = serialization.load_pem_private_key(
|
|
||||||
data=f.read(),
|
|
||||||
password=args.password.encode("UTF-8"),
|
|
||||||
)
|
|
||||||
with open(args.message, "rb") as f:
|
|
||||||
data = f.read()
|
|
||||||
signature = private_key.sign(
|
|
||||||
data,
|
|
||||||
ec.ECDSA(hashes.SHA256()),
|
|
||||||
)
|
|
||||||
with open("signature.bin", "wb") as f:
|
|
||||||
f.write(signature)
|
|
||||||
print("Wrote signature to signature.bin")
|
|
||||||
|
|
||||||
def validate():
|
|
||||||
"Validate the signature of some arbitrary data."
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("aegis_cert_pem", type=Path, help="The file for the PEM-encoded aegis public certificate.")
|
|
||||||
parser.add_argument("message", type=Path, help="The file containing the message to validate.")
|
|
||||||
parser.add_argument("signature", type=Path, help="The file containing the signature to validate.")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
with open(args.aegis_cert_pem, "rb") as f:
|
|
||||||
certificate = x509.load_pem_x509_certificate(
|
|
||||||
data=f.read(),
|
|
||||||
)
|
|
||||||
with open(args.message, "rb") as f:
|
|
||||||
data = f.read()
|
|
||||||
with open(args.signature, "rb") as f:
|
|
||||||
signature = f.read()
|
|
||||||
|
|
||||||
key = certificate.public_key()
|
|
||||||
key.verify(
|
|
||||||
signature=signature,
|
|
||||||
data=data,
|
|
||||||
signature_algorithm=ec.ECDSA(hashes.SHA256()),
|
|
||||||
)
|
|
||||||
print("Signature is valid")
|
|
||||||
|
|
||||||
def unbox():
|
|
||||||
"Take a message in a box, use a key, open the box, get the message."
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("aegis_key_pem", type=Path, help="The file for the PEM-encoded aegis key.")
|
|
||||||
parser.add_argument("ciphertext", type=Path, help="The file containing the boxed ciphertext.")
|
|
||||||
parser.add_argument("output", type=Path, help="The path to the file where the output will go.")
|
|
||||||
parser.add_argument("-p", "--password", help="The password to use to open the key file.")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
with open(args.aegis_key_pem, "rb") as f:
|
|
||||||
private_key = serialization.load_pem_private_key(
|
|
||||||
data=f.read(),
|
|
||||||
password=args.password.encode("UTF-8"),
|
|
||||||
)
|
|
||||||
with open(args.ciphertext, "rb") as f:
|
|
||||||
ciphertext = f.read()
|
|
||||||
aad = b"authenticated but unencrypted data"
|
|
||||||
|
|
||||||
with open("encryption.key", "rb") as f:
|
|
||||||
key = f.read()
|
|
||||||
with open("nonce", "rb") as f:
|
|
||||||
nonce = f.read()
|
|
||||||
|
|
||||||
chacha = aead.ChaCha20Poly1305(key)
|
|
||||||
message = chacha.decrypt(nonce, ciphertext, aad)
|
|
||||||
with open(args.output, "wb") as f:
|
|
||||||
f.write(message)
|
|
||||||
print(f"Wrote unboxed message to '{args.output}'")
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
import argparse
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from cryptography import x509
|
|
||||||
from cryptography.hazmat.primitives import serialization
|
|
||||||
|
|
||||||
def box_message():
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("recipient_certificate", type=Path, help="Path to the certificate of the recipient")
|
|
||||||
parser.add_argument("sender_key", type=Path, help="Path to the private key of the sender")
|
|
||||||
parser.add_argument("--sender-key-password", type="str", default=None, help="The password to the sender private key")
|
|
||||||
parser.add_argument("message", type=Path, help="Path to the message to box")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
recipient_cert = _load_certificate(args.recipient_certificate)
|
|
||||||
sender_key = _load_key(args.sender_key)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _load_certificate(path: Path) -> x509.Certificate:
|
|
||||||
with open(path, "rb") as f:
|
|
||||||
return x509.load_pem_x509_certificate(f.read())
|
|
||||||
|
|
||||||
def _load_key(path: Path, password: str) -> EllipticCurvePrivateKey:
|
|
||||||
with open(path, "rb") as f:
|
|
||||||
return serialization.load_pem_private_key(f.read(), password)
|
|
|
@ -1,21 +0,0 @@
|
||||||
[project]
|
|
||||||
name = "gongor"
|
|
||||||
version = "0.1"
|
|
||||||
description = "A system to manage Aegi"
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">=3.7"
|
|
||||||
license = {file = "LICENSE.txt"}
|
|
||||||
|
|
||||||
[project.scripts]
|
|
||||||
aegis-generate = "gongor.aegis:generate"
|
|
||||||
aegis-sign = "gongor.aegis:sign"
|
|
||||||
aegis-validate-signature = "gongor.aegis:validate"
|
|
||||||
aegis-box = "gongor.aegis:box"
|
|
||||||
aegis-unbox = "gongor.aegis:unbox"
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["setuptools >= 61.0.0"]
|
|
||||||
build-backend = "setuptools.build_meta"
|
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
|
||||||
include = ["gongor"]
|
|
Loading…
Reference in New Issue