Key storage

This module provides classes for the storage of asymmetric key pairs.

Keystore

Each of these key storages theoretically belongs to a single user.

wacryptolib.keystore.load_keystore_metadata(keystore_dir)

Return the authenticator metadata dict stored in the given folder, after validating its format.

Raises KeystoreMetadataDoesNotExist if no metadata file is present.

Raises SchemaValidationError if keystore appears initialized, but has corrupted metadata.

Return type:

dict

class wacryptolib.keystore.InMemoryKeystore

Bases: KeystoreReadWriteBase

Dummy key storage for use in tests, where keys are kepts only process-locally.

NOT MEANT TO BE THREAD-SAFE

add_free_keypair(*, key_algo, public_key, private_key)

Store a pair of asymmetric keys into storage, free for subsequent attachment to an UUID.

Parameters:
  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • public_key (bytes) -- public key in clear PEM format

  • private_key (bytes) -- private key in PEM format (potentially encrypted)

Return type:

None

attach_free_keypair_to_uuid(*, keychain_uid, key_algo)

Fetch one of the free keypairs of storage of type key_algo, and attach it to UUID keychain_uid.

If no free keypair is available, a KeyDoesNotExist is raised.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

None

Returns:

public key of the keypair, in clear PEM format

get_free_keypairs_count(key_algo)

Calculate the count of keypairs of type key_algo which are free for subsequent attachment to an UUID.

Parameters:

key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

int

Returns:

count of free keypairs of said type

get_private_key(*, keychain_uid, key_algo)

Fetch a private key from persistent storage.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

bytes

Returns:

private key in PEM format (potentially passphrase-protected), or raise KeyDoesNotExist

get_public_key(*, keychain_uid, key_algo)

Fetch a public key from persistent storage.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

bytes

Returns:

public key in clear PEM format, or raise KeyDoesNotExist

list_keypair_identifiers()

List identifiers of PUBLIC keys present in the storage, along with their potential private key existence.

Might raise an OperationNotSupported exception if not supported by this keystore.

Return type:

list

Returns:

a SORTED list of key information dicts with standard fields "keychain_uid" and "key_algo", as well as a boolean "private_key_present" which is True if the related private key exists in storage. Sorting is done by keychain_uid and then key_algo.

set_keypair(*, keychain_uid, key_algo, public_key, private_key)

Store a pair of asymmetric keys into storage, attached to a specific UUID.

Must raise a KeyAlreadyExists exception if a public/private key already exists for these uid/type identifiers.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • public_key (bytes) -- public key in clear PEM format

  • private_key (bytes) -- private key in PEM format (potentially encrypted)

Return type:

None

set_private_key(*, keychain_uid, key_algo, private_key)

Store a private key, which must not already exist - else a KeyAlreadyExists is raised.

Important : the PUBLIC key for this private key must already exist in the keystore, else KeyDoesNotExist is raised.

Parameters:
  • keychain_uid -- unique ID of the keychain

  • key_algo -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • private_key (bytes) -- private key in PEM format (potentially encrypted)

Return type:

None

set_public_key(*, keychain_uid, key_algo, public_key)

Store a public key, which must not already exist - else KeyAlreadyExists is raised.

Parameters:
  • keychain_uid -- unique ID of the keychain

  • key_algo -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • public_key (bytes) -- public key in clear PEM format

Return type:

None

class wacryptolib.keystore.FilesystemKeystore(keys_dir)

Bases: ReadonlyFilesystemKeystore, KeystoreReadWriteBase

Filesystem-based key storage.

Protected by a process-wide lock, but not safe to use in multiprocessing environment, or in a process which can be brutally shutdown. To prevent corruption, caller should only persist UUIDs when the key storage operation is successfully finished.

add_free_keypair(*, key_algo, public_key, private_key)

Store a pair of asymmetric keys into storage, free for subsequent attachment to an UUID.

Parameters:
  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • public_key (bytes) -- public key in clear PEM format

  • private_key (bytes) -- private key in PEM format (potentially encrypted)

Return type:

None

attach_free_keypair_to_uuid(*, keychain_uid, key_algo)

Fetch one of the free keypairs of storage of type key_algo, and attach it to UUID keychain_uid.

If no free keypair is available, a KeyDoesNotExist is raised.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

None

Returns:

public key of the keypair, in clear PEM format

export_to_keystore_tree(include_private_keys=True)

