- commit
- 25cfb6114c00dbe07be55fc144d6513d6470f5b6
- parent
- 6d9bc9fe0a96469ee864c6755c125991a8e73115
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-05-10 10:36
store primary password in kernel keyring
Diffstat
| A | xikeyring/kernel_keyring.py | 39 | +++++++++++++++++++++++++++++++++++++++ |
| M | xikeyring/keyring.py | 5 | +++-- |
2 files changed, 42 insertions, 2 deletions
diff --git a/xikeyring/kernel_keyring.py b/xikeyring/kernel_keyring.py
@@ -0,0 +1,39 @@
-1 1 import ctypes
-1 2 import os
-1 3
-1 4 keyutils = ctypes.CDLL('libkeyutils.so.1')
-1 5
-1 6 THREAD_KEYRING = -1
-1 7 PROCESS_KEYRING = -2
-1 8 SESSION_KEYRING = -3
-1 9 USER_KEYRING = -4
-1 10 USER_SESSION_KEYRING = -5
-1 11 GROUP_KEYRING = -6
-1 12
-1 13
-1 14 def add_key(name: bytes, value: bytes, keyring: int) -> tuple[int, int]:
-1 15 size = len(value)
-1 16 id = keyutils.add_key(b'user', name, value, size, keyring)
-1 17 if id == -1:
-1 18 errno = ctypes.get_errno()
-1 19 raise OSError(errno, os.strerror(errno))
-1 20 return id, size
-1 21
-1 22
-1 23 def get_key(id: int, size: int) -> bytes:
-1 24 buf = ctypes.create_string_buffer(size)
-1 25 result = keyutils.keyctl_read(id, buf, size)
-1 26 if result == -1:
-1 27 errno = ctypes.get_errno()
-1 28 raise OSError(errno, os.strerror(errno))
-1 29 return buf.value
-1 30
-1 31
-1 32 class KernelKey:
-1 33 def __init__(self, value: bytes, keyring: int = PROCESS_KEYRING):
-1 34 name = f'kernel-key-{id(self)}'.encode()
-1 35 self.id, self.size = add_key(name, value, keyring)
-1 36
-1 37 @property
-1 38 def value(self):
-1 39 return get_key(self.id, self.size)
diff --git a/xikeyring/keyring.py b/xikeyring/keyring.py
@@ -8,6 +8,7 @@ from cryptography.fernet import InvalidToken 8 8 from cryptography.hazmat.primitives import hashes 9 9 from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC 10 10 -1 11 from .kernel_keyring import KernelKey 11 12 from .prompt import PinentryPrompt as Prompt 12 13 13 14 TRUSTED_MANAGERS = [ @@ -32,7 +33,7 @@ class Item: 32 33 33 34 class Crypt: 34 35 def __init__(self, password: bytes):35 -1 self.password = password-1 36 self.password = KernelKey(password) 36 37 37 38 def get_key(self, salt: bytes, iterations: int) -> bytes: 38 39 if iterations < 100_000: @@ -43,7 +44,7 @@ class Crypt: 43 44 salt=salt, 44 45 iterations=iterations, 45 46 )46 -1 return base64.urlsafe_b64encode(kdf.derive(self.password))-1 47 return base64.urlsafe_b64encode(kdf.derive(self.password.value)) 47 48 48 49 def encode(self, salt: bytes, iterations: int, content: bytes) -> bytes: 49 50 return b'$'.join(