some more groundwork for HTTP signatures

This commit is contained in:
Lynne Megido 2020-04-11 17:14:53 +10:00
parent c1692b2acf
commit 5def1f2fe6
Signed by: lynnesbian
GPG Key ID: F0A184B5213D9F90
3 changed files with 46 additions and 2 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ config.json
planning.txt planning.txt
*.pyc *.pyc
/debug /debug
lynnesbian.json

View File

@ -1,7 +1,11 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import MySQLdb import MySQLdb
import markovify import markovify
import requests
from Crypto.PublicKey import RSA 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 from mastodon import Mastodon, MastodonUnauthorizedError
import html, re, json import html, re, json
@ -201,4 +205,42 @@ def get_key():
dc.close() dc.close()
db.commit() db.commit()
return key 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)

View File

@ -380,7 +380,8 @@ def webfinger():
@app.route("/actor") @app.route("/actor")
def 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'} return render_template("ap/actor.json", base_uri = cfg['base_uri'], pubkey = pubkey), 200, {'Content-type':'application/json'}