diff options
Diffstat (limited to 'src/pbe')
-rw-r--r-- | src/pbe/get_pbe.cpp | 29 | ||||
-rw-r--r-- | src/pbe/get_pbe.h | 9 | ||||
-rw-r--r-- | src/pbe/pbe.h | 18 | ||||
-rw-r--r-- | src/pbe/pbes1/pbes1.cpp | 155 | ||||
-rw-r--r-- | src/pbe/pbes1/pbes1.h | 31 | ||||
-rw-r--r-- | src/pbe/pbes2/pbes2.cpp | 142 | ||||
-rw-r--r-- | src/pbe/pbes2/pbes2.h | 19 |
7 files changed, 207 insertions, 196 deletions
diff --git a/src/pbe/get_pbe.cpp b/src/pbe/get_pbe.cpp index 3217101ef..9ce830639 100644 --- a/src/pbe/get_pbe.cpp +++ b/src/pbe/get_pbe.cpp @@ -24,7 +24,10 @@ namespace Botan { /* * Get an encryption PBE, set new parameters */ -PBE* get_pbe(const std::string& algo_spec) +PBE* get_pbe(const std::string& algo_spec, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng) { SCAN_Name request(algo_spec); @@ -59,13 +62,18 @@ PBE* get_pbe(const std::string& algo_spec) if(pbe == "PBE-PKCS5v15") return new PBE_PKCS5v15(block_cipher->clone(), hash_function->clone(), - ENCRYPTION); + passphrase, + msec, + rng); #endif #if defined(BOTAN_HAS_PBE_PKCS_V20) if(pbe == "PBE-PKCS5v20") return new PBE_PKCS5v20(block_cipher->clone(), - hash_function->clone()); + hash_function->clone(), + passphrase, + msec, + rng); #endif throw Algorithm_Not_Found(algo_spec); @@ -74,7 +82,9 @@ PBE* get_pbe(const std::string& algo_spec) /* * Get a decryption PBE, decode parameters */ -PBE* get_pbe(const OID& pbe_oid, DataSource& params) +PBE* get_pbe(const OID& pbe_oid, + const std::vector<byte>& params, + const std::string& passphrase) { SCAN_Name request(OIDS::lookup(pbe_oid)); @@ -111,17 +121,16 @@ PBE* get_pbe(const OID& pbe_oid, DataSource& params) if(!hash_function) throw Algorithm_Not_Found(digest_name); - PBE* pbe = new PBE_PKCS5v15(block_cipher->clone(), - hash_function->clone(), - DECRYPTION); - pbe->decode_params(params); - return pbe; + return new PBE_PKCS5v15(block_cipher->clone(), + hash_function->clone(), + params, + passphrase); } #endif #if defined(BOTAN_HAS_PBE_PKCS_V20) if(pbe == "PBE-PKCS5v20") - return new PBE_PKCS5v20(params); + return new PBE_PKCS5v20(params, passphrase); #endif throw Algorithm_Not_Found(pbe_oid.as_string()); diff --git a/src/pbe/get_pbe.h b/src/pbe/get_pbe.h index 73c53497c..719b92c30 100644 --- a/src/pbe/get_pbe.h +++ b/src/pbe/get_pbe.h @@ -9,6 +9,7 @@ #define BOTAN_LOOKUP_PBE_H__ #include <botan/pbe.h> +#include <vector> #include <string> namespace Botan { @@ -18,7 +19,10 @@ namespace Botan { * @param algo_spec the name of the PBE algorithm to retrieve * @return pointer to a PBE with randomly created parameters */ -BOTAN_DLL PBE* get_pbe(const std::string& algo_spec); +BOTAN_DLL PBE* get_pbe(const std::string& algo_spec, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng); /** * Factory function for PBEs. @@ -27,7 +31,8 @@ BOTAN_DLL PBE* get_pbe(const std::string& algo_spec); * @return pointer to the PBE with the specified parameters */ BOTAN_DLL PBE* get_pbe(const OID& pbe_oid, - DataSource& params); + const std::vector<byte>& params, + const std::string& password); } diff --git a/src/pbe/pbe.h b/src/pbe/pbe.h index 975f3e6c7..45c98e2c8 100644 --- a/src/pbe/pbe.h +++ b/src/pbe/pbe.h @@ -22,30 +22,12 @@ class BOTAN_DLL PBE : public Filter { public: /** - * Set this filter's key. - * @param pw the password to be used for the encryption - */ - virtual void set_key(const std::string& pw) = 0; - - /** - * Create a new random salt value and set the default iterations value. - * @param rng a random number generator - */ - virtual void new_params(RandomNumberGenerator& rng) = 0; - - /** * DER encode the params (the number of iterations and the salt value) * @return encoded params */ virtual std::vector<byte> encode_params() const = 0; /** - * Decode params and use them inside this Filter. - * @param src a data source to read the encoded params from - */ - virtual void decode_params(DataSource& src) = 0; - - /** * Get this PBE's OID. * @return object identifier */ diff --git a/src/pbe/pbes1/pbes1.cpp b/src/pbe/pbes1/pbes1.cpp index 41a793a24..e86a496ac 100644 --- a/src/pbe/pbes1/pbes1.cpp +++ b/src/pbe/pbes1/pbes1.cpp @@ -19,7 +19,7 @@ namespace Botan { */ void PBE_PKCS5v15::write(const byte input[], size_t length) { - pipe.write(input, length); + m_pipe.write(input, length); flush_pipe(true); } @@ -28,18 +28,18 @@ void PBE_PKCS5v15::write(const byte input[], size_t length) */ void PBE_PKCS5v15::start_msg() { - if(direction == ENCRYPTION) - pipe.append(new CBC_Encryption(block_cipher->clone(), - new PKCS7_Padding, - key, iv)); + if(m_direction == ENCRYPTION) + m_pipe.append(new CBC_Encryption(m_block_cipher->clone(), + new PKCS7_Padding, + m_key, m_iv)); else - pipe.append(new CBC_Decryption(block_cipher->clone(), - new PKCS7_Padding, - key, iv)); + m_pipe.append(new CBC_Decryption(m_block_cipher->clone(), + new PKCS7_Padding, + m_key, m_iv)); - pipe.start_msg(); - if(pipe.message_count() > 1) - pipe.set_default_msg(pipe.default_msg() + 1); + m_pipe.start_msg(); + if(m_pipe.message_count() > 1) + m_pipe.set_default_msg(m_pipe.default_msg() + 1); } /* @@ -47,9 +47,9 @@ void PBE_PKCS5v15::start_msg() */ void PBE_PKCS5v15::end_msg() { - pipe.end_msg(); + m_pipe.end_msg(); flush_pipe(false); - pipe.reset(); + m_pipe.reset(); } /* @@ -57,81 +57,39 @@ void PBE_PKCS5v15::end_msg() */ void PBE_PKCS5v15::flush_pipe(bool safe_to_skip) { - if(safe_to_skip && pipe.remaining() < 64) + if(safe_to_skip && m_pipe.remaining() < 64) return; secure_vector<byte> buffer(DEFAULT_BUFFERSIZE); - while(pipe.remaining()) + while(m_pipe.remaining()) { - size_t got = pipe.read(&buffer[0], buffer.size()); + size_t got = m_pipe.read(&buffer[0], buffer.size()); send(buffer, got); } } /* -* Set the passphrase to use -*/ -void PBE_PKCS5v15::set_key(const std::string& passphrase) - { - PKCS5_PBKDF1 pbkdf(hash_function->clone()); - - secure_vector<byte> key_and_iv = pbkdf.derive_key(16, passphrase, - &salt[0], salt.size(), - iterations).bits_of(); - - key.resize(8); - iv.resize(8); - copy_mem(&key[0], &key_and_iv[0], 8); - copy_mem(&iv[0], &key_and_iv[8], 8); - } - -/* -* Create a new set of PBES1 parameters -*/ -void PBE_PKCS5v15::new_params(RandomNumberGenerator& rng) - { - iterations = 10000; - salt = rng.random_vec(8); - } - -/* * Encode PKCS#5 PBES1 parameters */ std::vector<byte> PBE_PKCS5v15::encode_params() const { return DER_Encoder() .start_cons(SEQUENCE) - .encode(salt, OCTET_STRING) - .encode(iterations) + .encode(m_salt, OCTET_STRING) + .encode(m_iterations) .end_cons() .get_contents_unlocked(); } /* -* Decode PKCS#5 PBES1 parameters -*/ -void PBE_PKCS5v15::decode_params(DataSource& source) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(salt, OCTET_STRING) - .decode(iterations) - .verify_end() - .end_cons(); - - if(salt.size() != 8) - throw Decoding_Error("PBES1: Encoded salt is not 8 octets"); - } - -/* * Return an OID for this PBES1 type */ OID PBE_PKCS5v15::get_oid() const { const OID base_pbes1_oid("1.2.840.113549.1.5"); - const std::string cipher = block_cipher->name(); - const std::string digest = hash_function->name(); + const std::string cipher = m_block_cipher->name(); + const std::string digest = m_hash_function->name(); if(cipher == "DES" && digest == "MD2") return (base_pbes1_oid + 1); @@ -151,17 +109,52 @@ OID PBE_PKCS5v15::get_oid() const std::string PBE_PKCS5v15::name() const { - return "PBE-PKCS5v15(" + block_cipher->name() + "," + - hash_function->name() + ")"; + return "PBE-PKCS5v15(" + m_block_cipher->name() + "," + + m_hash_function->name() + ")"; + } + +PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng) : + m_direction(ENCRYPTION), + m_block_cipher(cipher), + m_hash_function(hash), + m_salt(rng.random_vec(8)) + { + 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()); + } + + PKCS5_PBKDF1 pbkdf(m_hash_function->clone()); + + secure_vector<byte> key_and_iv = + pbkdf.derive_key(16, passphrase, + &m_salt[0], m_salt.size(), + msec, m_iterations).bits_of(); + + m_key.assign(&key_and_iv[0], &key_and_iv[8]); + m_iv.assign(&key_and_iv[8], &key_and_iv[16]); + } -/* -* PKCS#5 v1.5 PBE Constructor -*/ PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher, HashFunction* hash, - Cipher_Dir dir) : - direction(dir), block_cipher(cipher), hash_function(hash) + const std::vector<byte>& params, + const std::string& passphrase) : + m_direction(DECRYPTION), + m_block_cipher(cipher), + m_hash_function(hash) { if(cipher->name() != "DES" && cipher->name() != "RC2") { @@ -175,12 +168,32 @@ PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher, throw Invalid_Argument("PBE_PKCS5v1.5: Unknown hash " + hash->name()); } + + BER_Decoder(params) + .start_cons(SEQUENCE) + .decode(m_salt, OCTET_STRING) + .decode(m_iterations) + .verify_end() + .end_cons(); + + if(m_salt.size() != 8) + throw Decoding_Error("PBES1: Encoded salt is not 8 octets"); + + PKCS5_PBKDF1 pbkdf(m_hash_function->clone()); + + secure_vector<byte> key_and_iv = + pbkdf.derive_key(16, passphrase, + &m_salt[0], m_salt.size(), + m_iterations).bits_of(); + + m_key.assign(&key_and_iv[0], &key_and_iv[8]); + m_iv.assign(&key_and_iv[8], &key_and_iv[16]); } PBE_PKCS5v15::~PBE_PKCS5v15() { - delete block_cipher; - delete hash_function; + delete m_block_cipher; + delete m_hash_function; } } diff --git a/src/pbe/pbes1/pbes1.h b/src/pbe/pbes1/pbes1.h index bbdbd5b9d..0c921dadd 100644 --- a/src/pbe/pbes1/pbes1.h +++ b/src/pbe/pbes1/pbes1.h @@ -21,6 +21,10 @@ namespace Botan { class BOTAN_DLL PBE_PKCS5v15 : public PBE { public: + OID get_oid() const; + + std::vector<byte> encode_params() const; + std::string name() const; void write(const byte[], size_t); @@ -30,29 +34,30 @@ class BOTAN_DLL PBE_PKCS5v15 : public PBE /** * @param cipher the block cipher to use (DES or RC2) * @param hash the hash function to use - * @param direction are we encrypting or decrypting */ PBE_PKCS5v15(BlockCipher* cipher, HashFunction* hash, - Cipher_Dir direction); + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng); + + PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + const std::vector<byte>& params, + const std::string& passphrase); ~PBE_PKCS5v15(); private: - void set_key(const std::string&); - void new_params(RandomNumberGenerator& rng); - std::vector<byte> encode_params() const; - void decode_params(DataSource&); - OID get_oid() const; void flush_pipe(bool); - Cipher_Dir direction; - BlockCipher* block_cipher; - HashFunction* hash_function; + Cipher_Dir m_direction; + BlockCipher* m_block_cipher; + HashFunction* m_hash_function; - secure_vector<byte> salt, key, iv; - size_t iterations; - Pipe pipe; + secure_vector<byte> m_salt, m_key, m_iv; + size_t m_iterations; + Pipe m_pipe; }; } diff --git a/src/pbe/pbes2/pbes2.cpp b/src/pbe/pbes2/pbes2.cpp index 0036359cc..dc8ffbbcd 100644 --- a/src/pbe/pbes2/pbes2.cpp +++ b/src/pbe/pbes2/pbes2.cpp @@ -76,30 +76,6 @@ void PBE_PKCS5v20::flush_pipe(bool safe_to_skip) } /* -* Set the passphrase to use -*/ -void PBE_PKCS5v20::set_key(const std::string& passphrase) - { - PKCS5_PBKDF2 pbkdf(new HMAC(hash_function->clone())); - - key = pbkdf.derive_key(key_length, passphrase, - &salt[0], salt.size(), - iterations).bits_of(); - } - -/* -* Create a new set of PBES2 parameters -*/ -void PBE_PKCS5v20::new_params(RandomNumberGenerator& rng) - { - iterations = 10000; - key_length = block_cipher->maximum_keylength(); - - salt = rng.random_vec(12); - iv = rng.random_vec(block_cipher->block_size()); - } - -/* * Encode PKCS#5 PBES2 parameters */ std::vector<byte> PBE_PKCS5v20::encode_params() const @@ -129,13 +105,74 @@ std::vector<byte> PBE_PKCS5v20::encode_params() const } /* -* Decode PKCS#5 PBES2 parameters +* Return an OID for PBES2 +*/ +OID PBE_PKCS5v20::get_oid() const + { + return OIDS::lookup("PBE-PKCS5v20"); + } + +/* +* Check if this is a known PBES2 cipher +*/ +bool PBE_PKCS5v20::known_cipher(const std::string& algo) + { + if(algo == "AES-128" || algo == "AES-192" || algo == "AES-256") + return true; + + if(algo == "DES" || algo == "TripleDES") + return true; + + return false; + } + +std::string PBE_PKCS5v20::name() const + { + return "PBE-PKCS5v20(" + block_cipher->name() + "," + + hash_function->name() + ")"; + } + +/* +* PKCS#5 v2.0 PBE Constructor */ -void PBE_PKCS5v20::decode_params(DataSource& source) +PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher, + HashFunction* digest, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng) : + direction(ENCRYPTION), + block_cipher(cipher), + hash_function(digest), + salt(rng.random_vec(12)), + iv(rng.random_vec(block_cipher->block_size())), + iterations(0), + key_length(block_cipher->maximum_keylength()) { + if(!known_cipher(block_cipher->name())) + throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid cipher " + cipher->name()); + if(hash_function->name() != "SHA-160") + throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid digest " + digest->name()); + + PKCS5_PBKDF2 pbkdf(new HMAC(hash_function->clone())); + + key = pbkdf.derive_key(key_length, passphrase, + &salt[0], salt.size(), + msec, iterations).bits_of(); + } + +/* +* PKCS#5 v2.0 PBE Constructor +*/ +PBE_PKCS5v20::PBE_PKCS5v20(const std::vector<byte>& params, + const std::string& passphrase) : +direction(DECRYPTION) + { + hash_function = nullptr; + block_cipher = nullptr; + AlgorithmIdentifier kdf_algo, enc_algo; - BER_Decoder(source) + BER_Decoder(params) .start_cons(SEQUENCE) .decode(kdf_algo) .decode(enc_algo) @@ -177,55 +214,12 @@ void PBE_PKCS5v20::decode_params(DataSource& source) if(salt.size() < 8) throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); - } - -/* -* Return an OID for PBES2 -*/ -OID PBE_PKCS5v20::get_oid() const - { - return OIDS::lookup("PBE-PKCS5v20"); - } -/* -* Check if this is a known PBES2 cipher -*/ -bool PBE_PKCS5v20::known_cipher(const std::string& algo) - { - if(algo == "AES-128" || algo == "AES-192" || algo == "AES-256") - return true; - if(algo == "DES" || algo == "TripleDES") - return true; - return false; - } - -std::string PBE_PKCS5v20::name() const - { - return "PBE-PKCS5v20(" + block_cipher->name() + "," + - hash_function->name() + ")"; - } - -/* -* PKCS#5 v2.0 PBE Constructor -*/ -PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher, - HashFunction* digest) : - direction(ENCRYPTION), block_cipher(cipher), hash_function(digest) - { - if(!known_cipher(block_cipher->name())) - throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid cipher " + cipher->name()); - if(hash_function->name() != "SHA-160") - throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid digest " + digest->name()); - } + PKCS5_PBKDF2 pbkdf(new HMAC(hash_function->clone())); -/* -* PKCS#5 v2.0 PBE Constructor -*/ -PBE_PKCS5v20::PBE_PKCS5v20(DataSource& params) : direction(DECRYPTION) - { - hash_function = nullptr; - block_cipher = nullptr; - decode_params(params); + key = pbkdf.derive_key(key_length, passphrase, + &salt[0], salt.size(), + iterations).bits_of(); } PBE_PKCS5v20::~PBE_PKCS5v20() diff --git a/src/pbe/pbes2/pbes2.h b/src/pbe/pbes2/pbes2.h index 5593c9091..635837b42 100644 --- a/src/pbe/pbes2/pbes2.h +++ b/src/pbe/pbes2/pbes2.h @@ -27,6 +27,10 @@ class BOTAN_DLL PBE_PKCS5v20 : public PBE */ static bool known_cipher(const std::string& cipher); + OID get_oid() const; + + std::vector<byte> encode_params() const; + std::string name() const; void write(const byte[], size_t); @@ -37,22 +41,21 @@ class BOTAN_DLL PBE_PKCS5v20 : public PBE * Load a PKCS #5 v2.0 encrypted stream * @param input is the input source */ - PBE_PKCS5v20(DataSource& input); + PBE_PKCS5v20(const std::vector<byte>& params, + const std::string& passphrase); /** * @param cipher the block cipher to use * @param hash the hash function to use */ - PBE_PKCS5v20(BlockCipher* cipher, HashFunction* hash); + PBE_PKCS5v20(BlockCipher* cipher, + HashFunction* hash, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng); ~PBE_PKCS5v20(); private: - void set_key(const std::string&); - void new_params(RandomNumberGenerator& rng); - std::vector<byte> encode_params() const; - void decode_params(DataSource&); - OID get_oid() const; - void flush_pipe(bool); Cipher_Dir direction; |