blob: aced15f03bb013911e98374a893c0750371df03b [file] [log] [blame]
// 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)
}