コード例 #1
0
ファイル: signed_obj.cpp プロジェクト: BenjaminSchiborr/safe
bool EAC_Signed_Object::check_signature(Public_Key& pub_key,
                                        const MemoryRegion<byte>& sig) const
   {
   try
      {
      std::vector<std::string> sig_info =
         split_on(OIDS::lookup(sig_algo.oid), '/');

      if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name())
         {
         return false;
         }

      std::string padding = sig_info[1];
      Signature_Format format =
         (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;

      SecureVector<byte> to_sign = tbs_data();

      PK_Verifier verifier(pub_key, padding, format);
      return verifier.verify_message(to_sign, sig);
      }
   catch(...)
      {
      return false;
      }
   }
コード例 #2
0
ファイル: x509_key.cpp プロジェクト: Andrew-He/botan
std::vector<byte> BER_encode(const Public_Key& key)
   {
   return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(key.algorithm_identifier())
            .encode(key.x509_subject_public_key(), BIT_STRING)
         .end_cons()
      .get_contents_unlocked();
   }
コード例 #3
0
ファイル: key_constraint.cpp プロジェクト: evpo/EncryptPad
/*
* Make sure the given key constraints are permitted for the given key type
*/
void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key,
                                                      Key_Constraints constraints)
   {
   const std::string name = pub_key.algo_name();

   size_t permitted = 0;

   if(name == "DH" || name == "ECDH")
      {
      permitted |= KEY_AGREEMENT | ENCIPHER_ONLY | DECIPHER_ONLY;
      }

   if(name == "RSA" || name == "ElGamal")
      {
      permitted |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT;
      }

   if(name == "RSA" || name == "DSA" ||
      name == "ECDSA" || name == "ECGDSA" || name == "ECKCDSA" || name == "GOST-34.10" ||
      name == "Ed25519")
      {
      permitted |= DIGITAL_SIGNATURE | NON_REPUDIATION | KEY_CERT_SIGN | CRL_SIGN;
      }

   if((constraints & permitted) != constraints)
      {
      throw Exception("Invalid " + name + " constraints " + key_constraints_to_string(constraints));
      }
   }
コード例 #4
0
/*
* Check the signature on an object
*/
bool X509_Object::check_signature(const Public_Key& pub_key) const
   {
   try {
      std::vector<std::string> sig_info =
         split_on(OIDS::lookup(m_sig_algo.oid), '/');

      if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name())
         return false;

      std::string padding = sig_info[1];
      Signature_Format format =
         (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;

      PK_Verifier verifier(pub_key, padding, format);

      return verifier.verify_message(tbs_data(), signature());
      }
   catch(std::exception&)
      {
      return false;
      }
   }
コード例 #5
0
ファイル: tls_policy.cpp プロジェクト: louiz/botan
void Policy::check_peer_key_acceptable(const Public_Key& public_key) const
   {
   const std::string algo_name = public_key.algo_name();

   const size_t keylength = public_key.key_length();
   size_t expected_keylength = 0;

   if(algo_name == "RSA")
      {
      expected_keylength = minimum_rsa_bits();
      }
   else if(algo_name == "DH")
      {
      expected_keylength = minimum_dh_group_size();
      }
   else if(algo_name == "DSA")
      {
      expected_keylength = minimum_dsa_group_size();
      }
   else if(algo_name == "ECDH" || algo_name == "Curve25519")
      {
      expected_keylength = minimum_ecdh_group_size();
      }
   else if(algo_name == "ECDSA")
      {
      expected_keylength = minimum_ecdsa_group_size();
      }
   // else some other algo, so leave expected_keylength as zero and the check is a no-op

   if(keylength < expected_keylength)
      throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                          "Peer sent " + 
                           std::to_string(keylength) + " bit " + algo_name + " key"
                           ", policy requires at least " +
                           std::to_string(expected_keylength));
   }
