diff options
author | lloyd <[email protected]> | 2014-12-08 07:21:12 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-12-08 07:21:12 +0000 |
commit | e14d04baf0261d5250285fcb6486950078b2c6e7 (patch) | |
tree | faddc8299e5f4c0495418e7b2fb8ad9181965ab0 | |
parent | 1b7dbd5ca22f83ac8011dc209d92d2562562c816 (diff) |
Cleanup for pbe name parsing in PKCS #8 encoder
-rw-r--r-- | src/cmd/keygen.cpp | 5 | ||||
-rw-r--r-- | src/lib/pubkey/pkcs8.cpp | 37 |
2 files changed, 26 insertions, 16 deletions
diff --git a/src/cmd/keygen.cpp b/src/cmd/keygen.cpp index 6aa74a08f..3054b98ee 100644 --- a/src/cmd/keygen.cpp +++ b/src/cmd/keygen.cpp @@ -61,12 +61,13 @@ Private_Key* gen_key(RandomNumberGenerator& rng, const std::string& algo, size_t int keygen(int argc, char* argv[]) { - OptionParser opts("algo=|bits=|passphrase="); + OptionParser opts("algo=|bits=|passphrase=|pbe="); opts.parse(argv); const std::string algo = opts.value_or_else("algo", "rsa"); const size_t bits = opts.int_value_or_else("bits", 1024); const std::string pass = opts.value_or_else("passphrase", ""); + const std::string pbe = opts.value_or_else("pbe", ""); try { @@ -88,7 +89,7 @@ int keygen(int argc, char* argv[]) if(pass == "") priv << PKCS8::PEM_encode(*key); else - priv << PKCS8::PEM_encode(*key, rng, pass); + priv << PKCS8::PEM_encode(*key, rng, pass, std::chrono::milliseconds(300), pbe); std::cout << "Wrote " << bits << " bit " << algo << " key to public.pem / private.pem\n"; } diff --git a/src/lib/pubkey/pkcs8.cpp b/src/lib/pubkey/pkcs8.cpp index 24a5bb21f..15f0c4539 100644 --- a/src/lib/pubkey/pkcs8.cpp +++ b/src/lib/pubkey/pkcs8.cpp @@ -1,6 +1,6 @@ /* * PKCS #8 -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2014 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -150,6 +150,24 @@ std::string PEM_encode(const Private_Key& key) return PEM_Code::encode(PKCS8::BER_encode(key), "PRIVATE KEY"); } +namespace { + +std::pair<std::string, std::string> +choose_pbe_params(const std::string& pbe_algo) + { + if(!pbe_algo.empty()) + { + SCAN_Name request(pbe_algo); + if(request.algo_name() != "PBE-PKCS5v20") + throw std::runtime_error("Unsupported PBE " + pbe_algo); + return std::make_pair(request.arg(1), request.arg(0)); + } + + return std::make_pair("AES-256/CBC", "SHA-256"); + } + +} + /* * BER encode a PKCS #8 private key, encrypted */ @@ -159,21 +177,12 @@ std::vector<byte> BER_encode(const Private_Key& key, std::chrono::milliseconds msec, const std::string& pbe_algo) { - const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-256,AES-256/CBC)"; - - SCAN_Name request(pbe_algo.empty() ? DEFAULT_PBE : pbe_algo); - - const std::string pbe = request.algo_name(); - - if(pbe != "PBE-PKCS5v20") - throw std::runtime_error("Unsupported PBE " + pbe); - - const std::string digest = request.arg(0); - const std::string cipher = request.arg(1); + const auto pbe_params = choose_pbe_params(pbe_algo); const std::pair<AlgorithmIdentifier, std::vector<byte>> pbe_info = - pbes2_encrypt(PKCS8::BER_encode(key), pass, msec, cipher, digest, rng, - global_state().algorithm_factory()); + pbes2_encrypt(PKCS8::BER_encode(key), pass, msec, + pbe_params.first, pbe_params.second, + rng, global_state().algorithm_factory()); return DER_Encoder() .start_cons(SEQUENCE) |