Botan 3.11.0
Crypto and TLS for C&
Botan::PKCS11::InterfaceWrapper Class Referencefinal

Wraps a PKCS #11 Interface object. More...

#include <p11.h>

Public Member Functions

const FunctionListfunc_2_40 () const
 Access a function list that contains all methods since PKCS #11 v.2.40.
const FunctionList30func_3_0 () const
 Access a function list that contains all methods since PKCS #11 v.3.0.
const FunctionList32func_3_2 () const
 Access a function list that contains all methods since PKCS #11 v.3.2.
 InterfaceWrapper (const InterfaceWrapper &)=default
 InterfaceWrapper (Interface raw_interface)
 Basic constructor using an interface.
 InterfaceWrapper (InterfaceWrapper &&)=default
std::span< const Utf8Charname () const
 Access the name of the interface.
InterfaceWrapperoperator= (const InterfaceWrapper &)=default
InterfaceWrapperoperator= (InterfaceWrapper &&)=default
const Interfaceraw_interface () const
 Access the underlying interface object.
Version version () const
 Access the version of the interface.
 ~InterfaceWrapper ()=default

Static Public Member Functions

static InterfaceWrapper latest_p11_interface (Dynamically_Loaded_Library &library)
static Utf8Charp11_interface_name_ptr ()

Detailed Description

Wraps a PKCS #11 Interface object.

This class provides an interface to access PKCS #11 functions of various versions. For example func_3_0() returns the PKCS #11 v3.0 function list for a loaded interface. Only the official "PKCS 11" named interfaces are supported.

Definition at line 1275 of file p11.h.

Constructor & Destructor Documentation

◆ InterfaceWrapper() [1/3]

Botan::PKCS11::InterfaceWrapper::InterfaceWrapper ( Interface raw_interface)
explicit

Basic constructor using an interface.

Definition at line 53 of file p11_interface.cpp.

53 : m_interface(raw_interface) {
54 BOTAN_ASSERT_NONNULL(raw_interface.pInterfaceName);
56}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
const Interface & raw_interface() const
Access the underlying interface object.
Definition p11.h:1290

References BOTAN_ASSERT_NONNULL, and raw_interface().

Referenced by InterfaceWrapper(), InterfaceWrapper(), latest_p11_interface(), operator=(), and operator=().

◆ InterfaceWrapper() [2/3]

Botan::PKCS11::InterfaceWrapper::InterfaceWrapper ( const InterfaceWrapper & )
default

References InterfaceWrapper().

◆ InterfaceWrapper() [3/3]

Botan::PKCS11::InterfaceWrapper::InterfaceWrapper ( InterfaceWrapper && )
default

References InterfaceWrapper().

◆ ~InterfaceWrapper()

Botan::PKCS11::InterfaceWrapper::~InterfaceWrapper ( )
default

Member Function Documentation

◆ func_2_40()

const FunctionList & Botan::PKCS11::InterfaceWrapper::func_2_40 ( ) const

Access a function list that contains all methods since PKCS #11 v.2.40.

Definition at line 124 of file p11_interface.cpp.

124 {
125 if(!std::ranges::equal(name(), PKCS11_INTERFACE_NAME)) {
126 throw Botan::Invalid_State("Vendor defined PKCS #11 interfaces are not supported.");
127 }
128 return *reinterpret_cast<FunctionList*>(raw_interface().pFunctionList);
129}
std::span< const Utf8Char > name() const
Access the name of the interface.
CK_FUNCTION_LIST FunctionList
Definition p11.h:1187
void * pFunctionList
Definition pkcs11.h:1307

References name(), CK_INTERFACE::pFunctionList, and raw_interface().

◆ func_3_0()

const FunctionList30 & Botan::PKCS11::InterfaceWrapper::func_3_0 ( ) const

Access a function list that contains all methods since PKCS #11 v.3.0.

Definition at line 131 of file p11_interface.cpp.

