Botan  2.7.0
Crypto and TLS for C++11
pubkey.cpp
Go to the documentation of this file.
1 /*
2 * (C) 1999-2010,2015,2018 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #include <botan/pubkey.h>
8 #include <botan/der_enc.h>
9 #include <botan/ber_dec.h>
10 #include <botan/bigint.h>
11 #include <botan/pk_ops.h>
12 #include <botan/internal/ct_utils.h>
13 #include <botan/rng.h>
14 
15 namespace Botan {
16 
17 secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const
18  {
19  uint8_t valid_mask = 0;
20 
21  secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
22 
23  if(valid_mask == 0)
24  throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
25 
26  return decoded;
27  }
28 
31  size_t length,
32  size_t expected_pt_len,
34  const uint8_t required_content_bytes[],
35  const uint8_t required_content_offsets[],
36  size_t required_contents_length) const
37  {
38  const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len);
39 
40  uint8_t valid_mask = 0;
41  secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
42 
43  valid_mask &= CT::is_equal(decoded.size(), expected_pt_len);
44 
45  decoded.resize(expected_pt_len);
46 
47  for(size_t i = 0; i != required_contents_length; ++i)
48  {
49  /*
50  These values are chosen by the application and for TLS are constants,
51  so this early failure via assert is fine since we know 0,1 < 48
52 
53  If there is a protocol that has content checks on the key where
54  the expected offsets are controllable by the attacker this could
55  still leak.
56 
57  Alternately could always reduce the offset modulo the length?
58  */
59 
60  const uint8_t exp = required_content_bytes[i];
61  const uint8_t off = required_content_offsets[i];
62 
63  BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
64 
65  valid_mask &= CT::is_equal(decoded[off], exp);
66  }
67 
68  CT::conditional_copy_mem(valid_mask,
69  /*output*/decoded.data(),
70  /*from0*/decoded.data(),
71  /*from1*/fake_pms.data(),
72  expected_pt_len);
73 
74  return decoded;
75  }
76 
79  size_t length,
80  size_t expected_pt_len,
81  RandomNumberGenerator& rng) const
82  {
83  return decrypt_or_random(in, length, expected_pt_len, rng,
84  nullptr, nullptr, 0);
85  }
86 
89  const std::string& padding,
90  const std::string& provider)
91  {
92  m_op = key.create_encryption_op(rng, padding, provider);
93  if(!m_op)
94  throw Invalid_Argument("Key type " + key.algo_name() + " does not support encryption");
95  }
96 
97 PK_Encryptor_EME::~PK_Encryptor_EME() { /* for unique_ptr */ }
98 
99 std::vector<uint8_t>
100 PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const
101  {
102  return unlock(m_op->encrypt(in, length, rng));
103  }
104 
106  {
107  return m_op->max_input_bits() / 8;
108  }
109 
112  const std::string& padding,
113  const std::string& provider)
114  {
115  m_op = key.create_decryption_op(rng, padding, provider);
116  if(!m_op)
117  throw Invalid_Argument("Key type " + key.algo_name() + " does not support decryption");
118  }
119 
120 PK_Decryptor_EME::~PK_Decryptor_EME() { /* for unique_ptr */ }
121 
122 secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask,
123  const uint8_t in[], size_t in_len) const
124  {
125  return m_op->decrypt(valid_mask, in, in_len);
126  }
127 
130  const std::string& param,
131  const std::string& provider)
132  {
133  m_op = key.create_kem_encryption_op(rng, param, provider);
134  if(!m_op)
135  throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM encryption");
136  }
137 
138 PK_KEM_Encryptor::~PK_KEM_Encryptor() { /* for unique_ptr */ }
139 
141  secure_vector<uint8_t>& out_shared_key,
142  size_t desired_shared_key_len,
144  const uint8_t salt[],
145  size_t salt_len)
146  {
147  m_op->kem_encrypt(out_encapsulated_key,
148  out_shared_key,
149  desired_shared_key_len,
150  rng,
151  salt,
152  salt_len);
153  }
154 
157  const std::string& param,
158  const std::string& provider)
159  {
160  m_op = key.create_kem_decryption_op(rng, param, provider);
161  if(!m_op)
162  throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM decryption");
163  }
164 
165 PK_KEM_Decryptor::~PK_KEM_Decryptor() { /* for unique_ptr */ }
166 
168  size_t encap_key_len,
169  size_t desired_shared_key_len,
170  const uint8_t salt[],
171  size_t salt_len)
172  {
173  return m_op->kem_decrypt(encap_key, encap_key_len,
174  desired_shared_key_len,
175  salt, salt_len);
176  }
177 
180  const std::string& kdf,
181  const std::string& provider)
182  {
183  m_op = key.create_key_agreement_op(rng, kdf, provider);
184  if(!m_op)
185  throw Invalid_Argument("Key type " + key.algo_name() + " does not support key agreement");
186  }
187 
188 PK_Key_Agreement::~PK_Key_Agreement() { /* for unique_ptr */ }
189 
191  {
192  if(this != &other)
193  {
194  m_op = std::move(other.m_op);
195  }
196  return (*this);
197  }
198 
200  m_op(std::move(other.m_op))
201  {}
202 
204  const uint8_t in[], size_t in_len,
205  const uint8_t salt[],
206  size_t salt_len) const
207  {
208  return m_op->agree(key_len, in, in_len, salt, salt_len);
209  }
210 
213  const std::string& emsa,
214  Signature_Format format,
215  const std::string& provider)
216  {
217  m_op = key.create_signature_op(rng, emsa, provider);
218  if(!m_op)
219  throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature generation");
220  m_sig_format = format;
221  m_parts = key.message_parts();
222  m_part_size = key.message_part_size();
223  }
224 
225 PK_Signer::~PK_Signer() { /* for unique_ptr */ }
226 
227 void PK_Signer::update(const uint8_t in[], size_t length)
228  {
229  m_op->update(in, length);
230  }
231 
232 namespace {
233 
234 std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig,
235  size_t parts,
236  size_t part_size)
237  {
238  if(sig.size() % parts != 0 || sig.size() != parts * part_size)
239  throw Encoding_Error("Unexpected size for DER signature");
240 
241  std::vector<BigInt> sig_parts(parts);
242  for(size_t i = 0; i != sig_parts.size(); ++i)
243  sig_parts[i].binary_decode(&sig[part_size*i], part_size);
244 
245  std::vector<uint8_t> output;
246  DER_Encoder(output)
248  .encode_list(sig_parts)
249  .end_cons();
250  return output;
251  }
252 
253 }
254 
255 std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng)
256  {
257  const std::vector<uint8_t> sig = unlock(m_op->sign(rng));
258 
259  if(m_sig_format == IEEE_1363)
260  {
261  return sig;
262  }
263  else if(m_sig_format == DER_SEQUENCE)
264  {
265  return der_encode_signature(sig, m_parts, m_part_size);
266  }
267  else
268  throw Internal_Error("PK_Signer: Invalid signature format enum");
269  }
270 
272  const std::string& emsa,
273  Signature_Format format,
274  const std::string& provider)
275  {
276  m_op = key.create_verification_op(emsa, provider);
277  if(!m_op)
278  throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature verification");
279  m_sig_format = format;
280  m_parts = key.message_parts();
281  m_part_size = key.message_part_size();
282  }
283 
284 PK_Verifier::~PK_Verifier() { /* for unique_ptr */ }
285 
287  {
288  if(format != IEEE_1363 && m_parts == 1)
289  throw Invalid_Argument("PK_Verifier: This algorithm does not support DER encoding");
290  m_sig_format = format;
291  }
292 
293 bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length,
294  const uint8_t sig[], size_t sig_length)
295  {
296  update(msg, msg_length);
297  return check_signature(sig, sig_length);
298  }
299 
300 void PK_Verifier::update(const uint8_t in[], size_t length)
301  {
302  m_op->update(in, length);
303  }
304 
305 bool PK_Verifier::check_signature(const uint8_t sig[], size_t length)
306  {
307  try {
308  if(m_sig_format == IEEE_1363)
309  {
310  return m_op->is_valid_signature(sig, length);
311  }
312  else if(m_sig_format == DER_SEQUENCE)
313  {
314  std::vector<uint8_t> real_sig;
315  BER_Decoder decoder(sig, length);
316  BER_Decoder ber_sig = decoder.start_cons(SEQUENCE);
317 
318  BOTAN_ASSERT_NOMSG(m_parts != 0 && m_part_size != 0);
319 
320  size_t count = 0;
321 
322  while(ber_sig.more_items())
323  {
324  BigInt sig_part;
325  ber_sig.decode(sig_part);
326  real_sig += BigInt::encode_1363(sig_part, m_part_size);
327  ++count;
328  }
329 
330  if(count != m_parts)
331  throw Decoding_Error("PK_Verifier: signature size invalid");
332 
333  const std::vector<uint8_t> reencoded =
334  der_encode_signature(real_sig, m_parts, m_part_size);
335 
336  if(reencoded.size() != length ||
337  same_mem(reencoded.data(), sig, reencoded.size()) == false)
338  {
339  throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
340  }
341 
342  return m_op->is_valid_signature(real_sig.data(), real_sig.size());
343  }
344  else
345  throw Internal_Error("PK_Verifier: Invalid signature format enum");
346  }
347  catch(Invalid_Argument&) { return false; }
348  }
349 
350 }
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:122
PK_Signer(const Private_Key &key, RandomNumberGenerator &rng, const std::string &emsa, Signature_Format format=IEEE_1363, const std::string &provider="")
Definition: pubkey.cpp:211
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:132
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:158
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
Definition: pubkey.cpp:293
virtual std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const
Definition: pk_keys.cpp:133
PK_KEM_Encryptor(const Public_Key &key, RandomNumberGenerator &rng, const std::string &kem_param="", const std::string &provider="")
Definition: pubkey.cpp:128
secure_vector< uint8_t > decrypt(const uint8_t in[], size_t length) const
Definition: pubkey.cpp:17
PK_Key_Agreement(const Private_Key &key, RandomNumberGenerator &rng, const std::string &kdf, const std::string &provider="")
Definition: pubkey.cpp:178
Signature_Format
Definition: pubkey.h:27
Definition: bigint.h:796
std::vector< uint8_t > signature(RandomNumberGenerator &rng)
Definition: pubkey.cpp:255
virtual std::string algo_name() const =0
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:56
virtual std::unique_ptr< PK_Ops::KEM_Decryption > create_kem_decryption_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const
Definition: pk_keys.cpp:125
DER_Encoder & end_cons()
Definition: der_enc.cpp:191
virtual std::unique_ptr< PK_Ops::KEM_Encryption > create_kem_encryption_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const
Definition: pk_keys.cpp:102
T is_equal(T x, T y)
Definition: ct_utils.h:136
BER_Decoder & decode(bool &out)
Definition: ber_dec.h:170
void update(uint8_t in)
Definition: pubkey.h:335
virtual std::unique_ptr< PK_Ops::Decryption > create_decryption_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const
Definition: pk_keys.cpp:117
PK_Decryptor_EME(const Private_Key &key, RandomNumberGenerator &rng, const std::string &eme, const std::string &provider="")
Definition: pubkey.cpp:110
T conditional_copy_mem(T value, T *to, const T *from0, const T *from1, size_t elems)
Definition: ct_utils.h:154
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:43
secure_vector< uint8_t > decrypt_or_random(const uint8_t in[], size_t length, size_t expected_pt_len, RandomNumberGenerator &rng) const
Definition: pubkey.cpp:78
secure_vector< uint8_t > decrypt(const uint8_t encap_key[], size_t encap_key_len, size_t desired_shared_key_len, const uint8_t salt[], size_t salt_len)
Definition: pubkey.cpp:167
virtual size_t message_part_size() const
Definition: pk_keys.h:118
size_t maximum_input_size() const override
Definition: pubkey.cpp:105
void update(uint8_t in)
Definition: pubkey.h:238
PK_KEM_Decryptor(const Private_Key &key, RandomNumberGenerator &rng, const std::string &kem_param="", const std::string &provider="")
Definition: pubkey.cpp:155
size_t salt_len
Definition: x509_obj.cpp:26
SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t params[], size_t params_len) const
Definition: pubkey.cpp:203
PK_Key_Agreement & operator=(PK_Key_Agreement &&)
Definition: pubkey.cpp:190
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:290
Definition: alg_id.cpp:13
void set_input_format(Signature_Format format)
Definition: pubkey.cpp:286
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:95
bool check_signature(const uint8_t sig[], size_t length)
Definition: pubkey.cpp:305
PK_Encryptor_EME(const Public_Key &key, RandomNumberGenerator &rng, const std::string &padding, const std::string &provider="")
Definition: pubkey.cpp:87
PK_Verifier(const Public_Key &pub_key, const std::string &emsa, Signature_Format format=IEEE_1363, const std::string &provider="")
Definition: pubkey.cpp:271
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:181
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:82
virtual std::unique_ptr< PK_Ops::Verification > create_verification_op(const std::string &params, const std::string &provider) const
Definition: pk_keys.cpp:110
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
virtual std::unique_ptr< PK_Ops::Encryption > create_encryption_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const
Definition: pk_keys.cpp:94
bool more_items() const
Definition: ber_dec.cpp:198
virtual size_t message_parts() const
Definition: pk_keys.h:107
virtual std::unique_ptr< PK_Ops::Key_Agreement > create_key_agreement_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const
Definition: pk_keys.cpp:141
void encrypt(secure_vector< uint8_t > &out_encapsulated_key, secure_vector< uint8_t > &out_shared_key, size_t desired_shared_key_len, Botan::RandomNumberGenerator &rng, const uint8_t salt[], size_t salt_len)
Definition: pubkey.cpp:140