Skip to content

Commit

Permalink
Apply internal review suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
FAlbertDev committed Jan 17, 2025
1 parent cc1ceff commit cad62aa
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 29 deletions.
32 changes: 13 additions & 19 deletions src/lib/prov/pkcs11/p11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,12 @@ bool LowLevel::C_GetInterfaceList(const Dynamically_Loaded_Library& pkcs11_modul
Ulong* count_ptr,
ReturnValue* return_value) {
using get_interface_list = CK_RV (*)(Interface*, Ulong*);
get_interface_list get_interface_list_ptr;
try {
get_interface_list_ptr = pkcs11_module.resolve<get_interface_list>("C_GetInterfaceList");
} catch(Invalid_Argument&) {
// Loading the library function failed. Probably due to a cryptoki library with PKCS #11 < 3.0.
return handle_return_value(CKR_GENERAL_ERROR, return_value);
if(auto get_interface_list_ptr = pkcs11_module.try_resolve_symbol<get_interface_list>("C_GetInterfaceList");
get_interface_list_ptr.has_value()) {
return handle_return_value(get_interface_list_ptr.value()(interface_list_ptr, count_ptr), return_value);
}

return handle_return_value(get_interface_list_ptr(interface_list_ptr, count_ptr), return_value);
// Loading the library function failed. Probably due to a cryptoki library with PKCS #11 < 3.0.
return handle_return_value(CKR_GENERAL_ERROR, return_value);
}

bool LowLevel::C_GetInterface(const Dynamically_Loaded_Library& pkcs11_module,
Expand All @@ -123,18 +120,15 @@ bool LowLevel::C_GetInterface(const Dynamically_Loaded_Library& pkcs11_module,
ReturnValue* return_value) {
using get_interface =
CK_RV (*)(Utf8Char* interface_name_ptr, Version* version_ptr, Interface* interface_ptr_ptr, Flags flags);
get_interface get_interface_ptr;
try {
get_interface_ptr = pkcs11_module.resolve<get_interface>("C_GetInterface");
} catch(Invalid_Argument&) {
// Loading the library function failed. Probably due to a cryptoki library with PKCS #11 < 3.0.
return handle_return_value(CKR_GENERAL_ERROR, return_value);
if(auto get_interface_ptr = pkcs11_module.try_resolve_symbol<get_interface>("C_GetInterface");
get_interface_ptr.has_value()) {
return handle_return_value(
get_interface_ptr.value()(
const_cast<Utf8Char*>(interface_name_ptr), const_cast<Version*>(version_ptr), interface_ptr_ptr, flags),
return_value);
}

return handle_return_value(
get_interface_ptr(
const_cast<Utf8Char*>(interface_name_ptr), const_cast<Version*>(version_ptr), interface_ptr_ptr, flags),
return_value);
// Loading the library function failed. Probably due to a cryptoki library with PKCS #11 < 3.0.
return handle_return_value(CKR_GENERAL_ERROR, return_value);
}

/****************************** Slot and token management functions ******************************/
Expand Down
2 changes: 1 addition & 1 deletion src/lib/prov/pkcs11/p11.h
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ class BOTAN_PUBLIC_API(3, 7) InterfaceWrapper {

public:
/// Basic constructor using an interface.
InterfaceWrapper(Interface raw_interface) : m_interface(raw_interface) {}
InterfaceWrapper(Interface raw_interface);

InterfaceWrapper(const InterfaceWrapper&) = default;
InterfaceWrapper& operator=(const InterfaceWrapper&) = default;
Expand Down
8 changes: 8 additions & 0 deletions src/lib/prov/pkcs11/p11_error.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/*
* PKCS #11 Error Information
* (C) 2025 Jack Lloyd
* (C) 2025 Fabian Albert - Rohde & Schwarz Cybersecurity GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/p11.h>
#include <botan/internal/fmt.h>

Expand Down
5 changes: 5 additions & 0 deletions src/lib/prov/pkcs11/p11_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ std::basic_string_view<Utf8Char> name_of(const Interface& interface) {

} // namespace

InterfaceWrapper::InterfaceWrapper(Interface raw_interface) : m_interface(raw_interface) {
BOTAN_ASSERT_NONNULL(raw_interface.pInterfaceName);
BOTAN_ASSERT_NONNULL(raw_interface.pFunctionList);
}

Version InterfaceWrapper::version() const {
return version_of(m_interface);
}
Expand Down
13 changes: 7 additions & 6 deletions src/lib/utils/dyn_load/dyn_load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,19 @@ Dynamically_Loaded_Library::~Dynamically_Loaded_Library() {
}

void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) const {
void* addr = nullptr;
if(void* addr = resolve_symbol_internal(symbol)) {
return addr;
}
throw Invalid_Argument(fmt("Failed to resolve symbol {} in {}", symbol, m_lib_name));
}

void* Dynamically_Loaded_Library::resolve_symbol_internal(const std::string& symbol) const {
void* addr = nullptr;
#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
addr = ::dlsym(m_lib, symbol.c_str());
#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
addr = reinterpret_cast<void*>(::GetProcAddress(reinterpret_cast<HMODULE>(m_lib), symbol.c_str()));
#endif

if(!addr) {
throw Invalid_Argument(fmt("Failed to resolve symbol {} in {}", symbol, m_lib_name));
}

return addr;
}

Expand Down
28 changes: 25 additions & 3 deletions src/lib/utils/dyn_load/dyn_load.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define BOTAN_DYNAMIC_LOADER_H_

#include <botan/types.h>
#include <optional>
#include <string>

namespace Botan {
Expand Down Expand Up @@ -36,24 +37,45 @@ class BOTAN_TEST_API Dynamically_Loaded_Library final {
*/
~Dynamically_Loaded_Library();

/**
* Try to load a symbol
* @param symbol names the symbol to load
* @return address of the loaded symbol or std::nullopt if the symbol
* was not found
*/
template <typename PtrT>
std::optional<PtrT> try_resolve_symbol(const std::string& symbol) const
requires(std::is_pointer_v<PtrT>)
{
void* addr = resolve_symbol_internal(symbol);
return addr ? reinterpret_cast<PtrT>(addr) : std::nullopt;
}

/**
* Load a symbol (or fail with an exception)
* @param symbol names the symbol to load
* @return address of the loaded symbol
* @throws Invalid_Argument if the symbol is not found
*/
void* resolve_symbol(const std::string& symbol) const;

/**
* Convenience function for casting symbol to the right type
* @param symbol names the symbol to load
* @return address of the loaded symbol
* @throws Invalid_Argument if the symbol is not found
*/
template <typename T>
T resolve(const std::string& symbol) const {
return reinterpret_cast<T>(resolve_symbol(symbol));
template <typename PtrT>
PtrT resolve(const std::string& symbol) const
requires(std::is_pointer_v<PtrT>)
{
return reinterpret_cast<PtrT>(resolve_symbol(symbol));
}

private:
/// Returns a pointer to the symbol or nullptr if the symbol is not found.
void* resolve_symbol_internal(const std::string& symbol) const;

Dynamically_Loaded_Library(const Dynamically_Loaded_Library&);
Dynamically_Loaded_Library& operator=(const Dynamically_Loaded_Library&);

Expand Down

0 comments on commit cad62aa

Please sign in to comment.