Botan 3.5.0
Crypto and TLS for C&
Botan::Encrypted_PSK_Database Class Referenceabstract

#include <psk_db.h>

Inheritance diagram for Botan::Encrypted_PSK_Database:
Botan::PSK_Database Botan::Encrypted_PSK_Database_SQL

Public Member Functions

 Encrypted_PSK_Database (const secure_vector< uint8_t > &master_key)
 
secure_vector< uint8_t > get (std::string_view name) const override
 
std::string get_str (std::string_view name) const
 
bool is_encrypted () const override
 
std::set< std::string > list_names () const override
 
void remove (std::string_view name) override
 
void set (std::string_view name, const uint8_t psk[], size_t psk_len) override
 
void set_str (std::string_view name, std::string_view psk)
 
template<typename Alloc >
void set_vec (std::string_view name, const std::vector< uint8_t, Alloc > &psk)
 
 ~Encrypted_PSK_Database () override
 

Protected Member Functions

virtual void kv_del (std::string_view index)=0
 
virtual std::string kv_get (std::string_view index) const =0
 
virtual std::set< std::string > kv_get_all () const =0
 
virtual void kv_set (std::string_view index, std::string_view value)=0
 

Detailed Description

A mixin for an encrypted PSK database. Both keys and values are encrypted with NIST AES-256 key wrapping. Values are padded to obscure their length before encryption, allowing it to be used as a password vault.

Subclasses must implement the virtual calls to handle storing and getting raw (base64 encoded) values.

Definition at line 79 of file psk_db.h.

Constructor & Destructor Documentation

◆ Encrypted_PSK_Database()

Botan::Encrypted_PSK_Database::Encrypted_PSK_Database ( const secure_vector< uint8_t > & master_key)
Parameters
master_keyspecifies the master key used to encrypt all keys and value. It can be of any length, but should be at least 256 bits.

Subkeys for the cryptographic algorithms used are derived from this master key. No key stretching is performed; if encrypting a PSK database using a password, it is recommended to use PBKDF2 to derive the database master key.

Definition at line 27 of file psk_db.cpp.

27 {
28 m_cipher = BlockCipher::create_or_throw("AES-256");
29 m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
30 m_hmac->set_key(master_key);
31
32 m_cipher->set_key(m_hmac->process("wrap"));
33 m_hmac->set_key(m_hmac->process("hmac"));
34}
static std::unique_ptr< BlockCipher > create_or_throw(std::string_view algo_spec, std::string_view provider="")
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition mac.cpp:148

References Botan::BlockCipher::create_or_throw(), and Botan::MessageAuthenticationCode::create_or_throw().

◆ ~Encrypted_PSK_Database()

Botan::Encrypted_PSK_Database::~Encrypted_PSK_Database ( )
overridedefault

Member Function Documentation

◆ get()

secure_vector< uint8_t > Botan::Encrypted_PSK_Database::get ( std::string_view name) const
overridevirtual

Return the value associated with the specified

Parameters
nameor otherwise throw an exception.

Implements Botan::PSK_Database.

Definition at line 63 of file psk_db.cpp.

63 {
64 const std::vector<uint8_t> wrapped_name =
65 nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()), name.size(), *m_cipher);
66
67 const std::string val_base64 = kv_get(base64_encode(wrapped_name));
68
69 if(val_base64.empty()) {
70 throw Invalid_Argument("Named PSK not located");
71 }
72
73 const secure_vector<uint8_t> val = base64_decode(val_base64);
74
75 auto wrap_cipher = m_cipher->new_object();
76 wrap_cipher->set_key(m_hmac->process(wrapped_name));
77
78 return nist_key_unwrap_padded(val.data(), val.size(), *wrap_cipher);
79}
virtual std::string kv_get(std::string_view index) const =0
std::string name
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition base64.cpp:146
size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition base64.cpp:154
std::vector< uint8_t > nist_key_wrap_padded(const uint8_t input[], size_t input_len, const BlockCipher &bc)
secure_vector< uint8_t > nist_key_unwrap_padded(const uint8_t input[], size_t input_len, const BlockCipher &bc)
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition mem_ops.h:273

References Botan::base64_decode(), Botan::base64_encode(), Botan::cast_char_ptr_to_uint8(), kv_get(), name, Botan::nist_key_unwrap_padded(), and Botan::nist_key_wrap_padded().

◆ get_str()

std::string Botan::PSK_Database::get_str ( std::string_view name) const
inherited

Get a PSK in the form of a string (eg if the PSK is a password)

Definition at line 18 of file psk_db.cpp.

18 {
19 secure_vector<uint8_t> psk = this->get(name);
20 return std::string(cast_uint8_ptr_to_char(psk.data()), psk.size());
21}
virtual secure_vector< uint8_t > get(std::string_view name) const =0
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition mem_ops.h:277

References Botan::cast_uint8_ptr_to_char(), and Botan::PSK_Database::get().

