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