mirror of
https://git.sr.ht/~tsileo/microblog.pub
synced 2025-06-05 21:59:23 +02:00
Initial commit for new v2
This commit is contained in:
84
app/key.py
Normal file
84
app/key.py
Normal file
@ -0,0 +1,84 @@
|
||||
import base64
|
||||
from typing import Any
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Util import number
|
||||
|
||||
from app.config import KEY_PATH
|
||||
|
||||
|
||||
def key_exists() -> bool:
|
||||
return KEY_PATH.exists()
|
||||
|
||||
|
||||
def generate_key() -> None:
|
||||
if key_exists():
|
||||
raise ValueError(f"Key at {KEY_PATH} already exists")
|
||||
k = RSA.generate(2048)
|
||||
privkey_pem = k.exportKey("PEM").decode("utf-8")
|
||||
KEY_PATH.write_text(privkey_pem)
|
||||
|
||||
|
||||
def get_pubkey_as_pem() -> str:
|
||||
text = KEY_PATH.read_text()
|
||||
return RSA.import_key(text).public_key().export_key("PEM").decode("utf-8")
|
||||
|
||||
|
||||
def get_key() -> str:
|
||||
return KEY_PATH.read_text()
|
||||
|
||||
|
||||
class Key(object):
|
||||
DEFAULT_KEY_SIZE = 2048
|
||||
|
||||
def __init__(self, owner: str, id_: str | None = None) -> None:
|
||||
self.owner = owner
|
||||
self.privkey_pem: str | None = None
|
||||
self.pubkey_pem: str | None = None
|
||||
self.privkey: RSA.RsaKey | None = None
|
||||
self.pubkey: RSA.RsaKey | None = None
|
||||
self.id_ = id_
|
||||
|
||||
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 self.id_ or f"{self.owner}#main-key"
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
"id": self.key_id(),
|
||||
"owner": self.owner,
|
||||
"publicKeyPem": self.pubkey_pem,
|
||||
"type": "Key",
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
try:
|
||||
k = cls(data["owner"], data["id"])
|
||||
k.load_pub(data["publicKeyPem"])
|
||||
except KeyError:
|
||||
raise ValueError(f"bad key data {data!r}")
|
||||
return k
|
||||
|
||||
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}"
|
Reference in New Issue
Block a user