/* * Return the hash used in generating the signature */ std::string X509_Object::hash_used_for_signature() const { const OID& oid = m_sig_algo.get_oid(); const std::vector<std::string> sig_info = split_on(OIDS::lookup(oid), '/'); if(sig_info.size() == 1 && sig_info[0] == "Ed25519") return "SHA-512"; else if(sig_info.size() != 2) throw Internal_Error("Invalid name format found for " + oid.as_string()); if(sig_info[1] == "EMSA4") { return OIDS::lookup(decode_pss_params(signature_algorithm().get_parameters()).hash_algo.get_oid()); } else { const std::vector<std::string> pad_and_hash = parse_algorithm_name(sig_info[1]); if(pad_and_hash.size() != 2) { throw Internal_Error("Invalid name format " + sig_info[1]); } return pad_and_hash[1]; } }
/* * Return the hash used in generating the signature */ std::string X509_Object::hash_used_for_signature() const { std::vector<std::string> sig_info = split_on(OIDS::lookup(m_sig_algo.oid), '/'); if(sig_info.size() != 2) throw Internal_Error("Invalid name format found for " + m_sig_algo.oid.as_string()); std::vector<std::string> pad_and_hash = parse_algorithm_name(sig_info[1]); if(pad_and_hash.size() != 2) throw Internal_Error("Invalid name format " + sig_info[1]); return pad_and_hash[1]; }
Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction) { if(auto sc = StreamCipher::create(algo)) { return new Stream_Cipher_Mode(sc.release()); } #if defined(BOTAN_HAS_AEAD_MODES) if(auto aead = get_aead(algo, direction)) { return aead; } #endif if(algo.find('/') != std::string::npos) { const std::vector<std::string> algo_parts = split_on(algo, '/'); const std::string cipher_name = algo_parts[0]; const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]); if(mode_info.empty()) return nullptr; std::ostringstream alg_args; alg_args << '(' << cipher_name; for(size_t i = 1; i < mode_info.size(); ++i) alg_args << ',' << mode_info[i]; for(size_t i = 2; i < algo_parts.size(); ++i) alg_args << ',' << algo_parts[i]; alg_args << ')'; const std::string mode_name = mode_info[0] + alg_args.str(); return get_cipher_mode(mode_name, direction); } #if defined(BOTAN_HAS_BLOCK_CIPHER) SCAN_Name spec(algo); if(spec.arg_count() == 0) { return nullptr; } std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0))); if(!bc) { return nullptr; } #if defined(BOTAN_HAS_MODE_CBC) if(spec.algo_name() == "CBC") { const std::string padding = spec.arg(1, "PKCS7"); if(padding == "CTS") { if(direction == ENCRYPTION) return new CTS_Encryption(bc.release()); else return new CTS_Decryption(bc.release()); } else { std::unique_ptr<BlockCipherModePaddingMethod> pad(get_bc_pad(padding)); if(pad) { if(direction == ENCRYPTION) return new CBC_Encryption(bc.release(), pad.release()); else return new CBC_Decryption(bc.release(), pad.release()); } } } #endif #if defined(BOTAN_HAS_MODE_XTS) if(spec.algo_name() == "XTS") { if(direction == ENCRYPTION) return new XTS_Encryption(bc.release()); else return new XTS_Decryption(bc.release()); } #endif #if defined(BOTAN_HAS_MODE_CFB) if(spec.algo_name() == "CFB") { const size_t feedback_bits = spec.arg_as_integer(1, 8*bc->block_size()); if(direction == ENCRYPTION) return new CFB_Encryption(bc.release(), feedback_bits); else return new CFB_Decryption(bc.release(), feedback_bits); } #endif #endif return nullptr; }
Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction) { const std::string provider = ""; const char* dir_string = (direction == ENCRYPTION) ? "_Encryption" : "_Decryption"; Cipher_Mode::Spec spec(algo_spec, dir_string); std::unique_ptr<Cipher_Mode> cipher_mode( Algo_Registry<Cipher_Mode>::global_registry().make( Cipher_Mode::Spec(algo_spec, dir_string), provider) ); if(cipher_mode) { return cipher_mode.release(); } const std::vector<std::string> algo_parts = split_on(algo_spec, '/'); if(algo_parts.size() < 2) return nullptr; const std::string cipher_name = algo_parts[0]; const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]); if(mode_info.empty()) return nullptr; std::ostringstream alg_args; alg_args << '(' << cipher_name; for(size_t i = 1; i < mode_info.size(); ++i) alg_args << ',' << mode_info[i]; for(size_t i = 2; i < algo_parts.size(); ++i) alg_args << ',' << algo_parts[i]; alg_args << ')'; const std::string mode_name = mode_info[0] + alg_args.str(); const std::string mode_name_directional = mode_info[0] + dir_string + alg_args.str(); cipher_mode.reset( Algo_Registry<Cipher_Mode>::global_registry().make( Cipher_Mode::Spec(mode_name_directional), provider) ); if(cipher_mode) { return cipher_mode.release(); } cipher_mode.reset( Algo_Registry<Cipher_Mode>::global_registry().make( Cipher_Mode::Spec(mode_name), provider) ); if(cipher_mode) { return cipher_mode.release(); } if(auto sc = StreamCipher::create(mode_name, provider)) { return new Stream_Cipher_Mode(sc.release()); } return nullptr; }