Пример #1
0
AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key,
                                          const std::string& cert_hash_name) const
   {
   if(cert_hash_name != m_hash->name())
      throw Invalid_Argument("Hash function from opts and hash_fn argument"
         " need to be identical");
   // check that the signature algorithm and the padding scheme fit
   if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA4"))
      {
      throw Invalid_Argument("Encoding scheme with canonical name EMSA4"
         " not supported for signature algorithm " + key.algo_name());
      }

   AlgorithmIdentifier sig_algo;
   // hardcoded as RSA is the only valid algorithm for EMSA4 at the moment
   sig_algo.oid = OIDS::lookup( "RSA/EMSA4" );

   const AlgorithmIdentifier hash_id(cert_hash_name, AlgorithmIdentifier::USE_NULL_PARAM);
   const AlgorithmIdentifier mgf_id("MGF1", hash_id.BER_encode());

   DER_Encoder(sig_algo.parameters)
      .start_cons(SEQUENCE)
      .start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).encode(hash_id).end_cons()
      .start_cons(ASN1_Tag(1), CONTEXT_SPECIFIC).encode(mgf_id).end_cons()
      .start_cons(ASN1_Tag(2), CONTEXT_SPECIFIC).encode(m_SALT_SIZE).end_cons()
      .start_cons(ASN1_Tag(3), CONTEXT_SPECIFIC).encode(size_t(1)).end_cons() // trailer field
      .end_cons();

   return sig_algo;
   }
Пример #2
0
/*
* BER encode a PKCS #8 private key, unencrypted
*/
secure_vector<byte> BER_encode(const Private_Key& key)
   {
   const size_t PKCS8_VERSION = 0;

   return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(PKCS8_VERSION)
            .encode(key.pkcs8_algorithm_identifier())
            .encode(key.pkcs8_private_key(), OCTET_STRING)
         .end_cons()
      .get_contents();
   }
Пример #3
0
bool Certificate_Store_In_SQL::insert_key(const X509_Certificate& cert, const Private_Key& key) {
   insert_cert(cert);

   if(find_key(cert))
      return false;

   auto pkcs8 = PKCS8::BER_encode(key, m_rng, m_password);
   auto fpr = key.fingerprint("SHA-256");

   auto stmt1 = m_database->new_statement(
         "INSERT OR REPLACE INTO " + m_prefix + "keys ( fingerprint, key ) VALUES ( ?1, ?2 )");

   stmt1->bind(1,fpr);
   stmt1->bind(2,pkcs8.data(),pkcs8.size());
   stmt1->spin();

   auto stmt2 = m_database->new_statement(
         "UPDATE " + m_prefix + "certificates SET priv_fingerprint = ?1 WHERE fingerprint == ?2");

   stmt2->bind(1,fpr);
   stmt2->bind(2,cert.fingerprint("SHA-256"));
   stmt2->spin();

   return true;
   }
Пример #4
0
/*
* BER encode a PKCS #8 private key, encrypted
*/
std::vector<uint8_t> BER_encode_encrypted_pbkdf_msec(const Private_Key& key,
                                                     RandomNumberGenerator& rng,
                                                     const std::string& pass,
                                                     std::chrono::milliseconds pbkdf_msec,
                                                     size_t* pbkdf_iterations,
                                                     const std::string& cipher,
                                                     const std::string& pbkdf_hash)
   {
#if defined(BOTAN_HAS_PKCS5_PBES2)
   const std::pair<AlgorithmIdentifier, std::vector<uint8_t>> pbe_info =
      pbes2_encrypt_msec(key.private_key_info(), pass,
                         pbkdf_msec, pbkdf_iterations,
                         cipher.empty() ? "AES-256/CBC" : cipher,
                         pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash,
                         rng);

   std::vector<uint8_t> output;
   DER_Encoder(output)
      .start_cons(SEQUENCE)
         .encode(pbe_info.first)
         .encode(pbe_info.second, OCTET_STRING)
      .end_cons();

   return output;
#else
   BOTAN_UNUSED(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash);
   throw Encoding_Error("BER_encode_encrypted_pbkdf_msec cannot encrypt because PBES2 disabled in build");
#endif
   }
