API

agentcrypt.io

class agentcrypt.io.Container(io_handle, ssh_key, cipher, nonce, salt, data=None, create_path=None)[source]

Bases: _io.BytesIO

The public interface for encrypting and decrypting data. Container objects represent files or streams of encrypted data. Instances of this class should be created with the help of the following static methods

  • create(): Store encrypted data in a new container.
  • load(): Load or modify an existing container.

Container inherits from io.BytesIO, thus it can be used as a stream. Use the inherited methode getvalue() to access the contained data in decrypted form.

classmethod create(write_target, ssh_key_fp=None, cipher_name=None, data=None)[source]

Creates a new container.

Parameters:
  • write_target – Either a filehandle or a path to the target container as string. If an instance of io.IOBase is detected (file instance in Python2) the parameter will be treated as handle. Otherwise it is interpreted as path and used as the first parameter to open(), to get a filehandle.
  • ssh_key_fp – The SHA256 fingerprint of the key to use for encryption. If set to None, the first key found in the key-agent is used (use ssh-add -l -E sha256 to get valid fingerprints).
  • cipher_name – The symmetric cipher to use. Must be one of the values from the cipher names published by crypto.Cipher. Use None to pick the strongest available cipher.
  • data – The initial data to write to the container. Additional data can be added with write() or writelines() after the container has been created.
Returns:

Container instance

classmethod load(rw_target)[source]

Loads an existing container.

Parameters:rw_target – A path (string) or a filehandle (io.IOBase in Python3, file instance in Python2) to load from.
Returns:Container instance

Use the inherited methode getvalue() to access the contained data in decrypted form.

save()[source]

Alias for close().

rekey(cipher_name=None)[source]

Creates a new nonce, optionally with a different cipher an marks the container as modified, so that it will be written, when flush() is called.

flush()[source]

Writes the container if it was modified. The container is modified, if either..

  • It was instantiated with the create() method and a data parameter that was not empty.
  • Any of the methods has been called, that modify the content (write(), rekey(), clear(), ..).
close()[source]

Writes the container, if it was modified and closes it. There is a cleanup logic, that will delete empty containers, if all of the following conditions hold true:

  • The container is new and empty (method create() was called with empty data parameter).
  • A new file was created for it (parameter write_target was not an existing filehandle).
  • The container has not been modified since it was created.
clear()[source]

Convenience method for clearing the container contents. Same as truncate(0) and seek(0).

agentcrypt.crypto

class agentcrypt.crypto.AgentKey(agent, agent_key)[source]

Bases: paramiko.agent.AgentKey

Specialization of paramiko.agent.AgentKey with a few additions for our purposes.

get_sha256_fingerprint()[source]

SHA256 fingerprint extension from pull request 1103.

get_ssh_signature_blob(data)[source]

Signs data and returns the signature as bytes.

Parameters:data – The bytes object to be signed.
Returns:The signature part of the resulting SSH_AGENT_SIGN_RESPONSE message as described in the RFCs referenced by the SSH Agent Protocol draft.
class agentcrypt.crypto.SSHAgent[source]

Bases: paramiko.agent.Agent

Specialization of paramiko.agent.Agent which uses crypto.AgentKey objects internally.

classmethod get_key(key_fp=None)[source]

Searches for the specified key in the agent. Creates a new instance of SSHAgent, if necessary (singleton logic).

Parameters:key_fp – The SHA256 fingerprint of the key to search for. If None, the first key is returned.
Returns:crypto.AgentKey instance, if a key was found, or None if nothing was found.
class agentcrypt.crypto.Cipher(cipher_name=None)[source]

Bases: object

Provides symmetric encryption with the help of the pyca/cryptography library.

AES_256_CBC = 'AES_256_CBC'

Cipher name.

AES_128_CBC = 'AES_128_CBC'

Cipher name.

DES_EDE3_CBC = 'DES_EDE3_CBC'

Cipher name.

Blowfish_CBC = 'Blowfish_CBC'

Cipher name.

__init__(cipher_name=None)[source]

Creates a new instance that uses the selected cipher.

Parameters:cipher_name – One of the cipher names exported by the static members above.
Returns:crypto.Cipher instance.
static get_kdf(salt, key_size)[source]

Returns the preferred Key Derivation Function (KDF) to be used for deriving the secret key from the signature returned by AgentKey.get_ssh_signature_blob().

Returns:PBKDF2HMAC instance.

This is the place to put another KDF, if preferred. An SCrypt example is provided in the code. BCrypt would add dependencies, that’s why there is no code for it, but it can be added quiet simply.

encrypt(data, password, salt)[source]

Encrypt data.

Parameters:
  • data – Cleartext data to encrypt.
  • password – The password (will be fed to the KDF in use).
  • salt – The salt (will be fed to the KDF in use).
Returns:

bytes object with encrypted data.

decrypt(data_enc, password, salt)[source]

Decrypt data.

Parameters:
  • databytes object with encrypted data.
  • password – The password (will be fed to the KDF in use).
  • salt – The salt (will be fed to the KDF in use).
Returns:

bytes object with cleartext data.

agentcrypt.exceptions

exception agentcrypt.exceptions.AgentCryptException(message)[source]

Bases: exceptions.Exception

Any error condition within the library is indicated by raising AgentCryptException.

Additional information about the root cause can be obtained by inspecting the __cause__ attribute set by raise from. If anything else than AgentCryptException is raised by an agentcrypt module, either a library is missing or it is probably a bug.

exception agentcrypt.exceptions.NoContainerException(message)[source]

Bases: agentcrypt.exceptions.AgentCryptException

Sub class of AgentCryptException that is raised, when an existing container cannot be loaded.