diff options
-rw-r--r-- | src/pbe/get_pbe.cpp | 40 | ||||
-rw-r--r-- | src/pbe/pbes1/pbes1.cpp | 75 | ||||
-rw-r--r-- | src/pbe/pbes1/pbes1.h | 17 |
3 files changed, 94 insertions, 38 deletions
diff --git a/src/pbe/get_pbe.cpp b/src/pbe/get_pbe.cpp index 103e64a0c..d5960f283 100644 --- a/src/pbe/get_pbe.cpp +++ b/src/pbe/get_pbe.cpp @@ -6,6 +6,8 @@ #include <botan/get_pbe.h> #include <botan/oids.h> #include <botan/scan_name.h> +#include <botan/parsing.h> +#include <botan/libstate.h> #if defined(BOTAN_HAS_PBE_PKCS_V15) #include <botan/pbes1.h> @@ -17,6 +19,40 @@ namespace Botan { +namespace { + +PBE* make_pbe_pkcs15(const std::string& cipher, + const std::string& digest, + Cipher_Dir direction) + { + std::vector<std::string> cipher_spec = split_on(cipher, '/'); + if(cipher_spec.size() != 2) + throw Invalid_Argument("PBE-PKCS5 v1.5: Invalid cipher spec " + cipher); + + const std::string cipher_algo = global_state().deref_alias(cipher_spec[0]); + const std::string cipher_mode = cipher_spec[1]; + + if(cipher_mode != "CBC") + throw Invalid_Argument("PBE-PKCS5 v1.5: Invalid cipher " + cipher); + + Algorithm_Factory& af = global_state().algorithm_factory(); + + const BlockCipher* block_cipher = af.make_block_cipher(cipher_algo); + if(!block_cipher) + throw Algorithm_Not_Found(cipher_algo); + + const HashFunction* hash_function = af.make_hash_function(digest); + if(!hash_function) + throw Algorithm_Not_Found(digest); + + return new PBE_PKCS5v15(block_cipher->clone(), + hash_function->clone(), + direction); + + } + +} + /************************************************* * Get an encryption PBE, set new parameters * *************************************************/ @@ -33,7 +69,7 @@ PBE* get_pbe(const std::string& pbe_name) #if defined(BOTAN_HAS_PBE_PKCS_V15) if(pbe == "PBE-PKCS5v15") - return new PBE_PKCS5v15(digest, cipher, ENCRYPTION); + return make_pbe_pkcs15(cipher, digest, ENCRYPTION); #endif #if defined(BOTAN_HAS_PBE_PKCS_V20) @@ -60,7 +96,7 @@ PBE* get_pbe(const OID& pbe_oid, DataSource& params) const std::string digest = request.arg(0); const std::string cipher = request.arg(1); - PBE* pbe = new PBE_PKCS5v15(digest, cipher, DECRYPTION); + PBE* pbe = make_pbe_pkcs15(cipher, digest, DECRYPTION); pbe->decode_params(params); return pbe; } diff --git a/src/pbe/pbes1/pbes1.cpp b/src/pbe/pbes1/pbes1.cpp index 4119f1a1e..c663865cf 100644 --- a/src/pbe/pbes1/pbes1.cpp +++ b/src/pbe/pbes1/pbes1.cpp @@ -7,11 +7,8 @@ #include <botan/pbkdf1.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> -#include <botan/parsing.h> -#include <botan/lookup.h> -#include <botan/libstate.h> +#include <botan/cbc.h> #include <algorithm> -#include <memory> namespace Botan { @@ -34,7 +31,15 @@ void PBE_PKCS5v15::write(const byte input[], u32bit length) *************************************************/ void PBE_PKCS5v15::start_msg() { - pipe.append(get_cipher(cipher, key, iv, direction)); + if(direction == ENCRYPTION) + pipe.append(new CBC_Encryption(block_cipher->clone(), + new PKCS7_Padding, + key, iv)); + else + pipe.append(new CBC_Decryption(block_cipher->clone(), + new PKCS7_Padding, + key, iv)); + pipe.start_msg(); if(pipe.message_count() > 1) pipe.set_default_msg(pipe.default_msg() + 1); @@ -71,7 +76,7 @@ void PBE_PKCS5v15::flush_pipe(bool safe_to_skip) *************************************************/ void PBE_PKCS5v15::set_key(const std::string& passphrase) { - PKCS5_PBKDF1 pbkdf(get_hash(digest)); + PKCS5_PBKDF1 pbkdf(hash_function->clone()); pbkdf.set_iterations(iterations); pbkdf.change_salt(salt, salt.size()); @@ -126,17 +131,21 @@ void PBE_PKCS5v15::decode_params(DataSource& source) OID PBE_PKCS5v15::get_oid() const { const OID base_pbes1_oid("1.2.840.113549.1.5"); - if(cipher == "DES/CBC" && digest == "MD2") + + const std::string cipher = block_cipher->name(); + const std::string digest = hash_function->name(); + + if(cipher == "DES" && digest == "MD2") return (base_pbes1_oid + 1); - else if(cipher == "DES/CBC" && digest == "MD5") + else if(cipher == "DES" && digest == "MD5") return (base_pbes1_oid + 3); - else if(cipher == "DES/CBC" && digest == "SHA-160") + else if(cipher == "DES" && digest == "SHA-160") return (base_pbes1_oid + 10); - else if(cipher == "RC2/CBC" && digest == "MD2") + else if(cipher == "RC2" && digest == "MD2") return (base_pbes1_oid + 4); - else if(cipher == "RC2/CBC" && digest == "MD5") + else if(cipher == "RC2" && digest == "MD5") return (base_pbes1_oid + 6); - else if(cipher == "RC2/CBC" && digest == "SHA-160") + else if(cipher == "RC2" && digest == "SHA-160") return (base_pbes1_oid + 11); else throw Internal_Error("PBE-PKCS5 v1.5: get_oid() has run out of options"); @@ -145,27 +154,29 @@ OID PBE_PKCS5v15::get_oid() const /************************************************* * PKCS#5 v1.5 PBE Constructor * *************************************************/ -PBE_PKCS5v15::PBE_PKCS5v15(const std::string& d_algo, - const std::string& c_algo, Cipher_Dir dir) : - direction(dir), - digest(global_state().deref_alias(d_algo)), - cipher(c_algo) +PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + Cipher_Dir dir) : + direction(dir), block_cipher(cipher), hash_function(hash) + { + if(cipher->name() != "DES" && cipher->name() != "RC2") + { + throw Invalid_Argument("PBE_PKCS5v1.5: Unknown cipher " + + cipher->name()); + } + + if(hash->name() != "MD2" && hash->name() != "MD5" && + hash->name() != "SHA-160") + { + throw Invalid_Argument("PBE_PKCS5v1.5: Unknown hash " + + hash->name()); + } + } + +PBE_PKCS5v15::~PBE_PKCS5v15() { - std::vector<std::string> cipher_spec = split_on(c_algo, '/'); - if(cipher_spec.size() != 2) - throw Invalid_Argument("PBE-PKCS5 v1.5: Invalid cipher spec " + c_algo); - const std::string cipher_algo = global_state().deref_alias(cipher_spec[0]); - const std::string cipher_mode = cipher_spec[1]; - - if(!have_block_cipher(cipher_algo)) - throw Algorithm_Not_Found(cipher_algo); - if(!have_hash(digest)) - throw Algorithm_Not_Found(digest); - - if((cipher_algo != "DES" && cipher_algo != "RC2") || (cipher_mode != "CBC")) - throw Invalid_Argument("PBE-PKCS5 v1.5: Invalid cipher " + cipher); - if(digest != "MD2" && digest != "MD5" && digest != "SHA-160") - throw Invalid_Argument("PBE-PKCS5 v1.5: Invalid digest " + digest); + delete block_cipher; + delete hash_function; } } diff --git a/src/pbe/pbes1/pbes1.h b/src/pbe/pbes1/pbes1.h index 78363c68b..2c96a8d1e 100644 --- a/src/pbe/pbes1/pbes1.h +++ b/src/pbe/pbes1/pbes1.h @@ -7,7 +7,8 @@ #define BOTAN_PBE_PKCS_V15_H__ #include <botan/pbe.h> -#include <botan/sym_algo.h> +#include <botan/block_cipher.h> +#include <botan/hash.h> #include <botan/pipe.h> namespace Botan { @@ -21,7 +22,12 @@ class BOTAN_DLL PBE_PKCS5v15 : public PBE void write(const byte[], u32bit); void start_msg(); void end_msg(); - PBE_PKCS5v15(const std::string&, const std::string&, Cipher_Dir); + + PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + Cipher_Dir); + + ~PBE_PKCS5v15(); private: void set_key(const std::string&); void new_params(RandomNumberGenerator& rng); @@ -30,8 +36,11 @@ class BOTAN_DLL PBE_PKCS5v15 : public PBE OID get_oid() const; void flush_pipe(bool); - const Cipher_Dir direction; - const std::string digest, cipher; + + Cipher_Dir direction; + BlockCipher* block_cipher; + HashFunction* hash_function; + SecureVector<byte> salt, key, iv; u32bit iterations; Pipe pipe; |