User.p256_key = k256_key, for ATProto

pull/631/head
Ryan Barrett 2023-08-31 13:49:45 -07:00
rodzic 3cb1fea53f
commit 3ff42f0cd4
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
3 zmienionych plików z 24 dodań i 16 usunięć

Wyświetl plik

@ -6,7 +6,9 @@ import logging
import random
from urllib.parse import quote, urlparse
from Crypto.PublicKey import ECC, RSA
import arroba.util
from Crypto.PublicKey import RSA
from cryptography.hazmat.primitives import serialization
import dag_json
from flask import g, request
from google.cloud import ndb
@ -78,15 +80,15 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
section 5.1 of the Magic Signatures spec
https://tools.ietf.org/html/draft-cavage-http-signatures-12
* P-256 keypair for AT Protocol's signing key
property: p256_key, PEM encoded
* K-256 keypair for AT Protocol's signing key
property: k256_key, PEM encoded
https://atproto.com/guides/overview#account-portability
"""
obj_key = ndb.KeyProperty(kind='Object') # user profile
mod = ndb.StringProperty()
public_exponent = ndb.StringProperty()
private_exponent = ndb.StringProperty()
p256_key = ndb.StringProperty()
k256_key = ndb.BlobProperty()
use_instead = ndb.KeyProperty()
# whether this user signed up or otherwise explicitly, deliberately
@ -159,10 +161,13 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
'private_exponent': long_to_base64(key.d),
})
if cls.LABEL != 'atprotocol':
key = ECC.generate(
curve='P-256', randfunc=random.randbytes if DEBUG else None)
kwargs['p256_key'] = key.export_key(format='PEM')
if cls.LABEL != 'atproto':
privkey = arroba.util.new_key()
kwargs['k256_key'] = privkey.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
user = cls(id=id, **kwargs)
try:

Wyświetl plik

@ -11,6 +11,8 @@ from oauth_dropins.webutil.testutil import NOW
from .testutil import Fake, TestCase
from atproto import ATProto
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
from models import Follower, Object, OBJECT_EXPIRE_AGE, Target, User
import protocol
from protocol import Protocol
@ -32,15 +34,15 @@ class UserTest(TestCase):
assert user.mod
assert user.public_exponent
assert user.private_exponent
assert user.p256_key
assert user.k256_key
# check that we can load the keys
assert user.public_pem()
assert user.private_pem()
p256_key = ECC.import_key(user.p256_key)
assert isinstance(p256_key, ECC.EccKey)
self.assertEqual('NIST P-256', p256_key.curve)
k256_key = serialization.load_pem_private_key(user.k256_key, password=None)
self.assertIsInstance(k256_key, ec.EllipticCurvePrivateKey)
self.assertIsInstance(k256_key.curve, ec.SECP256K1)
# direct should get set even if the user exists
same = Fake.get_or_create('a.b', direct=True)

Wyświetl plik

@ -142,6 +142,7 @@ models.reset_protocol_properties()
import app
from activitypub import ActivityPub, CONNEG_HEADERS_AS2_HTML
from atproto import ATProto
import common
from web import Web
from flask_app import app, cache, init_globals
@ -250,7 +251,7 @@ class TestCase(unittest.TestCase, testutil.Asserts):
mod=global_user.mod,
public_exponent=global_user.public_exponent,
private_exponent=global_user.private_exponent,
p256_key=global_user.p256_key,
k256_key=global_user.k256_key,
obj_key=obj_key,
**kwargs)
user.put()
@ -408,7 +409,7 @@ class TestCase(unittest.TestCase, testutil.Asserts):
self.assert_equals(obj_as2, got.as2())
# generated, computed, etc
ignore = ['created', 'mod', 'obj_key', 'p256_key', 'private_exponent',
ignore = ['created', 'mod', 'obj_key', 'k256_key', 'private_exponent',
'public_exponent', 'readable_id', 'updated']
for prop in ignore:
assert prop not in props
@ -420,8 +421,8 @@ class TestCase(unittest.TestCase, testutil.Asserts):
assert got.private_exponent
assert got.public_exponent
# if cls != ATProto:
# assert got.p256_key
if cls != ATProto:
assert got.k256_key
return got