コード例 #6
0
std::pair<std::string, Signature_Format>
Handshake_State::parse_sig_format(const Public_Key& key,
                                  const std::string& input_hash_algo,
                                  const std::string& input_sig_algo,
                                  bool for_client_auth,
                                  const Policy& policy) const
   {
   const std::string key_type = key.algo_name();

   if(!policy.allowed_signature_method(key_type))
      {
      throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
                          "Rejecting " + key_type + " signature");
      }

   std::string hash_algo;

   if(this->version().supports_negotiable_signature_algorithms())
      {
      if(input_sig_algo != key_type)
         throw Decoding_Error("Counterparty sent inconsistent key and sig types");

      if(input_hash_algo == "")
         throw Decoding_Error("Counterparty did not send hash/sig IDS");

      hash_algo = input_hash_algo;

      if(for_client_auth && !cert_req())
         {
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
                             "No certificate verify set");
         }

      /*
      Confirm the signature type we just received against the
      supported_algos list that we sent; it better be there.
      */

      const auto supported_algos =
         for_client_auth ? cert_req()->supported_algos() :
                           client_hello()->supported_algos();

      if(!supported_algos_include(supported_algos, key_type, hash_algo))
         {
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
                             "TLS signature extension did not allow for " +
                             key_type + "/" + hash_algo + " signature");
         }
      }
   else
      {
      if(input_hash_algo != "" || input_sig_algo != "")
         throw Decoding_Error("Counterparty sent hash/sig IDs with old version");

      if(key_type == "RSA")
         {
         hash_algo = "Parallel(MD5,SHA-160)";
         }
      else if(key_type == "DSA" || key_type == "ECDSA")
         {
         hash_algo = "SHA-1";
         }
      else
         {
         throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures");
         }

      /*
      There is no check on the acceptability of a v1.0/v1.1 hash type,
      since it's implicit with use of the protocol
      */
      }

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

   throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures");
   }
コード例 #7
0
ファイル: x509_obj.cpp プロジェクト: webmaster128/botan
Certificate_Status_Code X509_Object::verify_signature(const Public_Key& pub_key) const
   {
   const std::vector<std::string> sig_info =
      split_on(OIDS::lookup(m_sig_algo.get_oid()), '/');

   if(sig_info.size() < 1 || sig_info.size() > 2 || sig_info[0] != pub_key.algo_name())
      return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;

   std::string padding;
   if(sig_info.size() == 2)
      padding = sig_info[1];
   else if(sig_info[0] == "Ed25519")
      padding = "Pure";
   else
      return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;

   const Signature_Format format =
      (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;

   if(padding == "EMSA4")
      {
      // "MUST contain RSASSA-PSS-params"
      if(signature_algorithm().parameters.empty())
         {
         return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
         }

      Pss_params pss_parameter = decode_pss_params(signature_algorithm().parameters);

      // hash_algo must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512
      const std::string hash_algo = OIDS::lookup(pss_parameter.hash_algo.oid);
      if(hash_algo != "SHA-160" &&
         hash_algo != "SHA-224" &&
         hash_algo != "SHA-256" &&
         hash_algo != "SHA-384" &&
         hash_algo != "SHA-512")
         {
         return Certificate_Status_Code::UNTRUSTED_HASH;
         }

      const std::string mgf_algo = OIDS::lookup(pss_parameter.mask_gen_algo.oid);
      if(mgf_algo != "MGF1")
         {
         return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
         }

      // For MGF1, it is strongly RECOMMENDED that the underlying hash function be the same as the one identified by hashAlgorithm
      // Must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512
      if(pss_parameter.mask_gen_hash.oid != pss_parameter.hash_algo.oid)
         {
         return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
         }

      if(pss_parameter.trailer_field != 1)
         {
         return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
         }

      // salt_len is actually not used for verification. Length is inferred from the signature
      padding += "(" + hash_algo + "," + mgf_algo + "," + std::to_string(pss_parameter.salt_len) + ")";
      }

   try
      {
      PK_Verifier verifier(pub_key, padding, format);
      const bool valid = verifier.verify_message(tbs_data(), signature());

      if(valid)
         return Certificate_Status_Code::VERIFIED;
      else
         return Certificate_Status_Code::SIGNATURE_ERROR;
      }
   catch(Algorithm_Not_Found&)
      {
      return Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN;
      }
   catch(...)
      {
      // This shouldn't happen, fallback to generic signature error
      return Certificate_Status_Code::SIGNATURE_ERROR;
      }
   }