◆ is_encrypted()

bool Botan::Encrypted_PSK_Database::is_encrypted ( ) const
inlineoverridevirtual

Returns if the values in the PSK database are encrypted. If false, saved values are being stored in plaintext.

Implements Botan::PSK_Database.

Definition at line 102 of file psk_db.h.

102{ return true; }

◆ kv_del()

virtual void Botan::Encrypted_PSK_Database::kv_del ( std::string_view index)
protectedpure virtual

Remove an index

Referenced by remove().

◆ kv_get()

virtual std::string Botan::Encrypted_PSK_Database::kv_get ( std::string_view index) const
protectedpure virtual

Get a value previously saved with set_raw_value. Should return an empty string if index is not found.

Referenced by get().

◆ kv_get_all()

virtual std::set< std::string > Botan::Encrypted_PSK_Database::kv_get_all ( ) const
protectedpure virtual

Return all indexes in the table.

Referenced by list_names().

◆ kv_set()

virtual void Botan::Encrypted_PSK_Database::kv_set ( std::string_view index,
std::string_view value )
protectedpure virtual

Save a encrypted (name.value) pair to the database. Both will be base64 encoded strings.

Referenced by set().

◆ list_names()

std::set< std::string > Botan::Encrypted_PSK_Database::list_names ( ) const
overridevirtual

Return the set of names for which get() will return a value.

Implements Botan::PSK_Database.

Definition at line 38 of file psk_db.cpp.

38 {
39 const std::set<std::string> encrypted_names = kv_get_all();
40
41 std::set<std::string> names;
42
43 for(const auto& enc_name : encrypted_names) {
44 try {
45 const secure_vector<uint8_t> raw_name = base64_decode(enc_name);
46 const secure_vector<uint8_t> name_bits = nist_key_unwrap_padded(raw_name.data(), raw_name.size(), *m_cipher);
47
48 std::string pt_name(cast_uint8_ptr_to_char(name_bits.data()), name_bits.size());
49 names.insert(pt_name);
50 } catch(Invalid_Authentication_Tag&) {}
51 }
52
53 return names;
54}
virtual std::set< std::string > kv_get_all() const =0

References Botan::base64_decode(), Botan::cast_uint8_ptr_to_char(), kv_get_all(), and Botan::nist_key_unwrap_padded().

◆ remove()

void Botan::Encrypted_PSK_Database::remove ( std::string_view name)
overridevirtual

Remove a PSK from the database

Implements Botan::PSK_Database.

Definition at line 56 of file psk_db.cpp.

56 {
57 const std::vector<uint8_t> wrapped_name =
58 nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()), name.size(), *m_cipher);
59
60 this->kv_del(base64_encode(wrapped_name));
61}
virtual void kv_del(std::string_view index)=0

References Botan::base64_encode(), Botan::cast_char_ptr_to_uint8(), kv_del(), name, and Botan::nist_key_wrap_padded().

◆ set()

void Botan::Encrypted_PSK_Database::set ( std::string_view name,
const uint8_t psk[],
size_t psk_len )
overridevirtual

Set a value that can later be accessed with get(). If name already exists in the database, the old value will be overwritten.

Implements Botan::PSK_Database.

Definition at line 81 of file psk_db.cpp.

81 {
82 /*
83 * Both as a basic precaution wrt key seperation, and specifically to prevent
84 * cut-and-paste attacks against the database, each PSK is encrypted with a
85 * distinct key which is derived by hashing the wrapped key name with HMAC.
86 */
87 const std::vector<uint8_t> wrapped_name =
88 nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()), name.size(), *m_cipher);
89
90 auto wrap_cipher = m_cipher->new_object();
91 wrap_cipher->set_key(m_hmac->process(wrapped_name));
92 const std::vector<uint8_t> wrapped_key = nist_key_wrap_padded(val, len, *wrap_cipher);
93
94 this->kv_set(base64_encode(wrapped_name), base64_encode(wrapped_key));
95}
virtual void kv_set(std::string_view index, std::string_view value)=0

References Botan::base64_encode(), Botan::cast_char_ptr_to_uint8(), kv_set(), name, and Botan::nist_key_wrap_padded().

◆ set_str()

void Botan::PSK_Database::set_str ( std::string_view name,
std::string_view psk )
inherited

Definition at line 23 of file psk_db.cpp.

23 {
24 this->set(name, cast_char_ptr_to_uint8(psk.data()), psk.size());
25}
virtual void set(std::string_view name, const uint8_t psk[], size_t psk_len)=0

References Botan::cast_char_ptr_to_uint8(), and Botan::PSK_Database::set().

◆ set_vec()

template<typename Alloc >
void Botan::PSK_Database::set_vec ( std::string_view name,
const std::vector< uint8_t, Alloc > & psk )
inlineinherited

Definition at line 63 of file psk_db.h.

63 {
64 set(name, psk.data(), psk.size());
65 }

References name.


The documentation for this class was generated from the following files: