aboutsummaryrefslogtreecommitdiffstats
path: root/src/pbe
diff options
context:
space:
mode:
Diffstat (limited to 'src/pbe')
-rw-r--r--src/pbe/get_pbe.cpp29
-rw-r--r--src/pbe/get_pbe.h9
-rw-r--r--src/pbe/pbe.h18
-rw-r--r--src/pbe/pbes1/pbes1.cpp155
-rw-r--r--src/pbe/pbes1/pbes1.h31
-rw-r--r--src/pbe/pbes2/pbes2.cpp142
-rw-r--r--src/pbe/pbes2/pbes2.h19
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;