// 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. // //////////////////////////////////////////////////////////////////////////////// // Package monitoring defines the structs and interfaces for monitoring primitives with Tink. // This package isn't yet production ready and might go through various changes. package monitoring // KeyStatus represents KeyStatusType in tink/proto/tink.proto. type KeyStatus int const ( // Enabled keys can be used for cryptographic operations. Enabled KeyStatus = iota // Disabled keys can't be used, but can be re-enabled. Disabled // Destroyed keys don't exist in the keyset anymore. Destroyed // DoNotUse is intended to guard from failures that may be caused by future expansions. DoNotUse KeyStatus = 20 ) func (status KeyStatus) String() string { switch status { case Enabled: return "ENABLED" case Disabled: return "DISABLED" case Destroyed: return "DESTROYED" } return "UNKNOWN" } // Entry represents each entry inside a Keyset. type Entry struct { Status KeyStatus KeyID uint32 KeyType string KeyPrefix string } // KeysetInfo represents a keyset in a certain point in time for the // purpose of monitoring operations involving cryptographic keys. type KeysetInfo struct { Annotations map[string]string PrimaryKeyID uint32 Entries []*Entry } // NewKeysetInfo creates a new KeysetInfo. func NewKeysetInfo(annotations map[string]string, primaryKeyID uint32, entries []*Entry) *KeysetInfo { return &KeysetInfo{ Annotations: annotations, PrimaryKeyID: primaryKeyID, Entries: entries, } } // Context defines a context for monitoring events, wich includes the // primitive and API used, and information on the keyset. type Context struct { Primitive string APIFunction string KeysetInfo *KeysetInfo } // NewContext creates a new monitoring context. func NewContext(primitive string, apiFunction string, keysetInfo *KeysetInfo) *Context { return &Context{ Primitive: primitive, APIFunction: apiFunction, KeysetInfo: keysetInfo, } } // Logger is an interface for logging which can be created through a `Client`. // monitoring clients are invoked by Tink during cryptographic operations to emit // certain events. type Logger interface { // Logs a successful use of `keyID` on an input of `numBytes`. Tink primitive // wrappers call this method when they successfully use a key to carry out a // primitive method, e.g. aead.Encrypt(). As a consequence, implementations 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. Log(keyID uint32, numBytes int) // 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. LogFailure() } // Client represents an interface to hold monitoring client context to create a `Logger`. // A Client is registered with Tink's registry and used by primitives to obtain a `Logger`. type Client interface { NewLogger(context *Context) (Logger, error) }