diff options
author | lloyd <[email protected]> | 2010-03-21 21:54:47 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-03-21 21:54:47 +0000 |
commit | c23ae85c0529071b3170e88d361342d6a792f417 (patch) | |
tree | 5f731b328266809df9fd82cd1e1e5d4dc6c8e88b /src | |
parent | 8b0d3575e794073f6e6658544d8167e399762ce0 (diff) |
KeyPair::check_key's behavior of throwing an exception upon failure was
not useful; in all cases, we immediately caught it and then returned
false.
Modify as follows:
- Create the pubkey objects inside the checking code, so calling code
doesn't need to do it.
- Return true/false for pass/fail
Also add consistency checking for ECDSA keys
Diffstat (limited to 'src')
-rw-r--r-- | src/pubkey/dsa/dsa.cpp | 13 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa.cpp | 13 | ||||
-rw-r--r-- | src/pubkey/ecdsa/ecdsa.h | 2 | ||||
-rw-r--r-- | src/pubkey/elgamal/elgamal.cpp | 16 | ||||
-rw-r--r-- | src/pubkey/keypair/keypair.cpp | 51 | ||||
-rw-r--r-- | src/pubkey/keypair/keypair.h | 44 | ||||
-rw-r--r-- | src/pubkey/nr/nr.cpp | 16 | ||||
-rw-r--r-- | src/pubkey/rsa/rsa.cpp | 16 | ||||
-rw-r--r-- | src/pubkey/rw/rw.cpp | 16 |
9 files changed, 75 insertions, 112 deletions
diff --git a/src/pubkey/dsa/dsa.cpp b/src/pubkey/dsa/dsa.cpp index 7f0ab0bfa..7eefa5923 100644 --- a/src/pubkey/dsa/dsa.cpp +++ b/src/pubkey/dsa/dsa.cpp @@ -62,18 +62,7 @@ bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const if(!strong) return true; - try - { - PK_Signer this_signer(*this, "EMSA1(SHA-1)"); - PK_Verifier this_verifier(*this, "EMSA1(SHA-1)"); - KeyPair::check_key(rng, this_signer, this_verifier); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; + return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); } DSA_Signature_Operation::DSA_Signature_Operation(const DSA_PrivateKey& dsa) : diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 40ae7c3b9..8915a598e 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -8,9 +8,22 @@ */ #include <botan/ecdsa.h> +#include <botan/keypair.h> namespace Botan { +bool ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, + bool strong) const + { + if(!public_point().on_the_curve()) + return false; + + if(!strong) + return true; + + return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); + } + ECDSA_Signature_Operation::ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa) : base_point(ecdsa.domain().get_base_point()), order(ecdsa.domain().get_order()), diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h index cb4893002..62bd007f9 100644 --- a/src/pubkey/ecdsa/ecdsa.h +++ b/src/pubkey/ecdsa/ecdsa.h @@ -85,6 +85,8 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, */ ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) : EC_PrivateKey(domain, x) {} + + bool check_key(RandomNumberGenerator& rng, bool) const; }; class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature diff --git a/src/pubkey/elgamal/elgamal.cpp b/src/pubkey/elgamal/elgamal.cpp index 5640a4400..a264d209b 100644 --- a/src/pubkey/elgamal/elgamal.cpp +++ b/src/pubkey/elgamal/elgamal.cpp @@ -64,21 +64,7 @@ bool ElGamal_PrivateKey::check_key(RandomNumberGenerator& rng, if(!strong) return true; - try - { - PK_Encryptor_EME this_encryptor(*this, "EME1(SHA-1)"); - PK_Decryptor_EME this_decryptor(*this, "EME1(SHA-1)"); - - KeyPair::check_key(rng, - this_encryptor, - this_decryptor); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; + return KeyPair::encryption_consistency_check(rng, *this, "EME1(SHA-1)"); } ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key) diff --git a/src/pubkey/keypair/keypair.cpp b/src/pubkey/keypair/keypair.cpp index d54d8e442..c837bc1f6 100644 --- a/src/pubkey/keypair/keypair.cpp +++ b/src/pubkey/keypair/keypair.cpp @@ -6,6 +6,7 @@ */ #include <botan/keypair.h> +#include <botan/pubkey.h> namespace Botan { @@ -14,32 +15,42 @@ namespace KeyPair { /* * Check an encryption key pair for consistency */ -void check_key(RandomNumberGenerator& rng, - PK_Encryptor& encryptor, - PK_Decryptor& decryptor) +bool encryption_consistency_check(RandomNumberGenerator& rng, + const Private_Key& key, + const std::string& padding) { + PK_Encryptor_EME encryptor(key, padding); + PK_Decryptor_EME decryptor(key, padding); + + /* + Weird corner case, if the key is too small to encrypt anything at + all. This can happen with very small RSA keys with PSS + */ if(encryptor.maximum_input_size() == 0) - return; + return true; - SecureVector<byte> message(encryptor.maximum_input_size() - 1); - rng.randomize(message, message.size()); + SecureVector<byte> plaintext(encryptor.maximum_input_size() - 1); + rng.randomize(plaintext, plaintext.size()); + + SecureVector<byte> ciphertext = encryptor.encrypt(plaintext, rng); + if(ciphertext == plaintext) + return false; - SecureVector<byte> ciphertext = encryptor.encrypt(message, rng); - if(ciphertext == message) - throw Self_Test_Failure("Encryption key pair consistency failure"); + SecureVector<byte> decrypted = decryptor.decrypt(ciphertext); - SecureVector<byte> message2 = decryptor.decrypt(ciphertext); - if(message != message2) - throw Self_Test_Failure("Encryption key pair consistency failure"); + return (plaintext == decrypted); } /* * Check a signature key pair for consistency */ -void check_key(RandomNumberGenerator& rng, - PK_Signer& signer, - PK_Verifier& verifier) +bool signature_consistency_check(RandomNumberGenerator& rng, + const Private_Key& key, + const std::string& padding) { + PK_Signer signer(key, padding); + PK_Verifier verifier(key, padding); + SecureVector<byte> message(16); rng.randomize(message, message.size()); @@ -51,15 +62,19 @@ void check_key(RandomNumberGenerator& rng, } catch(Encoding_Error) { - return; + return false; } if(!verifier.verify_message(message, signature)) - throw Self_Test_Failure("Signature key pair consistency failure"); + return false; + // Now try to check a corrupt signature, ensure it does not succeed ++message[0]; + if(verifier.verify_message(message, signature)) - throw Self_Test_Failure("Signature key pair consistency failure"); + return false; + + return true; } } diff --git a/src/pubkey/keypair/keypair.h b/src/pubkey/keypair/keypair.h index 22dcca0ea..c7b128e53 100644 --- a/src/pubkey/keypair/keypair.h +++ b/src/pubkey/keypair/keypair.h @@ -1,44 +1,44 @@ /* * Keypair Checks -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_KEYPAIR_H__ -#define BOTAN_KEYPAIR_H__ +#ifndef BOTAN_KEYPAIR_CHECKS_H__ +#define BOTAN_KEYPAIR_CHECKS_H__ -#include <botan/pubkey.h> +#include <botan/pk_keys.h> namespace Botan { namespace KeyPair { /** -* Tests whether the specified encryptor and decryptor are related to each other, -* i.e. whether encrypting with the encryptor and consecutive decryption leads to -* the original plaintext. +* Tests whether the key is consistent for encryption; whether +* encrypting and then decrypting gives to the original plaintext. * @param rng the rng to use -* @param enc the encryptor to test -* @param dec the decryptor to test -* @throw Self_Test_Failure if the arguments are not related to each other +* @param key the key to test +* @param padding the encryption padding method to use +* @return true if consistent otherwise false */ -BOTAN_DLL void check_key(RandomNumberGenerator& rng, - PK_Encryptor& enc, - PK_Decryptor& dec); +BOTAN_DLL bool +encryption_consistency_check(RandomNumberGenerator& rng, + const Private_Key& key, + const std::string& padding); /** -* Tests whether the specified signer and verifier are related to each other, -* i.e. whether a signature created with the signer and can be -* successfully verified with the verifier. +* Tests whether the key is consistent for signatures; whether a +* signature can be created and then verified * @param rng the rng to use -* @param sig the signer to test -* @param ver the verifier to test -* @throw Self_Test_Failure if the arguments are not related to each other +* @param key the key to test +* @param padding the signature padding method to use +* @return true if consistent otherwise false */ -BOTAN_DLL void check_key(RandomNumberGenerator& rng, - PK_Signer& sig, - PK_Verifier& ver); +BOTAN_DLL bool +signature_consistency_check(RandomNumberGenerator& rng, + const Private_Key& key, + const std::string& padding); } diff --git a/src/pubkey/nr/nr.cpp b/src/pubkey/nr/nr.cpp index f9ba37c41..3c5b71ad2 100644 --- a/src/pubkey/nr/nr.cpp +++ b/src/pubkey/nr/nr.cpp @@ -68,21 +68,7 @@ bool NR_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const if(!strong) return true; - try - { - PK_Signer this_signer(*this, "EMSA1(SHA-1)"); - PK_Verifier this_verifier(*this, "EMSA1(SHA-1)"); - - KeyPair::check_key(rng, - this_signer, - this_verifier); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; + return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); } NR_Signature_Operation::NR_Signature_Operation(const NR_PrivateKey& nr) : diff --git a/src/pubkey/rsa/rsa.cpp b/src/pubkey/rsa/rsa.cpp index 3222b5113..133164c31 100644 --- a/src/pubkey/rsa/rsa.cpp +++ b/src/pubkey/rsa/rsa.cpp @@ -55,21 +55,7 @@ bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const if((e * d) % lcm(p - 1, q - 1) != 1) return false; - try - { - PK_Signer this_signer(*this, "EMSA4(SHA-1)"); - PK_Verifier this_verifier(*this, "EMSA4(SHA-1)"); - - KeyPair::check_key(rng, - this_signer, - this_verifier); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; + return KeyPair::signature_consistency_check(rng, *this, "EMSA4(SHA-1)"); } RSA_Private_Operation::RSA_Private_Operation(const RSA_PrivateKey& rsa) : diff --git a/src/pubkey/rw/rw.cpp b/src/pubkey/rw/rw.cpp index 508244112..91cebc5a8 100644 --- a/src/pubkey/rw/rw.cpp +++ b/src/pubkey/rw/rw.cpp @@ -56,21 +56,7 @@ bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const if((e * d) % (lcm(p - 1, q - 1) / 2) != 1) return false; - try - { - PK_Signer this_signer(*this, "EMSA2(SHA-1)"); - PK_Verifier this_verifier(*this, "EMSA2(SHA-1)"); - - KeyPair::check_key(rng, - this_signer, - this_verifier); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; + return KeyPair::signature_consistency_check(rng, *this, "EMSA2(SHA-1)"); } RW_Signature_Operation::RW_Signature_Operation(const RW_PrivateKey& rw) : |