Backed out changeset 390256672eac (bug 1958095) for causing bustages at libpkcs11testmodule.so. CLOSED TREE
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -5107,14 +5107,6 @@ dependencies = [
|
||||
"bindgen 0.69.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs11testmodule-static"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mozilla-central-workspace-hack",
|
||||
"pkcs11-bindings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.26"
|
||||
|
||||
@@ -11,9 +11,8 @@ members = [
|
||||
"netwerk/test/http3server",
|
||||
"security/manager/ssl/ipcclientcerts",
|
||||
"security/manager/ssl/osclientcerts",
|
||||
"security/manager/ssl/tests/unit/pkcs11testmodule",
|
||||
"security/manager/ssl/tests/unit/test_trust_anchors",
|
||||
"security/manager/ssl/trust_anchors",
|
||||
"security/manager/ssl/tests/unit/test_trust_anchors",
|
||||
"security/mls/mls_gk",
|
||||
"testing/geckodriver",
|
||||
"toolkit/components/uniffi-bindgen-gecko-js",
|
||||
|
||||
@@ -277,5 +277,4 @@ jsrust = ["dep:allocator-api2", "dep:arrayvec", "dep:byteorder", "dep:cc", "dep:
|
||||
minidump-analyzer-export = ["dep:allocator-api2", "dep:arrayvec", "dep:bitflags", "dep:byteorder", "dep:clap", "dep:env_logger", "dep:futures-channel", "dep:futures-core", "dep:futures-executor", "dep:futures-sink", "dep:futures-util", "dep:getrandom", "dep:hashbrown", "dep:hex", "dep:indexmap", "dep:log", "dep:memchr", "dep:nom", "dep:num-traits", "dep:object", "dep:once_cell", "dep:scroll", "dep:serde_json", "dep:time", "dep:time-macros", "dep:tracing", "dep:uuid", "dep:windows-sys", "dep:zerocopy"]
|
||||
mozwer_s = ["dep:allocator-api2", "dep:byteorder", "dep:getrandom", "dep:hashbrown", "dep:indexmap", "dep:log", "dep:once_cell", "dep:scroll", "dep:serde_json", "dep:uuid", "dep:windows-sys", "dep:zerocopy"]
|
||||
nmhproxy = ["dep:allocator-api2", "dep:bitflags", "dep:byteorder", "dep:form_urlencoded", "dep:hashbrown", "dep:icu_locid", "dep:icu_properties", "dep:idna", "dep:indexmap", "dep:once_cell", "dep:percent-encoding", "dep:serde_json", "dep:smallvec", "dep:stable_deref_trait", "dep:tinystr", "dep:unicode-bidi", "dep:url", "dep:windows-sys", "dep:yoke", "dep:zerocopy", "dep:zerofrom", "dep:zerovec"]
|
||||
pkcs11testmodule-static = []
|
||||
test-trust-anchors-static = ["dep:bindgen", "dep:bitflags", "dep:itertools", "dep:memchr", "dep:nom", "dep:regex", "dep:smallvec"]
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
[package]
|
||||
name = "pkcs11testmodule-static"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
mozilla-central-workspace-hack = { version = "0.1", features = ["pkcs11testmodule-static"], optional = true }
|
||||
pkcs11-bindings = "0.1.1"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
FINAL_TARGET = "_tests/xpcshell/security/manager/ssl/tests/unit/pkcs11testmodule"
|
||||
|
||||
USE_LIBS += ["pkcs11testmodule-static"]
|
||||
|
||||
# On Linux (but not when building for Android), this needs to use the C++
|
||||
# version to avoid linking against the wrong libc symbols.
|
||||
# On Android, this needs to use the C version to avoid multiple definitions
|
||||
# of symbols caused by their presence in libgcc and pkcs11testmodule-static.
|
||||
|
||||
if CONFIG["OS_ARCH"] == "Linux" and CONFIG["OS_TARGET"] != "Android":
|
||||
SOURCES += [
|
||||
"stub.cpp",
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
"stub.c",
|
||||
]
|
||||
|
||||
if CONFIG["OS_TARGET"] == "Android":
|
||||
OS_LIBS += ["m"]
|
||||
|
||||
if CONFIG["OS_ARCH"] == "WINNT":
|
||||
OS_LIBS += [
|
||||
"advapi32",
|
||||
"userenv",
|
||||
"ws2_32",
|
||||
]
|
||||
OS_LIBS += [
|
||||
"bcrypt",
|
||||
"ntdll",
|
||||
]
|
||||
# Version string comparison is generally wrong, but by the time it would
|
||||
# actually matter, either bug 1489995 would be fixed, or the build would
|
||||
# require version >= 1.78.
|
||||
if CONFIG["RUSTC_VERSION"] and CONFIG["RUSTC_VERSION"] >= "1.78.0":
|
||||
OS_LIBS += [
|
||||
"synchronization",
|
||||
]
|
||||
|
||||
SharedLibrary("pkcs11testmodule")
|
||||
|
||||
NoVisibilityFlags()
|
||||
SYMBOLS_FILE = "pkcs11testmodule.symbols"
|
||||
@@ -1,43 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pkcs11.h"
|
||||
|
||||
// The build system builds the rust library pkcs11testmodule as a static
|
||||
// library called pkcs11testmodule-static. On macOS and Windows, that static
|
||||
// library can be linked with an empty file and turned into a shared library
|
||||
// with the function C_GetFunctionList exposed. Unfortunately, on Linux,
|
||||
// exposing the C_GetFunctionList in the static library doesn't work for some
|
||||
// unknown reason. As a workaround, this file declares its own
|
||||
// C_GetFunctionList that can be exposed in the shared library. It then calls
|
||||
// the function PKCS11TestModule_GetFunctionList exposed (internally to the
|
||||
// linkage in question) by pkcs11testmodule-static. This enables the build
|
||||
// system to ultimately turn pkcs11testmodule-static into a shared library that
|
||||
// exposes a C_GetFunctionList function, meaning it can be used as a PKCS#11
|
||||
// module.
|
||||
|
||||
CK_RV PKCS11TestModule_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
|
||||
|
||||
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {
|
||||
return PKCS11TestModule_GetFunctionList(ppFunctionList);
|
||||
}
|
||||
|
||||
// On MinGW there's a toolchain mismatch that results in _Unwind_Resume being
|
||||
// undefined. It's never going to get called here anyway, so this defines it to
|
||||
// satisfy the linker. See bug 1745855 and
|
||||
// https://github.com/rust-lang/rust/issues/79609#issuecomment-987107562.
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# include "mozilla/Assertions.h"
|
||||
void _Unwind_Resume() { MOZ_CRASH("Unexpected call to _Unwind_*"); }
|
||||
void _Unwind_GetDataRelBase() { _Unwind_Resume(); }
|
||||
void _Unwind_GetTextRelBase() { _Unwind_Resume(); }
|
||||
void _Unwind_GetLanguageSpecificData() { _Unwind_Resume(); }
|
||||
void _Unwind_GetIPInfo() { _Unwind_Resume(); }
|
||||
void _Unwind_GetRegionStart() { _Unwind_Resume(); }
|
||||
void _Unwind_SetGR() { _Unwind_Resume(); }
|
||||
void _Unwind_SetIP() { _Unwind_Resume(); }
|
||||
void _GCC_specific_handler() { _Unwind_Resume(); }
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "pkcs11.h"
|
||||
|
||||
// The build system builds the rust library pkcs11testmodule as a static
|
||||
// library called pkcs11testmodule-static. On macOS and Windows, that static
|
||||
// library can be linked with an empty file and turned into a shared library
|
||||
// with the function C_GetFunctionList exposed. Unfortunately, on Linux,
|
||||
// exposing the C_GetFunctionList in the static library doesn't work for some
|
||||
// unknown reason. As a workaround, this file declares its own
|
||||
// C_GetFunctionList that can be exposed in the shared library. It then calls
|
||||
// the function PKCS11TestModule_GetFunctionList exposed (internally to the
|
||||
// linkage in question) by pkcs11testmodule-static. This enables the build
|
||||
// system to ultimately turn pkcs11testmodule-static into a shared library that
|
||||
// exposes a C_GetFunctionList function, meaning it can be used as a PKCS#11
|
||||
// module.
|
||||
|
||||
extern "C" {
|
||||
|
||||
CK_RV PKCS11TestModule_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
|
||||
|
||||
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {
|
||||
return PKCS11TestModule_GetFunctionList(ppFunctionList);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,17 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += ["dynamic-library"]
|
||||
FINAL_TARGET = "_tests/xpcshell/security/manager/ssl/tests/unit/pkcs11testmodule"
|
||||
|
||||
RustLibrary("pkcs11testmodule-static")
|
||||
UNIFIED_SOURCES += [
|
||||
"pkcs11testmodule.cpp",
|
||||
]
|
||||
|
||||
SharedLibrary("pkcs11testmodule")
|
||||
|
||||
# C_GetFunctionList needs to be exported. As it turns out, it's much easier to
|
||||
# just export all the symbols.
|
||||
NoVisibilityFlags()
|
||||
SYMBOLS_FILE = "pkcs11testmodule.symbols"
|
||||
|
||||
NO_PGO = True
|
||||
|
||||
@@ -0,0 +1,597 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This is a testing PKCS #11 module that simulates a token being inserted and
|
||||
// removed from a slot every 50ms. This is achieved mainly in
|
||||
// Test_C_WaitForSlotEvent. If the application that loaded this module calls
|
||||
// C_WaitForSlotEvent, this module waits for 50ms and returns, having changed
|
||||
// its internal state to report that the token has either been inserted or
|
||||
// removed, as appropriate.
|
||||
// This module also provides an alternate token that is always present for tests
|
||||
// that don't want the cyclic behavior described above.
|
||||
|
||||
#include <assert.h>
|
||||
#include <atomic>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
# include <windows.h> // for Sleep
|
||||
#else
|
||||
# include <unistd.h> // for usleep
|
||||
#endif
|
||||
|
||||
#include "pkcs11.h"
|
||||
|
||||
CK_RV Test_C_Initialize(CK_VOID_PTR) { return CKR_OK; }
|
||||
|
||||
CK_RV Test_C_Finalize(CK_VOID_PTR) { return CKR_OK; }
|
||||
|
||||
static const CK_VERSION CryptokiVersion = {2, 2};
|
||||
static const CK_VERSION TestLibraryVersion = {0, 0};
|
||||
static const char TestLibraryDescription[] = "Test PKCS11 Library";
|
||||
static const char TestManufacturerID[] = "Test PKCS11 Manufacturer ID";
|
||||
|
||||
/* The dest buffer is one in the CK_INFO or CK_TOKEN_INFO structs.
|
||||
* Those buffers are padded with spaces. DestSize corresponds to the declared
|
||||
* size for those buffers (e.g. 32 for `char foo[32]`).
|
||||
* The src buffer is a string literal. SrcSize includes the string
|
||||
* termination character (e.g. 4 for `const char foo[] = "foo"` */
|
||||
template <size_t DestSize, size_t SrcSize>
|
||||
void CopyString(unsigned char (&dest)[DestSize], const char (&src)[SrcSize]) {
|
||||
static_assert(DestSize >= SrcSize - 1, "DestSize >= SrcSize - 1");
|
||||
memcpy(dest, src, SrcSize - 1);
|
||||
memset(dest + SrcSize - 1, ' ', DestSize - SrcSize + 1);
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetInfo(CK_INFO_PTR pInfo) {
|
||||
if (!pInfo) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
pInfo->cryptokiVersion = CryptokiVersion;
|
||||
CopyString(pInfo->manufacturerID, TestManufacturerID);
|
||||
pInfo->flags = 0; // must be 0
|
||||
CopyString(pInfo->libraryDescription, TestLibraryDescription);
|
||||
pInfo->libraryVersion = TestLibraryVersion;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR) { return CKR_OK; }
|
||||
|
||||
static int tokenPresent = 0;
|
||||
|
||||
CK_RV Test_C_GetSlotList(CK_BBOOL limitToTokensPresent,
|
||||
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
|
||||
if (!pulCount) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
// We always return slot 2
|
||||
CK_ULONG slotCount = 1;
|
||||
if (!limitToTokensPresent) {
|
||||
// If we want empty slots, we also return slots 1 and 3
|
||||
slotCount += 2;
|
||||
} else if (tokenPresent) {
|
||||
// If we don't want empty slots, but token 1 is present, return that (but
|
||||
// not slot 3)
|
||||
slotCount++;
|
||||
}
|
||||
|
||||
if (pSlotList) {
|
||||
if (*pulCount < slotCount) {
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
// apparently CK_SLOT_IDs are integers [1,N] because
|
||||
// who likes counting from 0 all the time?
|
||||
switch (slotCount) {
|
||||
case 1:
|
||||
pSlotList[0] = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (tokenPresent) {
|
||||
pSlotList[0] = 1;
|
||||
pSlotList[1] = 2;
|
||||
} else {
|
||||
pSlotList[0] = 2;
|
||||
pSlotList[1] = 3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
pSlotList[0] = 1;
|
||||
pSlotList[1] = 2;
|
||||
pSlotList[2] = 3;
|
||||
break;
|
||||
default:
|
||||
assert("Unexpected slot count in Test_C_GetSlotList" == NULL);
|
||||
return CKR_GENERAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*pulCount = slotCount;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static const char TestSlotDescription[] = "Test PKCS11 Slot";
|
||||
static const char TestSlot2Description[] = "Test PKCS11 Slot 二";
|
||||
static const char TestSlot3Description[] = "Empty PKCS11 Slot";
|
||||
|
||||
CK_RV Test_C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
|
||||
if (!pInfo) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
switch (slotID) {
|
||||
case 1:
|
||||
CopyString(pInfo->slotDescription, TestSlotDescription);
|
||||
pInfo->flags =
|
||||
(tokenPresent ? CKF_TOKEN_PRESENT : 0) | CKF_REMOVABLE_DEVICE;
|
||||
break;
|
||||
case 2:
|
||||
CopyString(pInfo->slotDescription, TestSlot2Description);
|
||||
pInfo->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE;
|
||||
break;
|
||||
case 3:
|
||||
CopyString(pInfo->slotDescription, TestSlot3Description);
|
||||
pInfo->flags = CKF_REMOVABLE_DEVICE;
|
||||
break;
|
||||
default:
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
CopyString(pInfo->manufacturerID, TestManufacturerID);
|
||||
pInfo->hardwareVersion = TestLibraryVersion;
|
||||
pInfo->firmwareVersion = TestLibraryVersion;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
// Deliberately include énye to ensure we're handling encoding correctly.
|
||||
// The PKCS #11 base specification v2.20 specifies that strings be encoded
|
||||
// as UTF-8.
|
||||
static const char TestTokenLabel[] = "Test PKCS11 Tokeñ Label";
|
||||
static const char TestToken2Label[] = "Test PKCS11 Tokeñ 2 Label";
|
||||
static const char TestTokenModel[] = "Test Model";
|
||||
|
||||
std::atomic<bool> sLoggedIn = false;
|
||||
|
||||
CK_RV Test_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) {
|
||||
if (!pInfo) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
switch (slotID) {
|
||||
case 1:
|
||||
CopyString(pInfo->label, TestTokenLabel);
|
||||
break;
|
||||
case 2:
|
||||
CopyString(pInfo->label, TestToken2Label);
|
||||
break;
|
||||
default:
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
CopyString(pInfo->manufacturerID, TestManufacturerID);
|
||||
CopyString(pInfo->model, TestTokenModel);
|
||||
memset(pInfo->serialNumber, 0, sizeof(pInfo->serialNumber));
|
||||
pInfo->flags = CKF_TOKEN_INITIALIZED;
|
||||
if (slotID == 2) {
|
||||
pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH |
|
||||
CKF_USER_PIN_INITIALIZED | CKF_LOGIN_REQUIRED;
|
||||
}
|
||||
pInfo->ulMaxSessionCount = 1;
|
||||
pInfo->ulSessionCount = 0;
|
||||
pInfo->ulMaxRwSessionCount = 1;
|
||||
pInfo->ulRwSessionCount = 0;
|
||||
pInfo->ulMaxPinLen = 4;
|
||||
pInfo->ulMinPinLen = 4;
|
||||
pInfo->ulTotalPublicMemory = 1024;
|
||||
pInfo->ulFreePublicMemory = 1024;
|
||||
pInfo->ulTotalPrivateMemory = 1024;
|
||||
pInfo->ulFreePrivateMemory = 1024;
|
||||
pInfo->hardwareVersion = TestLibraryVersion;
|
||||
pInfo->firmwareVersion = TestLibraryVersion;
|
||||
memset(pInfo->utcTime, 0, sizeof(pInfo->utcTime));
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetMechanismList(CK_SLOT_ID, CK_MECHANISM_TYPE_PTR,
|
||||
CK_ULONG_PTR pulCount) {
|
||||
if (!pulCount) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
*pulCount = 0;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetMechanismInfo(CK_SLOT_ID, CK_MECHANISM_TYPE,
|
||||
CK_MECHANISM_INFO_PTR) {
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_InitToken(CK_SLOT_ID, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR) {
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_InitPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SetPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG,
|
||||
CK_UTF8CHAR_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY,
|
||||
CK_SESSION_HANDLE_PTR phSession) {
|
||||
switch (slotID) {
|
||||
case 1:
|
||||
*phSession = 1;
|
||||
break;
|
||||
case 2:
|
||||
*phSession = 2;
|
||||
break;
|
||||
default:
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_CloseSession(CK_SESSION_HANDLE) { return CKR_OK; }
|
||||
|
||||
CK_RV Test_C_CloseAllSessions(CK_SLOT_ID) { return CKR_OK; }
|
||||
|
||||
CK_RV Test_C_GetSessionInfo(CK_SESSION_HANDLE hSession,
|
||||
CK_SESSION_INFO_PTR pInfo) {
|
||||
if (!pInfo) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
switch (hSession) {
|
||||
case 1:
|
||||
pInfo->slotID = 1;
|
||||
pInfo->state = CKS_RO_PUBLIC_SESSION;
|
||||
break;
|
||||
case 2:
|
||||
pInfo->slotID = 2;
|
||||
pInfo->state = sLoggedIn ? CKS_RO_USER_FUNCTIONS : CKS_RO_PUBLIC_SESSION;
|
||||
break;
|
||||
default:
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
pInfo->flags = CKF_SERIAL_SESSION;
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_OBJECT_HANDLE, CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG) {
|
||||
// Sleep for 3 seconds to simulate the user using a protected auth path.
|
||||
#ifdef WIN32
|
||||
Sleep(3000); // Sleep takes the duration argument as milliseconds
|
||||
#else
|
||||
usleep(3000000); // usleep takes the duration argument as microseconds
|
||||
#endif
|
||||
sLoggedIn = true;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_Logout(CK_SESSION_HANDLE) {
|
||||
sLoggedIn = false;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_CreateObject(CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG,
|
||||
CK_OBJECT_HANDLE_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR,
|
||||
CK_ULONG, CK_OBJECT_HANDLE_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetObjectSize(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
|
||||
CK_ATTRIBUTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
|
||||
CK_ATTRIBUTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG) {
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE_PTR, CK_ULONG,
|
||||
CK_ULONG_PTR pulObjectCount) {
|
||||
*pulObjectCount = 0;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV Test_C_FindObjectsFinal(CK_SESSION_HANDLE) { return CKR_OK; }
|
||||
|
||||
CK_RV Test_C_EncryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR,
|
||||
CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_Encrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
|
||||
CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_EncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_EncryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DecryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR,
|
||||
CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_Decrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
|
||||
CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DecryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DecryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DigestInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_Digest(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
|
||||
CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DigestKey(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DigestFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SignInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_Sign(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
|
||||
CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SignUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SignFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SignRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR,
|
||||
CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SignRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
|
||||
CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_VerifyInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_Verify(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR,
|
||||
CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_VerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_VerifyFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_VerifyRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR,
|
||||
CK_OBJECT_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_VerifyRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DigestEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DecryptDigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SignEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DecryptVerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG,
|
||||
CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR,
|
||||
CK_ULONG, CK_OBJECT_HANDLE_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GenerateKeyPair(CK_SESSION_HANDLE, CK_MECHANISM_PTR,
|
||||
CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR,
|
||||
CK_ULONG, CK_OBJECT_HANDLE_PTR,
|
||||
CK_OBJECT_HANDLE_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_WrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
||||
CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_UnwrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
||||
CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
|
||||
CK_OBJECT_HANDLE_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_DeriveKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
||||
CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GenerateRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_GetFunctionStatus(CK_SESSION_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_CancelFunction(CK_SESSION_HANDLE) {
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV Test_C_WaitForSlotEvent(CK_FLAGS, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR) {
|
||||
#ifdef WIN32
|
||||
Sleep(50); // Sleep takes the duration argument as milliseconds
|
||||
#else
|
||||
usleep(50000); // usleep takes the duration argument as microseconds
|
||||
#endif
|
||||
*pSlot = 1;
|
||||
tokenPresent = !tokenPresent;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_FUNCTION_LIST FunctionList = {{2, 2},
|
||||
Test_C_Initialize,
|
||||
Test_C_Finalize,
|
||||
Test_C_GetInfo,
|
||||
Test_C_GetFunctionList,
|
||||
Test_C_GetSlotList,
|
||||
Test_C_GetSlotInfo,
|
||||
Test_C_GetTokenInfo,
|
||||
Test_C_GetMechanismList,
|
||||
Test_C_GetMechanismInfo,
|
||||
Test_C_InitToken,
|
||||
Test_C_InitPIN,
|
||||
Test_C_SetPIN,
|
||||
Test_C_OpenSession,
|
||||
Test_C_CloseSession,
|
||||
Test_C_CloseAllSessions,
|
||||
Test_C_GetSessionInfo,
|
||||
Test_C_GetOperationState,
|
||||
Test_C_SetOperationState,
|
||||
Test_C_Login,
|
||||
Test_C_Logout,
|
||||
Test_C_CreateObject,
|
||||
Test_C_CopyObject,
|
||||
Test_C_DestroyObject,
|
||||
Test_C_GetObjectSize,
|
||||
Test_C_GetAttributeValue,
|
||||
Test_C_SetAttributeValue,
|
||||
Test_C_FindObjectsInit,
|
||||
Test_C_FindObjects,
|
||||
Test_C_FindObjectsFinal,
|
||||
Test_C_EncryptInit,
|
||||
Test_C_Encrypt,
|
||||
Test_C_EncryptUpdate,
|
||||
Test_C_EncryptFinal,
|
||||
Test_C_DecryptInit,
|
||||
Test_C_Decrypt,
|
||||
Test_C_DecryptUpdate,
|
||||
Test_C_DecryptFinal,
|
||||
Test_C_DigestInit,
|
||||
Test_C_Digest,
|
||||
Test_C_DigestUpdate,
|
||||
Test_C_DigestKey,
|
||||
Test_C_DigestFinal,
|
||||
Test_C_SignInit,
|
||||
Test_C_Sign,
|
||||
Test_C_SignUpdate,
|
||||
Test_C_SignFinal,
|
||||
Test_C_SignRecoverInit,
|
||||
Test_C_SignRecover,
|
||||
Test_C_VerifyInit,
|
||||
Test_C_Verify,
|
||||
Test_C_VerifyUpdate,
|
||||
Test_C_VerifyFinal,
|
||||
Test_C_VerifyRecoverInit,
|
||||
Test_C_VerifyRecover,
|
||||
Test_C_DigestEncryptUpdate,
|
||||
Test_C_DecryptDigestUpdate,
|
||||
Test_C_SignEncryptUpdate,
|
||||
Test_C_DecryptVerifyUpdate,
|
||||
Test_C_GenerateKey,
|
||||
Test_C_GenerateKeyPair,
|
||||
Test_C_WrapKey,
|
||||
Test_C_UnwrapKey,
|
||||
Test_C_DeriveKey,
|
||||
Test_C_SeedRandom,
|
||||
Test_C_GenerateRandom,
|
||||
Test_C_GetFunctionStatus,
|
||||
Test_C_CancelFunction,
|
||||
Test_C_WaitForSlotEvent};
|
||||
|
||||
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {
|
||||
*ppFunctionList = &FunctionList;
|
||||
return CKR_OK;
|
||||
}
|
||||
@@ -1,790 +0,0 @@
|
||||
/* -*- Mode: rust; rust-indent-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
extern crate pkcs11_bindings;
|
||||
|
||||
use pkcs11_bindings::*;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
static LOGGED_IN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// This gets called to initialize the module. For this implementation, there
|
||||
/// is nothing to initialize.
|
||||
extern "C" fn C_Initialize(_pInitArgs: CK_VOID_PTR) -> CK_RV {
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_Finalize(_pReserved: CK_VOID_PTR) -> CK_RV {
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
// The specification mandates that these strings be padded with spaces to the appropriate length.
|
||||
// Since the length of fixed-size arrays in rust is part of the type, the compiler enforces that
|
||||
// these byte strings are of the correct length.
|
||||
const MANUFACTURER_ID_BYTES: &[u8; 32] = b"Test PKCS11 Manufacturer ID ";
|
||||
const LIBRARY_DESCRIPTION_BYTES: &[u8; 32] = b"Test PKCS11 Library ";
|
||||
|
||||
/// This gets called to gather some information about the module. In particular, this implementation
|
||||
/// supports (portions of) cryptoki (PKCS #11) version 2.2.
|
||||
extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV {
|
||||
if pInfo.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
let info = CK_INFO {
|
||||
cryptokiVersion: CK_VERSION { major: 2, minor: 2 },
|
||||
manufacturerID: *MANUFACTURER_ID_BYTES,
|
||||
flags: 0,
|
||||
libraryDescription: *LIBRARY_DESCRIPTION_BYTES,
|
||||
libraryVersion: CK_VERSION { major: 0, minor: 0 },
|
||||
};
|
||||
unsafe {
|
||||
*pInfo = info;
|
||||
}
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_GetSlotList(
|
||||
tokenPresent: CK_BBOOL,
|
||||
pSlotList: CK_SLOT_ID_PTR,
|
||||
pulCount: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
// There are 3 slots total, but slots 1 and 3 have no token present.
|
||||
let slot_count: usize = if tokenPresent == CK_TRUE { 1 } else { 3 };
|
||||
if pulCount.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
if !pSlotList.is_null() {
|
||||
if unsafe { *pulCount } < slot_count.try_into().unwrap() {
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
let slot_list = unsafe { std::slice::from_raw_parts_mut(pSlotList, slot_count) };
|
||||
if tokenPresent == CK_TRUE {
|
||||
// The token with ID 2 is always present.
|
||||
slot_list[0] = 2;
|
||||
} else {
|
||||
slot_list[0] = 1;
|
||||
slot_list[1] = 2;
|
||||
slot_list[2] = 3;
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
*pulCount = slot_count.try_into().unwrap();
|
||||
}
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
const SLOT_DESCRIPTIONS_BYTES: [&'static [u8; 64]; 3] = [
|
||||
b"Test PKCS11 Slot ",
|
||||
// \xE4\xBA\x8C is the utf-8 encoding of '二' (2)
|
||||
b"Test PKCS11 Slot \xE4\xBA\x8C ",
|
||||
b"Empty PKCS11 Slot ",
|
||||
];
|
||||
|
||||
extern "C" fn C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV {
|
||||
let Ok(slot_id): Result<usize, _> = slotID.try_into() else {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
};
|
||||
if slot_id <= 0 || slot_id > SLOT_DESCRIPTIONS_BYTES.len() || pInfo.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
// Only slot 2 has a token present.
|
||||
let slot_info = CK_SLOT_INFO {
|
||||
slotDescription: *SLOT_DESCRIPTIONS_BYTES[slot_id - 1],
|
||||
manufacturerID: *MANUFACTURER_ID_BYTES,
|
||||
flags: if slot_id == 2 { CKF_TOKEN_PRESENT } else { 0 } | CKF_REMOVABLE_DEVICE,
|
||||
hardwareVersion: CK_VERSION::default(),
|
||||
firmwareVersion: CK_VERSION::default(),
|
||||
};
|
||||
unsafe {
|
||||
*pInfo = slot_info;
|
||||
}
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
const TOKEN_LABELS_BYTES: [&'static [u8; 32]; 3] = [
|
||||
// \xC3\xB1 is the utf-8 encoding of 'ñ'
|
||||
b"Test PKCS11 Toke\xC3\xB1 Label ",
|
||||
b"Test PKCS11 Toke\xC3\xB1 2 Label ",
|
||||
b"Test PKCS11 Toke\xC3\xB1 3 Label ",
|
||||
];
|
||||
const TOKEN_MODEL_BYTES: &[u8; 16] = b"Test Model ";
|
||||
|
||||
extern "C" fn C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV {
|
||||
let Ok(slot_id): Result<usize, _> = slotID.try_into() else {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
};
|
||||
if slot_id <= 0 || slot_id > TOKEN_LABELS_BYTES.len() || pInfo.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
let token_info = CK_TOKEN_INFO {
|
||||
label: *TOKEN_LABELS_BYTES[slot_id - 1],
|
||||
manufacturerID: *MANUFACTURER_ID_BYTES,
|
||||
model: *TOKEN_MODEL_BYTES,
|
||||
serialNumber: [0; 16],
|
||||
// Token 2 has a protected authentication path and requires login.
|
||||
flags: if slot_id == 2 {
|
||||
CKF_PROTECTED_AUTHENTICATION_PATH | CKF_USER_PIN_INITIALIZED | CKF_LOGIN_REQUIRED
|
||||
} else {
|
||||
0
|
||||
} | CKF_TOKEN_INITIALIZED,
|
||||
ulMaxSessionCount: CK_ULONG::MAX,
|
||||
ulSessionCount: 0,
|
||||
ulMaxRwSessionCount: CK_ULONG::MAX,
|
||||
ulRwSessionCount: 0,
|
||||
ulMaxPinLen: CK_ULONG::MAX,
|
||||
ulMinPinLen: 0,
|
||||
ulTotalPublicMemory: CK_ULONG::MAX,
|
||||
ulFreePublicMemory: CK_ULONG::MAX,
|
||||
ulTotalPrivateMemory: CK_ULONG::MAX,
|
||||
ulFreePrivateMemory: CK_ULONG::MAX,
|
||||
hardwareVersion: CK_VERSION::default(),
|
||||
firmwareVersion: CK_VERSION::default(),
|
||||
utcTime: [0; 16],
|
||||
};
|
||||
unsafe {
|
||||
*pInfo = token_info;
|
||||
}
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_GetMechanismList(
|
||||
_slotID: CK_SLOT_ID,
|
||||
_pMechanismList: CK_MECHANISM_TYPE_PTR,
|
||||
pulCount: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
if pulCount.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
unsafe {
|
||||
*pulCount = 0;
|
||||
}
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_GetMechanismInfo(
|
||||
_slotID: CK_SLOT_ID,
|
||||
_type: CK_MECHANISM_TYPE,
|
||||
_pInfo: CK_MECHANISM_INFO_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_InitToken(
|
||||
_slotID: CK_SLOT_ID,
|
||||
_pPin: CK_UTF8CHAR_PTR,
|
||||
_ulPinLen: CK_ULONG,
|
||||
_pLabel: CK_UTF8CHAR_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_InitPIN(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pPin: CK_UTF8CHAR_PTR,
|
||||
_ulPinLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SetPIN(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pOldPin: CK_UTF8CHAR_PTR,
|
||||
_ulOldLen: CK_ULONG,
|
||||
_pNewPin: CK_UTF8CHAR_PTR,
|
||||
_ulNewLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_OpenSession(
|
||||
slotID: CK_SLOT_ID,
|
||||
_flags: CK_FLAGS,
|
||||
_pApplication: CK_VOID_PTR,
|
||||
_Notify: CK_NOTIFY,
|
||||
phSession: CK_SESSION_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
if phSession.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
// Be "clever" and differentiate sessions based on the slotID.
|
||||
unsafe { *phSession = slotID };
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_CloseSession(_hSession: CK_SESSION_HANDLE) -> CK_RV {
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_CloseAllSessions(_slotID: CK_SLOT_ID) -> CK_RV {
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
// The CKS_* definitions aren't exposed by pkcs11-bindings currently.
|
||||
const CKS_RO_PUBLIC_FUNCTIONS: CK_STATE = 0;
|
||||
const CKS_RO_USER_FUNCTIONS: CK_STATE = 1;
|
||||
|
||||
extern "C" fn C_GetSessionInfo(hSession: CK_SESSION_HANDLE, pInfo: CK_SESSION_INFO_PTR) -> CK_RV {
|
||||
if pInfo.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
let info = CK_SESSION_INFO {
|
||||
// For now, slotID <=> hSession
|
||||
slotID: hSession,
|
||||
// If slot 2 has been logged in to, session 2 is a "user" session.
|
||||
state: if hSession == 2 && LOGGED_IN.load(Ordering::Acquire) {
|
||||
CKS_RO_USER_FUNCTIONS
|
||||
} else {
|
||||
CKS_RO_PUBLIC_FUNCTIONS
|
||||
},
|
||||
flags: 0,
|
||||
ulDeviceError: 0,
|
||||
};
|
||||
unsafe {
|
||||
*pInfo = info;
|
||||
}
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_GetOperationState(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pOperationState: CK_BYTE_PTR,
|
||||
_pulOperationStateLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SetOperationState(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pOperationState: CK_BYTE_PTR,
|
||||
_ulOperationStateLen: CK_ULONG,
|
||||
_hEncryptionKey: CK_OBJECT_HANDLE,
|
||||
_hAuthenticationKey: CK_OBJECT_HANDLE,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_Login(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_userType: CK_USER_TYPE,
|
||||
_pPin: CK_UTF8CHAR_PTR,
|
||||
_ulPinLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
LOGGED_IN.store(true, Ordering::Release);
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_Logout(_hSession: CK_SESSION_HANDLE) -> CK_RV {
|
||||
LOGGED_IN.store(false, Ordering::Release);
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_CreateObject(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulCount: CK_ULONG,
|
||||
_phObject: CK_OBJECT_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_CopyObject(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_hObject: CK_OBJECT_HANDLE,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulCount: CK_ULONG,
|
||||
_phNewObject: CK_OBJECT_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DestroyObject(_hSession: CK_SESSION_HANDLE, _hObject: CK_OBJECT_HANDLE) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_GetObjectSize(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_hObject: CK_OBJECT_HANDLE,
|
||||
_pulSize: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_GetAttributeValue(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_hObject: CK_OBJECT_HANDLE,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulCount: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SetAttributeValue(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_hObject: CK_OBJECT_HANDLE,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulCount: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_FindObjectsInit(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulCount: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_FindObjects(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_phObject: CK_OBJECT_HANDLE_PTR,
|
||||
_ulMaxObjectCount: CK_ULONG,
|
||||
pulObjectCount: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
if pulObjectCount.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
unsafe { *pulObjectCount = 0 };
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_FindObjectsFinal(_hSession: CK_SESSION_HANDLE) -> CK_RV {
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
extern "C" fn C_EncryptInit(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hKey: CK_OBJECT_HANDLE,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_Encrypt(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pData: CK_BYTE_PTR,
|
||||
_ulDataLen: CK_ULONG,
|
||||
_pEncryptedData: CK_BYTE_PTR,
|
||||
_pulEncryptedDataLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_EncryptUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_ulPartLen: CK_ULONG,
|
||||
_pEncryptedPart: CK_BYTE_PTR,
|
||||
_pulEncryptedPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_EncryptFinal(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pLastEncryptedPart: CK_BYTE_PTR,
|
||||
_pulLastEncryptedPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DecryptInit(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hKey: CK_OBJECT_HANDLE,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_Decrypt(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pEncryptedData: CK_BYTE_PTR,
|
||||
_ulEncryptedDataLen: CK_ULONG,
|
||||
_pData: CK_BYTE_PTR,
|
||||
_pulDataLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DecryptUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pEncryptedPart: CK_BYTE_PTR,
|
||||
_ulEncryptedPartLen: CK_ULONG,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_pulPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DecryptFinal(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pLastPart: CK_BYTE_PTR,
|
||||
_pulLastPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DigestInit(_hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_Digest(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pData: CK_BYTE_PTR,
|
||||
_ulDataLen: CK_ULONG,
|
||||
_pDigest: CK_BYTE_PTR,
|
||||
_pulDigestLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DigestUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_ulPartLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DigestKey(_hSession: CK_SESSION_HANDLE, _hKey: CK_OBJECT_HANDLE) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DigestFinal(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pDigest: CK_BYTE_PTR,
|
||||
_pulDigestLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SignInit(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hKey: CK_OBJECT_HANDLE,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_Sign(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pData: CK_BYTE_PTR,
|
||||
_ulDataLen: CK_ULONG,
|
||||
_pSignature: CK_BYTE_PTR,
|
||||
_pulSignatureLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SignUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_ulPartLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SignFinal(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pSignature: CK_BYTE_PTR,
|
||||
_pulSignatureLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SignRecoverInit(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hKey: CK_OBJECT_HANDLE,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SignRecover(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pData: CK_BYTE_PTR,
|
||||
_ulDataLen: CK_ULONG,
|
||||
_pSignature: CK_BYTE_PTR,
|
||||
_pulSignatureLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_VerifyInit(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hKey: CK_OBJECT_HANDLE,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_Verify(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pData: CK_BYTE_PTR,
|
||||
_ulDataLen: CK_ULONG,
|
||||
_pSignature: CK_BYTE_PTR,
|
||||
_ulSignatureLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_VerifyUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_ulPartLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_VerifyFinal(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pSignature: CK_BYTE_PTR,
|
||||
_ulSignatureLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_VerifyRecoverInit(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hKey: CK_OBJECT_HANDLE,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_VerifyRecover(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pSignature: CK_BYTE_PTR,
|
||||
_ulSignatureLen: CK_ULONG,
|
||||
_pData: CK_BYTE_PTR,
|
||||
_pulDataLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DigestEncryptUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_ulPartLen: CK_ULONG,
|
||||
_pEncryptedPart: CK_BYTE_PTR,
|
||||
_pulEncryptedPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DecryptDigestUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pEncryptedPart: CK_BYTE_PTR,
|
||||
_ulEncryptedPartLen: CK_ULONG,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_pulPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SignEncryptUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_ulPartLen: CK_ULONG,
|
||||
_pEncryptedPart: CK_BYTE_PTR,
|
||||
_pulEncryptedPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DecryptVerifyUpdate(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pEncryptedPart: CK_BYTE_PTR,
|
||||
_ulEncryptedPartLen: CK_ULONG,
|
||||
_pPart: CK_BYTE_PTR,
|
||||
_pulPartLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_GenerateKey(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulCount: CK_ULONG,
|
||||
_phKey: CK_OBJECT_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_GenerateKeyPair(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_pPublicKeyTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulPublicKeyAttributeCount: CK_ULONG,
|
||||
_pPrivateKeyTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulPrivateKeyAttributeCount: CK_ULONG,
|
||||
_phPublicKey: CK_OBJECT_HANDLE_PTR,
|
||||
_phPrivateKey: CK_OBJECT_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_WrapKey(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hWrappingKey: CK_OBJECT_HANDLE,
|
||||
_hKey: CK_OBJECT_HANDLE,
|
||||
_pWrappedKey: CK_BYTE_PTR,
|
||||
_pulWrappedKeyLen: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_UnwrapKey(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hUnwrappingKey: CK_OBJECT_HANDLE,
|
||||
_pWrappedKey: CK_BYTE_PTR,
|
||||
_ulWrappedKeyLen: CK_ULONG,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulAttributeCount: CK_ULONG,
|
||||
_phKey: CK_OBJECT_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_DeriveKey(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pMechanism: CK_MECHANISM_PTR,
|
||||
_hBaseKey: CK_OBJECT_HANDLE,
|
||||
_pTemplate: CK_ATTRIBUTE_PTR,
|
||||
_ulAttributeCount: CK_ULONG,
|
||||
_phKey: CK_OBJECT_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_SeedRandom(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_pSeed: CK_BYTE_PTR,
|
||||
_ulSeedLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_GenerateRandom(
|
||||
_hSession: CK_SESSION_HANDLE,
|
||||
_RandomData: CK_BYTE_PTR,
|
||||
_ulRandomLen: CK_ULONG,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_GetFunctionStatus(_hSession: CK_SESSION_HANDLE) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_CancelFunction(_hSession: CK_SESSION_HANDLE) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
extern "C" fn C_WaitForSlotEvent(
|
||||
_flags: CK_FLAGS,
|
||||
_pSlot: CK_SLOT_ID_PTR,
|
||||
_pRserved: CK_VOID_PTR,
|
||||
) -> CK_RV {
|
||||
CKR_FUNCTION_NOT_SUPPORTED
|
||||
}
|
||||
|
||||
/// To be a valid PKCS #11 module, this list of functions must be supported. At least cryptoki 2.2
|
||||
/// must be supported for this module to work in NSS.
|
||||
static FUNCTION_LIST: CK_FUNCTION_LIST = CK_FUNCTION_LIST {
|
||||
version: CK_VERSION { major: 2, minor: 2 },
|
||||
C_Initialize: Some(C_Initialize),
|
||||
C_Finalize: Some(C_Finalize),
|
||||
C_GetInfo: Some(C_GetInfo),
|
||||
C_GetFunctionList: None,
|
||||
C_GetSlotList: Some(C_GetSlotList),
|
||||
C_GetSlotInfo: Some(C_GetSlotInfo),
|
||||
C_GetTokenInfo: Some(C_GetTokenInfo),
|
||||
C_GetMechanismList: Some(C_GetMechanismList),
|
||||
C_GetMechanismInfo: Some(C_GetMechanismInfo),
|
||||
C_InitToken: Some(C_InitToken),
|
||||
C_InitPIN: Some(C_InitPIN),
|
||||
C_SetPIN: Some(C_SetPIN),
|
||||
C_OpenSession: Some(C_OpenSession),
|
||||
C_CloseSession: Some(C_CloseSession),
|
||||
C_CloseAllSessions: Some(C_CloseAllSessions),
|
||||
C_GetSessionInfo: Some(C_GetSessionInfo),
|
||||
C_GetOperationState: Some(C_GetOperationState),
|
||||
C_SetOperationState: Some(C_SetOperationState),
|
||||
C_Login: Some(C_Login),
|
||||
C_Logout: Some(C_Logout),
|
||||
C_CreateObject: Some(C_CreateObject),
|
||||
C_CopyObject: Some(C_CopyObject),
|
||||
C_DestroyObject: Some(C_DestroyObject),
|
||||
C_GetObjectSize: Some(C_GetObjectSize),
|
||||
C_GetAttributeValue: Some(C_GetAttributeValue),
|
||||
C_SetAttributeValue: Some(C_SetAttributeValue),
|
||||
C_FindObjectsInit: Some(C_FindObjectsInit),
|
||||
C_FindObjects: Some(C_FindObjects),
|
||||
C_FindObjectsFinal: Some(C_FindObjectsFinal),
|
||||
C_EncryptInit: Some(C_EncryptInit),
|
||||
C_Encrypt: Some(C_Encrypt),
|
||||
C_EncryptUpdate: Some(C_EncryptUpdate),
|
||||
C_EncryptFinal: Some(C_EncryptFinal),
|
||||
C_DecryptInit: Some(C_DecryptInit),
|
||||
C_Decrypt: Some(C_Decrypt),
|
||||
C_DecryptUpdate: Some(C_DecryptUpdate),
|
||||
C_DecryptFinal: Some(C_DecryptFinal),
|
||||
C_DigestInit: Some(C_DigestInit),
|
||||
C_Digest: Some(C_Digest),
|
||||
C_DigestUpdate: Some(C_DigestUpdate),
|
||||
C_DigestKey: Some(C_DigestKey),
|
||||
C_DigestFinal: Some(C_DigestFinal),
|
||||
C_SignInit: Some(C_SignInit),
|
||||
C_Sign: Some(C_Sign),
|
||||
C_SignUpdate: Some(C_SignUpdate),
|
||||
C_SignFinal: Some(C_SignFinal),
|
||||
C_SignRecoverInit: Some(C_SignRecoverInit),
|
||||
C_SignRecover: Some(C_SignRecover),
|
||||
C_VerifyInit: Some(C_VerifyInit),
|
||||
C_Verify: Some(C_Verify),
|
||||
C_VerifyUpdate: Some(C_VerifyUpdate),
|
||||
C_VerifyFinal: Some(C_VerifyFinal),
|
||||
C_VerifyRecoverInit: Some(C_VerifyRecoverInit),
|
||||
C_VerifyRecover: Some(C_VerifyRecover),
|
||||
C_DigestEncryptUpdate: Some(C_DigestEncryptUpdate),
|
||||
C_DecryptDigestUpdate: Some(C_DecryptDigestUpdate),
|
||||
C_SignEncryptUpdate: Some(C_SignEncryptUpdate),
|
||||
C_DecryptVerifyUpdate: Some(C_DecryptVerifyUpdate),
|
||||
C_GenerateKey: Some(C_GenerateKey),
|
||||
C_GenerateKeyPair: Some(C_GenerateKeyPair),
|
||||
C_WrapKey: Some(C_WrapKey),
|
||||
C_UnwrapKey: Some(C_UnwrapKey),
|
||||
C_DeriveKey: Some(C_DeriveKey),
|
||||
C_SeedRandom: Some(C_SeedRandom),
|
||||
C_GenerateRandom: Some(C_GenerateRandom),
|
||||
C_GetFunctionStatus: Some(C_GetFunctionStatus),
|
||||
C_CancelFunction: Some(C_CancelFunction),
|
||||
C_WaitForSlotEvent: Some(C_WaitForSlotEvent),
|
||||
};
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// This is the only function this module exposes. NSS calls it to obtain the list of functions
|
||||
/// comprising this module.
|
||||
/// ppFunctionList must be a valid pointer.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn PKCS11TestModule_GetFunctionList(
|
||||
ppFunctionList: CK_FUNCTION_LIST_PTR_PTR,
|
||||
) -> CK_RV {
|
||||
if ppFunctionList.is_null() {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
// CK_FUNCTION_LIST_PTR is a *mut CK_FUNCTION_LIST, but as per the
|
||||
// specification, the caller must treat it as *const CK_FUNCTION_LIST.
|
||||
unsafe { *ppFunctionList = std::ptr::addr_of!(FUNCTION_LIST) as CK_FUNCTION_LIST_PTR };
|
||||
CKR_OK
|
||||
}
|
||||
Reference in New Issue
Block a user