1 /** 2 * Public Key Interface 3 * 4 * Copyright: 5 * (C) 1999-2010 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.pubkey.pubkey; 12 13 import botan.constants; 14 static if (BOTAN_HAS_PUBLIC_KEY_CRYPTO): 15 16 import botan.utils.types; 17 public import botan.pubkey.pk_keys; 18 public import botan.pubkey.pk_ops; 19 public import botan.algo_base.symkey; 20 public import botan.utils.types; 21 public import botan.rng.rng; 22 public import botan.pubkey.pkcs8; 23 public import botan.pubkey.algo.ec_group; 24 public import botan.pk_pad.emsa : EMSA; 25 import botan.pk_pad.eme; 26 import botan.pk_pad.emsa; 27 import botan.pk_pad.factory; 28 import botan.kdf.kdf; 29 import botan.asn1.der_enc; 30 import botan.asn1.ber_dec; 31 import botan.math.bigint.bigint; 32 import botan.utils.parsing; 33 import botan.libstate.libstate; 34 import botan.engine.engine; 35 import botan.utils.bit_ops; 36 import botan.utils.exceptn; 37 import botan.utils.mem_ops; 38 39 alias SignatureFormat = bool; 40 /** 41 * The two types of signature format supported by Botan. 42 */ 43 enum : SignatureFormat { IEEE_1363, DER_SEQUENCE } 44 45 alias FaultProtection = bool; 46 /** 47 * Enum marking if protection against fault attacks should be used 48 */ 49 enum : FaultProtection { 50 ENABLE_FAULT_PROTECTION, 51 DISABLE_FAULT_PROTECTION 52 } 53 54 /** 55 * Public Key Encryptor 56 */ 57 interface PKEncryptor 58 { 59 public: 60 61 /** 62 * Encrypt a message. 63 * 64 * Params: 65 * input = the message as a ubyte array 66 * length = the length of the above ubyte array 67 * rng = the random number source to use 68 * Returns: encrypted message 69 */ 70 final Vector!ubyte encrypt(const(ubyte)* input, size_t length, RandomNumberGenerator rng) const 71 { 72 return enc(input, length, rng); 73 } 74 75 /** 76 * Encrypt a message. 77 * 78 * Params: 79 * input = the message 80 * rng = the random number source to use 81 * Returns: encrypted message 82 */ 83 final Vector!ubyte encrypt(Alloc)(const ref Vector!( ubyte, Alloc ) input, RandomNumberGenerator rng) const 84 { 85 return enc(input.ptr, input.length, rng); 86 } 87 88 /** 89 * Return the maximum allowed message size in bytes. 90 * Returns: maximum message size in bytes 91 */ 92 abstract size_t maximumInputSize() const; 93 94 protected: 95 abstract Vector!ubyte enc(const(ubyte)*, size_t, RandomNumberGenerator) const; 96 } 97 98 /** 99 * Public Key Decryptor 100 */ 101 interface PKDecryptor 102 { 103 public: 104 /** 105 * Decrypt a ciphertext. 106 * 107 * Params: 108 * input = the ciphertext as a ubyte array 109 * length = the length of the above ubyte array 110 * Returns: decrypted message 111 */ 112 final SecureVector!ubyte decrypt(const(ubyte)* input, size_t length) const 113 { 114 return dec(input, length); 115 } 116 117 /** 118 * Decrypt a ciphertext. 119 * 120 * Params: 121 * input = the ciphertext 122 * Returns: decrypted message 123 */ 124 final SecureVector!ubyte decrypt(Alloc)(auto const ref Vector!( ubyte, Alloc ) input) const 125 { 126 return dec(input.ptr, input.length); 127 } 128 129 protected: 130 abstract SecureVector!ubyte dec(const(ubyte)*, size_t) const; 131 } 132 133 /** 134 * Public Key Signer. Use the signMessage() functions for small 135 * messages. Use multiple calls update() to process large messages and 136 * generate the signature by finally calling signature(). 137 */ 138 struct PKSigner 139 { 140 public: 141 /** 142 * Sign a message. 143 * 144 * Params: 145 * msg = the message to sign as a ubyte array 146 * length = the length of the above ubyte array 147 * rng = the rng to use 148 * Returns: signature 149 */ 150 Vector!ubyte signMessage(const(ubyte)* msg, size_t length, RandomNumberGenerator rng) 151 { 152 update(msg, length); 153 return signature(rng); 154 } 155 156 /** 157 * Sign a message. 158 * 159 * Params: 160 * input = the message to sign 161 * rng = the rng to use 162 * Returns: signature 163 */ 164 Vector!ubyte signMessage(ALLOC)(auto const ref Vector!(ubyte, ALLOC) input, RandomNumberGenerator rng) 165 { return signMessage(input.ptr, input.length, rng); } 166 167 Vector!ubyte signMessage(ALLOC)(auto const ref RefCounted!(Vector!(ubyte, ALLOC), ALLOC) input, RandomNumberGenerator rng) 168 { return signMessage(input.ptr, input.length, rng); } 169 170 /** 171 * Add a message part (single ubyte). 172 * 173 * Params: 174 * input = the ubyte to add 175 */ 176 void update(ubyte input) { update(&input, 1); } 177 178 /** 179 * Add a message part. 180 * 181 * Params: 182 * input = the message part to add as a ubyte array 183 * length = the length of the above ubyte array 184 */ 185 void update(const(ubyte)* input, size_t length) 186 { 187 m_emsa.update(input, length); 188 } 189 190 /** 191 * Add a message part. 192 * 193 * Params: 194 * input = the message part to add 195 */ 196 void update(ALLOC)(auto const ref RefCounted!(Vector!(ubyte, ALLOC), ALLOC) input) { update(input.ptr, input.length); } 197 void update(ALLOC)(auto const ref Vector!(ubyte, ALLOC) input) { update(input.ptr, input.length); } 198 199 /** 200 * Get the signature of the so far processed message (provided by the 201 * calls to update()). 202 * 203 * Params: 204 * rng = the rng to use 205 * Returns: signature of the total message 206 */ 207 Vector!ubyte signature(RandomNumberGenerator rng) 208 { 209 Vector!ubyte encoded = unlock(m_emsa.encodingOf(m_emsa.rawData(), m_op.maxInputBits(), rng)); 210 Vector!ubyte plain_sig = unlock(m_op.sign(encoded.ptr, encoded.length, rng)); 211 212 assert(selfTestSignature(encoded, plain_sig), "Signature was consistent"); 213 214 if (m_op.messageParts() == 1 || m_sig_format == IEEE_1363) 215 return plain_sig.move(); 216 217 if (m_sig_format == DER_SEQUENCE) 218 { 219 if (plain_sig.length % m_op.messageParts()) 220 throw new EncodingError("PKSigner: strange signature size found"); 221 const size_t SIZE_OF_PART = plain_sig.length / m_op.messageParts(); 222 223 Vector!(RefCounted!BigInt) sig_parts = Vector!(RefCounted!BigInt)(m_op.messageParts()); 224 for (size_t j = 0; j != sig_parts.length; ++j) 225 sig_parts[j].binaryDecode(&plain_sig[SIZE_OF_PART*j], SIZE_OF_PART); 226 227 return DEREncoder() 228 .startCons(ASN1Tag.SEQUENCE) 229 .encodeList(sig_parts) 230 .endCons() 231 .getContentsUnlocked(); 232 } 233 else 234 throw new EncodingError("PKSigner: Unknown signature format " ~ to!string(m_sig_format)); 235 } 236 237 /** 238 * Set the output format of the signature. 239 * 240 * Params: 241 * format = the signature format to use 242 */ 243 void setOutputFormat(SignatureFormat format) { m_sig_format = format; } 244 245 /** 246 * Construct a PK Signer. 247 * 248 * Params: 249 * key = the key to use inside this signer 250 * emsa_name = the EMSA to use, e.g. "EMSA1(SHA-224)". 251 * format = the signature format to use 252 * prot = says if fault protection should be enabled 253 */ 254 this(in PrivateKey key, in string emsa_name, 255 SignatureFormat format = IEEE_1363, 256 FaultProtection prot = DISABLE_FAULT_PROTECTION) 257 { 258 AlgorithmFactory af = globalState().algorithmFactory(); 259 260 RandomNumberGenerator rng = globalState().globalRng(); 261 262 foreach (Engine engine; af.engines[]) { 263 if (!m_op) 264 m_op = engine.getSignatureOp(key, rng); 265 if (!m_verify_op && prot == ENABLE_FAULT_PROTECTION) 266 m_verify_op = engine.getVerifyOp(key, rng); 267 if (m_op && (m_verify_op || prot == DISABLE_FAULT_PROTECTION)) 268 break; 269 } 270 scope(failure) { m_op.free(); m_verify_op.free(); } 271 272 if (!m_op || (!m_verify_op && prot == ENABLE_FAULT_PROTECTION)) 273 throw new LookupError("Signing with " ~ key.algoName ~ " not supported"); 274 275 m_emsa = getEmsa(emsa_name); 276 m_sig_format = format; 277 } 278 private: 279 /* 280 * Check the signature we just created, to help prevent fault attacks 281 */ 282 bool selfTestSignature()(auto const ref Vector!ubyte msg, auto const ref Vector!ubyte sig) const 283 { 284 if (!m_verify_op) 285 return true; // checking disabled, assume ok 286 287 if (m_verify_op.withRecovery()) 288 { 289 Vector!ubyte recovered = unlock((cast(Verification)*m_verify_op).verifyMr(sig.ptr, sig.length)); 290 291 if (msg.length > recovered.length) 292 { 293 size_t extra_0s = msg.length - recovered.length; 294 295 foreach (size_t i; 0 .. extra_0s) 296 if (msg[i] != 0) 297 return false; 298 299 return sameMem(&msg[extra_0s], recovered.ptr, recovered.length); 300 } 301 302 return (recovered == msg); 303 } 304 else 305 return (cast(Verification)*m_verify_op).verify(msg.ptr, msg.length, sig.ptr, sig.length); 306 } 307 308 Unique!Signature m_op; 309 Unique!Verification m_verify_op; 310 Unique!EMSA m_emsa; 311 SignatureFormat m_sig_format; 312 } 313 314 /** 315 * Public Key Verifier. Use the verifyMessage() functions for small 316 * messages. Use multiple calls update() to process large messages and 317 * verify the signature by finally calling checkSignature(). 318 */ 319 struct PKVerifier 320 { 321 public: 322 /** 323 * Verify a signature. 324 * 325 * Params: 326 * msg = the message that the signature belongs to, as a ubyte array 327 * msg_length = the length of the above ubyte array msg 328 * sig = the signature as a ubyte array 329 * sig_length = the length of the above ubyte array sig 330 * Returns: true if the signature is valid 331 */ 332 bool verifyMessage(const(ubyte)* msg, size_t msg_length, 333 const(ubyte)* sig, size_t sig_length) 334 { 335 update(msg, msg_length); 336 //logTrace("Done update"); 337 return checkSignature(sig, sig_length); 338 } 339 340 /** 341 * Verify a signature. 342 * 343 * Params: 344 * msg = the message that the signature belongs to 345 * sig = the signature 346 * Returns: true if the signature is valid 347 */ 348 bool verifyMessage(Alloc, Alloc2)(auto const ref Vector!( ubyte, Alloc ) msg, 349 auto const ref Vector!( ubyte, Alloc2 ) sig) 350 { 351 return verifyMessage(msg.ptr, msg.length, sig.ptr, sig.length); 352 } 353 354 /// ditto 355 bool verifyMessage(Alloc, Alloc2)(auto const ref RefCounted!(Vector!( ubyte, Alloc ), Alloc) msg, 356 auto const ref RefCounted!(Vector!( ubyte, Alloc2 ), Alloc2) sig) 357 { 358 return verifyMessage(msg.ptr, msg.length, sig.ptr, sig.length); 359 } 360 361 /** 362 * Add a message part (single ubyte) of the message corresponding to the 363 * signature to be verified. 364 * 365 * Params: 366 * input = the ubyte to add 367 */ 368 void update(ubyte input) { update(&input, 1); } 369 370 /** 371 * Add a message part of the message corresponding to the 372 * signature to be verified. 373 * 374 * Params: 375 * input = the new message part as a ubyte array 376 * length = the length of the above ubyte array 377 */ 378 void update(const(ubyte)* input, size_t length) 379 { 380 m_emsa.update(input, length); 381 } 382 383 /** 384 * Add a message part of the message corresponding to the 385 * signature to be verified. 386 * 387 * Params: 388 * input = the new message part 389 */ 390 void update(const ref Vector!ubyte input) 391 { update(input.ptr, input.length); } 392 393 /** 394 * Check the signature of the buffered message, i.e. the one build 395 * by successive calls to update. 396 * 397 * Params: 398 * sig = the signature to be verified as a ubyte array 399 * length = the length of the above ubyte array 400 * Returns: true if the signature is valid, false otherwise 401 */ 402 bool checkSignature(const(ubyte)* sig, size_t length) 403 { 404 try { 405 if (m_sig_format == IEEE_1363) 406 return validateSignature(m_emsa.rawData(), sig, length); 407 else if (m_sig_format == DER_SEQUENCE) 408 { 409 BERDecoder decoder = BERDecoder(sig, length); 410 BERDecoder ber_sig = decoder.startCons(ASN1Tag.SEQUENCE); 411 412 size_t count = 0; 413 SecureVector!ubyte real_sig; 414 while (ber_sig.moreItems()) 415 { 416 BigInt sig_part; 417 ber_sig.decode(sig_part); 418 real_sig ~= BigInt.encode1363(sig_part, m_op.messagePartSize()); 419 ++count; 420 } 421 422 if (count != m_op.messageParts()) 423 throw new DecodingError("PKVerifier: signature size invalid"); 424 425 return validateSignature(m_emsa.rawData(), real_sig.ptr, real_sig.length); 426 } 427 else 428 throw new DecodingError("PKVerifier: Unknown signature format " ~ to!string(m_sig_format)); 429 } 430 catch(InvalidArgument) { return false; } 431 } 432 433 /** 434 * Check the signature of the buffered message, i.e. the one build 435 * by successive calls to update. 436 * 437 * Params: 438 * sig = the signature to be verified 439 * Returns: true if the signature is valid, false otherwise 440 */ 441 bool checkSignature(Alloc)(auto const ref Vector!( ubyte, Alloc ) sig) 442 { 443 return checkSignature(sig.ptr, sig.length); 444 } 445 446 /** 447 * Set the format of the signatures fed to this verifier. 448 * 449 * Params: 450 * format = the signature format to use 451 */ 452 void setInputFormat(SignatureFormat format) 453 { 454 if (m_op.messageParts() == 1 && format != IEEE_1363) 455 throw new InvalidState("PKVerifier: This algorithm always uses IEEE 1363"); 456 m_sig_format = format; 457 } 458 459 /** 460 * Construct a PK Verifier. 461 * 462 * Params: 463 * key = the public key to verify against 464 * emsa_name = the EMSA to use (eg "EMSA3(SHA-1)") 465 * format = the signature format to use 466 */ 467 this(in PublicKey key, in string emsa_name, SignatureFormat format = IEEE_1363) 468 { 469 AlgorithmFactory af = globalState().algorithmFactory(); 470 RandomNumberGenerator rng = globalState().globalRng(); 471 472 foreach (Engine engine; af.engines[]) { 473 m_op = engine.getVerifyOp(key, rng); 474 if (m_op) 475 break; 476 } 477 scope(failure) m_op.free(); 478 if (!m_op) 479 throw new LookupError("Verification with " ~ key.algoName ~ " not supported"); 480 m_emsa = getEmsa(emsa_name); 481 m_sig_format = format; 482 } 483 484 private: 485 bool validateSignature()(auto const ref SecureVector!ubyte msg, const(ubyte)* sig, size_t sig_len) 486 { 487 if (m_op.withRecovery()) 488 { 489 SecureVector!ubyte output_of_key = m_op.verifyMr(sig, sig_len); 490 return m_emsa.verify(output_of_key, msg, m_op.maxInputBits()); 491 } 492 else 493 { 494 RandomNumberGenerator rng = globalState().globalRng(); 495 496 SecureVector!ubyte encoded = m_emsa.encodingOf(msg, m_op.maxInputBits(), rng); 497 498 return m_op.verify(encoded.ptr, encoded.length, sig, sig_len); 499 } 500 } 501 502 Unique!Verification m_op; 503 Unique!EMSA m_emsa; 504 SignatureFormat m_sig_format; 505 } 506 507 /** 508 * Key used for key agreement 509 */ 510 class PKKeyAgreement 511 { 512 public: 513 514 /* 515 * Perform Key Agreement Operation 516 * Params: 517 * key_len = the desired key output size 518 * input = the other parties key 519 * in_len = the length of in in bytes 520 * params = extra derivation params 521 * params_len = the length of params in bytes 522 */ 523 SymmetricKey deriveKey(size_t key_len, const(ubyte)* input, 524 size_t in_len, const(ubyte)* params, 525 size_t params_len) const 526 { 527 SecureVector!ubyte z = (cast(KeyAgreement)*m_op).agree(input, in_len); 528 529 if (!m_kdf) 530 return SymmetricKey(z); 531 532 return SymmetricKey(m_kdf.deriveKey(key_len, z, params, params_len)); 533 } 534 535 /* 536 * Perform Key Agreement Operation 537 * Params: 538 * key_len = the desired key output size 539 * input = the other parties key 540 * in_len = the length of in in bytes 541 * params = extra derivation params 542 * params_len = the length of params in bytes 543 */ 544 SymmetricKey deriveKey()(size_t key_len, auto const ref Vector!ubyte input, 545 const(ubyte)* params, size_t params_len) const 546 { 547 return deriveKey(key_len, input.ptr, input.length, params, params_len); 548 } 549 550 /* 551 * Perform Key Agreement Operation 552 * Params: 553 * key_len = the desired key output size 554 * input = the other parties key 555 * in_len = the length of in in bytes 556 * params = extra derivation params 557 */ 558 SymmetricKey deriveKey(size_t key_len, const(ubyte)* input, size_t in_len, in string params = "") const 559 { 560 return deriveKey(key_len, input, in_len, cast(const(ubyte)*)(params.ptr), params.length); 561 } 562 563 /* 564 * Perform Key Agreement Operation 565 * Params: 566 * key_len = the desired key output size 567 * input = the other parties key 568 * params = extra derivation params 569 */ 570 SymmetricKey deriveKey()(size_t key_len, 571 auto const ref Vector!ubyte input, 572 in string params = "") const 573 { 574 return deriveKey(key_len, input.ptr, input.length, 575 cast(const(ubyte)*)(params.ptr), 576 params.length); 577 } 578 579 /** 580 * Construct a PK Key Agreement. 581 * 582 * Params: 583 * key = the key to use 584 * kdf_name = name of the KDF to use (or 'Raw' for no KDF) 585 */ 586 this(in PKKeyAgreementKey key, in string kdf_name) 587 { 588 AlgorithmFactory af = globalState().algorithmFactory(); 589 RandomNumberGenerator rng = globalState().globalRng(); 590 591 foreach (Engine engine; af.engines[]) 592 { 593 m_op = engine.getKeyAgreementOp(key, rng); 594 if (m_op) 595 break; 596 } 597 598 if (!m_op) 599 throw new LookupError("Key agreement with " ~ key.algoName ~ " not supported"); 600 601 m_kdf = getKdf(kdf_name); 602 } 603 private: 604 Unique!KeyAgreement m_op; 605 Unique!KDF m_kdf; 606 } 607 608 /** 609 * Encryption with an MR algorithm and an EME. 610 */ 611 class PKEncryptorEME : PKEncryptor 612 { 613 public: 614 /* 615 * Return the max size, in bytes, of a message 616 */ 617 override size_t maximumInputSize() const 618 { 619 if (!m_eme) 620 return (m_op.maxInputBits() / 8); 621 else 622 return m_eme.maximumInputSize(m_op.maxInputBits()); 623 } 624 625 /** 626 * Construct an instance. 627 * 628 * Params: 629 * key = the key to use inside the decryptor 630 * eme_name = the EME to use 631 */ 632 this(in PublicKey key, in string eme_name) 633 { 634 635 AlgorithmFactory af = globalState().algorithmFactory(); 636 RandomNumberGenerator rng = globalState().globalRng(); 637 638 foreach (Engine engine; af.engines[]) { 639 m_op = engine.getEncryptionOp(key, rng); 640 if (m_op) 641 break; 642 } 643 644 if (!m_op) 645 throw new LookupError("Encryption with " ~ key.algoName ~ " not supported"); 646 647 m_eme = getEme(eme_name); 648 } 649 650 protected: 651 override Vector!ubyte enc(const(ubyte)* input, size_t length, RandomNumberGenerator rng) const 652 { 653 if (m_eme) 654 { 655 SecureVector!ubyte encoded = m_eme.encode(input, length, m_op.maxInputBits(), rng); 656 657 if (8*(encoded.length - 1) + highBit(encoded[0]) > m_op.maxInputBits()) 658 throw new InvalidArgument("PKEncryptorEME: Input is too large"); 659 660 return unlock((cast(Encryption)*m_op).encrypt(encoded.ptr, encoded.length, rng)); 661 } 662 else 663 { 664 if (8*(length - 1) + highBit(input[0]) > m_op.maxInputBits()) 665 throw new InvalidArgument("PKEncryptorEME: Input is too large"); 666 667 return unlock((cast(Encryption)*m_op).encrypt(input, length, rng)); 668 } 669 } 670 671 private: 672 Unique!Encryption m_op; 673 Unique!EME m_eme; 674 } 675 676 /** 677 * Decryption with an MR algorithm and an EME. 678 */ 679 class PKDecryptorEME : PKDecryptor 680 { 681 public: 682 /** 683 * Construct an instance. 684 * 685 * Params: 686 * key = the key to use inside the encryptor 687 * eme_name = the EME to use 688 */ 689 this(in PrivateKey key, in string eme_name) 690 { 691 AlgorithmFactory af = globalState().algorithmFactory(); 692 RandomNumberGenerator rng = globalState().globalRng(); 693 694 foreach (Engine engine; af.engines[]) 695 { 696 m_op = engine.getDecryptionOp(key, rng); 697 if (m_op) 698 break; 699 } 700 701 if (!m_op) 702 throw new LookupError("Decryption with " ~ key.algoName ~ " not supported"); 703 704 m_eme = getEme(eme_name); 705 } 706 707 protected: 708 /* 709 * Decrypt a message 710 */ 711 override SecureVector!ubyte dec(const(ubyte)* msg, size_t length) const 712 { 713 try { 714 SecureVector!ubyte decrypted = (cast(Decryption)*m_op).decrypt(msg, length); 715 if (m_eme) 716 return m_eme.decode(decrypted, m_op.maxInputBits()); 717 else 718 return decrypted.move(); 719 } 720 catch(InvalidArgument) 721 { 722 throw new DecodingError("PKDecryptorEME: Input is invalid"); 723 } 724 } 725 726 private: 727 Unique!Decryption m_op; 728 Unique!EME m_eme; 729 }