From 9df1c8dab0c3b7218cbf40d743d73e9bd36c24cd Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sun, 19 Nov 2017 13:11:17 -0500 Subject: PSK Database --- doc/manual/cli.rst | 36 ++++++++++++++-- doc/manual/contents.rst | 1 + doc/manual/psk_db.rst | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 doc/manual/psk_db.rst (limited to 'doc') diff --git a/doc/manual/cli.rst b/doc/manual/cli.rst index 71e3b17c6..72e3d3b31 100644 --- a/doc/manual/cli.rst +++ b/doc/manual/cli.rst @@ -14,15 +14,16 @@ The CLI offers access to the following functionalities: - TLS server/client - Primality testing, prime factorization and prime sampling +.. highlight:: sh + General Command Usage --------------------------------- -All commands follow the predefined syntax - -.. code-block:: sh +All commands follow the predefined syntax:: $ botan -and are listed whith their available arguments when botan is called with an invalid or without a command. +and are listed with their available arguments when ``botan`` is called +with an unknown command, or without any command, or with ``--help``. Hash ---------------- @@ -128,6 +129,33 @@ Number Theory ``gen_prime --count=1 bits`` Samples *count* primes with a length of *bits* bits. +PSK Database +-------------------- + +Only available if sqlite3 support was compiled in. + +``psk_set db db_key name psk`` + + Using the PSK database named db and encrypting under the (hex) key ``db_key``, + save the provided psk (also hex) under ``name``:: + + $ botan psk_set psk.db deadba55 bunny f00fee + +``psk_get db db_key name`` + + Get back a value saved with ``psk_set``:: + + $ botan psk_get psk.db deadba55 bunny + f00fee + +``psk_list db db_key`` + + List all values saved to the database under the given key:: + + $ botan psk_list psk.db deadba55 + bunny + + Miscellaneous Commands ------------------------------------- ``version --full`` diff --git a/doc/manual/contents.rst b/doc/manual/contents.rst index 0c9ac4b7f..48e6edbfe 100644 --- a/doc/manual/contents.rst +++ b/doc/manual/contents.rst @@ -27,6 +27,7 @@ Contents passhash cryptobox srp + psk_db fpe compression pkcs11 diff --git a/doc/manual/psk_db.rst b/doc/manual/psk_db.rst new file mode 100644 index 000000000..2668c6bad --- /dev/null +++ b/doc/manual/psk_db.rst @@ -0,0 +1,108 @@ +PSK Database +====================== + +.. versionadded:: 2.4.0 + +Many applications need to store pre-shared keys (hereafter PSKs) for +authentication purposes. + +An abstract interface to PSK stores is provided in ``psk_db.h`` + +.. cpp:class:: PSK_Database + + .. cpp:function:: bool is_encrypted() const + + Returns true if (at least) the PSKs themselves are encrypted. Returns + false if PSKs are stored in plaintext. + + .. cpp:function:: std::set list_names() const + + Return the set of valid names stored in the database, ie values for which + ``get`` will return a value. + + .. cpp:function:: void set(const std::string& name, const uint8_t psk[], size_t psk_len) + + Save a PSK. If ``name`` already exists, the current value will be + overwritten. + + .. cpp:function:: secure_vector get(const std::string& name) const + + Return a value saved with ``set``. Throws an exception if ``name`` doesn't + exist. + + .. cpp:function:: void remove(const std::string& name) + + Remove ``name`` from the database. If ``name`` doesn't exist, ignores the request. + + .. cpp::function:: std::string get_str(const std::string& name) const + + Like ``get`` but casts the return value to a string. + + .. cpp:function:: void set_str(const std::string& name, const std::string& psk) + + Like ``set`` but accepts the psk as a string (eg for a password). + + .. cpp:function:: template void set_vec(const std::string& name, \ + const std::vector& psk) + + Like ``set`` but accepting a vector. + +The same header also provides a specific instantiation of ``PSK_Database`` which +encrypts both names and PSKs. It must be subclassed to provide the storage. + +.. cpp:class:: Encrypted_PSK_Database : public PSK_Database + + .. cpp:function:: Encrypted_PSK_Database(const secure_vector& master_key) + + Initializes or opens a PSK database. The master key is used the secure the + contents. It may be of any length. If encrypting PSKs under a passphrase, + use a suitable key derivation scheme (such as PBKDF2) to derive the secret + key. If the master key is lost, all PSKs stored are unrecoverable. + + Both names and values are encrypted using NIST key wrapping (see NIST + SP800-38F) with AES-256. First the master key is used with HMAC(SHA-256) + to derive two 256-bit keys, one for encrypting all names and the other to + key an instance of HMAC(SHA-256). Values are each encrypted under an + individual key created by hashing the encrypted name with HMAC. This + associates the encrypted key with the name, and prevents an attacker with + write access to the data store from taking an encrypted key associated + with one entity and copying it to another entity. + + Names and PSKs are both padded to the next multiple of 8 bytes, providing + some obfuscation of the length. + + One artifact of the names being encrypted is that is is possible to use + multiple different master keys with the same underlying storage. Each + master key will be responsible for a subset of the keys. An attacker who + knows one of the keys will be able to tell there are other values + encrypted under another key. + + .. cpp:function:: virtual void kv_set(const std::string& index, const std::string& value) = 0 + + Save an encrypted value. Both ``index`` and ``value`` will be non-empty + base64 encoded strings. + + .. cpp:function:: virtual std::string kv_get(const std::string& index) const = 0 + + Return a value saved with ``kv_set``, or return the empty string. + + .. cpp:function:: virtual void kv_del(const std::string& index) = 0 + + Remove a value saved with ``kv_set``. + + .. cpp:function:: virtual std::set kv_get_all() const = 0 + + Return all active names (ie values for which ``kv_get`` will return a + non-empty string). + +A subclass of ``Encrypted_PSK_Database`` which stores data in a SQL database +is also available. This class is declared in ``psk_db_sql.h``: + +.. cpp:class:: Encrypted_PSK_Database_SQL : public Encrypted_PSK_Database + + .. cpp:function:: Encrypted_PSK_Database_SQL(const secure_vector& master_key, \ + std::shared_ptr db, \ + const std::string& table_name) + + Creates or uses the named table in ``db``. The SQL schema of the table is + ``(psk_name TEXT PRIMARY KEY, psk_value TEXT)``. -- cgit v1.2.3