Can now fetch public key from actor url

This commit is contained in:
Eliot Berriot 2018-03-28 18:04:21 +02:00
parent 2f473d7570
commit 707868d794
No known key found for this signature in database
GPG Key ID: DD6965E2476E5C27
6 changed files with 71 additions and 29 deletions

View File

@ -0,0 +1,4 @@
class MalformedPayload(ValueError):
pass

View File

@ -4,16 +4,16 @@ import requests_http_signature
from funkwhale_api.factories import registry
from . import signing
from . import keys
registry.register(signing.get_key_pair, name='federation.KeyPair')
registry.register(keys.get_key_pair, name='federation.KeyPair')
@registry.register(name='federation.SignatureAuth')
class SignatureAuthFactory(factory.Factory):
algorithm = 'rsa-sha256'
key = factory.LazyFunction(lambda: signing.get_key_pair()[0])
key = factory.LazyFunction(lambda: keys.get_key_pair()[0])
key_id = factory.Faker('url')
class Meta:

View File

@ -0,0 +1,43 @@
from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend as crypto_default_backend
import requests
from . import exceptions
def get_key_pair(size=2048):
key = rsa.generate_private_key(
backend=crypto_default_backend(),
public_exponent=65537,
key_size=size
)
private_key = key.private_bytes(
crypto_serialization.Encoding.PEM,
crypto_serialization.PrivateFormat.PKCS8,
crypto_serialization.NoEncryption())
public_key = key.public_key().public_bytes(
crypto_serialization.Encoding.PEM,
crypto_serialization.PublicFormat.PKCS1
)
return private_key, public_key
def get_public_key(actor_url):
"""
Given an actor_url, request it and extract publicKey data from
the response payload.
"""
response = requests.get(actor_url)
response.raise_for_status()
payload = response.json()
try:
return {
'public_key_pem': payload['publicKey']['publicKeyPem'],
'id': payload['publicKey']['id'],
'owner': payload['publicKey']['owner'],
}
except KeyError:
raise exceptions.MalformedPayload(str(payload))

View File

@ -1,28 +1,6 @@
import requests
import requests_http_signature
from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend as crypto_default_backend
def get_key_pair(size=2048):
key = rsa.generate_private_key(
backend=crypto_default_backend(),
public_exponent=65537,
key_size=size
)
private_key = key.private_bytes(
crypto_serialization.Encoding.PEM,
crypto_serialization.PrivateFormat.PKCS8,
crypto_serialization.NoEncryption())
public_key = key.public_key().public_bytes(
crypto_serialization.Encoding.PEM,
crypto_serialization.PublicFormat.PKCS1
)
return private_key, public_key
def verify(request, public_key):
return requests_http_signature.HTTPSignatureAuth.verify(

View File

@ -0,0 +1,16 @@
from funkwhale_api.federation import keys
def test_public_key_fetching(r_mock):
payload = {
'id': 'https://actor.mock/users/actor#main-key',
'owner': 'test',
'publicKeyPem': 'test_pem',
}
actor = 'https://actor.mock/'
r_mock.get(actor, json={'publicKey': payload})
r = keys.get_public_key(actor)
assert r['id'] == payload['id']
assert r['owner'] == payload['owner']
assert r['public_key_pem'] == payload['publicKeyPem']

View File

@ -4,6 +4,7 @@ import pytest
import requests_http_signature
from funkwhale_api.federation import signing
from funkwhale_api.federation import keys
def test_can_sign_and_verify_request(factories):
@ -45,7 +46,7 @@ def test_verify_fails_with_wrong_key(factories):
def test_can_verify_django_request(factories, api_request):
private_key, public_key = signing.get_key_pair()
private_key, public_key = keys.get_key_pair()
signed_request = factories['federation.SignedRequest'](
auth__key=private_key
)
@ -61,7 +62,7 @@ def test_can_verify_django_request(factories, api_request):
def test_can_verify_django_request_digest(factories, api_request):
private_key, public_key = signing.get_key_pair()
private_key, public_key = keys.get_key_pair()
signed_request = factories['federation.SignedRequest'](
auth__key=private_key,
method='post',
@ -81,7 +82,7 @@ def test_can_verify_django_request_digest(factories, api_request):
def test_can_verify_django_request_digest_failure(factories, api_request):
private_key, public_key = signing.get_key_pair()
private_key, public_key = keys.get_key_pair()
signed_request = factories['federation.SignedRequest'](
auth__key=private_key,
method='post',
@ -102,7 +103,7 @@ def test_can_verify_django_request_digest_failure(factories, api_request):
def test_can_verify_django_request_failure(factories, api_request):
private_key, public_key = signing.get_key_pair()
private_key, public_key = keys.get_key_pair()
signed_request = factories['federation.SignedRequest'](
auth__key=private_key
)