sync_key.py
61 lines
| 2.0 KiB
| text/x-python
|
PythonLexer
neko259
|
r794 | import base64 | ||
neko259
|
r807 | from ecdsa import SigningKey, VerifyingKey, BadSignatureError | ||
neko259
|
r794 | from django.db import models | ||
TYPE_ECDSA = 'ecdsa' | ||||
APP_LABEL_BOARDS = 'boards' | ||||
class KeyPairManager(models.Manager): | ||||
neko259
|
r796 | def generate_key(self, key_type=TYPE_ECDSA, primary=False): | ||
if primary and self.filter(primary=True).exists(): | ||||
raise Exception('There can be only one primary key') | ||||
neko259
|
r794 | if key_type == TYPE_ECDSA: | ||
private = SigningKey.generate() | ||||
public = private.get_verifying_key() | ||||
neko259
|
r836 | private_key_str = base64.b64encode(private.to_string()).decode() | ||
public_key_str = base64.b64encode(public.to_string()).decode() | ||||
neko259
|
r794 | |||
return self.create(public_key=public_key_str, | ||||
neko259
|
r809 | private_key=private_key_str, | ||
key_type=TYPE_ECDSA, primary=primary) | ||||
neko259
|
r794 | else: | ||
neko259
|
r796 | raise Exception('Key type not supported') | ||
neko259
|
r794 | |||
neko259
|
r1244 | def verify(self, signature, string): | ||
if signature.key_type == TYPE_ECDSA: | ||||
public = VerifyingKey.from_string(base64.b64decode(signature.key)) | ||||
signature_byte = base64.b64decode(signature.signature) | ||||
neko259
|
r794 | try: | ||
neko259
|
r807 | return public.verify(signature_byte, string.encode()) | ||
neko259
|
r794 | except BadSignatureError: | ||
return False | ||||
else: | ||||
neko259
|
r796 | raise Exception('Key type not supported') | ||
neko259
|
r794 | |||
neko259
|
r836 | def has_primary(self): | ||
return self.filter(primary=True).exists() | ||||
neko259
|
r794 | |||
class KeyPair(models.Model): | ||||
class Meta: | ||||
app_label = APP_LABEL_BOARDS | ||||
objects = KeyPairManager() | ||||
public_key = models.TextField() | ||||
private_key = models.TextField() | ||||
key_type = models.TextField() | ||||
neko259
|
r796 | primary = models.BooleanField(default=False) | ||
neko259
|
r794 | |||
def __str__(self): | ||||
neko259
|
r841 | return '%s::%s' % (self.key_type, self.public_key) | ||
neko259
|
r794 | |||
def sign(self, string): | ||||
neko259
|
r836 | private = SigningKey.from_string(base64.b64decode( | ||
self.private_key.encode())) | ||||
neko259
|
r837 | signature_byte = private.sign_deterministic(string.encode()) | ||
return base64.b64encode(signature_byte).decode() | ||||