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 17// Package monitoring defines the structs and interfaces for monitoring primitives with Tink. 18// This package isn't yet production ready and might go through various changes. 19package monitoring 20 21// KeyStatus represents KeyStatusType in tink/proto/tink.proto. 22type KeyStatus int 23 24const ( 25 // Enabled keys can be used for cryptographic operations. 26 Enabled KeyStatus = iota 27 // Disabled keys can't be used, but can be re-enabled. 28 Disabled 29 // Destroyed keys don't exist in the keyset anymore. 30 Destroyed 31 32 // DoNotUse is intended to guard from failures that may be caused by future expansions. 33 DoNotUse KeyStatus = 20 34) 35 36func (status KeyStatus) String() string { 37 switch status { 38 case Enabled: 39 return "ENABLED" 40 case Disabled: 41 return "DISABLED" 42 case Destroyed: 43 return "DESTROYED" 44 } 45 return "UNKNOWN" 46} 47 48// Entry represents each entry inside a Keyset. 49type Entry struct { 50 Status KeyStatus 51 KeyID uint32 52 KeyType string 53 KeyPrefix string 54} 55 56// KeysetInfo represents a keyset in a certain point in time for the 57// purpose of monitoring operations involving cryptographic keys. 58type KeysetInfo struct { 59 Annotations map[string]string 60 PrimaryKeyID uint32 61 Entries []*Entry 62} 63 64// NewKeysetInfo creates a new KeysetInfo. 65func NewKeysetInfo(annotations map[string]string, primaryKeyID uint32, entries []*Entry) *KeysetInfo { 66 return &KeysetInfo{ 67 Annotations: annotations, 68 PrimaryKeyID: primaryKeyID, 69 Entries: entries, 70 } 71} 72 73// Context defines a context for monitoring events, wich includes the 74// primitive and API used, and information on the keyset. 75type Context struct { 76 Primitive string 77 APIFunction string 78 KeysetInfo *KeysetInfo 79} 80 81// NewContext creates a new monitoring context. 82func NewContext(primitive string, apiFunction string, keysetInfo *KeysetInfo) *Context { 83 return &Context{ 84 Primitive: primitive, 85 APIFunction: apiFunction, 86 KeysetInfo: keysetInfo, 87 } 88} 89 90// Logger is an interface for logging which can be created through a `Client`. 91// monitoring clients are invoked by Tink during cryptographic operations to emit 92// certain events. 93type Logger interface { 94 // Logs a successful use of `keyID` on an input of `numBytes`. Tink primitive 95 // wrappers call this method when they successfully use a key to carry out a 96 // primitive method, e.g. aead.Encrypt(). As a consequence, implementations of 97 // MonitoringClient should be mindful on the amount of work performed by this 98 // method, as this will be called on each cryptographic operation. Implementations 99 // of MonitoringClient are responsible to add context to identify, e.g., the 100 // primitive and the API function. 101 Log(keyID uint32, numBytes int) 102 103 // Logs a failure. Tink calls this method when a cryptographic operation 104 // failed, e.g. no key could be found to decrypt a ciphertext. In this 105 // case the failure is not associated with a specific key, therefore this 106 // method has no arguments. The MonitoringClient implementation is responsible 107 // to add context to identify where the failure comes from. 108 LogFailure() 109} 110 111// Client represents an interface to hold monitoring client context to create a `Logger`. 112// A Client is registered with Tink's registry and used by primitives to obtain a `Logger`. 113type Client interface { 114 NewLogger(context *Context) (Logger, error) 115} 116