Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
14 namespace Botan {
15
16 Encrypted_PSK_Database::Encrypted_PSK_Database(const secure_vector<uint8_t>& master_key)
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
26 Encrypted_PSK_Database::~Encrypted_PSK_Database()
27 {
28 // for ~unique_ptr
29 }
30
31 std::set<std::string> Encrypted_PSK_Database::list_names() const
32 {
33 const std::set<std::string> encrypted_names = kv_get_all();
34
35 std::set<std::string> names;
36
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.data(), raw_name.size(), *m_cipher);
44
45 std::string pt_name(cast_uint8_ptr_to_char(name_bits.data()), name_bits.size());
46 names.insert(pt_name);
47 }
48 catch(Invalid_Authentication_Tag&)
49 {
50 }
51 }
52
53 return names;
54 }
55
56 void Encrypted_PSK_Database::remove(const std::string& name)
57 {
58 const std::vector<uint8_t> wrapped_name =
59 nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()),
60 name.size(),
61 *m_cipher);
62
63 this->kv_del(base64_encode(wrapped_name));
64 }
65
66 secure_vector<uint8_t> Encrypted_PSK_Database::get(const std::string& name) const
67 {
68 const std::vector<uint8_t> wrapped_name =
69 nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()),
70 name.size(),
71 *m_cipher);
72
73 const std::string val_base64 = kv_get(base64_encode(wrapped_name));
74
75 if(val_base64.empty())
76 throw Invalid_Argument("Named PSK not located");
77
78 const secure_vector<uint8_t> val = base64_decode(val_base64);
79
80 std::unique_ptr<BlockCipher> wrap_cipher(m_cipher->clone());
81 wrap_cipher->set_key(m_hmac->process(wrapped_name));
82
83 return nist_key_unwrap_padded(val.data(), val.size(), *wrap_cipher);
84 }
85
86 void Encrypted_PSK_Database::set(const std::string& name, const uint8_t val[], size_t len)
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 =
94 nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()),
95 name.size(),
96 *m_cipher);
97
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);
101
102 this->kv_set(base64_encode(wrapped_name), base64_encode(wrapped_key));
103 }
104
105 }
Botan::Invalid_Argument
Definition: exceptn.h:136
Botan::Encrypted_PSK_Database::Encrypted_PSK_Database
Encrypted_PSK_Database(const secure_vector< uint8_t > &master_key)
Definition: psk_db.cpp:16
Botan::Encrypted_PSK_Database::get
secure_vector< uint8_t > get(const std::string &name) const override
Definition: psk_db.cpp:66
Botan::cast_char_ptr_to_uint8
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:189
Botan::Encrypted_PSK_Database::kv_set
virtual void kv_set(const std::string &index, const std::string &value)=0
Botan::Encrypted_PSK_Database::kv_get_all
virtual std::set< std::string > kv_get_all() const =0
Botan::Encrypted_PSK_Database::list_names
std::set< std::string > list_names() const override
Definition: psk_db.cpp:31
name
std::string name
Definition: commoncrypto_hash.cpp:23
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::base64_encode
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:166
Botan::nist_key_unwrap_padded
secure_vector< uint8_t > nist_key_unwrap_padded(const uint8_t input[], size_t input_len, const BlockCipher &bc)
Definition: nist_keywrap.cpp:161
Botan
Definition: alg_id.cpp:13
Botan::Encrypted_PSK_Database::set
void set(const std::string &name, const uint8_t psk[], size_t psk_len) override
Definition: psk_db.cpp:86
Botan::BlockCipher::create_or_throw
static std::unique_ptr< BlockCipher > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: block_cipher.cpp:348
Botan::base64_decode
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:181
Botan::cast_uint8_ptr_to_char
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:194
Botan::nist_key_wrap_padded
std::vector< uint8_t > nist_key_wrap_padded(const uint8_t input[], size_t input_len, const BlockCipher &bc)
Definition: nist_keywrap.cpp:134
Botan::Encrypted_PSK_Database::~Encrypted_PSK_Database
~Encrypted_PSK_Database()
Definition: psk_db.cpp:26
Botan::Encrypted_PSK_Database::kv_del
virtual void kv_del(const std::string &index)=0
Botan::Encrypted_PSK_Database::kv_get
virtual std::string kv_get(const std::string &index) const =0
Botan::MessageAuthenticationCode::create_or_throw
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: mac.cpp:141
Botan::Encrypted_PSK_Database::remove
void remove(const std::string &name) override
Definition: psk_db.cpp:56
Botan::Invalid_Authentication_Tag
Definition: exceptn.h:290