131 {
132 if(!std::ranges::equal(name(), PKCS11_INTERFACE_NAME)) {
133 throw Botan::Invalid_State("Vendor defined PKCS #11 interfaces are not supported.");
134 }
135 if(version() < Version{3, 0}) {
136 throw Botan::Invalid_State("Loaded interface does not support PKCS #11 v3.0 features");
137 }
138 return *reinterpret_cast<FunctionList30*>(raw_interface().pFunctionList);
139}
Version version() const
Access the version of the interface.
CK_VERSION Version
Definition p11.h:1200
CK_FUNCTION_LIST_3_0 FunctionList30
Definition p11.h:1189

References name(), CK_INTERFACE::pFunctionList, raw_interface(), and version().

◆ func_3_2()

const FunctionList32 & Botan::PKCS11::InterfaceWrapper::func_3_2 ( ) const

Access a function list that contains all methods since PKCS #11 v.3.2.

Definition at line 141 of file p11_interface.cpp.

141 {
142 if(!std::ranges::equal(name(), PKCS11_INTERFACE_NAME)) {
143 throw Botan::Invalid_State("Vendor defined PKCS #11 interfaces are not supported.");
144 }
145 if(version() < Version{3, 2}) {
146 throw Botan::Invalid_State("Loaded interface does not support PKCS #11 v3.2 features");
147 }
148 return *reinterpret_cast<FunctionList32*>(raw_interface().pFunctionList);
149}
CK_FUNCTION_LIST_3_2 FunctionList32
Definition p11.h:1190

References name(), CK_INTERFACE::pFunctionList, raw_interface(), and version().

◆ latest_p11_interface()

InterfaceWrapper Botan::PKCS11::InterfaceWrapper::latest_p11_interface ( Dynamically_Loaded_Library & library)
static

Find the latest supported "PKCS 11" interface. Fork safe interfaces are preferred over non fork safe ones of the same version.

Definition at line 66 of file p11_interface.cpp.

66 {
67 Ulong count = 0;
68 auto rv = LowLevel::C_GetInterfaceList(library, nullptr, &count, nullptr);
69 if(!rv) {
70 // Method could not be executed. Probably due to a cryptoki library with PKCS #11 < 3.0.
71 // Try the legacy C_GetFunctionList method (for PKCS#11 version 2.40).
72 FunctionList* func_list = nullptr; // NOLINT(*-const-correctness) bug in clang-tidy
73 rv = LowLevel::C_GetFunctionList(library, &func_list, nullptr);
74 if(!rv) {
75 throw Invalid_Argument("Failed to load function list for PKCS#11 library.");
76 }
77
80 .pFunctionList = func_list,
81 .flags = 0,
82 }};
83 }
84 std::vector<Interface> interface_list(count);
85 rv = LowLevel::C_GetInterfaceList(library, interface_list.data(), &count, nullptr);
86 if(!rv) {
87 // The interface list count could be computed but the interface list cannot be received. This should not happen.
88 throw Invalid_Argument("Unexpected error while loading PKCS#11 interface list.");
89 }
90
91 // We only load interfaces named "PKCS 11" (which are the pure ones defined in the spec) with
92 // version >= 2.40.
93 auto is_valid_interface = [](const Interface& i) {
94 // This is also done by the example in PKCS #11 (version >= 3.0) spec.
95 // Note that version above the currently supported maximal version should
96 // be compatible too.
97 const Version version = version_of(i);
98 return version >= Version{2, 40};
99 };
100 std::vector<Interface> valid_interfaces;
101 std::copy_if(interface_list.begin(), interface_list.end(), std::back_inserter(valid_interfaces), is_valid_interface);
102
103 if(valid_interfaces.empty()) {
104 throw Invalid_Argument("No supported PKCS #11 interfaces found.");
105 }
106
107 // We prioritize valid interfaces the following way:
108 // Higher versions are preferred over lower ones. If multiple interfaces of
109 // the highest version exist, fork safe interfaces are preferred.
110 auto priority_comparator = [](const Interface& left, const Interface& right) {
111 const Version left_version = version_of(left);
112 const Version right_version = version_of(right);
113
114 if(left_version == right_version) {
115 return (left.flags & static_cast<CK_FLAGS>(Flag::InterfaceForkSafe)) <
116 (right.flags & static_cast<CK_FLAGS>(Flag::InterfaceForkSafe));
117 }
118 return left_version < right_version;
119 };
120 auto best_interface = std::max_element(valid_interfaces.begin(), valid_interfaces.end(), priority_comparator);
121 return InterfaceWrapper(*best_interface);
122}
static Utf8Char * p11_interface_name_ptr()
InterfaceWrapper(Interface raw_interface)
Basic constructor using an interface.
static bool C_GetFunctionList(const Dynamically_Loaded_Library &pkcs11_module, FunctionList **function_list_ptr_ptr, ReturnValue *return_value=ThrowException)
Definition p11.cpp:90
static bool C_GetInterfaceList(const Dynamically_Loaded_Library &pkcs11_module, Interface *interface_list_ptr, Ulong *count_ptr, ReturnValue *return_value=ThrowException)
Definition p11.cpp:100
CK_INTERFACE Interface
Definition p11.h:1191
CK_ULONG Ulong
Definition p11.h:1203
CK_ULONG CK_FLAGS
Definition pkcs11.h:49

