in kmsp11/main/bridge.cc [59:121]
absl::Status Initialize(CK_VOID_PTR pInitArgs) {
auto* init_args = static_cast<CK_C_INITIALIZE_ARGS*>(pInitArgs);
if (init_args) {
if ((init_args->flags & CKF_OS_LOCKING_OK) != CKF_OS_LOCKING_OK &&
(init_args->CreateMutex || init_args->DestroyMutex ||
init_args->LockMutex || init_args->UnlockMutex)) {
return NewInvalidArgumentError("library requires os locking",
CKR_CANT_LOCK, SOURCE_LOCATION);
}
if ((init_args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) ==
CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
return NewInvalidArgumentError("library requires thread creation",
CKR_NEED_TO_CREATE_THREADS,
SOURCE_LOCATION);
}
}
LibraryConfig config;
if (init_args && init_args->pReserved) {
// This behavior isn't part of the spec, but there are numerous libraries
// in the wild that allow specifying a config file in pInitArgs->pReserved.
// There's also support for providing config this way in the OpenSSL engine:
// https://github.com/OpenSC/libp11/blob/4084f83ee5ea51353facf151126b7d6d739d0784/src/eng_front.c#L62
ASSIGN_OR_RETURN(
config, LoadConfigFromFile(static_cast<char*>(init_args->pReserved)));
} else {
ASSIGN_OR_RETURN(config, LoadConfigFromEnvironment());
}
// Registering fork handlers is a one-time operation.
if (!config.skip_fork_handlers()) {
static const absl::Status kForkHandlersRegistered = RegisterForkHandlers();
RETURN_IF_ERROR(kForkHandlersRegistered);
}
Provider* existing_provider = GetGlobalProvider();
if (existing_provider) {
return FailedPreconditionError("the library is already initialized",
CKR_CRYPTOKI_ALREADY_INITIALIZED,
SOURCE_LOCATION);
}
CHECK(kCryptoLibraryInitialized);
if (config.require_fips_mode()) {
absl::Status self_test_result = CheckFipsSelfTest();
CHECK(self_test_result.ok()) << "FIPS tests failed: " << self_test_result;
}
// Provider::New emits info log messages (for example, noting that a CKV is
// being skipped due to state DISABLED), so logging should be initialized
// before it is invoked.
RETURN_IF_ERROR(
InitializeLogging(config.log_directory(), config.log_filename_suffix()));
absl::StatusOr<std::unique_ptr<Provider>> new_provider =
Provider::New(config);
if (!new_provider.ok()) {
ShutdownLogging();
return new_provider.status();
}
return SetGlobalProvider(std::move(new_provider).value());
}