aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pbe/get_pbe.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pbe/get_pbe.cpp')
-rw-r--r--src/lib/pbe/get_pbe.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/lib/pbe/get_pbe.cpp b/src/lib/pbe/get_pbe.cpp
new file mode 100644
index 000000000..4ec518776
--- /dev/null
+++ b/src/lib/pbe/get_pbe.cpp
@@ -0,0 +1,140 @@
+/*
+* PBE Retrieval
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#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>
+#endif
+
+#if defined(BOTAN_HAS_PBE_PKCS_V20)
+ #include <botan/pbes2.h>
+ #include <botan/hmac.h>
+#endif
+
+namespace Botan {
+
+/*
+* Get an encryption PBE, set new parameters
+*/
+PBE* get_pbe(const std::string& algo_spec,
+ const std::string& passphrase,
+ std::chrono::milliseconds msec,
+ RandomNumberGenerator& rng)
+ {
+ SCAN_Name request(algo_spec);
+
+ const std::string pbe = request.algo_name();
+ std::string digest_name = request.arg(0);
+ const std::string cipher = request.arg(1);
+
+ std::vector<std::string> cipher_spec = split_on(cipher, '/');
+ if(cipher_spec.size() != 2)
+ throw Invalid_Argument("PBE: Invalid cipher spec " + cipher);
+
+ const std::string cipher_algo = SCAN_Name::deref_alias(cipher_spec[0]);
+ const std::string cipher_mode = cipher_spec[1];
+
+ if(cipher_mode != "CBC")
+ throw Invalid_Argument("PBE: Invalid cipher mode " + cipher);
+
+ Algorithm_Factory& af = global_state().algorithm_factory();
+
+ const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo);
+ if(!block_cipher)
+ throw Algorithm_Not_Found(cipher_algo);
+
+ const HashFunction* hash_function = af.prototype_hash_function(digest_name);
+ if(!hash_function)
+ throw Algorithm_Not_Found(digest_name);
+
+ if(request.arg_count() != 2)
+ throw Invalid_Algorithm_Name(algo_spec);
+
+#if defined(BOTAN_HAS_PBE_PKCS_V15)
+ if(pbe == "PBE-PKCS5v15")
+ return new PBE_PKCS5v15(block_cipher->clone(),
+ hash_function->clone(),
+ passphrase,
+ msec,
+ rng);
+#endif
+
+#if defined(BOTAN_HAS_PBE_PKCS_V20)
+ if(pbe == "PBE-PKCS5v20")
+ return new PBE_PKCS5v20(block_cipher->clone(),
+ new HMAC(hash_function->clone()),
+ passphrase,
+ msec,
+ rng);
+#endif
+
+ throw Algorithm_Not_Found(algo_spec);
+ }
+
+/*
+* Get a decryption PBE, decode parameters
+*/
+PBE* get_pbe(const OID& pbe_oid,
+ const std::vector<byte>& params,
+ const std::string& passphrase)
+ {
+ SCAN_Name request(OIDS::lookup(pbe_oid));
+
+ const std::string pbe = request.algo_name();
+
+#if defined(BOTAN_HAS_PBE_PKCS_V15)
+ if(pbe == "PBE-PKCS5v15")
+ {
+ if(request.arg_count() != 2)
+ throw Invalid_Algorithm_Name(request.as_string());
+
+ std::string digest_name = request.arg(0);
+ const std::string cipher = request.arg(1);
+
+ std::vector<std::string> cipher_spec = split_on(cipher, '/');
+ if(cipher_spec.size() != 2)
+ throw Invalid_Argument("PBE: Invalid cipher spec " + cipher);
+
+ const std::string cipher_algo = SCAN_Name::deref_alias(cipher_spec[0]);
+ const std::string cipher_mode = cipher_spec[1];
+
+ if(cipher_mode != "CBC")
+ throw Invalid_Argument("PBE: Invalid cipher mode " + cipher);
+
+ Algorithm_Factory& af = global_state().algorithm_factory();
+
+ const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo);
+ if(!block_cipher)
+ throw Algorithm_Not_Found(cipher_algo);
+
+ const HashFunction* hash_function =
+ af.prototype_hash_function(digest_name);
+
+ if(!hash_function)
+ throw Algorithm_Not_Found(digest_name);
+
+ 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, passphrase);
+#endif
+
+ throw Algorithm_Not_Found(pbe_oid.as_string());
+ }
+
+}