From 0f9761ff5c0101b571ce08cc1e8cc118ee6aeb95 Mon Sep 17 00:00:00 2001 From: SouthFox Date: Mon, 19 Jun 2023 14:34:03 +0800 Subject: [PATCH] [feat] check inbox signature --- demo/actor.py | 11 +++++++++++ demo/httpsig.py | 2 +- demo/utils/checker.py | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 demo/actor.py diff --git a/demo/actor.py b/demo/actor.py new file mode 100644 index 0000000..a2adff5 --- /dev/null +++ b/demo/actor.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +"""ActivityPub Actor""" +import demo.activitypub as ap + + +def fetch_actor( + actor_url: str, +) -> dict: + """Fetch actor""" + ap_object = ap.fetch(actor_url) + return ap_object diff --git a/demo/httpsig.py b/demo/httpsig.py index 4bda3ff..1d0fa29 100644 --- a/demo/httpsig.py +++ b/demo/httpsig.py @@ -8,7 +8,7 @@ from dataclasses import dataclass from Crypto.Hash import SHA256 from Crypto.Signature import PKCS1_v1_5 from Crypto.PublicKey import RSA -from httpx import Headers +from werkzeug.datastructures import Headers @dataclass diff --git a/demo/utils/checker.py b/demo/utils/checker.py index 2048aec..006a146 100644 --- a/demo/utils/checker.py +++ b/demo/utils/checker.py @@ -1,19 +1,48 @@ """Request checker""" +import json + from flask import Request, abort -from demo.httpsig import HttpSignature +from demo.httpsig import HttpSignature, SignedData +from demo.actor import fetch_actor def inbox_prechecker( request: Request, ) -> bool: """Inbox request prechecker""" + payload = request.headers + ap_body = request.data try: - payload = request.headers parsec_signature = HttpSignature.parse_signature( payload["signature"] ) - print(parsec_signature) except KeyError: abort(401, "Missing signature key!") + actor_id = request.get_json()["actor"] + actor = fetch_actor(actor_id) + + try: + pub_key = actor["publicKey"]["publicKeyPem"] + except json.JSONDecodeError: + raise ValueError + except KeyError: + print("actore gone?") + raise KeyError + + sigdate = SignedData( + method = request.method, + path = request.path, + signed_list = parsec_signature["headers"], + body_digest = HttpSignature.calculation_digest(ap_body), + headers = request.headers, + ) + + is_verify = HttpSignature.verify_signature( + HttpSignature.build_signature_string(sigdate), + parsec_signature["signature"], + pub_key, + ) + + print(is_verify) return True