Class Gateway

Package: keychain.core.gateway

Inheritance: Gateway

Description

Gateway performs application-level cryptographic operations encrypt, decrypt, sign, and verify.

Through the Gateway users create personas and contacts, and execute the cryptographic operations with respect to those entities.

The Gateway works together with the Monitor. The Gateway executes actions, and the Monitor keeps the underlying state of personas and contacts and their associated keychains up to date.

Since: v2.0

Public Constructors

Constructor

Gateway(settings: Settings, db_path: str)

Constructs a Gateway using the provided Settings and path to the Keychain database.

Public Member Functions

Return type Method and Description

None

seed()

Seeds the private key pool and generates a mnemonic recovery string.

bool

set_active_persona(persona: Facade)

Sets the active persona to the provided Facade

Facade

get_active_persona()

Returns the current active persona, if any

bool

mature_persona_exists()

Returns True if there is a mature persona in the Gateway

list[Facade]

get_contacts()

Returns a list of Facade contacts for the current active persona

list[Facade]

get_personas()

Returns a list of personas in the Gateway

Facade

create_persona(name: str, sub_name: str, security_level: SecurityLevel)

Creates a persona in the Gateway with the given identity information and security level

Facade

create_contact(name: str, sub_name: str, uri: Uri)

Creates a contact for the current active persona with the given identity information

None

delete_facade(facade: Facade)

Deletes the provided Facade, either persona or contact

bytearray

encrypt(clear_text: str, contacts: list[Facade])

Encrypts a clear text string so it can be decrypted by the provided list[Facade] contacts

bytearray

sign(clear_text: str)

Signs a clear text string with the current active persona’s signature

bytearray

sign_then_encrypt(clear_text: str, contacts: list[Facade])

Signs a clear text string with the current active persona’s signature, then encrypts for the provided contact list

bytearray

add_signature(signed_msg: bytearray)

Adds the current active persona’s signature to an already-signed message

tuple[str|bytearray, CharEncoding]

decrypt(cipher_text: str)

Decrypts the cipher text into a bytearray with information about how the text was originally encoded

tuple[str|bytearray, CharEncoding, list[Verification]]

decrypt_then_verify(cipher_text: str)

Decrypts the cipher text into a bytearray with original encoding information, providing a list of Verification objects representing information about each signature on the message

tuple[str|bytearray, CharEncoding, list[Verification]]

verify(signed_data: str)

Given a signed message that is not encrypted, returns the message payload and a list[Verification] where each entry corresponds to a signature. The Verification stores information about that signature, such as whether it is cryptographically valid, from a known contact, etc.

Static Member Functions

Return type Method and Description

Settings

init(config_path: str, db_path: str, force_wipe: bool, drop_sql_file: str, create_sql_file: str)

Creates a Keychain Settings and validates the license

Public Member Functions Detail

seed

seed() → None

Seeds the private key pool and generates a mnemonic recovery string. Should be run once a Gateway is created before other operations.

set_active_persona

set_active_persona(persona: Facade) → bool

Sets the active persona in the Gateway. Most operations in Gateway require an active persona. Gateway keeps track of the active persona internally as state, rather than passing the target persona in to various methods. Therefore it is necessary to change the active persona before any encrypt, sign, verify, decrypt, or contact-related methods.

Parameters:

persona - the persona to set active. This must be a Facade which was created as a persona, generally through create_persona. The full list of personas the Gateway is aware of is available through get_personas.

Returns:

True if set was successful

Raises:

BadInputType - if the persona argument is not a Facade

KeychainError - if the Keychain library ran into an error preventing success

get_active_persona

get_active_persona() → Facade

Returns the current active persona in the Gateway, if one has been set. When the Gateway is created, if there is at least one mature persona in it, then one of them will be activated even if set_active_persona has not been invoked yet. Users are encouraged to not rely on this mechanic however as the chosen persona is not deterministic from the user point of view.

Returns:

The current active persona

Raises:

KeychainError - if the Keychain library ran into an error preventing success

mature_persona_exists

mature_persona_exists() → bool

Checks to see if the Gateway has a mature persona within it. If any of the personas are mature, it will return True.

Returns:

True if there is at least 1 mature persona in the Gateway

get_contacts

get_contacts() → list[Facade]

Returns all contacts for the current active persona.

Returns:

a list of Facade objects representing the contacts for the active persona

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

get_personas

get_personas() → list[Facade]

Returns all personas in the Gateway

Returns:

a list of Facade objects representing the personas in the Gateway regardless of confirmation state

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

create_persona

create_persona(name: str, sub_name: str, security_level: SecurityLevel) → Facade

Creates a new persona in the Gateway with the given identity information and security level. This persona will be returned immediately, regardless of its status on the blockchain. It can only be set as the active persona once its status is CONFIRMED.

Parameters:

name - the persona name, an arbitrary user set value

sub_name - the persona sub-name, an arbitrary user set value

security_level - the cipher strength to use for the persona

Returns:

The newly created persona

Raises:

KeychainError - if the Keychain library ran into an error preventing success

create_contact

create_contact(name: str, sub_name: str, uri: Uri) → Facade

Creates a new contact for the current active persona with the given identity information. The contact Uri must be reachable on the blockchain.

Parameters:

name - the contact name, an arbitrary user set value

sub_name - the contact sub-name, an arbitrary user set value

uri - the contact Uri, a digital identification that in v2.4 is a reference to multiple blockchain transactions holding the contact public key information.

