Botan: src/pubkey/pubkey.cpp Source File

Botan 1.10.17

pubkey.cpp
Go to the documentation of this file.
1 /*
2 * Public Key Base
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/pubkey.h>
9 #include <botan/der_enc.h>
10 #include <botan/ber_dec.h>
11 #include <botan/bigint.h>
12 #include <botan/parsing.h>
13 #include <botan/libstate.h>
14 #include <botan/engine.h>
15 #include <botan/lookup.h>
16 #include <botan/internal/bit_ops.h>
17 #include <botan/internal/assert.h>
18 #include <memory>
19
20 namespace Botan {
21
22 /*
23 * PK_Encryptor_EME Constructor
24 */
25 PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
26 const std::string& eme_name)
27 {
28 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
29
30 op = 0;
31
32 while(const Engine* engine = i.next())
33 {
34 op = engine->get_encryption_op(key);
35 if(op)
36 break;
37 }
38
39 if(!op)
40 throw Lookup_Error("Encryption with " + key.algo_name() + " not supported");
41
42 eme = (eme_name == "Raw") ? 0 : get_eme(eme_name);
43 }
44
45 /*
46 * Encrypt a message
47 */
48 SecureVector<byte>
49 PK_Encryptor_EME::enc(const byte in[],
50 size_t length,
51 RandomNumberGenerator& rng) const
52 {
53 if(eme)
54 {
55 SecureVector<byte> encoded =
56 eme->encode(in, length, op->max_input_bits(), rng);
57
58 if(8*(encoded.size() - 1) + high_bit(encoded[0]) > op->max_input_bits())
59 throw Invalid_Argument("PK_Encryptor_EME: Input is too large");
60
61 return op->encrypt(&encoded[0], encoded.size(), rng);
62 }
63 else
64 {
65 if(8*(length - 1) + high_bit(in[0]) > op->max_input_bits())
66 throw Invalid_Argument("PK_Encryptor_EME: Input is too large");
67
68 return op->encrypt(&in[0], length, rng);
69 }
70 }
71
72 /*
73 * Return the max size, in bytes, of a message
74 */
75 size_t PK_Encryptor_EME::maximum_input_size() const
76 {
77 if(!eme)
78 return (op->max_input_bits() / 8);
79 else
80 return eme->maximum_input_size(op->max_input_bits());
81 }
82
83 /*
84 * PK_Decryptor_EME Constructor
85 */
86 PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
87 const std::string& eme_name)
88 {
89 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
90
91 op = 0;
92
93 while(const Engine* engine = i.next())
94 {
95 op = engine->get_decryption_op(key);
96 if(op)
97 break;
98 }
99
100 if(!op)
101 throw Lookup_Error("Decryption with " + key.algo_name() + " not supported");
102
103 eme = (eme_name == "Raw") ? 0 : get_eme(eme_name);
104 }
105
106 /*
107 * Decrypt a message
108 */
109 SecureVector<byte> PK_Decryptor_EME::dec(const byte msg[],
110 size_t length) const
111 {
112 try {
113 SecureVector<byte> decrypted = op->decrypt(msg, length);
114 if(eme)
115 return eme->decode(decrypted, op->max_input_bits());
116 else
117 return decrypted;
118 }
119 catch(Invalid_Argument)
120 {
121 throw Decoding_Error("PK_Decryptor_EME: Input is invalid");
122 }
123 }
124
125 /*
126 * PK_Signer Constructor
127 */
128 PK_Signer::PK_Signer(const Private_Key& key,
129 const std::string& emsa_name,
130 Signature_Format format,
131 Fault_Protection prot)
132 {
133 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
134
135 op = 0;
136 verify_op = 0;
137
138 while(const Engine* engine = i.next())
139 {
140 if(!op)
141 op = engine->get_signature_op(key);
142
143 if(!verify_op && prot == ENABLE_FAULT_PROTECTION)
144 verify_op = engine->get_verify_op(key);
145
146 if(op && (verify_op || prot == DISABLE_FAULT_PROTECTION))
147 break;
148 }
149
150 if(!op || (!verify_op && prot == ENABLE_FAULT_PROTECTION))
151 throw Lookup_Error("Signing with " + key.algo_name() + " not supported");
152
153 emsa = get_emsa(emsa_name);
154 sig_format = format;
155 }
156
157 /*
158 * Sign a message
159 */
160 SecureVector<byte> PK_Signer::sign_message(const byte msg[], size_t length,
161 RandomNumberGenerator& rng)
162 {
163 update(msg, length);
164 return signature(rng);
165 }
166
167 /*
168 * Add more to the message to be signed
169 */
170 void PK_Signer::update(const byte in[], size_t length)
171 {
172 emsa->update(in, length);
173 }
174
175 /*
176 * Check the signature we just created, to help prevent fault attacks
177 */
178 bool PK_Signer::self_test_signature(const MemoryRegion<byte>& msg,
179 const MemoryRegion<byte>& sig) const
180 {
181 if(!verify_op)
182 return true; // checking disabled, assume ok
183
184 if(verify_op->with_recovery())
185 {
186 SecureVector<byte> recovered =
187 verify_op->verify_mr(&sig[0], sig.size());
188
189 if(msg.size() > recovered.size())
190 {
191 size_t extra_0s = msg.size() - recovered.size();
192
193 for(size_t i = 0; i != extra_0s; ++i)
194 if(msg[i] != 0)
195 return false;
196
197 return same_mem(&msg[extra_0s], &recovered[0], recovered.size());
198 }
199
200 return (recovered == msg);
201 }
202 else
203 return verify_op->verify(&msg[0], msg.size(),
204 &sig[0], sig.size());
205 }
206
207 /*
208 * Create a signature
209 */
210 SecureVector<byte> PK_Signer::signature(RandomNumberGenerator& rng)
211 {
212 SecureVector<byte> encoded = emsa->encoding_of(emsa->raw_data(),
213 op->max_input_bits(),
214 rng);
215
216 SecureVector<byte> plain_sig = op->sign(&encoded[0], encoded.size(), rng);
217
218 BOTAN_ASSERT(self_test_signature(encoded, plain_sig),
219 "PK_Signer consistency check failed");
220
221 if(op->message_parts() == 1 || sig_format == IEEE_1363)
222 return plain_sig;
223
224 if(sig_format == DER_SEQUENCE)
225 {
226 if(plain_sig.size() % op->message_parts())
227 throw Encoding_Error("PK_Signer: strange signature size found");
228 const size_t SIZE_OF_PART = plain_sig.size() / op->message_parts();
229
230 std::vector<BigInt> sig_parts(op->message_parts());
231 for(size_t j = 0; j != sig_parts.size(); ++j)
232 sig_parts[j].binary_decode(&plain_sig[SIZE_OF_PART*j], SIZE_OF_PART);
233
234 return DER_Encoder()
235 .start_cons(SEQUENCE)
236 .encode_list(sig_parts)
237 .end_cons()
238 .get_contents();
239 }
240 else
241 throw Encoding_Error("PK_Signer: Unknown signature format " +
242 to_string(sig_format));
243 }
244
245 /*
246 * PK_Verifier Constructor
247 */
248 PK_Verifier::PK_Verifier(const Public_Key& key,
249 const std::string& emsa_name,
250 Signature_Format format)
251 {
252 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
253
254 op = 0;
255
256 while(const Engine* engine = i.next())
257 {
258 op = engine->get_verify_op(key);
259 if(op)
260 break;
261 }
262
263 if(!op)
264 throw Lookup_Error("Verification with " + key.algo_name() + " not supported");
265
266 emsa = get_emsa(emsa_name);
267 sig_format = format;
268 }
269
270 /*
271 * Set the signature format
272 */
273 void PK_Verifier::set_input_format(Signature_Format format)
274 {
275 if(op->message_parts() == 1 && format != IEEE_1363)
276 throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363");
277 sig_format = format;
278 }
279
280 /*
281 * Verify a message
282 */
283 bool PK_Verifier::verify_message(const byte msg[], size_t msg_length,
284 const byte sig[], size_t sig_length)
285 {
286 update(msg, msg_length);
287 return check_signature(sig, sig_length);
288 }
289
290 /*
291 * Append to the message
292 */
293 void PK_Verifier::update(const byte in[], size_t length)
294 {
295 emsa->update(in, length);
296 }
297
298 /*
299 * Check a signature
300 */
301 bool PK_Verifier::check_signature(const byte sig[], size_t length)
302 {
303 try {
304 if(sig_format == IEEE_1363)
305 return validate_signature(emsa->raw_data(), sig, length);
306 else if(sig_format == DER_SEQUENCE)
307 {
308 BER_Decoder decoder(sig, length);
309 BER_Decoder ber_sig = decoder.start_cons(SEQUENCE);
310
311 size_t count = 0;
312 SecureVector<byte> real_sig;
313 while(ber_sig.more_items())
314 {
315 BigInt sig_part;
316 ber_sig.decode(sig_part);
317 real_sig += BigInt::encode_1363(sig_part, op->message_part_size());
318 ++count;
319 }
320
321 if(count != op->message_parts())
322 throw Decoding_Error("PK_Verifier: signature size invalid");
323
324 return validate_signature(emsa->raw_data(),
325 &real_sig[0], real_sig.size());
326 }
327 else
328 throw Decoding_Error("PK_Verifier: Unknown signature format " +
329 to_string(sig_format));
330 }
331 catch(Invalid_Argument) { return false; }
332 }
333
334 /*
335 * Verify a signature
336 */
337 bool PK_Verifier::validate_signature(const MemoryRegion<byte>& msg,
338 const byte sig[], size_t sig_len)
339 {
340 if(op->with_recovery())
341 {
342 SecureVector<byte> output_of_key = op->verify_mr(sig, sig_len);
343 return emsa->verify(output_of_key, msg, op->max_input_bits());
344 }
345 else
346 {
347 Null_RNG rng;
348
349 SecureVector<byte> encoded =
350 emsa->encoding_of(msg, op->max_input_bits(), rng);
351
352 return op->verify(&encoded[0], encoded.size(), sig, sig_len);
353 }
354 }
355
356 /*
357 * PK_Key_Agreement Constructor
358 */
359 PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key,
360 const std::string& kdf_name)
361 {
362 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
363
364 op = 0;
365
366 while(const Engine* engine = i.next())
367 {
368 op = engine->get_key_agreement_op(key);
369 if(op)
370 break;
371 }
372
373 if(!op)
374 throw Lookup_Error("Key agreement with " + key.algo_name() + " not supported");
375
376 kdf = (kdf_name == "Raw") ? 0 : get_kdf(kdf_name);
377 }
378
379 SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, const byte in[],
380 size_t in_len, const byte params[],
381 size_t params_len) const
382 {
383 SecureVector<byte> z = op->agree(in, in_len);
384
385 if(!kdf)
386 return z;
387
388 return kdf->derive_key(key_len, z, params, params_len);
389 }
390
391 }
Botan::PK_Verifier::check_signature
bool check_signature(const byte sig[], size_t length)
Definition: pubkey.cpp:301
Botan::DER_Encoder::encode_list
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:75
Botan::DER_Encoder::get_contents
SecureVector< byte > get_contents()
Definition: der_enc.cpp:122
Botan::PK_Ops::Verification::verify_mr
virtual SecureVector< byte > verify_mr(const byte[], size_t)
Definition: pk_ops.h:133
Botan::get_emsa
EMSA * get_emsa(const std::string &algo_spec)
Definition: get_enc.cpp:86
Botan::PK_Ops::Key_Agreement::agree
virtual SecureVector< byte > agree(const byte w[], size_t w_len)=0
Botan::OctetString
Definition: symkey.h:19
Botan::BigInt
Definition: bigint.h:22
Botan::same_mem
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:57
Botan::PK_Ops::Decryption::max_input_bits
virtual size_t max_input_bits() const =0
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::PK_Ops::Verification::message_parts
virtual size_t message_parts() const
Definition: pk_ops.h:98
Botan::KDF::derive_key
SecureVector< byte > derive_key(size_t key_len, const MemoryRegion< byte > &secret, const std::string &salt="") const
Definition: kdf.cpp:15
Botan::Private_Key
Definition: pk_keys.h:86
Botan::PK_Ops::Decryption::decrypt
virtual SecureVector< byte > decrypt(const byte msg[], size_t msg_len)=0
Botan::BER_Decoder::decode
BER_Decoder & decode(bool &)
Definition: ber_dec.cpp:344
Botan::PK_Signer::signature
SecureVector< byte > signature(RandomNumberGenerator &rng)
Definition: pubkey.cpp:210
Botan::PK_Encryptor_EME::PK_Encryptor_EME
PK_Encryptor_EME(const Public_Key &key, const std::string &eme)
Definition: pubkey.cpp:25
Botan::PK_Encryptor_EME::maximum_input_size
size_t maximum_input_size() const
Definition: pubkey.cpp:75
Botan::Signature_Format
Signature_Format
Definition: pubkey.h:24
Botan::PK_Ops::Signature::message_parts
virtual size_t message_parts() const
Definition: pk_ops.h:56
Botan::Invalid_State
Definition: exceptn.h:25
Botan::Public_Key::algo_name
virtual std::string algo_name() const =0
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan::PK_Ops::Signature::sign
virtual SecureVector< byte > sign(const byte msg[], size_t msg_len, RandomNumberGenerator &rng)=0
Botan::PK_Ops::Verification::with_recovery
virtual bool with_recovery() const =0
Botan::DER_Encoder::end_cons
DER_Encoder & end_cons()
Definition: der_enc.cpp:145
Botan::PK_Ops::Signature::max_input_bits
virtual size_t max_input_bits() const =0
Botan::EMSA::encoding_of
virtual SecureVector< byte > encoding_of(const MemoryRegion< byte > &msg, size_t output_bits, RandomNumberGenerator &rng)=0
Botan::BER_Decoder::start_cons
BER_Decoder start_cons(ASN1_Tag, ASN1_Tag=UNIVERSAL)
Definition: ber_dec.cpp:238
Botan::PK_Ops::Encryption::max_input_bits
virtual size_t max_input_bits() const =0
Botan::PK_Verifier::PK_Verifier
PK_Verifier(const Public_Key &pub_key, const std::string &emsa, Signature_Format format=IEEE_1363)
Definition: pubkey.cpp:248
Botan::PK_Ops::Verification::verify
virtual bool verify(const byte[], size_t, const byte[], size_t)
Definition: pk_ops.h:120
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, msg)
Definition: assert.h:19
Botan::PK_Ops::Verification::message_part_size
virtual size_t message_part_size() const
Definition: pk_ops.h:104
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::EME::maximum_input_size
virtual size_t maximum_input_size(size_t keybits) const =0
Botan::Engine
Definition: engine.h:32
Botan::PK_Signer::PK_Signer
PK_Signer(const Private_Key &key, const std::string &emsa, Signature_Format format=IEEE_1363, Fault_Protection prot=ENABLE_FAULT_PROTECTION)
Definition: pubkey.cpp:128
Botan::EMSA::raw_data
virtual SecureVector< byte > raw_data()=0
Botan::DER_Encoder
Definition: der_enc.h:22
Botan::PK_Signer::sign_message
SecureVector< byte > sign_message(const byte in[], size_t length, RandomNumberGenerator &rng)
Definition: pubkey.cpp:160
Botan::PK_Ops::Encryption::encrypt
virtual SecureVector< byte > encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator &rng)=0
Botan::Algorithm_Factory::Engine_Iterator
Definition: algo_factory.h:190
Botan::Global_State_Management::global_state
Library_State & global_state()
Definition: global_state.cpp:32
Botan::PK_Ops::Verification::max_input_bits
virtual size_t max_input_bits() const =0
Botan::EME::decode
SecureVector< byte > decode(const byte in[], size_t in_length, size_t key_length) const
Definition: eme.cpp:35
Botan::PK_Verifier::verify_message
bool verify_message(const byte msg[], size_t msg_length, const byte sig[], size_t sig_length)
Definition: pubkey.cpp:283
Botan::Lookup_Error
Definition: exceptn.h:35
Botan::Decoding_Error
Definition: exceptn.h:138
Botan::SEQUENCE
Definition: asn1_int.h:35
Botan::high_bit
size_t high_bit(T n)
Definition: bit_ops.h:33
Botan::EMSA::verify
virtual bool verify(const MemoryRegion< byte > &coded, const MemoryRegion< byte > &raw, size_t key_bits)=0
Botan::MemoryRegion< byte >
Botan
Definition: algo_base.h:14
Botan::get_eme
EME * get_eme(const std::string &algo_spec)
Definition: get_enc.cpp:143
Botan::ENABLE_FAULT_PROTECTION
Definition: pubkey.h:30
Botan::PK_Verifier::set_input_format
void set_input_format(Signature_Format format)
Definition: pubkey.cpp:273
Botan::Public_Key
Definition: pk_keys.h:21
Botan::IEEE_1363
Definition: pubkey.h:24
Botan::EMSA::update
virtual void update(const byte input[], size_t length)=0
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::PK_Key_Agreement_Key
Definition: pk_keys.h:118
Botan::DISABLE_FAULT_PROTECTION
Definition: pubkey.h:31
Botan::PK_Decryptor_EME::PK_Decryptor_EME
PK_Decryptor_EME(const Private_Key &key, const std::string &eme)
Definition: pubkey.cpp:86
Botan::Algorithm_Factory::Engine_Iterator::next
Engine * next()
Definition: algo_factory.h:196
Botan::DER_Encoder::start_cons
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:135
Botan::DER_SEQUENCE
Definition: pubkey.h:24
Botan::Fault_Protection
Fault_Protection
Definition: pubkey.h:29
Botan::to_string
std::string to_string(u64bit n, size_t min_len)
Definition: parsing.cpp:42
Botan::SecureVector< byte >
Botan::EME::encode
SecureVector< byte > encode(const byte in[], size_t in_length, size_t key_length, RandomNumberGenerator &rng) const
Definition: eme.cpp:15
Botan::get_kdf
KDF * get_kdf(const std::string &algo_spec)
Definition: get_enc.cpp:174
Botan::BER_Decoder::more_items
bool more_items() const
Definition: ber_dec.cpp:153
Botan::BER_Decoder
Definition: ber_dec.h:19
Botan::PK_Key_Agreement::PK_Key_Agreement
PK_Key_Agreement(const PK_Key_Agreement_Key &key, const std::string &kdf)
Definition: pubkey.cpp:359
Botan::BigInt::encode_1363
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:78
Botan::Encoding_Error
Definition: exceptn.h:129
Botan::PK_Key_Agreement::derive_key
SymmetricKey derive_key(size_t key_len, const byte in[], size_t in_len, const byte params[], size_t params_len) const
Definition: pubkey.cpp:379
Botan::PK_Verifier::update
void update(byte in)
Definition: pubkey.h:242
Botan::PK_Signer::update
void update(byte in)
Definition: pubkey.h:150