References Botan::PKCS11::LowLevel::C_GetFunctionList(), Botan::PKCS11::LowLevel::C_GetInterfaceList(), CK_INTERFACE::flags, Botan::PKCS11::InterfaceForkSafe, InterfaceWrapper(), p11_interface_name_ptr(), and version().

Referenced by Botan::PKCS11::Module::reload().

◆ name()

std::span< const Utf8Char > Botan::PKCS11::InterfaceWrapper::name ( ) const

Access the name of the interface.

Definition at line 62 of file p11_interface.cpp.

62 {
63 return name_of(m_interface);
64}

Referenced by func_2_40(), func_3_0(), and func_3_2().

◆ operator=() [1/2]

InterfaceWrapper & Botan::PKCS11::InterfaceWrapper::operator= ( const InterfaceWrapper & )
default

References InterfaceWrapper().

◆ operator=() [2/2]

InterfaceWrapper & Botan::PKCS11::InterfaceWrapper::operator= ( InterfaceWrapper && )
default

References InterfaceWrapper().

◆ p11_interface_name_ptr()

Utf8Char * Botan::PKCS11::InterfaceWrapper::p11_interface_name_ptr ( )
static

Returns an immortal pointer to the Utf8Char string "PKCS 11". Used to define an interface object.

Warning
Unfortunately, the interface object requires a non constant pointer. However, this string MUST NOT be modified!

Definition at line 151 of file p11_interface.cpp.

151 {
152 static std::array<Utf8Char, 8> STATIC_PKCS11_INTERFACE_NAME_ARR = {"PKCS 11"};
153 return STATIC_PKCS11_INTERFACE_NAME_ARR.data();
154}

Referenced by latest_p11_interface(), and Botan::PKCS11::LowLevel::LowLevel().

◆ raw_interface()

const Interface & Botan::PKCS11::InterfaceWrapper::raw_interface ( ) const
inline

Access the underlying interface object.

Definition at line 1290 of file p11.h.

1290{ return m_interface; }

Referenced by func_2_40(), func_3_0(), func_3_2(), and InterfaceWrapper().

◆ version()

Version Botan::PKCS11::InterfaceWrapper::version ( ) const

Access the version of the interface.

Definition at line 58 of file p11_interface.cpp.

58 {
59 return version_of(m_interface);
60}

Referenced by func_3_0(), func_3_2(), and latest_p11_interface().


The documentation for this class was generated from the following files: