summaryrefslogtreecommitdiff
path: root/src/xpit_/identity.py
blob: 2786b2d43a0af57d74fdd6a8efc9203518d4aa99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import os
import base64
from sys import stdout
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes, PublicKeyTypes

# TODO guard against bad file access
def create(path: str) -> None:
    private_key = ed25519.Ed25519PrivateKey.generate()
    public_key = private_key.public_key()
    enc = serialization.NoEncryption()

    os.mkdir(path)

    data = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=enc,
    )
    with open(os.path.join(path, "private.pem"), "wb") as f:
        f.write(data)

    data = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo,
    )
    with open(os.path.join(path, "public.pub"), "wb") as f:
        f.write(data)

def load(identities_dir: str, identity: str) -> tuple[PrivateKeyTypes, PublicKeyTypes]:
    if not os.path.isdir(identities_dir):
        os.makedirs(identities_dir)

    path = os.path.join(identities_dir, identity)

    if not os.path.isdir(path):
        stdout.write(f"Generating new identity '{identity}'...\n")
        create(path)
        stdout.write(f"Created new identity '{identity}' at: {path}\n")

    with open(os.path.join(path, "private.pem"), "rb") as f:
        private_key_data = f.read()
    with open(os.path.join(path, "public.pub"), "rb") as f:
        public_key_data = f.read()

    return (
        serialization.load_pem_private_key(private_key_data, password=None),
        serialization.load_pem_public_key(public_key_data)
    )

def id_from_pubkey(pubkey: PublicKeyTypes) -> bytes:
    der = pubkey.public_bytes(
        encoding=serialization.Encoding.DER,
        format=serialization.PublicFormat.SubjectPublicKeyInfo,
    )
    b64 = base64.b64encode(der)
    return b64[16:24]