/src/botan/src/lib/pubkey/pubkey.cpp
Line | Count | Source (jump to first uncovered line) |
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/internal/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 | 0 | { |
19 | 0 | uint8_t valid_mask = 0; |
20 | |
|
21 | 0 | secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length); |
22 | |
|
23 | 0 | if(valid_mask == 0) |
24 | 0 | throw Decoding_Error("Invalid public key ciphertext, cannot decrypt"); |
25 | | |
26 | 0 | return decoded; |
27 | 0 | } |
28 | | |
29 | | secure_vector<uint8_t> |
30 | | PK_Decryptor::decrypt_or_random(const uint8_t in[], |
31 | | size_t length, |
32 | | size_t expected_pt_len, |
33 | | RandomNumberGenerator& rng, |
34 | | const uint8_t required_content_bytes[], |
35 | | const uint8_t required_content_offsets[], |
36 | | size_t required_contents_length) const |
37 | 0 | { |
38 | 0 | const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len); |
39 | |
|
40 | 0 | uint8_t decrypt_valid = 0; |
41 | 0 | secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length); |
42 | |
|
43 | 0 | auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF); |
44 | 0 | valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len)); |
45 | |
|
46 | 0 | decoded.resize(expected_pt_len); |
47 | |
|
48 | 0 | for(size_t i = 0; i != required_contents_length; ++i) |
49 | 0 | { |
50 | | /* |
51 | | These values are chosen by the application and for TLS are constants, |
52 | | so this early failure via assert is fine since we know 0,1 < 48 |
53 | | |
54 | | If there is a protocol that has content checks on the key where |
55 | | the expected offsets are controllable by the attacker this could |
56 | | still leak. |
57 | | |
58 | | Alternately could always reduce the offset modulo the length? |
59 | | */ |
60 | |
|
61 | 0 | const uint8_t exp = required_content_bytes[i]; |
62 | 0 | const uint8_t off = required_content_offsets[i]; |
63 | |
|
64 | 0 | BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext"); |
65 | |
|
66 | 0 | auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp); |
67 | |
|
68 | 0 | valid_mask &= eq; |
69 | 0 | } |
70 | | |
71 | | // If valid_mask is false, assign fake pre master instead |
72 | 0 | valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len); |
73 | |
|
74 | 0 | return decoded; |
75 | 0 | } |
76 | | |
77 | | secure_vector<uint8_t> |
78 | | PK_Decryptor::decrypt_or_random(const uint8_t in[], |
79 | | size_t length, |
80 | | size_t expected_pt_len, |
81 | | RandomNumberGenerator& rng) const |
82 | 0 | { |
83 | 0 | return decrypt_or_random(in, length, expected_pt_len, rng, |
84 | 0 | nullptr, nullptr, 0); |
85 | 0 | } |
86 | | |
87 | | PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, |
88 | | RandomNumberGenerator& rng, |
89 | | const std::string& padding, |
90 | | const std::string& provider) |
91 | 0 | { |
92 | 0 | m_op = key.create_encryption_op(rng, padding, provider); |
93 | 0 | if(!m_op) |
94 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support encryption"); |
95 | 0 | } |
96 | | |
97 | 0 | PK_Encryptor_EME::~PK_Encryptor_EME() = default; |
98 | | |
99 | | size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const |
100 | 0 | { |
101 | 0 | return m_op->ciphertext_length(ptext_len); |
102 | 0 | } |
103 | | |
104 | | std::vector<uint8_t> |
105 | | PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const |
106 | 0 | { |
107 | 0 | return unlock(m_op->encrypt(in, length, rng)); |
108 | 0 | } |
109 | | |
110 | | size_t PK_Encryptor_EME::maximum_input_size() const |
111 | 0 | { |
112 | 0 | return m_op->max_input_bits() / 8; |
113 | 0 | } |
114 | | |
115 | | PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, |
116 | | RandomNumberGenerator& rng, |
117 | | const std::string& padding, |
118 | | const std::string& provider) |
119 | 0 | { |
120 | 0 | m_op = key.create_decryption_op(rng, padding, provider); |
121 | 0 | if(!m_op) |
122 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support decryption"); |
123 | 0 | } |
124 | | |
125 | 0 | PK_Decryptor_EME::~PK_Decryptor_EME() = default; |
126 | | |
127 | | size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const |
128 | 0 | { |
129 | 0 | return m_op->plaintext_length(ctext_len); |
130 | 0 | } |
131 | | |
132 | | secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, |
133 | | const uint8_t in[], size_t in_len) const |
134 | 0 | { |
135 | 0 | return m_op->decrypt(valid_mask, in, in_len); |
136 | 0 | } |
137 | | |
138 | | PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, |
139 | | RandomNumberGenerator& rng, |
140 | | const std::string& param, |
141 | | const std::string& provider) |
142 | 0 | { |
143 | 0 | m_op = key.create_kem_encryption_op(rng, param, provider); |
144 | 0 | if(!m_op) |
145 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM encryption"); |
146 | 0 | } |
147 | | |
148 | 0 | PK_KEM_Encryptor::~PK_KEM_Encryptor() = default; |
149 | | |
150 | | void PK_KEM_Encryptor::encrypt(secure_vector<uint8_t>& out_encapsulated_key, |
151 | | secure_vector<uint8_t>& out_shared_key, |
152 | | size_t desired_shared_key_len, |
153 | | RandomNumberGenerator& rng, |
154 | | const uint8_t salt[], |
155 | | size_t salt_len) |
156 | 0 | { |
157 | 0 | m_op->kem_encrypt(out_encapsulated_key, |
158 | 0 | out_shared_key, |
159 | 0 | desired_shared_key_len, |
160 | 0 | rng, |
161 | 0 | salt, |
162 | 0 | salt_len); |
163 | 0 | } |
164 | | |
165 | | PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key, |
166 | | RandomNumberGenerator& rng, |
167 | | const std::string& param, |
168 | | const std::string& provider) |
169 | 0 | { |
170 | 0 | m_op = key.create_kem_decryption_op(rng, param, provider); |
171 | 0 | if(!m_op) |
172 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM decryption"); |
173 | 0 | } |
174 | | |
175 | 0 | PK_KEM_Decryptor::~PK_KEM_Decryptor() = default; |
176 | | |
177 | | secure_vector<uint8_t> PK_KEM_Decryptor::decrypt(const uint8_t encap_key[], |
178 | | size_t encap_key_len, |
179 | | size_t desired_shared_key_len, |
180 | | const uint8_t salt[], |
181 | | size_t salt_len) |
182 | 0 | { |
183 | 0 | return m_op->kem_decrypt(encap_key, encap_key_len, |
184 | 0 | desired_shared_key_len, |
185 | 0 | salt, salt_len); |
186 | 0 | } |
187 | | |
188 | 0 | PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default; |
189 | | |
190 | | PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, |
191 | | RandomNumberGenerator& rng, |
192 | | const std::string& kdf, |
193 | | const std::string& provider) |
194 | 0 | { |
195 | 0 | m_op = key.create_key_agreement_op(rng, kdf, provider); |
196 | 0 | if(!m_op) |
197 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support key agreement"); |
198 | 0 | } |
199 | | |
200 | 0 | PK_Key_Agreement::~PK_Key_Agreement() = default; |
201 | | |
202 | | size_t PK_Key_Agreement::agreed_value_size() const |
203 | 0 | { |
204 | 0 | return m_op->agreed_value_size(); |
205 | 0 | } |
206 | | |
207 | | SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, |
208 | | const uint8_t in[], size_t in_len, |
209 | | const uint8_t salt[], |
210 | | size_t salt_len) const |
211 | 0 | { |
212 | 0 | return m_op->agree(key_len, in, in_len, salt, salt_len); |
213 | 0 | } |
214 | | |
215 | | static void check_der_format_supported(Signature_Format format, size_t parts) |
216 | 588 | { |
217 | 588 | if(format != Signature_Format::Standard && parts == 1) |
218 | 0 | throw Invalid_Argument("PK: This algorithm does not support DER encoding"); |
219 | 588 | } |
220 | | |
221 | | PK_Signer::PK_Signer(const Private_Key& key, |
222 | | RandomNumberGenerator& rng, |
223 | | const std::string& emsa, |
224 | | Signature_Format format, |
225 | | const std::string& provider) |
226 | 183 | { |
227 | 183 | m_op = key.create_signature_op(rng, emsa, provider); |
228 | 183 | if(!m_op) |
229 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature generation"); |
230 | 183 | m_sig_format = format; |
231 | 183 | m_parts = key.message_parts(); |
232 | 183 | m_part_size = key.message_part_size(); |
233 | 183 | check_der_format_supported(format, m_parts); |
234 | 183 | } |
235 | | |
236 | 181 | PK_Signer::~PK_Signer() = default; |
237 | | |
238 | | void PK_Signer::update(const uint8_t in[], size_t length) |
239 | 181 | { |
240 | 181 | m_op->update(in, length); |
241 | 181 | } |
242 | | |
243 | | namespace { |
244 | | |
245 | | std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, |
246 | | size_t parts, |
247 | | size_t part_size) |
248 | 130 | { |
249 | 130 | if(sig.size() % parts != 0 || sig.size() != parts * part_size) |
250 | 0 | throw Encoding_Error("Unexpected size for DER signature"); |
251 | | |
252 | 130 | std::vector<BigInt> sig_parts(parts); |
253 | 390 | for(size_t i = 0; i != sig_parts.size(); ++i) |
254 | 260 | sig_parts[i].binary_decode(&sig[part_size*i], part_size); |
255 | | |
256 | 130 | std::vector<uint8_t> output; |
257 | 130 | DER_Encoder(output) |
258 | 130 | .start_sequence() |
259 | 130 | .encode_list(sig_parts) |
260 | 130 | .end_cons(); |
261 | 130 | return output; |
262 | 130 | } |
263 | | |
264 | | } |
265 | | |
266 | | size_t PK_Signer::signature_length() const |
267 | 0 | { |
268 | 0 | if(m_sig_format == Signature_Format::Standard) |
269 | 0 | { |
270 | 0 | return m_op->signature_length(); |
271 | 0 | } |
272 | 0 | else if(m_sig_format == Signature_Format::DerSequence) |
273 | 0 | { |
274 | | // This is a large over-estimate but its easier than computing |
275 | | // the exact value |
276 | 0 | return m_op->signature_length() + (8 + 4*m_parts); |
277 | 0 | } |
278 | 0 | else |
279 | 0 | throw Internal_Error("PK_Signer: Invalid signature format enum"); |
280 | 0 | } |
281 | | |
282 | | std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) |
283 | 181 | { |
284 | 181 | std::vector<uint8_t> sig = unlock(m_op->sign(rng)); |
285 | | |
286 | 181 | if(m_sig_format == Signature_Format::Standard) |
287 | 50 | { |
288 | 50 | return sig; |
289 | 50 | } |
290 | 131 | else if(m_sig_format == Signature_Format::DerSequence) |
291 | 130 | { |
292 | 130 | return der_encode_signature(sig, m_parts, m_part_size); |
293 | 130 | } |
294 | 1 | else |
295 | 1 | throw Internal_Error("PK_Signer: Invalid signature format enum"); |
296 | 181 | } |
297 | | |
298 | | PK_Verifier::PK_Verifier(const Public_Key& key, |
299 | | const std::string& emsa, |
300 | | Signature_Format format, |
301 | | const std::string& provider) |
302 | 407 | { |
303 | 407 | m_op = key.create_verification_op(emsa, provider); |
304 | 407 | if(!m_op) |
305 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature verification"); |
306 | 407 | m_sig_format = format; |
307 | 407 | m_parts = key.message_parts(); |
308 | 407 | m_part_size = key.message_part_size(); |
309 | 407 | check_der_format_supported(format, m_parts); |
310 | 407 | } |
311 | | |
312 | 407 | PK_Verifier::~PK_Verifier() = default; |
313 | | |
314 | | void PK_Verifier::set_input_format(Signature_Format format) |
315 | 0 | { |
316 | 0 | check_der_format_supported(format, m_parts); |
317 | 0 | m_sig_format = format; |
318 | 0 | } |
319 | | |
320 | | bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, |
321 | | const uint8_t sig[], size_t sig_length) |
322 | 407 | { |
323 | 407 | update(msg, msg_length); |
324 | 407 | return check_signature(sig, sig_length); |
325 | 407 | } |
326 | | |
327 | | void PK_Verifier::update(const uint8_t in[], size_t length) |
328 | 407 | { |
329 | 407 | m_op->update(in, length); |
330 | 407 | } |
331 | | |
332 | | bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) |
333 | 407 | { |
334 | 407 | try { |
335 | 407 | if(m_sig_format == Signature_Format::Standard) |
336 | 407 | { |
337 | 407 | return m_op->is_valid_signature(sig, length); |
338 | 407 | } |
339 | 0 | else if(m_sig_format == Signature_Format::DerSequence) |
340 | 0 | { |
341 | 0 | std::vector<uint8_t> real_sig; |
342 | 0 | BER_Decoder decoder(sig, length); |
343 | 0 | BER_Decoder ber_sig = decoder.start_sequence(); |
344 | |
|
345 | 0 | BOTAN_ASSERT_NOMSG(m_parts != 0 && m_part_size != 0); |
346 | |
|
347 | 0 | size_t count = 0; |
348 | |
|
349 | 0 | while(ber_sig.more_items()) |
350 | 0 | { |
351 | 0 | BigInt sig_part; |
352 | 0 | ber_sig.decode(sig_part); |
353 | 0 | real_sig += BigInt::encode_1363(sig_part, m_part_size); |
354 | 0 | ++count; |
355 | 0 | } |
356 | |
|
357 | 0 | if(count != m_parts) |
358 | 0 | throw Decoding_Error("PK_Verifier: signature size invalid"); |
359 | | |
360 | 0 | const std::vector<uint8_t> reencoded = |
361 | 0 | der_encode_signature(real_sig, m_parts, m_part_size); |
362 | |
|
363 | 0 | if(reencoded.size() != length || |
364 | 0 | same_mem(reencoded.data(), sig, reencoded.size()) == false) |
365 | 0 | { |
366 | 0 | throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding"); |
367 | 0 | } |
368 | | |
369 | 0 | return m_op->is_valid_signature(real_sig.data(), real_sig.size()); |
370 | 0 | } |
371 | 0 | else |
372 | 0 | throw Internal_Error("PK_Verifier: Invalid signature format enum"); |
373 | 407 | } |
374 | 407 | catch(Invalid_Argument&) { return false; } |
375 | 407 | catch(Decoding_Error&) { return false; } |
376 | 407 | catch(Encoding_Error&) { return false; } |
377 | 407 | } |
378 | | |
379 | | } |