From ef253d302717cbeca449cd2b474f0222a367ee40 Mon Sep 17 00:00:00 2001 From: David Buchanan Date: Thu, 5 Dec 2024 18:12:39 +0000 Subject: [PATCH] add plcsign util --- src/millipds/__main__.py | 16 ++++++++++++++-- src/millipds/crypto.py | 9 +++++++++ test_data/devenv_test_setup.sh | 6 ++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/millipds/__main__.py b/src/millipds/__main__.py index 32e8eb3..a4630b2 100644 --- a/src/millipds/__main__.py +++ b/src/millipds/__main__.py @@ -8,6 +8,7 @@ millipds util keygen [--p256 | --k256] millipds util print_pubkey millipds util plcgen --genesis_json=PATH --rotation_key=PEM --handle=HANDLE --pds_host=URL --repo_pubkey=DIDKEY + millipds util plcsign --unsigned_op=PATH --rotation_key=PEM [--prev_op=PATH] millipds (-h | --help) millipds --version @@ -146,13 +147,24 @@ def main(): }, "prev": None, } - rawsig = crypto.raw_sign(rotation_key, cbrrr.encode_dag_cbor(genesis)) - genesis["sig"] = base64.urlsafe_b64encode(rawsig).decode().rstrip("=") + genesis["sig"] = crypto.plc_sign(rotation_key, genesis) genesis_digest = hashlib.sha256(cbrrr.encode_dag_cbor(genesis)).digest() plc = "did:plc:" + base64.b32encode(genesis_digest)[:24].lower().decode() with open(args["--genesis_json"], "w") as out: json.dump(genesis, out, indent=4) print(plc) + elif args["plcsign"]: + with open(args["--unsigned_op"]) as op_json: + op = json.load(op_json) + with open(args["--rotation_key"]) as pem: + rotation_key = crypto.privkey_from_pem(pem.read()) + if args["--prev_op"]: + with open(args["--prev_op"]) as op_json: + prev_op = json.load(op_json) + op["prev"] = cbrrr.CID.cidv1_dag_cbor_sha256_32_from(cbrrr.encode_dag_cbor(prev_op)).encode() + del op["sig"] # remove any existing sig + op["sig"] = crypto.plc_sign(rotation_key, op) + print(json.dumps(op, indent=4)) else: print("invalid util subcommand") return diff --git a/src/millipds/crypto.py b/src/millipds/crypto.py index 9fd5430..8da882b 100644 --- a/src/millipds/crypto.py +++ b/src/millipds/crypto.py @@ -1,4 +1,5 @@ from typing import Literal +import base64 from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives import hashes @@ -11,6 +12,8 @@ import base58 +import cbrrr + """ This is scary hand-rolled cryptography, because there aren't really any alternative options in the python ecosystem. pyca/crytography probably won't add low-s support unless @@ -100,3 +103,9 @@ def encode_pubkey_as_did_key(pubkey: ec.EllipticCurvePublicKey) -> str: ) multicodec = MULTICODEC_PUBKEY_PREFIX[type(pubkey.curve)] + compressed_public_bytes return "did:key:z" + base58.b58encode(multicodec).decode() + +def plc_sign(privkey: ec.EllipticCurvePrivateKey, op: dict) -> str: + if "sig" in op: + raise ValueError("op is already signed!") + rawsig = raw_sign(privkey, cbrrr.encode_dag_cbor(op)) + return base64.urlsafe_b64encode(rawsig).decode().rstrip("=") diff --git a/test_data/devenv_test_setup.sh b/test_data/devenv_test_setup.sh index e501fd7..14b2095 100755 --- a/test_data/devenv_test_setup.sh +++ b/test_data/devenv_test_setup.sh @@ -8,12 +8,14 @@ HANDLE="bob.test" rm -rf ./data millipds init millipds.test +millipds config --pds_pfx=http://$PDS_HOST -./create_identity.sh $HANDLE http://$PDS_HOST $PLC_HOST +# generates keys and publishes to PLC +./create_identity.sh $HANDLE http://$PDS_HOST $PLC_HOST DID_PLC=$(cat "${HANDLE}_did.txt") -millipds config --pds_pfx=http://$PDS_HOST +# create the account using the generated identity millipds account create $DID_PLC $HANDLE --unsafe_password="lol" --signing_key="${HANDLE}_repo_key.pem" #millipds run