Пример #5
0
/*
* BER encode a PKCS #8 private key, encrypted
*/
std::vector<uint8_t> BER_encode(const Private_Key& key,
                             RandomNumberGenerator& rng,
                             const std::string& pass,
                             std::chrono::milliseconds msec,
                             const std::string& pbe_algo)
   {
#if defined(BOTAN_HAS_PKCS5_PBES2)
   const auto pbe_params = choose_pbe_params(pbe_algo, key.algo_name());

   const std::pair<AlgorithmIdentifier, std::vector<uint8_t>> pbe_info =
      pbes2_encrypt_msec(PKCS8::BER_encode(key), pass, msec, nullptr,
                         pbe_params.first, pbe_params.second, rng);

   std::vector<uint8_t> output;
   DER_Encoder der(output);
   der.start_cons(SEQUENCE)
         .encode(pbe_info.first)
         .encode(pbe_info.second, OCTET_STRING)
      .end_cons();

   return output;
#else
   BOTAN_UNUSED(key, rng, pass, msec, pbe_algo);
   throw Encoding_Error("PKCS8::BER_encode cannot encrypt because PBES2 was disabled in build");
#endif
   }
Пример #6
0
void Certificate_Store_In_SQL::remove_key(const Private_Key& key)
   {
   auto fpr = key.fingerprint("SHA-256");
   auto stmt = m_database->new_statement("DELETE FROM " + m_prefix + "keys WHERE fingerprint == ?1");

   stmt->bind(1,fpr);
   stmt->spin();
   }
Пример #7
0
/*
* Choose a signing format for the key
*/
std::unique_ptr<PK_Signer> X509_Object::choose_sig_format(AlgorithmIdentifier& sig_algo,
                                                          const Private_Key& key,
                                                          RandomNumberGenerator& rng,
                                                          const std::string& hash_fn,
                                                          const std::string& padding_algo)
   {
   const Signature_Format format = (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363;

   const std::string emsa = choose_sig_algo(sig_algo, key, hash_fn, padding_algo);

   return std::unique_ptr<PK_Signer>(new PK_Signer(key, rng, emsa, format));
   }
Пример #8
0
std::vector<std::shared_ptr<const X509_Certificate>>
Certificate_Store_In_SQL::find_certs_for_key(const Private_Key& key) const
   {
   auto fpr = key.fingerprint("SHA-256");
   auto stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE priv_fingerprint == ?1");

   stmt->bind(1,fpr);

   std::vector<std::shared_ptr<const X509_Certificate>> certs;
   while(stmt->step())
      {
      auto blob = stmt->get_blob(0);
      certs.push_back(std::make_shared<X509_Certificate>(
            std::vector<uint8_t>(blob.first,blob.first + blob.second)));
      }

   return certs;
   }
Пример #9
0
/*
* BER encode a PKCS #8 private key, encrypted
*/
std::vector<byte> BER_encode(const Private_Key& key,
                             RandomNumberGenerator& rng,
                             const std::string& pass,
                             std::chrono::milliseconds msec,
                             const std::string& pbe_algo)
   {
   const auto pbe_params = choose_pbe_params(pbe_algo, key.algo_name());

   const std::pair<AlgorithmIdentifier, std::vector<byte>> pbe_info =
      pbes2_encrypt(PKCS8::BER_encode(key), pass, msec,
                    pbe_params.first, pbe_params.second, rng);

   return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(pbe_info.first)
            .encode(pbe_info.second, OCTET_STRING)
         .end_cons()
      .get_contents_unlocked();
   }
Пример #10
0
std::pair<std::string, Signature_Format>
Handshake_State::choose_sig_format(const Private_Key& key,
                                   std::string& hash_algo_out,
                                   std::string& sig_algo_out,
                                   bool for_client_auth,
                                   const Policy& policy) const
   {
   const std::string sig_algo = key.algo_name();

   const std::string hash_algo =
      choose_hash(sig_algo,
                  this->version(),
                  policy,
                  for_client_auth,
                  client_hello(),
                  cert_req());

   if(this->version().supports_negotiable_signature_algorithms())
      {
      hash_algo_out = hash_algo;
      sig_algo_out = sig_algo;
      }

   if(sig_algo == "RSA")
      {
      const std::string padding = "EMSA3(" + hash_algo + ")";

      return std::make_pair(padding, IEEE_1363);
      }
   else if(sig_algo == "DSA" || sig_algo == "ECDSA")
      {
      const std::string padding = "EMSA1(" + hash_algo + ")";

      return std::make_pair(padding, DER_SEQUENCE);
      }

   throw Invalid_Argument(sig_algo + " is invalid/unknown for TLS signatures");
   }
Пример #11
0
/*
* BER encode a PKCS #8 private key, unencrypted
*/
secure_vector<uint8_t> BER_encode(const Private_Key& key)
   {
   // keeping around for compat
   return key.private_key_info();
   }