Cryptainer

This module provides utilities to write and read encrypted cryptainers, which themselves use encryption/signing keys from trustees.

Cryptainer object processing

wacryptolib.cryptainer.encrypt_payload_into_cryptainer(payload, *, cryptoconf, cryptainer_metadata, keystore_pool=None)

Turn a raw payload into a secure cryptainer, which can only be decrypted with the agreement of the owner and third-party trustees.

Parameters:
  • payload (Union[bytes, BinaryIO]) -- bytestring of media (image, video, sound...) or readable file object (file immediately deleted then)

  • cryptoconf (dict) -- tree of specific encryption settings

  • cryptainer_metadata (Optional[dict]) -- dict of metadata describing the payload (remains unencrypted in cryptainer)

  • keystore_pool (Optional[KeystorePoolBase]) -- optional key storage pool, might be required by cryptoconf

Return type:

dict

Returns:

dict of cryptainer

wacryptolib.cryptainer.decrypt_payload_from_cryptainer(cryptainer, *, keystore_pool=None, passphrase_mapper=None, verify_integrity_tags=True, gateway_urls=None, revelation_requestor_uid=None)

Decrypt a cryptainer with the help of third-parties.

Parameters:
  • cryptainer (dict) -- the cryptainer tree, which holds all information about involved keys

  • keystore_pool (Optional[KeystorePoolBase]) -- optional key storage pool

  • passphrase_mapper (Optional[dict]) -- optional dict mapping trustee IDs to their lists of passphrases

  • verify_integrity_tags (bool) -- whether to check MAC tags of the ciphertext

Return type:

tuple

Returns:

tuple (data)

wacryptolib.cryptainer.extract_metadata_from_cryptainer(cryptainer)

Read the metadata tree (possibly None) from a cryptainer.

CURRENTLY CRYPTAINER METADATA ARE NEITHER ENCRYPTED NOR AUTHENTIFIED.

Parameters:

cryptainer (dict) -- the cryptainer tree, which also holds cryptainer_metadata about encrypted content

Return type:

Optional[dict]

Returns:

dict

wacryptolib.cryptainer.get_cryptoconf_summary(cryptoconf_or_cryptainer)

Returns a string summary of the layers of encryption/signature of a cryptainer or a configuration tree.

class wacryptolib.cryptainer.CryptainerEncryptionPipeline(cryptainer_filepath, *, cryptoconf, cryptainer_metadata, keystore_pool=None, dump_initial_cryptainer=True)

Bases: object

Helper which prebuilds a cryptainer without signatures nor payload, fills its OFFLOADED ciphertext file chunk by chunk, and then dumps the final cryptainer (with signatures) to disk.

wacryptolib.cryptainer.encrypt_payload_and_stream_cryptainer_to_filesystem(payload, *, cryptainer_filepath, cryptoconf, cryptainer_metadata, keystore_pool=None)

Optimized version which directly streams encrypted payload to offloaded file, instead of creating a whole cryptainer and then dumping it to disk.

The cryptoconf used must be streamable with an EncryptionPipeline!

Return type:

None

Validation utilities

wacryptolib.cryptainer.check_cryptainer_sanity(cryptainer, jsonschema_mode=False)

Validate the format of a cryptainer.

Parameters:

jsonschema_mode -- If True, the cryptainer must have been loaded as raw json (with $binary, $numberInt and such) and will be checked using a jsonschema validator.

wacryptolib.cryptainer.check_cryptoconf_sanity(cryptoconf, jsonschema_mode=False)

Validate the format of a conf.

Parameters:

jsonschema_mode -- If True, the cryptainer must have been loaded as raw json (with $binary, $numberInt and such) and will be checked using a jsonschema validator.

Filesystem operations

wacryptolib.cryptainer.dump_cryptainer_to_filesystem(cryptainer_filepath, cryptainer, offload_payload_ciphertext=True)

Dump a cryptainer to a file path, overwriting it if existing.

If offload_payload_ciphertext, actual encrypted payload is dumped to a separate bytes file nearby the json-formatted cryptainer.

Return type:

None

wacryptolib.cryptainer.load_cryptainer_from_filesystem(cryptainer_filepath, include_payload_ciphertext=True)

Load a json-formatted cryptainer from a file path, potentially loading its offloaded ciphertext from a separate nearby bytes file.

Field payload_ciphertext is only present in result dict if include_payload_ciphertext is True.

Return type:

dict

wacryptolib.cryptainer.delete_cryptainer_from_filesystem(cryptainer_filepath)

Delete a cryptainer file and its potential offloaded payload file.

wacryptolib.cryptainer.get_cryptainer_size_on_filesystem(cryptainer_filepath)

Return the total size in bytes occupied by a cryptainer and its potential offloaded payload file.

Cryptainer storage system

class wacryptolib.cryptainer.ReadonlyCryptainerStorage(cryptainer_dir, keystore_pool=None)

Bases: object

This class provides read access to a directory filled with cryptainers..

