aboutsummaryrefslogtreecommitdiffstats
path: root/src/pubkey/pkcs8.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-05-25 22:52:00 +0000
committerlloyd <[email protected]>2012-05-25 22:52:00 +0000
commit12090a7148d9ee73572cc1a7268fc489504a8173 (patch)
tree51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/pubkey/pkcs8.cpp
parent9594979caf775dc4062850044715b804d1fda60c (diff)
parent65cc04445f8d40497f02a14bd8cb97081790e54b (diff)
propagate from branch 'net.randombit.botan.x509-path-validation' (head 63b5a20eab129ca13287fda33d2d02eec329708f)
to branch 'net.randombit.botan' (head 8b8150f09c55184f028f2929c4e7f7cd0d46d96e)
Diffstat (limited to 'src/pubkey/pkcs8.cpp')
-rw-r--r--src/pubkey/pkcs8.cpp70
1 files changed, 48 insertions, 22 deletions
diff --git a/src/pubkey/pkcs8.cpp b/src/pubkey/pkcs8.cpp
index 16440b648..baf6d1250 100644
--- a/src/pubkey/pkcs8.cpp
+++ b/src/pubkey/pkcs8.cpp
@@ -24,10 +24,10 @@ namespace {
/*
* Get info from an EncryptedPrivateKeyInfo
*/
-SecureVector<byte> PKCS8_extract(DataSource& source,
+secure_vector<byte> PKCS8_extract(DataSource& source,
AlgorithmIdentifier& pbe_alg_id)
{
- SecureVector<byte> key_data;
+ secure_vector<byte> key_data;
BER_Decoder(source)
.start_cons(SEQUENCE)
@@ -41,11 +41,13 @@ SecureVector<byte> PKCS8_extract(DataSource& source,
/*
* PEM decode and/or decrypt a private key
*/
-SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui,
- AlgorithmIdentifier& pk_alg_id)
+secure_vector<byte> PKCS8_decode(
+ DataSource& source,
+ std::function<std::pair<bool,std::string> ()> get_passphrase,
+ AlgorithmIdentifier& pk_alg_id)
{
AlgorithmIdentifier pbe_alg_id;
- SecureVector<byte> key_data, key;
+ secure_vector<byte> key_data, key;
bool is_encrypted = true;
try {
@@ -69,9 +71,9 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui,
if(key_data.empty())
throw PKCS8_Exception("No key data found");
}
- catch(Decoding_Error)
+ catch(Decoding_Error& e)
{
- throw Decoding_Error("PKCS #8 private key decoding failed");
+ throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what()));
}
if(!is_encrypted)
@@ -89,16 +91,14 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui,
if(is_encrypted)
{
DataSource_Memory params(pbe_alg_id.parameters);
- std::auto_ptr<PBE> pbe(get_pbe(pbe_alg_id.oid, params));
+ std::unique_ptr<PBE> pbe(get_pbe(pbe_alg_id.oid, params));
- User_Interface::UI_Result result = User_Interface::OK;
- const std::string passphrase =
- ui.get_passphrase("PKCS #8 private key", source.id(), result);
+ std::pair<bool, std::string> pass = get_passphrase();
- if(result == User_Interface::CANCEL_ACTION)
+ if(pass.first == false)
break;
- pbe->set_key(passphrase);
+ pbe->set_key(pass.second);
Pipe decryptor(pbe.release());
decryptor.process_msg(key_data);
@@ -131,7 +131,7 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui,
/*
* BER encode a PKCS #8 private key, unencrypted
*/
-SecureVector<byte> BER_encode(const Private_Key& key)
+secure_vector<byte> BER_encode(const Private_Key& key)
{
const size_t PKCS8_VERSION = 0;
@@ -155,14 +155,14 @@ std::string PEM_encode(const Private_Key& key)
/*
* BER encode a PKCS #8 private key, encrypted
*/
-SecureVector<byte> BER_encode(const Private_Key& key,
+secure_vector<byte> BER_encode(const Private_Key& key,
RandomNumberGenerator& rng,
const std::string& pass,
const std::string& pbe_algo)
{
const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,AES-256/CBC)";
- std::auto_ptr<PBE> pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE)));
+ std::unique_ptr<PBE> pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE)));
pbe->new_params(rng);
pbe->set_key(pass);
@@ -200,10 +200,10 @@ std::string PEM_encode(const Private_Key& key,
*/
Private_Key* load_key(DataSource& source,
RandomNumberGenerator& rng,
- const User_Interface& ui)
+ std::function<std::pair<bool, std::string> ()> get_pass)
{
AlgorithmIdentifier alg_id;
- SecureVector<byte> pkcs8_key = PKCS8_decode(source, ui, alg_id);
+ secure_vector<byte> pkcs8_key = PKCS8_decode(source, get_pass, alg_id);
const std::string alg_name = OIDS::lookup(alg_id.oid);
if(alg_name == "" || alg_name == alg_id.oid.as_string())
@@ -218,12 +218,38 @@ Private_Key* load_key(DataSource& source,
*/
Private_Key* load_key(const std::string& fsname,
RandomNumberGenerator& rng,
- const User_Interface& ui)
+ std::function<std::pair<bool, std::string> ()> get_pass)
{
DataSource_Stream source(fsname, true);
- return PKCS8::load_key(source, rng, ui);
+ return PKCS8::load_key(source, rng, get_pass);
}
+namespace {
+
+class Single_Shot_Passphrase
+ {
+ public:
+ Single_Shot_Passphrase(const std::string& pass) :
+ passphrase(pass), first(true) {}
+
+ std::pair<bool, std::string> operator()()
+ {
+ if(first)
+ {
+ first = false;
+ return std::make_pair(true, passphrase);
+ }
+ else
+ return std::make_pair(false, "");
+ }
+
+ private:
+ std::string passphrase;
+ bool first;
+ };
+
+}
+
/*
* Extract a private key and return it
*/
@@ -231,7 +257,7 @@ Private_Key* load_key(DataSource& source,
RandomNumberGenerator& rng,
const std::string& pass)
{
- return PKCS8::load_key(source, rng, User_Interface(pass));
+ return PKCS8::load_key(source, rng, Single_Shot_Passphrase(pass));
}
/*
@@ -241,7 +267,7 @@ Private_Key* load_key(const std::string& fsname,
RandomNumberGenerator& rng,
const std::string& pass)
{
- return PKCS8::load_key(fsname, rng, User_Interface(pass));
+ return PKCS8::load_key(fsname, rng, Single_Shot_Passphrase(pass));
}
/*