Export keystore metadata and keys (public and, if include_private_keys is true, private) to a data tree.

get_free_keypairs_count(key_algo)

Calculate the count of keypairs of type key_algo which are free for subsequent attachment to an UUID.

Parameters:

key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

int

Returns:

count of free keypairs of said type

get_keystore_metadata(include_keypair_identifiers=False)

Return a metadata dict for the filesystem keystore, or raise KeystoreMetadataDoesNotExist.

get_private_key(*, keychain_uid, key_algo)

Fetch a private key from persistent storage.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

bytes

Returns:

private key in PEM format (potentially passphrase-protected), or raise KeyDoesNotExist

get_public_key(*, keychain_uid, key_algo)

Fetch a public key from persistent storage.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

Return type:

bytes

Returns:

public key in clear PEM format, or raise KeyDoesNotExist

import_from_keystore_tree(keystore_tree)

Import keystore metadata and keys (public and, if included, private) fom a data tree.

If keystore already exists, it is completed with new keys, but metadata are untouched.

Returns True if and only if keystore was updated instead of created.

Return type:

bool

list_keypair_identifiers()

List identifiers of PUBLIC keys present in the storage, along with their potential private key existence.

Might raise an OperationNotSupported exception if not supported by this keystore.

Return type:

list

Returns:

a SORTED list of key information dicts with standard fields "keychain_uid" and "key_algo", as well as a boolean "private_key_present" which is True if the related private key exists in storage. Sorting is done by keychain_uid and then key_algo.

set_keypair(*, keychain_uid, key_algo, public_key, private_key)

Store a pair of asymmetric keys into storage, attached to a specific UUID.

Must raise a KeyAlreadyExists exception if a public/private key already exists for these uid/type identifiers.

Parameters:
  • keychain_uid (UUID) -- unique ID of the keychain

  • key_algo (str) -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • public_key (bytes) -- public key in clear PEM format

  • private_key (bytes) -- private key in PEM format (potentially encrypted)

Return type:

None

set_private_key(*, keychain_uid, key_algo, private_key)

Store a private key, which must not already exist - else a KeyAlreadyExists is raised.

Important : the PUBLIC key for this private key must already exist in the keystore, else KeyDoesNotExist is raised.

Parameters:
  • keychain_uid -- unique ID of the keychain

  • key_algo -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • private_key (bytes) -- private key in PEM format (potentially encrypted)

Return type:

None

set_public_key(*, keychain_uid, key_algo, public_key)

Store a public key, which must not already exist - else KeyAlreadyExists is raised.

Parameters:
  • keychain_uid -- unique ID of the keychain

  • key_algo -- one of SUPPORTED_ASYMMETRIC_KEY_ALGOS

  • public_key (bytes) -- public key in clear PEM format

Return type:

None

Keystore pools

These combine local and imported key storages under a single interface.

class wacryptolib.keystore.InMemoryKeystorePool

Bases: KeystorePoolBase

Dummy key storage pool for use in tests, where keys are kepts only process-locally.

NOT MEANT TO BE THREAD-SAFE

class wacryptolib.keystore.FilesystemKeystorePool(root_dir)

Bases: KeystorePoolBase

This class handles a set of locally stored key storages.

The local storage represents the current device/owner, and is expected to be used by read-write trustees, whereas imported key storages are supposed to be readonly, and only filled with keypairs imported from key-devices.

export_foreign_keystore_to_keystore_tree(keystore_uid, include_private_keys=True)

Exports data tree from the keystore targeted by keystore_uid.

get_all_foreign_keystore_metadata(include_keypair_identifiers=False)

Return a dict mapping key storage UUIDs to the dicts of their metadata.

Raises if any metadata loading fails.

Return type:

dict

get_foreign_keystore(keystore_uid, writable=False)

The selected storage MUST exist, else a KeystoreDoesNotExist is raised.

get_foreign_keystore_metadata(keystore_uid, include_keypair_identifiers=False)

Return a metadata dict for the keystore keystore_uid.

get_local_keyfactory()

Storage automatically created if unexisting.

import_foreign_keystore_from_keystore_tree(keystore_tree)

Imports/updates data tree into the keystore targeted by keystore_uid.

Return type:

bool

list_foreign_keystore_uids()

Return a sorted list of UUIDs of key storages, corresponding to the keystore_uid of their origin authentication devices.

Return type:

list