| // Copyright 2022 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 TINK_MONITORING_MONITORING_H_ |
| #define TINK_MONITORING_MONITORING_H_ |
| |
| #include <cstdint> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/container/flat_hash_map.h" |
| #include "tink/internal/key_status_util.h" |
| #include "tink/key_status.h" |
| #include "tink/util/statusor.h" |
| |
| namespace crypto { |
| namespace tink { |
| |
| // Immutable representation of a KeySet in a certain point in time for the |
| // purpose of monitoring operations involving cryptographic keys. |
| class MonitoringKeySetInfo { |
| public: |
| // Description about each entry of the KeySet. |
| class Entry { |
| public: |
| // Constructs a new KeySet entry with a given `status`, `key_id`, |
| // `key_type`, and `key_prefix`. |
| Entry(KeyStatus status, uint32_t key_id, absl::string_view key_type, |
| absl::string_view key_prefix) |
| : status_(status), |
| key_id_(key_id), |
| key_type_(key_type), |
| key_prefix_(key_prefix) {} |
| |
| // Returns the status of this entry. |
| std::string GetStatus() const { return internal::ToKeyStatusName(status_); } |
| // Returns the ID of the entry within the keyset. |
| uint32_t GetKeyId() const { return key_id_; } |
| // Returns the key type. |
| std::string GetKeyType() const { return key_type_; } |
| // Returns the key prefix. |
| std::string GetKeyPrefix() const { return key_prefix_; } |
| |
| private: |
| const KeyStatus status_; |
| // Identifies a key within a keyset. |
| const uint32_t key_id_; |
| // This field stores the key type. |
| const std::string key_type_; |
| // Stores the key output prefix. |
| const std::string key_prefix_; |
| }; |
| |
| // Constructs a MonitoringKeySetInfo object with the given |
| // `keyset_annotations`, `keyset_entries` and primary key ID `primary_key_id`. |
| MonitoringKeySetInfo( |
| const absl::flat_hash_map<std::string, std::string>& keyset_annotations, |
| const std::vector<Entry>& keyset_entries, uint32_t primary_key_id) |
| : keyset_annotations_(keyset_annotations), |
| keyset_entries_(keyset_entries), |
| primary_key_id_(primary_key_id) {} |
| |
| // Returns a const reference to the annotations of this keyset. |
| const absl::flat_hash_map<std::string, std::string>& GetAnnotations() const { |
| return keyset_annotations_; |
| } |
| // Returns a const reference to the array of entries for this keyset. |
| const std::vector<Entry>& GetEntries() const { return keyset_entries_; } |
| // Returns the ID of the primary key in this keyset. |
| uint32_t GetPrimaryKeyId() const { return primary_key_id_; } |
| |
| private: |
| // Annotations of this keyset in the form 'key' -> 'value'. |
| const absl::flat_hash_map<std::string, std::string> keyset_annotations_; |
| const std::vector<Entry> keyset_entries_; |
| const uint32_t primary_key_id_; |
| }; |
| |
| // Defines a context for monitoring events, wich includes the primitive and API |
| // used, and info on the keyset. |
| class MonitoringContext { |
| public: |
| // Construct a new context for the given `primitive`, `api_function` and |
| // `keyset_info`. |
| MonitoringContext(absl::string_view primitive, absl::string_view api_function, |
| const MonitoringKeySetInfo& keyset_info) |
| : primitive_(primitive), |
| api_function_(api_function), |
| keyset_info_(keyset_info) {} |
| |
| // Returns the primitive. |
| std::string GetPrimitive() const { return primitive_; } |
| // Returns the API function. |
| std::string GetApi() const { return api_function_; } |
| // Returns a constant reference to the keyset info. |
| const MonitoringKeySetInfo& GetKeySetInfo() const { return keyset_info_; } |
| |
| private: |
| const std::string primitive_; |
| const std::string api_function_; |
| const MonitoringKeySetInfo keyset_info_; |
| }; |
| |
| // Interface for a monitoring client which can be registered with Tink. A |
| // monitoring client getis informed by Tink about certain events happening |
| // during cryptographic operations. |
| class MonitoringClient { |
| public: |
| virtual ~MonitoringClient() = default; |
| // Logs a successful use of `key_id` on an input of `num_bytes_as_input`. Tink |
| // primitive wrappers call this method when they successfully used a key to |
| // carry out a primitive method, e.g. Aead::Encrypt(). As a consequence, |
| // subclasses of MonitoringClient should be mindful on the amount of work |
| // performed by this method, as this will be called on each cryptographic |
| // operation. Implementations of MonitoringClient are responsible to add |
| // context to identify, e.g., the primitive and the API function. |
| virtual void Log(uint32_t key_id, int64_t num_bytes_as_input) = 0; |
| |
| // Logs a failure. Tink calls this method when a cryptographic operation |
| // failed, e.g. no key could be found to decrypt a ciphertext. In this |
| // case the failure is not associated with a specific key, therefore this |
| // method has no arguments. The MonitoringClient implementation is responsible |
| // to add context to identify where the failure comes from. |
| virtual void LogFailure() = 0; |
| }; |
| |
| // Interface for a factory class that creates monitoring clients. |
| class MonitoringClientFactory { |
| public: |
| virtual ~MonitoringClientFactory() = default; |
| // Create a new monitoring client that logs events related to the given |
| // `context`. |
| virtual crypto::tink::util::StatusOr<std::unique_ptr<MonitoringClient>> New( |
| const MonitoringContext& context) = 0; |
| }; |
| |
| } // namespace tink |
| } // namespace crypto |
| |
| #endif // TINK_MONITORING_MONITORING_H_ |