8#include <botan/pkcs8.h> 
   10#include <botan/asn1_obj.h> 
   11#include <botan/assert.h> 
   12#include <botan/ber_dec.h> 
   13#include <botan/der_enc.h> 
   15#include <botan/pk_algs.h> 
   17#include <botan/internal/fmt.h> 
   18#include <botan/internal/scan_name.h> 
   20#if defined(BOTAN_HAS_PKCS5_PBES2) 
   21   #include <botan/internal/pbes2.h> 
   43                                    const std::function<std::string()>& get_passphrase,
 
   53            key_data = PKCS8_extract(source, pbe_alg_id);
 
   57               key_data.push_back(*b);
 
   65         if(label == 
"PRIVATE KEY") {
 
   67         } 
else if(label == 
"ENCRYPTED PRIVATE KEY") {
 
   69            key_data = PKCS8_extract(key_source, pbe_alg_id);
 
   75      if(key_data.empty()) {
 
   88#if defined(BOTAN_HAS_PKCS5_PBES2) 
   92         throw Decoding_Error(
"Private key is encrypted but PBES2 was disabled in build");
 
  105   } 
catch(std::exception& e) {
 
  120#if defined(BOTAN_HAS_PKCS5_PBES2) 
  124std::pair<std::string, std::string> choose_pbe_params(std::string_view pbe_algo, std::string_view key_algo) {
 
  125   if(pbe_algo.empty()) {
 
  131      const bool nonstandard_pk = (key_algo == 
"McEliece" || key_algo == 
"XMSS");
 
  134   #if defined(BOTAN_HAS_AEAD_SIV) && defined(BOTAN_HAS_SHA2_64) 
  135         return std::make_pair(
"AES-256/SIV", 
"SHA-512");
 
  136   #elif defined(BOTAN_HAS_AEAD_GCM) && defined(BOTAN_HAS_SHA2_64) 
  137         return std::make_pair(
"AES-256/GCM", 
"SHA-512");
 
  142      return std::make_pair(
"AES-256/CBC", 
"SHA-256");
 
  145   SCAN_Name request(pbe_algo);
 
  147   if(request.arg_count() != 2 || (request.algo_name() != 
"PBE-PKCS5v20" && request.algo_name() != 
"PBES2")) {
 
  148      throw Invalid_Argument(
fmt(
"Unsupported PBE '{}'", pbe_algo));
 
  151   return std::make_pair(request.arg(0), request.arg(1));
 
  163                                std::string_view pass,
 
  164                                std::chrono::milliseconds msec,
 
  165                                std::string_view pbe_algo) {
 
  166#if defined(BOTAN_HAS_PKCS5_PBES2) 
  167   const auto pbe_params = choose_pbe_params(pbe_algo, key.
algo_name());
 
  169   const std::pair<AlgorithmIdentifier, std::vector<uint8_t>> pbe_info =
 
  172   std::vector<uint8_t> output;
 
  179   throw Encoding_Error(
"PKCS8::BER_encode cannot encrypt because PBES2 was disabled in build");
 
 
  188                       std::string_view pass,
 
  189                       std::chrono::milliseconds msec,
 
  190                       std::string_view pbe_algo) {
 
 
  203                                                     std::string_view pass,
 
  204                                                     size_t pbkdf_iterations,
 
  205                                                     std::string_view cipher,
 
  206                                                     std::string_view pbkdf_hash) {
 
  207#if defined(BOTAN_HAS_PKCS5_PBES2) 
  208   const std::pair<AlgorithmIdentifier, std::vector<uint8_t>> pbe_info =
 
  212                         cipher.empty() ? 
"AES-256/CBC" : cipher,
 
  213                         pbkdf_hash.empty() ? 
"SHA-256" : pbkdf_hash,
 
  216   std::vector<uint8_t> output;
 
  223   BOTAN_UNUSED(key, rng, pass, pbkdf_iterations, cipher, pbkdf_hash);
 
  224   throw Encoding_Error(
"PKCS8::BER_encode_encrypted_pbkdf_iter cannot encrypt because PBES2 disabled in build");
 
 
  233                                            std::string_view pass,
 
  234                                            size_t pbkdf_iterations,
 
  235                                            std::string_view cipher,
 
  236                                            std::string_view pbkdf_hash) {
 
  238                           "ENCRYPTED PRIVATE KEY");
 
 
  246                                                     std::string_view pass,
 
  247                                                     std::chrono::milliseconds pbkdf_msec,
 
  248                                                     size_t* pbkdf_iterations,
 
  249                                                     std::string_view cipher,
 
  250                                                     std::string_view pbkdf_hash) {
 
  251#if defined(BOTAN_HAS_PKCS5_PBES2) 
  252   const std::pair<AlgorithmIdentifier, std::vector<uint8_t>> pbe_info =
 
  257                         cipher.empty() ? 
"AES-256/CBC" : cipher,
 
  258                         pbkdf_hash.empty() ? 
"SHA-256" : pbkdf_hash,
 
  261   std::vector<uint8_t> output;
 
  270   BOTAN_UNUSED(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash);
 
  271   throw Encoding_Error(
"BER_encode_encrypted_pbkdf_msec cannot encrypt because PBES2 disabled in build");
 
 
  280                                            std::string_view pass,
 
  281                                            std::chrono::milliseconds pbkdf_msec,
 
  282                                            size_t* pbkdf_iterations,
 
  283                                            std::string_view cipher,
 
  284                                            std::string_view pbkdf_hash) {
 
  287      "ENCRYPTED PRIVATE KEY");
 
 
  296                                      const std::function<std::string()>& get_pass,
 
  302   if(alg_name.empty()) {
 
  314std::unique_ptr<Private_Key> 
load_key(
DataSource& source, 
const std::function<std::string()>& get_pass) {
 
  315   return load_key(source, get_pass, 
true);
 
 
  318std::unique_ptr<Private_Key> 
load_key(std::span<const uint8_t> source,
 
  319                                      const std::function<std::string()>& get_passphrase) {
 
  321   return load_key(ds, get_passphrase);
 
 
  324std::unique_ptr<Private_Key> 
load_key(std::span<const uint8_t> source, std::string_view pass) {
 
 
  329std::unique_ptr<Private_Key> 
load_key(std::span<const uint8_t> source) {
 
 
  339      source, [pass]() { 
return std::string(pass); }, 
true);
 
 
  346   auto fail_fn = []() -> std::string {
 
  347      throw PKCS8_Exception(
"Internal error: Attempt to read password for unencrypted key");
 
  350   return load_key(source, fail_fn, 
false);
 
 
 
const std::vector< uint8_t > & parameters() const
 
virtual std::string algo_name() const =0
 
BER_Decoder & decode(bool &out)
 
BER_Decoder & verify_end()
 
BER_Decoder start_sequence()
 
BER_Decoder & decode_and_check(const T &expected, std::string_view error_msg)
 
DER_Encoder & start_sequence()
 
DER_Encoder & encode(bool b)
 
size_t read_byte(uint8_t &out)
 
std::string to_formatted_string() const
 
std::string human_name_or_empty() const
 
secure_vector< uint8_t > private_key_info() const
 
bool maybe_BER(DataSource &source)
 
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
 
bool matches(DataSource &source, std::string_view extra, size_t search_range)
 
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
 
std::vector< uint8_t > BER_encode(const Private_Key &key, RandomNumberGenerator &rng, std::string_view pass, std::chrono::milliseconds msec, std::string_view pbe_algo)
 
std::string PEM_encode_encrypted_pbkdf_iter(const Private_Key &key, RandomNumberGenerator &rng, std::string_view pass, size_t pbkdf_iterations, std::string_view cipher, std::string_view pbkdf_hash)
 
std::string PEM_encode(const Private_Key &key)
 
std::string PEM_encode_encrypted_pbkdf_msec(const Private_Key &key, RandomNumberGenerator &rng, std::string_view pass, std::chrono::milliseconds pbkdf_msec, size_t *pbkdf_iterations, std::string_view cipher, std::string_view pbkdf_hash)
 
std::vector< uint8_t > BER_encode_encrypted_pbkdf_iter(const Private_Key &key, RandomNumberGenerator &rng, std::string_view pass, size_t pbkdf_iterations, std::string_view cipher, std::string_view pbkdf_hash)
 
std::vector< uint8_t > BER_encode_encrypted_pbkdf_msec(const Private_Key &key, RandomNumberGenerator &rng, std::string_view pass, std::chrono::milliseconds pbkdf_msec, size_t *pbkdf_iterations, std::string_view cipher, std::string_view pbkdf_hash)
 
std::unique_ptr< Private_Key > load_key(DataSource &source, const std::function< std::string()> &get_pass)
 
std::string fmt(std::string_view format, const T &... args)
 
std::pair< AlgorithmIdentifier, std::vector< uint8_t > > pbes2_encrypt_iter(std::span< const uint8_t > key_bits, std::string_view passphrase, size_t pbkdf_iter, std::string_view cipher, std::string_view digest, RandomNumberGenerator &rng)
 
secure_vector< uint8_t > pbes2_decrypt(std::span< const uint8_t > key_bits, std::string_view passphrase, const std::vector< uint8_t > ¶ms)
 
std::pair< AlgorithmIdentifier, std::vector< uint8_t > > pbes2_encrypt_msec(std::span< const uint8_t > key_bits, std::string_view passphrase, std::chrono::milliseconds msec, size_t *out_iterations_if_nonnull, std::string_view cipher, std::string_view digest, RandomNumberGenerator &rng)
 
std::vector< T, secure_allocator< T > > secure_vector
 
std::unique_ptr< Private_Key > load_private_key(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)