kmsp11/provider.h (70 lines of code) (raw):

/* * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef KMSP11_PROVIDER_H_ #define KMSP11_PROVIDER_H_ #include <thread> #include "absl/status/statusor.h" #include "absl/synchronization/notification.h" #include "kmsp11/config/config.pb.h" #include "kmsp11/cryptoki.h" #include "kmsp11/mechanism.h" #include "kmsp11/session.h" #include "kmsp11/token.h" #include "kmsp11/util/errors.h" #include "kmsp11/util/handle_map.h" namespace cloud_kms::kmsp11 { // Provider models a "run" of a Cryptoki library, from C_Initialize to // C_Finalize. // // See go/kms-pkcs11-model class Provider { public: static absl::StatusOr<std::unique_ptr<Provider>> New(LibraryConfig config); const LibraryConfig& library_config() const { return library_config_; } const CK_INFO& info() const { return info_; } const unsigned long token_count() const { return tokens_.size(); } KmsClient* kms_client() { return kms_client_.get(); } absl::StatusOr<Token*> TokenAt(CK_SLOT_ID slot_id); absl::StatusOr<CK_SESSION_HANDLE> OpenSession(CK_SLOT_ID slot_id, SessionType session_type); absl::StatusOr<std::shared_ptr<Session>> GetSession( CK_SESSION_HANDLE session_handle); absl::Status CloseSession(CK_SESSION_HANDLE session_handle); absl::Status CloseAllSessions(CK_SLOT_ID slot_id); // Returns a sorted list of the mechanism types supported in this library. absl::Span<const CK_MECHANISM_TYPE> Mechanisms(); // Returns details about the provided mechanism type. absl::StatusOr<CK_MECHANISM_INFO> MechanismInfo(CK_MECHANISM_TYPE type); private: class Refresher { public: Refresher(Provider* provider, absl::Duration interval); virtual ~Refresher(); private: absl::Notification shutdown_; std::thread thread_; }; Provider(LibraryConfig library_config, CK_INFO info, std::vector<std::unique_ptr<Token>>&& tokens, std::unique_ptr<KmsClient> kms_client, absl::Duration refresh_interval) : library_config_(library_config), info_(info), tokens_(std::move(tokens)), sessions_(CKR_SESSION_HANDLE_INVALID), kms_client_(std::move(kms_client)) { if (refresh_interval > absl::ZeroDuration()) { refresher_.emplace(this, refresh_interval); } auto all_mechanisms = AllMechanisms(); auto all_mac_mechanisms = AllMacMechanisms(); auto all_raw_encryption_mechanisms = AllRawEncryptionMechanisms(); std::vector<CK_MECHANISM_TYPE> types(all_mechanisms.size()); for (const auto& [mechanism_type, mechanism] : all_mechanisms) { types.push_back(mechanism_type); } std::sort(types.begin(), types.end()); mechanism_types_ = types; } const LibraryConfig library_config_; const CK_INFO info_; const std::vector<std::unique_ptr<Token>> tokens_; HandleMap<Session> sessions_; std::unique_ptr<KmsClient> kms_client_; std::optional<Refresher> refresher_; std::vector<CK_MECHANISM_TYPE> mechanism_types_; }; } // namespace cloud_kms::kmsp11 #endif // KMSP11_PROVIDER_H_