kopia lustrzana https://gitlab.com/marnanel/chapeau
Actor class, and crypto for it, though we don't use them yet in this branch
rodzic
1da029d0d3
commit
4bb225c4e8
|
@ -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)),
|
||||
)
|
|
@ -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)
|
||||
|
Ładowanie…
Reference in New Issue