diff options
Diffstat (limited to 'src/lib/pubkey/pkcs8.cpp')
-rw-r--r-- | src/lib/pubkey/pkcs8.cpp | 95 |
1 files changed, 24 insertions, 71 deletions
diff --git a/src/lib/pubkey/pkcs8.cpp b/src/lib/pubkey/pkcs8.cpp index a1731c8ef..7b7b54891 100644 --- a/src/lib/pubkey/pkcs8.cpp +++ b/src/lib/pubkey/pkcs8.cpp @@ -12,7 +12,6 @@ #include <botan/oids.h> #include <botan/pem.h> #include <botan/pbes2.h> -#include <botan/libstate.h> #include <botan/scan_name.h> #include <botan/internal/pk_algs.h> @@ -44,7 +43,7 @@ secure_vector<byte> PKCS8_extract(DataSource& source, */ secure_vector<byte> PKCS8_decode( DataSource& source, - std::function<std::pair<bool,std::string> ()> get_passphrase, + std::function<std::string ()> get_passphrase, AlgorithmIdentifier& pk_alg_id) { AlgorithmIdentifier pbe_alg_id; @@ -77,49 +76,29 @@ secure_vector<byte> PKCS8_decode( throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); } - if(!is_encrypted) - key = key_data; - - const size_t MAX_TRIES = 3; - - size_t tries = 0; - while(true) + try { - try { - if(MAX_TRIES && tries >= MAX_TRIES) - break; - - if(is_encrypted) - { - std::pair<bool, std::string> pass = get_passphrase(); - - if(pass.first == false) - break; - - if(OIDS::lookup(pbe_alg_id.oid) != "PBE-PKCS5v20") - throw std::runtime_error("Unknown PBE type " + pbe_alg_id.oid.as_string()); - - key = pbes2_decrypt(key_data, pass.second, pbe_alg_id.parameters); - } - - BER_Decoder(key) - .start_cons(SEQUENCE) - .decode_and_check<size_t>(0, "Unknown PKCS #8 version number") - .decode(pk_alg_id) - .decode(key, OCTET_STRING) - .discard_remaining() - .end_cons(); - - break; - } - catch(Decoding_Error) + if(is_encrypted) { - ++tries; + if(OIDS::lookup(pbe_alg_id.oid) != "PBE-PKCS5v20") + throw std::runtime_error("Unknown PBE type " + pbe_alg_id.oid.as_string()); + key = pbes2_decrypt(key_data, get_passphrase(), pbe_alg_id.parameters); } - } + else + key = key_data; - if(key.empty()) - throw Decoding_Error("PKCS #8 private key decoding failed"); + BER_Decoder(key) + .start_cons(SEQUENCE) + .decode_and_check<size_t>(0, "Unknown PKCS #8 version number") + .decode(pk_alg_id) + .decode(key, OCTET_STRING) + .discard_remaining() + .end_cons(); + } + catch(std::exception& e) + { + throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); + } return key; } @@ -215,7 +194,7 @@ std::string PEM_encode(const Private_Key& key, */ Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, - std::function<std::pair<bool, std::string> ()> get_pass) + std::function<std::string ()> get_pass) { AlgorithmIdentifier alg_id; secure_vector<byte> pkcs8_key = PKCS8_decode(source, get_pass, alg_id); @@ -233,38 +212,12 @@ Private_Key* load_key(DataSource& source, */ Private_Key* load_key(const std::string& fsname, RandomNumberGenerator& rng, - std::function<std::pair<bool, std::string> ()> get_pass) + std::function<std::string ()> get_pass) { DataSource_Stream source(fsname, true); 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 */ @@ -272,7 +225,7 @@ Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, const std::string& pass) { - return PKCS8::load_key(source, rng, Single_Shot_Passphrase(pass)); + return PKCS8::load_key(source, rng, [pass]() { return pass; }); } /* @@ -282,7 +235,7 @@ Private_Key* load_key(const std::string& fsname, RandomNumberGenerator& rng, const std::string& pass) { - return PKCS8::load_key(fsname, rng, Single_Shot_Passphrase(pass)); + return PKCS8::load_key(fsname, rng, [pass]() { return pass; }); } /* |