aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/pbe/get_pbe.cpp40
-rw-r--r--src/pbe/pbes1/pbes1.cpp75
-rw-r--r--src/pbe/pbes1/pbes1.h17
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;