xref: /aosp_15_r20/external/tink/cc/monitoring/monitoring.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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