From 5def1f2fe64591466e40a4e8d56feab34dbdf175 Mon Sep 17 00:00:00 2001 From: Lynnesbian Date: Sat, 11 Apr 2020 17:14:53 +1000 Subject: [PATCH] some more groundwork for HTTP signatures --- .gitignore | 1 + app/functions.py | 44 +++++++++++++++++++++++++++++++++++++++++++- app/webui.py | 3 ++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0e41b37..d0abd4f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ config.json planning.txt *.pyc /debug +lynnesbian.json \ No newline at end of file diff --git a/app/functions.py b/app/functions.py index e03e1f8..39f1cc1 100644 --- a/app/functions.py +++ b/app/functions.py @@ -1,7 +1,11 @@ from bs4 import BeautifulSoup import MySQLdb import markovify +import requests from Crypto.PublicKey import RSA +from Crypto.Hash import SHA256 +from Crypto.Signature import PKCS1_v1_5 +from base64 import b64decode, b64encode from mastodon import Mastodon, MastodonUnauthorizedError import html, re, json @@ -201,4 +205,42 @@ def get_key(): dc.close() db.commit() - return key \ No newline at end of file + return key + +def signed_get(url, timeout = 10, additional_headers = {}, request_json = True): + headers = {} + if request_json: + headers = { + "Accept": "application/json", + "Content-Type": "application/json" + } + + headers = {**headers, **additional_headers} + + # sign request headers + key = RSA.importKey(get_key()['private']) + sigstring = '' + for header, value in headers.items(): + sigstring += '{}: {}\n'.format(header.lower(), value) + + sigstring.rstrip("\n") + + pkcs = PKCS1_v1_5.new(key) + h = SHA256.new() + h.update(sigstring.encode('ascii')) + + signed_sigstring = b64encode(pkcs.sign(h)).decode('ascii') + + sig = { + 'keyId': "{}/actor".format(cfg['base_uri']), + 'algorithm': 'rsa-sha256', + 'headers': ' '.join(headers.keys()), + 'signature': signed_sigstring + } + + sig_header = ['{}="{}"'.format(k, v) for k, v in sig.items()] + headers['signature'] = ','.join(sig_header) + + r = requests.Request('GET', url, headers) + return r.headers + # return requests.get(url, timeout = timeout) \ No newline at end of file diff --git a/app/webui.py b/app/webui.py index 1e2c693..cea8c6b 100644 --- a/app/webui.py +++ b/app/webui.py @@ -380,7 +380,8 @@ def webfinger(): @app.route("/actor") def actor(): - pubkey = functions.get_key()['public'].replace("\n", "\\n") + # pubkey = functions.get_key()['public'].replace("\n", "\\n") + pubkey = functions.signed_get("https://fedi.lynnesbian.space/users/lynnesbian/outbox.json?page=true") return render_template("ap/actor.json", base_uri = cfg['base_uri'], pubkey = pubkey), 200, {'Content-type':'application/json'}