Botan 3.13.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 p11_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 1283 of file p11.h.

Constructor & Destructor Documentation

◆ InterfaceWrapper() [1/3]

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

Basic constructor using an interface.

Definition at line 52 of file p11_interface.cpp.

52 : m_p11_interface(p11_interface) {
53 if(p11_interface.pInterfaceName == nullptr || p11_interface.pFunctionList == nullptr) {
54 throw PKCS11_Error("PKCS #11 interface has null pInterfaceName or pFunctionList");
55 }
56}

References CK_INTERFACE::pFunctionList, and CK_INTERFACE::pInterfaceName.

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 127 of file p11_interface.cpp.

127 {
128 if(!std::ranges::equal(name(), PKCS11_INTERFACE_NAME)) {
129 throw Botan::Invalid_State("Vendor defined PKCS #11 interfaces are not supported.");
130 }
131 return *reinterpret_cast<FunctionList*>(raw_interface().pFunctionList);
132}
std::span< const Utf8Char > name() const
Access the name of the interface.
const Interface & raw_interface() const
Access the underlying interface object.
Definition p11.h:1298
CK_FUNCTION_LIST FunctionList
Definition p11.h:1188
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 134 of file p11_interface.cpp.

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

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 144 of file p11_interface.cpp.

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

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 || func_list == nullptr) {
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 if(i.pFunctionList == nullptr || i.pInterfaceName == nullptr) {
95 return false;
96 }
97 if(!std::ranges::equal(name_of(i), PKCS11_INTERFACE_NAME)) {
98 return false;
99 }
100 const Version version = version_of(i);
101 return version >= Version{2, 40};
102 };
103 std::vector<Interface> valid_interfaces;
104 std::copy_if(interface_list.begin(), interface_list.end(), std::back_inserter(valid_interfaces), is_valid_interface);
105
106 if(valid_interfaces.empty()) {
107 throw Invalid_Argument("No supported PKCS #11 interfaces found.");
108 }
109
110 // We prioritize valid interfaces the following way:
111 // Higher versions are preferred over lower ones. If multiple interfaces of
112 // the highest version exist, fork safe interfaces are preferred.
113 auto priority_comparator = [](const Interface& left, const Interface& right) {
114 const Version left_version = version_of(left);
115 const Version right_version = version_of(right);
116
117 if(left_version == right_version) {
118 return (left.flags & static_cast<CK_FLAGS>(Flag::InterfaceForkSafe)) <
119 (right.flags & static_cast<CK_FLAGS>(Flag::InterfaceForkSafe));
120 }
121 return left_version < right_version;
122 };
123 auto best_interface = std::max_element(valid_interfaces.begin(), valid_interfaces.end(), priority_comparator);
124 return InterfaceWrapper(*best_interface);
125}
static Utf8Char * p11_interface_name_ptr()
InterfaceWrapper(Interface p11_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:1192
CK_ULONG Ulong
Definition p11.h:1204
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_p11_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 154 of file p11_interface.cpp.

154 {
155 static std::array<Utf8Char, 8> STATIC_PKCS11_INTERFACE_NAME_ARR = {"PKCS 11"};
156 return STATIC_PKCS11_INTERFACE_NAME_ARR.data();
157}

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 1298 of file p11.h.

1298{ return m_p11_interface; }

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

◆ 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_p11_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: