Botan 3.0.0
Crypto and TLS for C&
psk_db.cpp
Go to the documentation of this file.
1/*
2* (C) 2017 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/psk_db.h>
8#include <botan/exceptn.h>
9#include <botan/nist_keywrap.h>
10#include <botan/base64.h>
11#include <botan/mac.h>
12#include <botan/block_cipher.h>
13
14namespace Botan {
15
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);
21
22 m_cipher->set_key(m_hmac->process("wrap"));
23 m_hmac->set_key(m_hmac->process("hmac"));
24 }
25
27
28std::set<std::string> Encrypted_PSK_Database::list_names() const
29 {
30 const std::set<std::string> encrypted_names = kv_get_all();
31
32 std::set<std::string> names;
33
34 for(const auto& enc_name : encrypted_names)
35 {
36 try
37 {
38 const secure_vector<uint8_t> raw_name = base64_decode(enc_name);
39 const secure_vector<uint8_t> name_bits =
40 nist_key_unwrap_padded(raw_name.data(), raw_name.size(), *m_cipher);
41
42 std::string pt_name(cast_uint8_ptr_to_char(name_bits.data()), name_bits.size());
43 names.insert(pt_name);
44 }
46 {
47 }
48 }
49
50 return names;
51 }
52
54 {
55 const std::vector<uint8_t> wrapped_name =
57 name.size(),
58 *m_cipher);
59
60 this->kv_del(base64_encode(wrapped_name));
61 }
62
64 {
65 const std::vector<uint8_t> wrapped_name =
67 name.size(),
68 *m_cipher);
69
70 const std::string val_base64 = kv_get(base64_encode(wrapped_name));
71
72 if(val_base64.empty())
73 throw Invalid_Argument("Named PSK not located");
74
75 const secure_vector<uint8_t> val = base64_decode(val_base64);
76
77 auto wrap_cipher = m_cipher->new_object();
78 wrap_cipher->set_key(m_hmac->process(wrapped_name));
79
80 return nist_key_unwrap_padded(val.data(), val.size(), *wrap_cipher);
81 }
82
83void Encrypted_PSK_Database::set(std::string_view name, const uint8_t val[], size_t len)
84 {
85 /*
86 * Both as a basic precaution wrt key seperation, and specifically to prevent
87 * cut-and-paste attacks against the database, each PSK is encrypted with a
88 * distinct key which is derived by hashing the wrapped key name with HMAC.
89 */
90 const std::vector<uint8_t> wrapped_name =
92 name.size(),
93 *m_cipher);
94
95 auto wrap_cipher = m_cipher->new_object();
96 wrap_cipher->set_key(m_hmac->process(wrapped_name));
97 const std::vector<uint8_t> wrapped_key = nist_key_wrap_padded(val, len, *wrap_cipher);
98
99 this->kv_set(base64_encode(wrapped_name), base64_encode(wrapped_key));
100 }
101
102}
static std::unique_ptr< BlockCipher > create_or_throw(std::string_view algo_spec, std::string_view provider="")
virtual void kv_set(std::string_view index, std::string_view value)=0
virtual void kv_del(std::string_view index)=0
virtual std::string kv_get(std::string_view index) const =0
secure_vector< uint8_t > get(std::string_view name) const override
Definition: psk_db.cpp:63
Encrypted_PSK_Database(const secure_vector< uint8_t > &master_key)
Definition: psk_db.cpp:16
std::set< std::string > list_names() const override
Definition: psk_db.cpp:28
virtual std::set< std::string > kv_get_all() const =0
void remove(std::string_view name) override
Definition: psk_db.cpp:53
void set(std::string_view name, const uint8_t psk[], size_t psk_len) override
Definition: psk_db.cpp:83
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition: mac.cpp:134
std::string name
Definition: alg_id.cpp:12
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:178
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:193
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 char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:188
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:183