Actor class, and crypto for it, though we don't use them yet in this branch

2019-08-17
Marnanel Thurman 2019-05-24 20:37:02 +01:00
rodzic 1da029d0d3
commit 4bb225c4e8
2 zmienionych plików z 105 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,67 @@
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from struct import pack
import base64
import hashlib
def base64url_encode(data):
"""
base64-encodes its input, using the modified URL-safe
alphabet given in RFC 4648.
"""
b = base64.b64encode(s=data,
altchars=b'-_')
return str(b, encoding='ASCII')
def bignum_to_bytes(bignum):
temp = bignum
result = []
while temp!=0:
result.append(temp & 0xFF)
temp >>= 8
result.reverse()
return bytes(result)
class Key(object):
"""
An RSA public/private key pair, which can produce
a magic-envelope signature for itself.
I was going to subclass the RSA key object,
but it's hidden away and has an underscore prefix,
so I guess the developers thought that was a bad idea.
So I'm wrapping it, instead.
"""
def __init__(self):
self._rsa_key = RSA.generate(1024)
def private_as_pem(self):
return str(self._rsa_key.exportKey('PEM'),
encoding='ASCII')
def public_as_pem(self):
return str(self._rsa_key.publickey().exportKey('PEM'),
encoding='ASCII')
def modulus(self):
return self._rsa_key.n
def public_exponent(self):
return self._rsa_key.e
def private_exponent(self):
return self._rsa_key.d
def magic_envelope(self):
return 'RSA.{0}.{1}'.format(
base64url_encode(
bignum_to_bytes(
self._rsa_key.n)),
base64url_encode(
bignum_to_bytes(
self._rsa_key.e)),
)

Wyświetl plik

@ -0,0 +1,38 @@
from django.db import models
import django_kepi.models.thing
import django_kepi.crypto
import logging
logger = logging.getLogger(name='django_kepi')
######################
class Actor(models.Model):
thing = models.OneToOneField(
'django_kepi.Thing',
primary_key=True,
on_delete=models.CASCADE,
)
privateKey = models.TextField(
)
publicKey = models.TextField(
)
@property
def name(self):
return self.thing.name
def save(self, *args, **kwargs):
if self.privateKey is None and self.publicKey is None:
logger.info('Generating key pair for %s.',
self.name)
key = django_kepi.crypto.Key()
self.privateKey = key.private_as_pem()
self.publicKey = key.public_as_pem()
super().save(*args, **kwargs)