Returns:

The contact object

Raises:

KeychainError - if the Keychain library ran into an error preventing success.

In v2.4 the more specific NoActivePersona is not raised. If there is no active persona, it will be caught and raised as KeychainError. This is changed in v3

delete_facade

delete_facade(facade: Facade)

Deletes a contact or persona from the Gateway. If deleting a persona, it must not be the active one. If deleting a contact, the contact must be for the current active persona.

Parameters:

facade - the contact or persona to remove.

Raises:

BadInputType - if the facade parameter is not actually a Facade

KeychainError - if the Keychain library ran into an error preventing success.

encrypt

encrypt(clear_text: str, contacts: list[Facade]) → bytearray

Encrypts a clear text string so it can be decrypted by the provided list of contacts. It is OK to include personas in this list as well.

Parameters:

clear_text - the text to encrypt

contacts - the list of contacts for whom to encrypt the text. Note that the more contacts there are, the larger the cipher-text becomes. However, the size increase per-contact is small relative to message size (~10^2 bytes per contact)

Returns:

a bytearray which contains the encrypted message (cipher-text), original string encoding (for portability), and contact-specific encrypted versions of the symmetric key used to encrypt/decrypt the cipher-text, 1 per contact

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

sign

sign(clear_text: str) → bytearray

Signs a clear text string with the current active persona’s signature.

Parameters:

clear_text - the text to sign

Returns:

a bytearray which is the Keychain representation of the message and persona’s signature

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

sign_then_encrypt

sign_then_encrypt(clear_text: str, contacts: list[Facade]) → bytearray

Signs the clear text and then encrypts it for the provided contacts

Parameters:

clear_text - the text to sign and encrypt

contacts - the list of contacts and/or personas for whom to encrypt the text

Returns:

a bytearray which contains the encrypted message (cipher-text), original string encoding (for portability), contact-specific encrypted versions of the symmetric key used to encrypt/decrypt the cipher-text (1 per contact), and persona signature

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

add_signature

add_signature(signed_msg: bytearray) → bytearray

Adds the current active persona’s signature to an already-signed message. This is fundamentally different from sign. add_signature adds a signature alongside other existing signatures, effectively attesting a message but not the other signatures. sign by contrast adds a signature on the entirety of the envelope, attesting both the message and any other signatures that may be attached.

Parameters:

signed_msg - the already-signed message

Returns:

a new signed message where the current active persona’s signature is added alongside other signatures

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

decrypt

decrypt(cipher_text: str) → tuple[str|bytearray, CharEncoding]

Decrypts a cipher-text for the given persona, if the text was originally encrypted with the persona as intended recipient, yielding a bytearray or string representing the message (which may have signatures, or be wrapped further) and original CharEncoding of the message. The encoding is useful if the result is a bytearray.

Parameters:

cipher_text - the encrypted text

Returns:

a bytearray or string which contains the unencrypted and possibly signed message, as well as the original encoding information

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

decrypt_then_verify

decrypt_then_verify(cipher_text: str) → tuple[str|bytearray, CharEncoding, list[Verification]]

Decrypts the cipher text into a bytearray or str with original encoding information, providing a list of Verification objects representing information about each signature on the message

Parameters:

cipher_text - the encrypted text

Returns:

a bytearray or string which contains the unencrypted message, original string encoding, and list of Verification objects containing information on each of the signatures

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

verify

verify(signed_data: str) → tuple[str|bytearray, CharEncoding, list[Verification]]

Given a signed message, returns the message payload and a list[Verification] where each entry corresponds to a signature. The Verification stores information about that signature, such as whether it is cryptographically valid, from a known contact, etc.

Note that the Verification objects are for the payload, but the payload may itself be a nested message which has been signed. It is important to check the message to see if it is plaintext or in fact another Keychain signed/encrypted message, and then act on it.

For example

# as persona A
gateway.set_active_persona(persona_a)
a = gateway.sign("hello")
# as persona B
gateway.set_active_persona(persona_b)
b = gateway.sign(a)

msg, enc, verifications = gateway.verify(b)
# msg is a bytearray, enc = CharEncoding.BINARY, and verifications is len == 1 and has B's facade

actual_msg, actual_enc, orig_verification = gateway.verify(msg)
# actual_msg = "hello", actual_enc = "UTF-8", and orig_verification is len == 1 and has A's facade

Parameters:

signed_data - the signed message

Returns:

a list of Verification objects containing information on each of the signatures

Raises:

NoActivePersona - if there is not currently an active persona

KeychainError - if the Keychain library ran into an error preventing success

Static Member Functions Detail

init

Settings init(config_path: str, db_path: str, force_wipe: bool, drop_sql_file: str, create_sql_file: str)

Creates a Keychain Settings and validates the license. The Settings is required for Gateway construction, meaning this method must be called before any other operations. Valid paths to config (keychain.cfg) and the Keychain DB must be passed. If force_wipe is True, the database will be destroyed and recreated, so the 2 SQL files must also exist.

Parameters:

config_path - the path to the Keychain configuration file (e.g. keychain.cfg)

db_path - the path to the Keychain DB

force_wipe - whether to wipe the DB and recreate or not

drop_sql_file - the path to an SQL file that drops all Keychain tables in an existing DB

create_sql_file - the path to an SQL file that recreates Keychain tables

Returns:

A Settings object holding the configuration and values passed in