Botan 2.19.1
Crypto and TLS for C&
Public Member Functions | Protected Member Functions | List of all members
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 (const std::string &name) const override
std::string get_str (const std::string &name) const
bool is_encrypted () const override
std::set< std::string > list_names () const override
void remove (const std::string &name) override
void set (const std::string &name, const uint8_t psk[], size_t psk_len) override
void set_str (const std::string &name, const std::string &psk)
template<typename Alloc >
void set_vec (const std::string &name, const std::vector< uint8_t, Alloc > &psk)
 ~Encrypted_PSK_Database ()

Protected Member Functions

virtual void kv_del (const std::string &index)=0
virtual std::string kv_get (const std::string &index) const =0
virtual std::set< std::string > kv_get_all () const =0
virtual void kv_set (const std::string &index, const std::string &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 90 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)
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 16 of file psk_db.cpp.

17 {
18 m_cipher = BlockCipher::create_or_throw("AES-256");
19 m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
20 m_hmac->set_key(master_key);
22 m_cipher->set_key(m_hmac->process("wrap"));
23 m_hmac->set_key(m_hmac->process("hmac"));
24 }
static std::unique_ptr< BlockCipher > create_or_throw(const std::string &algo_spec, const std::string &provider="")
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: mac.cpp:141

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

◆ ~Encrypted_PSK_Database()

Botan::Encrypted_PSK_Database::~Encrypted_PSK_Database ( )

Definition at line 26 of file psk_db.cpp.

27 {
28 // for ~unique_ptr
29 }

Member Function Documentation

◆ get()

secure_vector< uint8_t > Botan::Encrypted_PSK_Database::get ( const std::string &  name) const

Return the value associated with the specified

nameor otherwise throw an exception.

Implements Botan::PSK_Database.

Definition at line 66 of file psk_db.cpp.

67 {
68 const std::vector<uint8_t> wrapped_name =
70 name.size(),
71 *m_cipher);
73 const std::string val_base64 = kv_get(base64_encode(wrapped_name));
75 if(val_base64.empty())
76 throw Invalid_Argument("Named PSK not located");
78 const secure_vector<uint8_t> val = base64_decode(val_base64);
80 std::unique_ptr<BlockCipher> wrap_cipher(m_cipher->clone());
81 wrap_cipher->set_key(m_hmac->process(wrapped_name));
83 return nist_key_unwrap_padded(, val.size(), *wrap_cipher);
84 }
virtual std::string kv_get(const std::string &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:185
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:200
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)
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:190

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 ( const std::string &  name) const

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

Definition at line 59 of file psk_db.h.

60 {
61 secure_vector<uint8_t> psk = get(name);
62 return std::string(cast_uint8_ptr_to_char(, psk.size());
63 }
virtual secure_vector< uint8_t > get(const std::string &name) const =0
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:195

References Botan::cast_uint8_ptr_to_char(), and name.

◆ is_encrypted()

bool Botan::Encrypted_PSK_Database::is_encrypted ( ) const

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 114 of file psk_db.h.

114{ return true; }

◆ kv_del()

virtual void Botan::Encrypted_PSK_Database::kv_del ( const std::string &  index)
protectedpure virtual

Remove an index

Referenced by remove().

◆ kv_get()

virtual std::string Botan::Encrypted_PSK_Database::kv_get ( const std::string &  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 ( const std::string &  index,
const std::string &  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

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

Implements Botan::PSK_Database.

Definition at line 31 of file psk_db.cpp.

32 {
33 const std::set<std::string> encrypted_names = kv_get_all();
35 std::set<std::string> names;
37 for(std::string enc_name : encrypted_names)
38 {
39 try
40 {
41 const secure_vector<uint8_t> raw_name = base64_decode(enc_name);
42 const secure_vector<uint8_t> name_bits =
43 nist_key_unwrap_padded(, raw_name.size(), *m_cipher);
45 std::string pt_name(cast_uint8_ptr_to_char(, name_bits.size());
46 names.insert(pt_name);
47 }
48 catch(Invalid_Authentication_Tag&)
49 {
50 }
51 }
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 ( const std::string &  name)

Remove a PSK from the database

Implements Botan::PSK_Database.

Definition at line 56 of file psk_db.cpp.

57 {
58 const std::vector<uint8_t> wrapped_name =
60 name.size(),
61 *m_cipher);
63 this->kv_del(base64_encode(wrapped_name));
64 }
virtual void kv_del(const std::string &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 ( const std::string &  name,
const uint8_t  psk[],
size_t  psk_len 

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 86 of file psk_db.cpp.

87 {
88 /*
89 * Both as a basic precaution wrt key seperation, and specifically to prevent
90 * cut-and-paste attacks against the database, each PSK is encrypted with a
91 * distinct key which is derived by hashing the wrapped key name with HMAC.
92 */
93 const std::vector<uint8_t> wrapped_name =
95 name.size(),
96 *m_cipher);
98 std::unique_ptr<BlockCipher> wrap_cipher(m_cipher->clone());
99 wrap_cipher->set_key(m_hmac->process(wrapped_name));
100 const std::vector<uint8_t> wrapped_key = nist_key_wrap_padded(val, len, *wrap_cipher);
102 this->kv_set(base64_encode(wrapped_name), base64_encode(wrapped_key));
103 }
virtual void kv_set(const std::string &index, const std::string &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 ( const std::string &  name,
const std::string &  psk 

Definition at line 65 of file psk_db.h.

66 {
67 set(name, cast_char_ptr_to_uint8(, psk.size());
68 }
virtual void set(const std::string &name, const uint8_t psk[], size_t psk_len)=0

References Botan::cast_char_ptr_to_uint8(), and name.

◆ set_vec()

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

Definition at line 71 of file psk_db.h.

74 {
75 set(name,, psk.size());
76 }

References name.

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