1 /*
2 * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 /*****************************************************************************
28 BotanRSA.cpp
29
30 Botan RSA asymmetric algorithm implementation
31 *****************************************************************************/
32
33 #include "config.h"
34 #include "log.h"
35 #include "BotanRSA.h"
36 #include "BotanRNG.h"
37 #include "CryptoFactory.h"
38 #include "BotanCryptoFactory.h"
39 #include "RSAParameters.h"
40 #include "BotanRSAKeyPair.h"
41 #include <algorithm>
42 #include <botan/rsa.h>
43 #include <botan/version.h>
44 #include <sstream>
45
46 // Constructor
BotanRSA()47 BotanRSA::BotanRSA()
48 {
49 signer = NULL;
50 verifier = NULL;
51 }
52
53 // Destructor
~BotanRSA()54 BotanRSA::~BotanRSA()
55 {
56 delete signer;
57 delete verifier;
58 }
59
60 // Signing functions
sign(PrivateKey * privateKey,const ByteString & dataToSign,ByteString & signature,const AsymMech::Type mechanism,const void * param,const size_t paramLen)61 bool BotanRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
62 ByteString& signature, const AsymMech::Type mechanism,
63 const void* param /* = NULL */, const size_t paramLen /* = 0 */)
64 {
65 std::string emsa = "";
66
67 switch (mechanism)
68 {
69 case AsymMech::RSA:
70 emsa = "Raw";
71 break;
72 case AsymMech::RSA_PKCS:
73 emsa = "EMSA3(Raw)";
74 break;
75 #ifdef WITH_RAW_PSS
76 case AsymMech::RSA_PKCS_PSS:
77 emsa = getCipherRawPss(privateKey->getBitLength(), dataToSign.size(), param, paramLen);
78 if (emsa == "")
79 {
80 return false;
81 }
82 break;
83 #endif
84 default:
85 // Call default implementation
86 return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
87 }
88
89 // Check if the private key is the right type
90 if (!privateKey->isOfType(BotanRSAPrivateKey::type))
91 {
92 ERROR_MSG("Invalid key type supplied");
93
94 return false;
95 }
96
97 BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) privateKey;
98 Botan::RSA_PrivateKey* botanKey = pk->getBotanKey();
99
100 if (!botanKey)
101 {
102 ERROR_MSG("Could not get the Botan private key");
103
104 return false;
105 }
106
107 try
108 {
109 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
110 signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
111 }
112 catch (...)
113 {
114 ERROR_MSG("Could not create the signer token");
115
116 return false;
117 }
118
119 // Perform the signature operation
120 std::vector<uint8_t> signResult;
121 try
122 {
123 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
124 signResult = signer->sign_message(dataToSign.const_byte_str(), dataToSign.size(), *rng->getRNG());
125 }
126 catch (std::exception& e)
127 {
128 ERROR_MSG("Could not sign the data: %s", e.what());
129
130 delete signer;
131 signer = NULL;
132
133 return false;
134 }
135
136 // Return the result
137 signature.resize(signResult.size());
138 memcpy(&signature[0], signResult.data(), signResult.size());
139
140 delete signer;
141 signer = NULL;
142
143 return true;
144 }
145
signInit(PrivateKey * privateKey,const AsymMech::Type mechanism,const void * param,const size_t paramLen)146 bool BotanRSA::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
147 const void* param /* = NULL */, const size_t paramLen /* = 0 */)
148 {
149 if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
150 {
151 return false;
152 }
153
154 // Check if the private key is the right type
155 if (!privateKey->isOfType(BotanRSAPrivateKey::type))
156 {
157 ERROR_MSG("Invalid key type supplied");
158
159 ByteString dummy;
160 AsymmetricAlgorithm::signFinal(dummy);
161
162 return false;
163 }
164
165 std::string emsa;
166 std::ostringstream request;
167 size_t sLen;
168
169 switch (mechanism)
170 {
171 case AsymMech::RSA_MD5_PKCS:
172 emsa = "EMSA3(MD5)";
173 break;
174 case AsymMech::RSA_SHA1_PKCS:
175 emsa = "EMSA3(SHA-160)";
176 break;
177 case AsymMech::RSA_SHA224_PKCS:
178 emsa = "EMSA3(SHA-224)";
179 break;
180 case AsymMech::RSA_SHA256_PKCS:
181 emsa = "EMSA3(SHA-256)";
182 break;
183 case AsymMech::RSA_SHA384_PKCS:
184 emsa = "EMSA3(SHA-384)";
185 break;
186 case AsymMech::RSA_SHA512_PKCS:
187 emsa = "EMSA3(SHA-512)";
188 break;
189 case AsymMech::RSA_SHA1_PKCS_PSS:
190 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
191 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA1 ||
192 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA1)
193 {
194 ERROR_MSG("Invalid parameters");
195 ByteString dummy;
196 AsymmetricAlgorithm::signFinal(dummy);
197 return false;
198 }
199 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
200 if (sLen > ((privateKey->getBitLength()+6)/8-2-20))
201 {
202 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
203 (unsigned long)sLen, privateKey->getBitLength());
204 ByteString dummy;
205 AsymmetricAlgorithm::signFinal(dummy);
206 return false;
207 }
208 request << "EMSA4(SHA-160,MGF1," << sLen << ")";
209 emsa = request.str();
210 break;
211 case AsymMech::RSA_SHA224_PKCS_PSS:
212 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
213 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA224 ||
214 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA224)
215 {
216 ERROR_MSG("Invalid parameters");
217 ByteString dummy;
218 AsymmetricAlgorithm::signFinal(dummy);
219 return false;
220 }
221 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
222 if (sLen > ((privateKey->getBitLength()+6)/8-2-28))
223 {
224 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
225 (unsigned long)sLen, privateKey->getBitLength());
226 ByteString dummy;
227 AsymmetricAlgorithm::signFinal(dummy);
228 return false;
229 }
230 request << "EMSA4(SHA-224,MGF1," << sLen << ")";
231 emsa = request.str();
232 break;
233 case AsymMech::RSA_SHA256_PKCS_PSS:
234 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
235 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA256 ||
236 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA256)
237 {
238 ERROR_MSG("Invalid parameters");
239 ByteString dummy;
240 AsymmetricAlgorithm::signFinal(dummy);
241 return false;
242 }
243 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
244 if (sLen > ((privateKey->getBitLength()+6)/8-2-32))
245 {
246 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
247 (unsigned long)sLen, privateKey->getBitLength());
248 ByteString dummy;
249 AsymmetricAlgorithm::signFinal(dummy);
250 return false;
251 }
252 request << "EMSA4(SHA-256,MGF1," << sLen << ")";
253 emsa = request.str();
254 break;
255 case AsymMech::RSA_SHA384_PKCS_PSS:
256 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
257 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA384 ||
258 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA384)
259 {
260 ERROR_MSG("Invalid parameters");
261 ByteString dummy;
262 AsymmetricAlgorithm::signFinal(dummy);
263 return false;
264 }
265 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
266 if (sLen > ((privateKey->getBitLength()+6)/8-2-48))
267 {
268 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
269 (unsigned long)sLen, privateKey->getBitLength());
270 ByteString dummy;
271 AsymmetricAlgorithm::signFinal(dummy);
272 return false;
273 }
274 request << "EMSA4(SHA-384,MGF1," << sLen << ")";
275 emsa = request.str();
276 break;
277 case AsymMech::RSA_SHA512_PKCS_PSS:
278 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
279 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA512 ||
280 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA512)
281 {
282 ERROR_MSG("Invalid parameters");
283 ByteString dummy;
284 AsymmetricAlgorithm::signFinal(dummy);
285 return false;
286 }
287 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
288 if (sLen > ((privateKey->getBitLength()+6)/8-2-64))
289 {
290 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
291 (unsigned long)sLen, privateKey->getBitLength());
292 ByteString dummy;
293 AsymmetricAlgorithm::signFinal(dummy);
294 return false;
295 }
296 request << "EMSA4(SHA-512,MGF1," << sLen << ")";
297 emsa = request.str();
298 break;
299 case AsymMech::RSA_SSL:
300 emsa = "EMSA3(Parallel(MD5,SHA-160))";
301 break;
302 default:
303 ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
304
305 ByteString dummy;
306 AsymmetricAlgorithm::signFinal(dummy);
307
308 return false;
309 }
310
311 BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) currentPrivateKey;
312 Botan::RSA_PrivateKey* botanKey = pk->getBotanKey();
313
314 if (!botanKey)
315 {
316 ERROR_MSG("Could not get the Botan private key");
317
318 ByteString dummy;
319 AsymmetricAlgorithm::signFinal(dummy);
320
321 return false;
322 }
323
324 try
325 {
326 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
327 signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
328 }
329 catch (...)
330 {
331 ERROR_MSG("Could not create the signer token");
332
333 ByteString dummy;
334 AsymmetricAlgorithm::signFinal(dummy);
335
336 return false;
337 }
338
339 return true;
340 }
341
signUpdate(const ByteString & dataToSign)342 bool BotanRSA::signUpdate(const ByteString& dataToSign)
343 {
344 if (!AsymmetricAlgorithm::signUpdate(dataToSign))
345 {
346 return false;
347 }
348
349 try
350 {
351 if (dataToSign.size() != 0)
352 {
353 signer->update(dataToSign.const_byte_str(),
354 dataToSign.size());
355 }
356 }
357 catch (...)
358 {
359 ERROR_MSG("Could not add data to signer token");
360
361 ByteString dummy;
362 AsymmetricAlgorithm::signFinal(dummy);
363
364 delete signer;
365 signer = NULL;
366
367 return false;
368 }
369
370 return true;
371 }
372
signFinal(ByteString & signature)373 bool BotanRSA::signFinal(ByteString& signature)
374 {
375 if (!AsymmetricAlgorithm::signFinal(signature))
376 {
377 return false;
378 }
379
380 // Perform the signature operation
381 std::vector<uint8_t> signResult;
382 try
383 {
384 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
385 signResult = signer->signature(*rng->getRNG());
386 }
387 catch (...)
388 {
389 ERROR_MSG("Could not sign the data");
390
391 delete signer;
392 signer = NULL;
393
394 return false;
395 }
396
397 // Return the result
398 signature.resize(signResult.size());
399 memcpy(&signature[0], signResult.data(), signResult.size());
400
401 delete signer;
402 signer = NULL;
403
404 return true;
405 }
406
407 // Verification functions
verify(PublicKey * publicKey,const ByteString & originalData,const ByteString & signature,const AsymMech::Type mechanism,const void * param,const size_t paramLen)408 bool BotanRSA::verify(PublicKey* publicKey, const ByteString& originalData,
409 const ByteString& signature, const AsymMech::Type mechanism,
410 const void* param /* = NULL */, const size_t paramLen /* = 0 */)
411 {
412 std::string emsa = "";
413
414 switch (mechanism)
415 {
416 case AsymMech::RSA:
417 emsa = "Raw";
418 break;
419 case AsymMech::RSA_PKCS:
420 emsa = "EMSA3(Raw)";
421 break;
422 #ifdef WITH_RAW_PSS
423 case AsymMech::RSA_PKCS_PSS:
424 emsa = getCipherRawPss(publicKey->getBitLength(), originalData.size(), param, paramLen);
425 if (emsa == "")
426 {
427 return false;
428 }
429 break;
430 #endif
431 default:
432 // Call the generic function
433 return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen);
434 }
435
436 // Check if the public key is the right type
437 if (!publicKey->isOfType(BotanRSAPublicKey::type))
438 {
439 ERROR_MSG("Invalid key type supplied");
440
441 return false;
442 }
443
444 BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
445 Botan::RSA_PublicKey* botanKey = pk->getBotanKey();
446
447 if (!botanKey)
448 {
449 ERROR_MSG("Could not get the Botan public key");
450
451 return false;
452 }
453
454 try
455 {
456 verifier = new Botan::PK_Verifier(*botanKey, emsa);
457 }
458 catch (...)
459 {
460 ERROR_MSG("Could not create the verifier token");
461
462 return false;
463 }
464
465 // Perform the verify operation
466 bool verResult;
467 try
468 {
469 verResult = verifier->verify_message(originalData.const_byte_str(),
470 originalData.size(),
471 signature.const_byte_str(),
472 signature.size());
473 }
474 catch (...)
475 {
476 ERROR_MSG("Could not check the signature");
477
478 delete verifier;
479 verifier = NULL;
480
481 return false;
482 }
483
484 delete verifier;
485 verifier = NULL;
486
487 return verResult;
488 }
489
verifyInit(PublicKey * publicKey,const AsymMech::Type mechanism,const void * param,const size_t paramLen)490 bool BotanRSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
491 const void* param /* = NULL */, const size_t paramLen /* = 0 */)
492 {
493 if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
494 {
495 return false;
496 }
497
498 // Check if the public key is the right type
499 if (!publicKey->isOfType(BotanRSAPublicKey::type))
500 {
501 ERROR_MSG("Invalid key type supplied");
502
503 ByteString dummy;
504 AsymmetricAlgorithm::verifyFinal(dummy);
505
506 return false;
507 }
508
509 std::string emsa;
510 std::ostringstream request;
511 size_t sLen;
512
513 switch (mechanism)
514 {
515 case AsymMech::RSA_MD5_PKCS:
516 emsa = "EMSA3(MD5)";
517 break;
518 case AsymMech::RSA_SHA1_PKCS:
519 emsa = "EMSA3(SHA-160)";
520 break;
521 case AsymMech::RSA_SHA224_PKCS:
522 emsa = "EMSA3(SHA-224)";
523 break;
524 case AsymMech::RSA_SHA256_PKCS:
525 emsa = "EMSA3(SHA-256)";
526 break;
527 case AsymMech::RSA_SHA384_PKCS:
528 emsa = "EMSA3(SHA-384)";
529 break;
530 case AsymMech::RSA_SHA512_PKCS:
531 emsa = "EMSA3(SHA-512)";
532 break;
533 case AsymMech::RSA_SHA1_PKCS_PSS:
534 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
535 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA1 ||
536 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA1)
537 {
538 ERROR_MSG("Invalid parameters");
539 ByteString dummy;
540 AsymmetricAlgorithm::verifyFinal(dummy);
541 return false;
542 }
543 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
544 if (sLen > ((publicKey->getBitLength()+6)/8-2-20))
545 {
546 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
547 (unsigned long)sLen, publicKey->getBitLength());
548 ByteString dummy;
549 AsymmetricAlgorithm::verifyFinal(dummy);
550 return false;
551 }
552 request << "EMSA4(SHA-160,MGF1," << sLen << ")";
553 emsa = request.str();
554 break;
555 case AsymMech::RSA_SHA224_PKCS_PSS:
556 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
557 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA224 ||
558 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA224)
559 {
560 ERROR_MSG("Invalid parameters");
561 ByteString dummy;
562 AsymmetricAlgorithm::verifyFinal(dummy);
563 return false;
564 }
565 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
566 if (sLen > ((publicKey->getBitLength()+6)/8-2-28))
567 {
568 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
569 (unsigned long)sLen, publicKey->getBitLength());
570 ByteString dummy;
571 AsymmetricAlgorithm::verifyFinal(dummy);
572 return false;
573 }
574 request << "EMSA4(SHA-224,MGF1," << sLen << ")";
575 emsa = request.str();
576 break;
577 case AsymMech::RSA_SHA256_PKCS_PSS:
578 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
579 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA256 ||
580 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA256)
581 {
582 ERROR_MSG("Invalid parameters");
583 ByteString dummy;
584 AsymmetricAlgorithm::verifyFinal(dummy);
585 return false;
586 }
587 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
588 if (sLen > ((publicKey->getBitLength()+6)/8-2-32))
589 {
590 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
591 (unsigned long)sLen, publicKey->getBitLength());
592 ByteString dummy;
593 AsymmetricAlgorithm::verifyFinal(dummy);
594 return false;
595 }
596 request << "EMSA4(SHA-256,MGF1," << sLen << ")";
597 emsa = request.str();
598 break;
599 case AsymMech::RSA_SHA384_PKCS_PSS:
600 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
601 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA384 ||
602 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA384)
603 {
604 ERROR_MSG("Invalid parameters");
605 ByteString dummy;
606 AsymmetricAlgorithm::verifyFinal(dummy);
607 return false;
608 }
609 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
610 if (sLen > ((publicKey->getBitLength()+6)/8-2-48))
611 {
612 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
613 (unsigned long)sLen, publicKey->getBitLength());
614 ByteString dummy;
615 AsymmetricAlgorithm::verifyFinal(dummy);
616 return false;
617 }
618 request << "EMSA4(SHA-384,MGF1," << sLen << ")";
619 emsa = request.str();
620 break;
621 case AsymMech::RSA_SHA512_PKCS_PSS:
622 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
623 ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA512 ||
624 ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA512)
625 {
626 ERROR_MSG("Invalid parameters");
627 ByteString dummy;
628 AsymmetricAlgorithm::verifyFinal(dummy);
629 return false;
630 }
631 sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
632 if (sLen > ((publicKey->getBitLength()+6)/8-2-64))
633 {
634 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
635 (unsigned long)sLen, publicKey->getBitLength());
636 ByteString dummy;
637 AsymmetricAlgorithm::verifyFinal(dummy);
638 return false;
639 }
640 request << "EMSA4(SHA-512,MGF1," << sLen << ")";
641 emsa = request.str();
642 break;
643 case AsymMech::RSA_SSL:
644 emsa = "EMSA3(Parallel(MD5,SHA-160))";
645 break;
646 default:
647 ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
648
649 ByteString dummy;
650 AsymmetricAlgorithm::verifyFinal(dummy);
651
652 return false;
653 }
654
655 BotanRSAPublicKey* pk = (BotanRSAPublicKey*) currentPublicKey;
656 Botan::RSA_PublicKey* botanKey = pk->getBotanKey();
657
658 if (!botanKey)
659 {
660 ERROR_MSG("Could not get the Botan public key");
661
662 ByteString dummy;
663 AsymmetricAlgorithm::verifyFinal(dummy);
664
665 return false;
666 }
667
668 try
669 {
670 verifier = new Botan::PK_Verifier(*botanKey, emsa);
671 }
672 catch (...)
673 {
674 ERROR_MSG("Could not create the verifier token");
675
676 ByteString dummy;
677 AsymmetricAlgorithm::verifyFinal(dummy);
678
679 return false;
680 }
681
682 return true;
683 }
684
verifyUpdate(const ByteString & originalData)685 bool BotanRSA::verifyUpdate(const ByteString& originalData)
686 {
687 if (!AsymmetricAlgorithm::verifyUpdate(originalData))
688 {
689 return false;
690 }
691
692 try
693 {
694 if (originalData.size() != 0)
695 {
696 verifier->update(originalData.const_byte_str(),
697 originalData.size());
698 }
699 }
700 catch (...)
701 {
702 ERROR_MSG("Could not add data to the verifier token");
703
704 ByteString dummy;
705 AsymmetricAlgorithm::verifyFinal(dummy);
706
707 delete verifier;
708 verifier = NULL;
709
710 return false;
711 }
712
713 return true;
714 }
715
verifyFinal(const ByteString & signature)716 bool BotanRSA::verifyFinal(const ByteString& signature)
717 {
718 if (!AsymmetricAlgorithm::verifyFinal(signature))
719 {
720 return false;
721 }
722
723 // Perform the verify operation
724 bool verResult;
725 try
726 {
727 verResult = verifier->check_signature(signature.const_byte_str(), signature.size());
728 }
729 catch (...)
730 {
731 ERROR_MSG("Could not check the signature");
732
733 delete verifier;
734 verifier = NULL;
735
736 return false;
737 }
738
739 delete verifier;
740 verifier = NULL;
741
742 return verResult;
743 }
744
745 // Encryption functions
encrypt(PublicKey * publicKey,const ByteString & data,ByteString & encryptedData,const AsymMech::Type padding)746 bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data,
747 ByteString& encryptedData, const AsymMech::Type padding)
748 {
749 // Check if the public key is the right type
750 if (!publicKey->isOfType(BotanRSAPublicKey::type))
751 {
752 ERROR_MSG("Invalid key type supplied");
753
754 return false;
755 }
756
757 std::string eme;
758
759 switch (padding)
760 {
761 case AsymMech::RSA_PKCS:
762 eme = "PKCS1v15";
763 break;
764 case AsymMech::RSA_PKCS_OAEP:
765 eme = "EME1(SHA-160)";
766 break;
767 case AsymMech::RSA:
768 eme = "Raw";
769 break;
770 default:
771 ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);
772
773 return false;
774 }
775
776 BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
777 Botan::RSA_PublicKey* botanKey = pk->getBotanKey();
778
779 if (!botanKey)
780 {
781 ERROR_MSG("Could not get the Botan public key");
782
783 return false;
784 }
785
786 Botan::PK_Encryptor_EME* encryptor = NULL;
787 try
788 {
789 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
790 encryptor = new Botan::PK_Encryptor_EME(*botanKey, *rng->getRNG(), eme);
791 }
792 catch (...)
793 {
794 ERROR_MSG("Could not create the encryptor token");
795
796 return false;
797 }
798
799 // Perform the encryption operation
800 std::vector<uint8_t> encResult;
801 try
802 {
803 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
804 encResult = encryptor->encrypt(data.const_byte_str(), data.size(), *rng->getRNG());
805 }
806 catch (...)
807 {
808 ERROR_MSG("Could not encrypt the data");
809
810 delete encryptor;
811
812 return false;
813 }
814
815 // Return the result
816 encryptedData.resize(encResult.size());
817 memcpy(&encryptedData[0], encResult.data(), encResult.size());
818
819 delete encryptor;
820
821 return true;
822 }
823
824 // Decryption functions
decrypt(PrivateKey * privateKey,const ByteString & encryptedData,ByteString & data,const AsymMech::Type padding)825 bool BotanRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData,
826 ByteString& data, const AsymMech::Type padding)
827 {
828 // Check if the private key is the right type
829 if (!privateKey->isOfType(BotanRSAPrivateKey::type))
830 {
831 ERROR_MSG("Invalid key type supplied");
832
833 return false;
834 }
835
836 std::string eme;
837
838 switch (padding)
839 {
840 case AsymMech::RSA_PKCS:
841 eme = "PKCS1v15";
842 break;
843 case AsymMech::RSA_PKCS_OAEP:
844 eme = "EME1(SHA-160)";
845 break;
846 case AsymMech::RSA:
847 eme = "Raw";
848 break;
849 default:
850 ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);
851
852 return false;
853 }
854
855 BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) privateKey;
856 Botan::RSA_PrivateKey* botanKey = pk->getBotanKey();
857
858 if (!botanKey)
859 {
860 ERROR_MSG("Could not get the Botan private key");
861
862 return false;
863 }
864
865 Botan::PK_Decryptor_EME* decryptor = NULL;
866 try
867 {
868 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
869 decryptor = new Botan::PK_Decryptor_EME(*botanKey, *rng->getRNG(), eme);
870 }
871 catch (...)
872 {
873 ERROR_MSG("Could not create the decryptor token");
874
875 return false;
876 }
877
878 // Perform the decryption operation
879 Botan::secure_vector<uint8_t> decResult;
880 try
881 {
882 decResult = decryptor->decrypt(encryptedData.const_byte_str(), encryptedData.size());
883 }
884 catch (...)
885 {
886 ERROR_MSG("Could not decrypt the data");
887
888 delete decryptor;
889
890 return false;
891 }
892
893 // Return the result
894 if (padding == AsymMech::RSA)
895 {
896 // We compensate that Botan removes leading zeros
897 int modSize = pk->getN().size();
898 int decSize = decResult.size();
899 data.resize(modSize);
900 memcpy(&data[0] + modSize - decSize, decResult.data(), decSize);
901 }
902 else
903 {
904 data.resize(decResult.size());
905 memcpy(&data[0], decResult.data(), decResult.size());
906 }
907
908 delete decryptor;
909
910 return true;
911 }
912
913 // Key factory
generateKeyPair(AsymmetricKeyPair ** ppKeyPair,AsymmetricParameters * parameters,RNG *)914 bool BotanRSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
915 {
916 // Check parameters
917 if ((ppKeyPair == NULL) ||
918 (parameters == NULL))
919 {
920 return false;
921 }
922
923 if (!parameters->areOfType(RSAParameters::type))
924 {
925 ERROR_MSG("Invalid parameters supplied for RSA key generation");
926
927 return false;
928 }
929
930 RSAParameters* params = (RSAParameters*) parameters;
931
932 if (params->getBitLength() < getMinKeySize() || params->getBitLength() > getMaxKeySize())
933 {
934 ERROR_MSG("This RSA key size (%lu) is not supported", params->getBitLength());
935
936 return false;
937 }
938
939 // Retrieve the desired public exponent
940 unsigned long e = params->getE().long_val();
941
942 // Check the public exponent
943 if ((e == 0) || (e % 2 != 1))
944 {
945 ERROR_MSG("Invalid RSA public exponent %d", e);
946
947 return false;
948 }
949
950 // Create an asymmetric key-pair object to return
951 BotanRSAKeyPair* kp = new BotanRSAKeyPair();
952
953 // Generate the key-pair
954 Botan::RSA_PrivateKey* rsa = NULL;
955 try {
956 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
957 rsa = new Botan::RSA_PrivateKey(*rng->getRNG(), params->getBitLength(), e);
958 }
959 catch (std::exception& ex) {
960 ERROR_MSG("RSA key generation failed: %s", ex.what());
961
962 delete kp;
963
964 return false;
965 }
966
967 ((BotanRSAPublicKey*) kp->getPublicKey())->setFromBotan(rsa);
968 ((BotanRSAPrivateKey*) kp->getPrivateKey())->setFromBotan(rsa);
969
970 *ppKeyPair = kp;
971
972 // Release the key
973 delete rsa;
974
975 return true;
976 }
977
getMinKeySize()978 unsigned long BotanRSA::getMinKeySize()
979 {
980 return 1024;
981 }
982
getMaxKeySize()983 unsigned long BotanRSA::getMaxKeySize()
984 {
985 return 4096;
986 }
987
reconstructKeyPair(AsymmetricKeyPair ** ppKeyPair,ByteString & serialisedData)988 bool BotanRSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
989 {
990 // Check input
991 if ((ppKeyPair == NULL) ||
992 (serialisedData.size() == 0))
993 {
994 return false;
995 }
996
997 ByteString dPub = ByteString::chainDeserialise(serialisedData);
998 ByteString dPriv = ByteString::chainDeserialise(serialisedData);
999
1000 BotanRSAKeyPair* kp = new BotanRSAKeyPair();
1001
1002 bool rv = true;
1003
1004 if (!((RSAPublicKey*) kp->getPublicKey())->deserialise(dPub))
1005 {
1006 rv = false;
1007 }
1008
1009 if (!((RSAPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
1010 {
1011 rv = false;
1012 }
1013
1014 if (!rv)
1015 {
1016 delete kp;
1017
1018 return false;
1019 }
1020
1021 *ppKeyPair = kp;
1022
1023 return true;
1024 }
1025
reconstructPublicKey(PublicKey ** ppPublicKey,ByteString & serialisedData)1026 bool BotanRSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
1027 {
1028 // Check input
1029 if ((ppPublicKey == NULL) ||
1030 (serialisedData.size() == 0))
1031 {
1032 return false;
1033 }
1034
1035 BotanRSAPublicKey* pub = new BotanRSAPublicKey();
1036
1037 if (!pub->deserialise(serialisedData))
1038 {
1039 delete pub;
1040
1041 return false;
1042 }
1043
1044 *ppPublicKey = pub;
1045
1046 return true;
1047 }
1048
reconstructPrivateKey(PrivateKey ** ppPrivateKey,ByteString & serialisedData)1049 bool BotanRSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
1050 {
1051 // Check input
1052 if ((ppPrivateKey == NULL) ||
1053 (serialisedData.size() == 0))
1054 {
1055 return false;
1056 }
1057
1058 BotanRSAPrivateKey* priv = new BotanRSAPrivateKey();
1059
1060 if (!priv->deserialise(serialisedData))
1061 {
1062 delete priv;
1063
1064 return false;
1065 }
1066
1067 *ppPrivateKey = priv;
1068
1069 return true;
1070 }
1071
newPublicKey()1072 PublicKey* BotanRSA::newPublicKey()
1073 {
1074 return (PublicKey*) new BotanRSAPublicKey();
1075 }
1076
newPrivateKey()1077 PrivateKey* BotanRSA::newPrivateKey()
1078 {
1079 return (PrivateKey*) new BotanRSAPrivateKey();
1080 }
1081
newParameters()1082 AsymmetricParameters* BotanRSA::newParameters()
1083 {
1084 return (AsymmetricParameters*) new RSAParameters();
1085 }
1086
reconstructParameters(AsymmetricParameters ** ppParams,ByteString & serialisedData)1087 bool BotanRSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
1088 {
1089 // Check input parameters
1090 if ((ppParams == NULL) || (serialisedData.size() == 0))
1091 {
1092 return false;
1093 }
1094
1095 RSAParameters* params = new RSAParameters();
1096
1097 if (!params->deserialise(serialisedData))
1098 {
1099 delete params;
1100
1101 return false;
1102 }
1103
1104 *ppParams = params;
1105
1106 return true;
1107 }
1108
1109 #ifdef WITH_RAW_PSS
getCipherRawPss(size_t bitLength,size_t dataSize,const void * param,const size_t paramLen)1110 std::string BotanRSA::getCipherRawPss(size_t bitLength, size_t dataSize, const void* param, const size_t paramLen)
1111 {
1112 if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS))
1113 {
1114 ERROR_MSG("Invalid parameters");
1115 return "";
1116 }
1117
1118 std::string hashStr = "";
1119 size_t allowedLen = 0;
1120 switch (((RSA_PKCS_PSS_PARAMS*) param)->hashAlg)
1121 {
1122 case HashAlgo::SHA1:
1123 hashStr = "SHA-160";
1124 allowedLen = 20;
1125 break;
1126 case HashAlgo::SHA224:
1127 hashStr = "SHA-224";
1128 allowedLen = 28;
1129 break;
1130 case HashAlgo::SHA256:
1131 hashStr = "SHA-256";
1132 allowedLen = 32;
1133 break;
1134 case HashAlgo::SHA384:
1135 hashStr = "SHA-384";
1136 allowedLen = 48;
1137 break;
1138 case HashAlgo::SHA512:
1139 hashStr = "SHA-512";
1140 allowedLen = 64;
1141 break;
1142 default:
1143 ERROR_MSG("Invalid hash parameter");
1144 return "";
1145 }
1146
1147 if (dataSize != allowedLen)
1148 {
1149 ERROR_MSG("Data to sign does not match expected (%d) for RSA PSS", (int)allowedLen);
1150 return "";
1151 }
1152
1153 size_t sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
1154 if (sLen > ((bitLength+6)/8-2-20))
1155 {
1156 ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
1157 (unsigned long)sLen, bitLength);
1158 return "";
1159 }
1160
1161 std::ostringstream request;
1162 request << "PSSR_Raw(" << hashStr << ",MGF1," << sLen << ")";
1163 return request.str();
1164 }
1165 #endif
1166