Parameters:
  • cryptainer_dir (Path) -- the folder where cryptainer files are stored

  • keystore_pool (Optional[KeystorePoolBase]) -- optional KeystorePool, which might be required by current cryptoconf

check_cryptainer_sanity(cryptainer_name_or_idx)

Allows the validation of a cryptainer structure

decrypt_cryptainer_from_storage(cryptainer_name_or_idx, passphrase_mapper=None, verify_integrity_tags=True, gateway_urls=None, revelation_requestor_uid=None)

Return the decrypted content of the cryptainer cryptainer_name_or_idx (which must be in list_cryptainer_names(), or an index suitable for this sorted list).

Return type:

tuple

list_cryptainer_names(as_sorted_list=False, as_absolute_paths=False, finished=True)

Returns the list of encrypted cryptainers present in storage, sorted by name or not, absolute or not, as Path objects.

If finished ìs None, both finished and pending cryptainers are listed.

list_cryptainer_properties(as_sorted_list=False, with_creation_datetime=False, with_age=False, with_size=False, with_offloaded=False, finished=True)

Returns an list of dicts (unsorted by default) having the fields "name", [age] and [size], depending on requested properties.

load_cryptainer_from_storage(cryptainer_name_or_idx, include_payload_ciphertext=True)

Return the encrypted cryptainer dict for cryptainer_name_or_idx (which must be in list_cryptainer_names(), or an index suitable for this sorted list).

Only FINISHED cryptainers are expected to be loaded.

Return type:

dict

class wacryptolib.cryptainer.CryptainerStorage(cryptainer_dir, keystore_pool=None, default_cryptoconf=None, max_cryptainer_quota=None, max_cryptainer_count=None, max_cryptainer_age=None, max_workers=1, offload_payload_ciphertext=True)

Bases: ReadonlyCryptainerStorage

This class encrypts file streams and stores them into filesystem, in a thread-safe way.

Exceeding cryptainers are automatically purged when enqueuing new files or waiting for idle state. A thread pool is used to encrypt files in the background.

Parameters:
  • cryptainers_dir -- the folder where cryptainer files are stored

  • keystore_pool (Optional[KeystorePoolBase]) -- optional KeystorePool, which might be required by current cryptoconf

  • default_cryptoconf (Optional[dict]) -- cryptoconf to use when none is provided when enqueuing payload

  • max_cryptainer_quota (Optional[int]) -- if set, cryptainers are deleted if they exceed this size in bytes

  • max_cryptainer_count (Optional[int]) -- if set, oldest exceeding cryptainers (time taken from their name, else their file-stats) are automatically erased

  • max_cryptainer_age (Optional[timedelta]) -- if set, cryptainers exceeding this age (taken from their name, else their file-stats) in days are automatically erased

  • max_workers (int) -- count of worker threads to use in parallel

  • offload_payload_ciphertext -- whether actual encrypted payload must be kept separated from structured cryptainer file

create_cryptainer_encryption_stream(filename_base, cryptainer_metadata, cryptoconf=None, dump_initial_cryptainer=True, cryptainer_encryption_stream_class=None, cryptainer_encryption_stream_extra_kwargs=None)

Create and return a cryptainer encryption stream.

Purges exceeding cryptainers and pending results beforehand.

encrypt_file(filename_base, payload, cryptainer_metadata, cryptoconf=None)

Synchronously encrypt the provided payload into cryptainer storage.

Does NOT purge exceeding cryptainers and pending results beforehand.

Returns the cryptainer basename.

Return type:

str

enqueue_file_for_encryption(filename_base, payload, cryptainer_metadata, cryptoconf=None)

Enqueue a payload for asynchronous encryption and storage.

Purges exceeding cryptainers and pending results beforehand.

The filename of final cryptainer might be different from provided one. Deware, target cryptainer with the same constructed name might be overwritten.

Parameters:
  • payload -- Bytes string, or a file-like object open for reading, which will be automatically closed.

  • cryptainer_metadata -- Dict of metadata added (unencrypted) to cryptainer.

  • keychain_uid -- If provided, replaces autogenerated default keychain_uid for this cryptainer.

  • cryptoconf -- If provided, replaces default cryptoconf for this cryptainer.

wait_for_idle_state()

Wait for each pending future to be completed.

Trustee operations

wacryptolib.cryptainer.get_trustee_proxy(trustee, keystore_pool)

Return an TrusteeApi subclass instance (or proxy) depending on the content of trustee dict.

wacryptolib.cryptainer.gather_trustee_dependencies(cryptainers)

Analyse a cryptainer and return the trustees (and their keypairs) used by it.

Return type:

dict

Returns:

dict with lists of keypair identifiers in fields "encryption" and "signature".

wacryptolib.cryptainer.request_decryption_authorizations(trustee_dependencies, keystore_pool, request_message, passphrases=None)

Loop on encryption trustees and request decryption authorization for all the keypairs that they own.

Return type:

dict

Returns:

dict mapping trustee ids to authorization result dicts.