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