Subpackage exporter
derivepassphrase.exporter
¶
Foreign configuration exporter for derivepassphrase.
get_vault_key
¶
get_vault_key() -> bytes
Automatically determine the vault(1) master key/password.
Query the VAULT_KEY
, LOGNAME
, USER
and USERNAME
environment
variables, in that order. This is the same algorithm that vault
uses.
Returns:
Type | Description |
---|---|
bytes
|
The master key/password. This is generally used as input to a key-derivation function to determine the actual encryption and signing keys for the vault configuration. |
Raises:
Type | Description |
---|---|
KeyError
|
We cannot find any of the named environment variables.
Please set |
get_vault_path
¶
Automatically determine the vault(1) configuration path.
Query the VAULT_PATH
environment variable, or default to
~/.vault
. This is the same algorithm that vault uses. If not
absolute, then VAULT_PATH
is relative to the home directory.
Returns:
Type | Description |
---|---|
str | bytes | PathLike
|
The vault configuration path. Depending on the vault version, this may be a file or a directory. |
Raises:
Type | Description |
---|---|
RuntimeError
|
We cannot determine the home directory. Please set |
derivepassphrase.exporter.storeroom
¶
Exporter for the vault “storeroom” configuration format.
The “storeroom” format is the experimental format used in alpha and beta versions of vault beyond v0.3.0. The configuration is stored as a separate directory, which acts like a hash table (i.e. has named slots) and provides an impure quasi-filesystem interface. Each hash table entry is separately encrypted and authenticated. James Coglan designed this format to avoid concurrent write issues when updating or synchronizing the vault configuration with e.g. a cloud service.
The public interface is the export_storeroom_data
function.
Multiple non-public functions are additionally documented here for
didactical and educational reasons, but they are not part of the module
API, are subject to change without notice (including removal), and
should not be used or relied on.
KeyPair
¶
Bases: TypedDict
A pair of AES256 keys, one for encryption and one for signing.
Attributes:
Name | Type | Description |
---|---|---|
encryption_key |
bytes
|
AES256 key, used for encryption with AES256-CBC (with PKCS#7 padding). |
signing_key |
bytes
|
AES256 key, used for signing with HMAC-SHA256. |
MasterKeys
¶
Bases: TypedDict
A triple of AES256 keys, for encryption, signing and hashing.
Attributes:
Name | Type | Description |
---|---|---|
hashing_key |
bytes
|
AES256 key, used for hashing with HMAC-SHA256 to derive a hash table slot for an item. |
encryption_key |
bytes
|
AES256 key, used for encryption with AES256-CBC (with PKCS#7 padding). |
signing_key |
bytes
|
AES256 key, used for signing with HMAC-SHA256. |
derive_master_keys_keys
¶
Derive encryption and signing keys for the master keys data.
The master password is run through a key derivation function to obtain a 64-byte string, which is then split to yield two 32-byte keys. The key derivation function is PBKDF2, using HMAC-SHA1 and salted with the storeroom master keys UUID.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
password
|
str | bytes
|
A master password for the storeroom instance. Usually read
from the |
required |
iterations
|
int
|
A count of rounds for the underlying key derivation function. Usually stored as a setting next to the encrypted master keys data. |
required |
Returns:
Type | Description |
---|---|
KeyPair
|
A 2-tuple of keys, the encryption key and the signing key, to decrypt and verify the master keys data with. |
Warning
Non-public function, provided for didactical and educational purposes only. Subject to change without notice, including removal.
decrypt_master_keys_data
¶
decrypt_master_keys_data(
data: bytes, keys: KeyPair
) -> MasterKeys
Decrypt the master keys data.
The master keys data contains:
- a 16-byte IV,
- a 96-byte AES256-CBC-encrypted payload, plus 16 further bytes of PKCS7 padding, and
- a 32-byte MAC of the preceding 128 bytes.
The decrypted payload itself consists of three 32-byte keys: the hashing, encryption and signing keys, in that order.
The encrypted payload is encrypted with the encryption key, and the MAC is created based on the signing key. As per standard cryptographic procedure, the MAC can be verified before attempting to decrypt the payload.
Because the payload size is both fixed and a multiple of the cipher
blocksize, in this case, the PKCS7 padding always is b'\x10' * 16
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data
|
bytes
|
The encrypted master keys data. |
required |
keys
|
KeyPair
|
The encryption and signing keys for the master keys data.
These should have previously been derived via the
|
required |
Returns:
Type | Description |
---|---|
MasterKeys
|
The master encryption, signing and hashing keys. |
Raises:
Type | Description |
---|---|
InvalidSignature
|
The data does not contain a valid signature under the given key. |
ValueError
|
The format is invalid, in a non-cryptographic way. (For example, it contains an unsupported version marker, or unexpected extra contents, or invalid padding.) |
Warning
Non-public function, provided for didactical and educational purposes only. Subject to change without notice, including removal.
decrypt_session_keys
¶
decrypt_session_keys(
data: bytes, master_keys: MasterKeys
) -> KeyPair
Decrypt the bucket item’s session keys.
The bucket item’s session keys are single-use keys for encrypting and signing a single item in the storage bucket. The encrypted session key data consists of:
- a 16-byte IV,
- a 64-byte AES256-CBC-encrypted payload, plus 16 further bytes of PKCS7 padding, and
- a 32-byte MAC of the preceding 96 bytes.
The encrypted payload is encrypted with the master encryption key, and the MAC is created with the master signing key. As per standard cryptographic procedure, the MAC can be verified before attempting to decrypt the payload.
Because the payload size is both fixed and a multiple of the cipher
blocksize, in this case, the PKCS7 padding always is b'\x10' * 16
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data
|
bytes
|
The encrypted bucket item session key data. |
required |
master_keys
|
MasterKeys
|
The master keys. Presumably these have previously been
obtained via the |
required |
Returns:
Type | Description |
---|---|
KeyPair
|
The bucket item’s encryption and signing keys. |
Raises:
Type | Description |
---|---|
InvalidSignature
|
The data does not contain a valid signature under the given key. |
ValueError
|
The format is invalid, in a non-cryptographic way. (For example, it contains an unsupported version marker, or unexpected extra contents, or invalid padding.) |
Warning
Non-public function, provided for didactical and educational purposes only. Subject to change without notice, including removal.
decrypt_contents
¶
Decrypt the bucket item’s contents.
The data consists of:
- a 16-byte IV,
- a variable-sized AES256-CBC-encrypted payload (using PKCS7 padding on the inside), and
- a 32-byte MAC of the preceding bytes.
The encrypted payload is encrypted with the bucket item’s session encryption key, and the MAC is created with the bucket item’s session signing key. As per standard cryptographic procedure, the MAC can be verified before attempting to decrypt the payload.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data
|
bytes
|
The encrypted bucket item payload data. |
required |
session_keys
|
KeyPair
|
The bucket item’s session keys. Presumably these have
previously been obtained via the |
required |
Returns:
Type | Description |
---|---|
bytes
|
The bucket item’s payload. |
Raises:
Type | Description |
---|---|
InvalidSignature
|
The data does not contain a valid signature under the given key. |
ValueError
|
The format is invalid, in a non-cryptographic way. (For example, it contains an unsupported version marker, or unexpected extra contents, or invalid padding.) |
Warning
Non-public function, provided for didactical and educational purposes only. Subject to change without notice, including removal.
decrypt_bucket_item
¶
decrypt_bucket_item(
bucket_item: bytes, master_keys: MasterKeys
) -> bytes
Decrypt a bucket item.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
bucket_item
|
bytes
|
The encrypted bucket item. |
required |
master_keys
|
MasterKeys
|
The master keys. Presumably these have previously been
obtained via the |
required |
Returns:
Type | Description |
---|---|
bytes
|
The decrypted bucket item. |
Raises:
Type | Description |
---|---|
InvalidSignature
|
The data does not contain a valid signature under the given key. |
ValueError
|
The format is invalid, in a non-cryptographic way. (For example, it contains an unsupported version marker, or unexpected extra contents, or invalid padding.) |
Warning
Non-public function, provided for didactical and educational purposes only. Subject to change without notice, including removal.
decrypt_bucket_file
¶
decrypt_bucket_file(
filename: str,
master_keys: MasterKeys,
*,
root_dir: str | bytes | PathLike = "."
) -> Iterator[bytes]
Decrypt a complete bucket.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filename
|
str
|
The bucket file’s filename. |
required |
master_keys
|
MasterKeys
|
The master keys. Presumably these have previously been
obtained via the |
required |
root_dir
|
str | bytes | PathLike
|
The root directory of the data store. The filename is interpreted relatively to this directory. |
'.'
|
Yields:
Type | Description |
---|---|
bytes
|
A decrypted bucket item. |
Raises:
Type | Description |
---|---|
InvalidSignature
|
The data does not contain a valid signature under the given key. |
ValueError
|
The format is invalid, in a non-cryptographic way. (For example, it contains an unsupported version marker, or unexpected extra contents, or invalid padding.) |
Warning
Non-public function, provided for didactical and educational purposes only. Subject to change without notice, including removal.
export_storeroom_data
¶
export_storeroom_data(
storeroom_path: str | bytes | PathLike | None = None,
master_keys_key: str | bytes | None = None,
) -> dict[str, Any]
Export the full configuration stored in the storeroom.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
storeroom_path
|
str | bytes | PathLike | None
|
Path to the storeroom; usually |
None
|
master_keys_key
|
str | bytes | None
|
Encryption key/password for the master keys, usually the
username, or passed via the |
None
|
Returns:
Type | Description |
---|---|
dict[str, Any]
|
The full configuration, as stored in the storeroom. This may or may not be a valid configuration according to vault or derivepassphrase. |
Raises:
Type | Description |
---|---|
RuntimeError
|
Something went wrong during data collection, e.g. we encountered unsupported or corrupted data in the storeroom. |
JSONDecodeError
|
An internal JSON data structure failed to parse from disk. The storeroom is probably corrupted. |
derivepassphrase.exporter.vault_native
¶
Exporter for the vault native configuration format (v0.2 or v0.3).
The vault native formats are the configuration formats used by vault v0.2 and v0.3. The configuration is stored as a single encrypted file, which is encrypted and authenticated. v0.2 and v0.3 differ in some details concerning key derivation and expected format of internal structures, so they are not compatible. v0.2 additionally contains cryptographic weaknesses (API misuse of a key derivation function, and a low-entropy method of generating initialization vectors for CBC block encryption mode) and should thus be avoided if possible.
The public interface is the export_vault_native_data
function.
Multiple non-public classes are additionally documented here for
didactical and educational reasons, but they are not part of the module
API, are subject to change without notice (including removal), and
should not be used or relied on.
VaultNativeConfigParser
¶
Bases: ABC
A base parser for vault’s native configuration format.
Certain details are specific to the respective vault versions, and are abstracted out. This class by itself is not instantiable because of this.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
contents
|
Buffer
|
The binary contents of the encrypted configuration file. Note: On disk, these are usually stored in base64-encoded form, not in the “raw” form as needed here. |
required |
password
|
str | Buffer
|
The vault master key/master passphrase the file is
encrypted with. Must be non-empty. See
If this is a text string, then the UTF-8 encoding of the string is used as the binary password. |
required |
Warning
Non-public class, provided for didactical and educational purposes only. Subject to change without notice, including removal.
__call__
¶
__call__() -> Any
Return the decrypted and parsed vault configuration.
Raises:
Type | Description |
---|---|
InvalidSignature
|
The encrypted configuration does not contain a valid signature. |
ValueError
|
The format is invalid, in a non-cryptographic way. (For example, it contains an unsupported version marker, or unexpected extra contents, or invalid padding.) |
VaultNativeV03ConfigParser
¶
Bases: VaultNativeConfigParser
A parser for vault’s native configuration format (v0.3).
This is the modern, pre-storeroom configuration format.
Warning
Non-public class, provided for didactical and educational purposes only. Subject to change without notice, including removal.
VaultNativeV02ConfigParser
¶
Bases: VaultNativeConfigParser
A parser for vault’s native configuration format (v0.2).
This is the classic configuration format. Compared to v0.3, it contains an (accidental) API misuse for the generation of the master keys, a low-entropy method of generating initialization vectors for the AES-CBC encryption step, and extra layers of base64 encoding. Because of these significantly weakened confidentiality guarantees, v0.2 configurations should be upgraded to at least v0.3 as soon as possible.
Warning
Non-public class, provided for didactical and educational purposes only. Subject to change without notice, including removal.
export_vault_native_data
¶
export_vault_native_data(
contents: Buffer | None = None,
key: str | Buffer | None = None,
*,
try_formats: Sequence[str] = ("v0.3", "v0.2")
) -> Any
Export the full configuration stored in vault native format.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
contents
|
Buffer | None
|
The binary encrypted contents of the vault configuration
file. If not given, then query
Note: On disk, these are usually stored in base64-encoded form, not in the “raw” form as needed here. |
None
|
key
|
str | Buffer | None
|
Encryption key/password for the configuration file, usually
the username, or passed via the |
None
|
try_formats
|
Sequence[str]
|
A sequence of formats to try out, in order. Each key must
be one of |
('v0.3', 'v0.2')
|
Returns:
Type | Description |
---|---|
Any
|
The vault configuration, as recorded in the configuration file. This may or may not be a valid configuration according to vault or derivepassphrase. |
Raises:
Type | Description |
---|---|
RuntimeError
|
Something went wrong during data collection, e.g. we encountered unsupported or corrupted data in the storeroom. |
JSONDecodeError
|
An internal JSON data structure failed to parse from disk. The storeroom is probably corrupted. |
ValueError
|
The requested formats to try out are invalid, or the encrypted contents aren’t in any of the attempted configuration formats. |