1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 /////////////////////////////////////////////////////////////////////////////// 16 #ifndef TINK_MONITORING_MONITORING_H_ 17 #define TINK_MONITORING_MONITORING_H_ 18 19 #include <cstdint> 20 #include <memory> 21 #include <string> 22 #include <vector> 23 24 #include "absl/container/flat_hash_map.h" 25 #include "tink/internal/key_status_util.h" 26 #include "tink/key_status.h" 27 #include "tink/util/statusor.h" 28 29 namespace crypto { 30 namespace tink { 31 32 // Immutable representation of a KeySet in a certain point in time for the 33 // purpose of monitoring operations involving cryptographic keys. 34 class MonitoringKeySetInfo { 35 public: 36 // Description about each entry of the KeySet. 37 class Entry { 38 public: 39 // Constructs a new KeySet entry with a given `status`, `key_id`, 40 // `key_type`, and `key_prefix`. Entry(KeyStatus status,uint32_t key_id,absl::string_view key_type,absl::string_view key_prefix)41 Entry(KeyStatus status, uint32_t key_id, absl::string_view key_type, 42 absl::string_view key_prefix) 43 : status_(status), 44 key_id_(key_id), 45 key_type_(key_type), 46 key_prefix_(key_prefix) {} 47 48 // Returns the status of this entry. GetStatus()49 std::string GetStatus() const { return internal::ToKeyStatusName(status_); } 50 // Returns the ID of the entry within the keyset. GetKeyId()51 uint32_t GetKeyId() const { return key_id_; } 52 // Returns the key type. GetKeyType()53 std::string GetKeyType() const { return key_type_; } 54 // Returns the key prefix. GetKeyPrefix()55 std::string GetKeyPrefix() const { return key_prefix_; } 56 57 private: 58 const KeyStatus status_; 59 // Identifies a key within a keyset. 60 const uint32_t key_id_; 61 // This field stores the key type. 62 const std::string key_type_; 63 // Stores the key output prefix. 64 const std::string key_prefix_; 65 }; 66 67 // Constructs a MonitoringKeySetInfo object with the given 68 // `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)69 MonitoringKeySetInfo( 70 const absl::flat_hash_map<std::string, std::string>& keyset_annotations, 71 const std::vector<Entry>& keyset_entries, uint32_t primary_key_id) 72 : keyset_annotations_(keyset_annotations), 73 keyset_entries_(keyset_entries), 74 primary_key_id_(primary_key_id) {} 75 76 // Returns a const reference to the annotations of this keyset. GetAnnotations()77 const absl::flat_hash_map<std::string, std::string>& GetAnnotations() const { 78 return keyset_annotations_; 79 } 80 // Returns a const reference to the array of entries for this keyset. GetEntries()81 const std::vector<Entry>& GetEntries() const { return keyset_entries_; } 82 // Returns the ID of the primary key in this keyset. GetPrimaryKeyId()83 uint32_t GetPrimaryKeyId() const { return primary_key_id_; } 84 85 private: 86 // Annotations of this keyset in the form 'key' -> 'value'. 87 const absl::flat_hash_map<std::string, std::string> keyset_annotations_; 88 const std::vector<Entry> keyset_entries_; 89 const uint32_t primary_key_id_; 90 }; 91 92 // Defines a context for monitoring events, wich includes the primitive and API 93 // used, and info on the keyset. 94 class MonitoringContext { 95 public: 96 // Construct a new context for the given `primitive`, `api_function` and 97 // `keyset_info`. MonitoringContext(absl::string_view primitive,absl::string_view api_function,const MonitoringKeySetInfo & keyset_info)98 MonitoringContext(absl::string_view primitive, absl::string_view api_function, 99 const MonitoringKeySetInfo& keyset_info) 100 : primitive_(primitive), 101 api_function_(api_function), 102 keyset_info_(keyset_info) {} 103 104 // Returns the primitive. GetPrimitive()105 std::string GetPrimitive() const { return primitive_; } 106 // Returns the API function. GetApi()107 std::string GetApi() const { return api_function_; } 108 // Returns a constant reference to the keyset info. GetKeySetInfo()109 const MonitoringKeySetInfo& GetKeySetInfo() const { return keyset_info_; } 110 111 private: 112 const std::string primitive_; 113 const std::string api_function_; 114 const MonitoringKeySetInfo keyset_info_; 115 }; 116 117 // Interface for a monitoring client which can be registered with Tink. A 118 // monitoring client getis informed by Tink about certain events happening 119 // during cryptographic operations. 120 class MonitoringClient { 121 public: 122 virtual ~MonitoringClient() = default; 123 // Logs a successful use of `key_id` on an input of `num_bytes_as_input`. Tink 124 // primitive wrappers call this method when they successfully used a key to 125 // carry out a primitive method, e.g. Aead::Encrypt(). As a consequence, 126 // subclasses of MonitoringClient should be mindful on the amount of work 127 // performed by this method, as this will be called on each cryptographic 128 // operation. Implementations of MonitoringClient are responsible to add 129 // context to identify, e.g., the primitive and the API function. 130 virtual void Log(uint32_t key_id, int64_t num_bytes_as_input) = 0; 131 132 // Logs a failure. Tink calls this method when a cryptographic operation 133 // failed, e.g. no key could be found to decrypt a ciphertext. In this 134 // case the failure is not associated with a specific key, therefore this 135 // method has no arguments. The MonitoringClient implementation is responsible 136 // to add context to identify where the failure comes from. 137 virtual void LogFailure() = 0; 138 }; 139 140 // Interface for a factory class that creates monitoring clients. 141 class MonitoringClientFactory { 142 public: 143 virtual ~MonitoringClientFactory() = default; 144 // Create a new monitoring client that logs events related to the given 145 // `context`. 146 virtual crypto::tink::util::StatusOr<std::unique_ptr<MonitoringClient>> New( 147 const MonitoringContext& context) = 0; 148 }; 149 150 } // namespace tink 151 } // namespace crypto 152 153 #endif // TINK_MONITORING_MONITORING_H_ 154