rra
4 years ago
3 changed files with 90 additions and 77 deletions
@ -0,0 +1,74 @@ |
|||||
|
import os |
||||
|
import re |
||||
|
import base64 |
||||
|
from Crypto.PublicKey import RSA |
||||
|
from Crypto.Util import number |
||||
|
from typing import Any |
||||
|
from typing import Dict |
||||
|
from typing import Optional |
||||
|
|
||||
|
KEY_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '.') |
||||
|
|
||||
|
class Key(object): |
||||
|
DEFAULT_KEY_SIZE = 2048 |
||||
|
|
||||
|
def __init__(self, owner: str) -> None: |
||||
|
self.owner = owner |
||||
|
self.privkey_pem: Optional[str] = None |
||||
|
self.pubkey_pem: Optional[str] = None |
||||
|
self.privkey: Optional[Any] = None |
||||
|
self.pubkey: Optional[Any] = None |
||||
|
|
||||
|
def load_pub(self, pubkey_pem: str) -> None: |
||||
|
self.pubkey_pem = pubkey_pem |
||||
|
self.pubkey = RSA.importKey(pubkey_pem) |
||||
|
|
||||
|
def load(self, privkey_pem: str) -> None: |
||||
|
self.privkey_pem = privkey_pem |
||||
|
self.privkey = RSA.importKey(self.privkey_pem) |
||||
|
self.pubkey_pem = self.privkey.publickey().exportKey("PEM").decode("utf-8") |
||||
|
|
||||
|
def new(self) -> None: |
||||
|
k = RSA.generate(self.DEFAULT_KEY_SIZE) |
||||
|
self.privkey_pem = k.exportKey("PEM").decode("utf-8") |
||||
|
self.pubkey_pem = k.publickey().exportKey("PEM").decode("utf-8") |
||||
|
self.privkey = k |
||||
|
|
||||
|
def key_id(self) -> str: |
||||
|
return f"{self.owner}#main-key" |
||||
|
|
||||
|
def to_dict(self) -> Dict[str, Any]: |
||||
|
return { |
||||
|
"id": self.key_id(), |
||||
|
"owner": self.owner, |
||||
|
"publicKeyPem": self.pubkey_pem, |
||||
|
} |
||||
|
|
||||
|
def to_magic_key(self) -> str: |
||||
|
mod = base64.urlsafe_b64encode( |
||||
|
number.long_to_bytes(self.privkey.n) # type: ignore |
||||
|
).decode("utf-8") |
||||
|
pubexp = base64.urlsafe_b64encode( |
||||
|
number.long_to_bytes(self.privkey.e) # type: ignore |
||||
|
).decode("utf-8") |
||||
|
return f"data:application/magic-public-key,RSA.{mod}.{pubexp}" |
||||
|
|
||||
|
|
||||
|
def get_key(owner: str) -> Key: |
||||
|
""""Loads or generates an RSA key.""" |
||||
|
k = Key(owner) |
||||
|
user = re.sub('[^\w\d]', "_", owner) |
||||
|
key_path = os.path.join(KEY_DIR, f"key_{user}.pem") |
||||
|
if os.path.isfile(key_path): |
||||
|
with open(key_path) as f: |
||||
|
privkey_pem = f.read() |
||||
|
k.load(privkey_pem) |
||||
|
else: |
||||
|
k.new() |
||||
|
with open(key_path, "w") as f: |
||||
|
f.write(k.privkey_pem) |
||||
|
|
||||
|
return k |
||||
|
|
||||
|
|
||||
|
|
Loading…
Reference in new issue