wrapping

package module
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2022 License: MPL-2.0 Imports: 13 Imported by: 23

README

Go-KMS-Wrapping - Go library for encrypting values through various KMS providers

Godoc

NOTE: This is version 0 of the library. The main branch contains version 2, which provides a more modularized approach and the ability to run wrappers as plugins. This branch is expected to contain only necessary backports, not further development. Additionally, currently no compatibility guarantees are provided for this version.

Go-KMS-Wrapping is a library that can be used to encrypt things through various KMS providers -- public clouds, Vault's Transit plugin, etc. It is similar in concept to various other cryptosystems (like NaCl) but focuses on using third party KMSes. This library is the underpinning of Vault's auto-unseal functionality, and should be ready to use for many other applications.

For KMS providers that do not support encrypting arbitrarily large values, the library will generate an envelope data encryption key (DEK), encrypt the value with it using an authenticated cipher, and use the KMS to encrypt the DEK.

The key being used by a given implementation can change; the library stores information about which key was actually used to encrypt a given value as part of the returned data, and this key will be used for decryption. By extension, this means that users should be careful not to delete keys in KMS systems simply because they're not configured to be used by this library currently, as they may have been used for past encryption operations.

Features

  • Supports many KMSes:
    • AEAD using AES-GCM and a provided key
    • Alibaba Cloud KMS (uses envelopes)
    • AWS KMS (uses envelopes)
    • Azure KeyVault (uses envelopes)
    • GCP CKMS (uses envelopes)
    • Huawei Cloud KMS (uses envelopes)
    • OCI KMS (uses envelopes)
    • Tencent Cloud KMS (uses envelopes)
    • Vault Transit mount
    • Yandex.Cloud KMS (uses envelopes)
  • Transparently supports multiple decryption targets, allowing for key rotation
  • Supports Additional Authenticated Data (AAD) for all KMSes except Vault Transit.

A multiwrapper KMS is also included, capable of encrypting to a specified wrapper and decrypting using one of several wrappers switched on key ID. This can allow easy key rotation for KMSes that do not natively support it.

The structwrapping package allows for structs to have members encrypted and decrypted in a single pass via a single wrapper. This can be used for workflows such as database library callback functions to easily encrypt/decrypt data as it goes to/from storage.

Installation

Import like any other library; supports go modules. It has not been tested with non-go mod vendoring tools.

Overview

The library exports a Wrapper interface that is implemented by multiple providers. Each of these providers may have some functions specific to them, usually to pass configuration information. A normal workflow is to create the provider directly, pass it any needed configuration via the provider-specific methods, and then have the rest of your code use the Wrapper interface.

Some of the functions make use of option structs that are currently empty. This is to allow options to be added later without breaking backwards compatibility.

The best place to find the currently available set of configuration options supported by each provider is its code, but it can also be found in Vault's seal configuration documentation. All environment variables noted there also work in this library, however, non-Vault-specific variants of the environment variables are also available for each provider. See the code/comments in each given provider for the currently allowed env vars.

Usage

Following is an example usage of the AWS KMS provider.

// Context used in this library is passed to various underlying provider
// libraries; how it's used is dependent on the provider libraries
ctx := context.Background()

wrapper := awskms.NewWrapper(nil)
_, err := wrapper.SetConfig(&map[string]string{
    "kms_key_id": "1234abcd-12ab-34cd-56ef-1234567890ab"
})
if err != nil {
    return err
}
blobInfo, err := wrapper.Encrypt(ctx, []byte{"foo"}, nil)
if err != nil {
    return err
}

//
// Do some things...
//

plaintext, err := wrapper.Decrypt(ctx, blobInfo)
if err != nil {
    return err
}
if string(plaintext) != "foo" {
    return errors.New("mismatch between input and output")
}

Documentation

Index

Constants

View Source
const (
	AEAD            = "aead"
	AliCloudKMS     = "alicloudkms"
	AWSKMS          = "awskms"
	AzureKeyVault   = "azurekeyvault"
	GCPCKMS         = "gcpckms"
	HuaweiCloudKMS  = "huaweicloudkms"
	MultiWrapper    = "multiwrapper"
	OCIKMS          = "ocikms"
	PKCS11          = "pkcs11"
	Shamir          = "shamir"
	TencentCloudKMS = "tencentcloudkms"
	Transit         = "transit"
	YandexCloudKMS  = "yandexcloudkms"
	Test            = "test-auto"

	// HSMAutoDeprecated is a deprecated type relevant to Vault prior to 0.9.0.
	// It is still referenced in certain code paths for upgrade purporses
	HSMAutoDeprecated = "hsm-auto"
)

These values define known types of Wrappers

Variables

View Source
var File_github_com_hashicorp_go_kms_wrapping_types_proto protoreflect.FileDescriptor

Functions

This section is empty.

Types

type EncryptedBlobInfo

type EncryptedBlobInfo struct {

	// Ciphertext is the encrypted bytes
	Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"`
	// IV is the initialization value used during encryption
	IV []byte `protobuf:"bytes,2,opt,name=iv,proto3" json:"iv,omitempty"`
	// HMAC is the bytes of the HMAC, if any
	HMAC []byte `protobuf:"bytes,3,opt,name=hmac,proto3" json:"hmac,omitempty"`
	// Wrapped can be used by the client to indicate whether Ciphertext
	// actually contains wrapped data or not. This can be useful if you want to
	// reuse the same struct to pass data along before and after wrapping.
	Wrapped bool `protobuf:"varint,4,opt,name=wrapped,proto3" json:"wrapped,omitempty"`
	// KeyInfo contains information about the key that was used to create this value
	KeyInfo *KeyInfo `protobuf:"bytes,5,opt,name=key_info,json=keyInfo,proto3" json:"key_info,omitempty"`
	// ValuePath can be used by the client to store information about where the
	// value came from
	ValuePath string `protobuf:"bytes,6,opt,name=ValuePath,proto3" json:"ValuePath,omitempty"`
	// contains filtered or unexported fields
}

EncryptedBlobInfo contains information about the encrypted value along with information about the key used to encrypt it

func (*EncryptedBlobInfo) Descriptor deprecated

func (*EncryptedBlobInfo) Descriptor() ([]byte, []int)

Deprecated: Use EncryptedBlobInfo.ProtoReflect.Descriptor instead.

func (*EncryptedBlobInfo) GetCiphertext

func (x *EncryptedBlobInfo) GetCiphertext() []byte

func (*EncryptedBlobInfo) GetHMAC

func (x *EncryptedBlobInfo) GetHMAC() []byte

func (*EncryptedBlobInfo) GetIV

func (x *EncryptedBlobInfo) GetIV() []byte

func (*EncryptedBlobInfo) GetKeyInfo

func (x *EncryptedBlobInfo) GetKeyInfo() *KeyInfo

func (*EncryptedBlobInfo) GetValuePath

func (x *EncryptedBlobInfo) GetValuePath() string

func (*EncryptedBlobInfo) GetWrapped

func (x *EncryptedBlobInfo) GetWrapped() bool

func (*EncryptedBlobInfo) ProtoMessage

func (*EncryptedBlobInfo) ProtoMessage()

func (*EncryptedBlobInfo) ProtoReflect added in v0.5.7

func (x *EncryptedBlobInfo) ProtoReflect() protoreflect.Message

func (*EncryptedBlobInfo) Reset

func (x *EncryptedBlobInfo) Reset()

func (*EncryptedBlobInfo) String

func (x *EncryptedBlobInfo) String() string

type Envelope

type Envelope struct {
	// contains filtered or unexported fields
}

Envelope performs encryption or decryption, wrapping sensitive data. It creates a random key. This is usable on its own but since many KMS systems or key types cannot support large values, this is used by implementations in this package to encrypt large values with a DEK and use the actual KMS to encrypt the DEK.

func NewEnvelope

func NewEnvelope(opts *EnvelopeOptions) *Envelope

NewEnvelope retuns an Envelope that is ready to use for use. It is valid to pass nil EnvelopeOptions.

func (*Envelope) Decrypt

func (e *Envelope) Decrypt(data *EnvelopeInfo, aad []byte) ([]byte, error)

Decrypt takes in EnvelopeInfo and potentially additional data and decrypts. Additional data is separate from the encrypted blob info as it is expected that will be sourced from a separate location.

func (*Envelope) Descriptor deprecated added in v0.5.11

func (*Envelope) Descriptor() ([]byte, []int)

Deprecated: Use Envelope.ProtoReflect.Descriptor instead.

func (*Envelope) Encrypt

func (e *Envelope) Encrypt(plaintext []byte, aad []byte) (*EnvelopeInfo, error)

Encrypt takes in plaintext and envelope encrypts it, generating an EnvelopeInfo value

func (*Envelope) ProtoMessage added in v0.5.11

func (*Envelope) ProtoMessage()

func (*Envelope) ProtoReflect added in v0.5.11

func (x *Envelope) ProtoReflect() protoreflect.Message

func (*Envelope) Reset added in v0.5.11

func (x *Envelope) Reset()

func (*Envelope) String added in v0.5.11

func (x *Envelope) String() string

type EnvelopeInfo

type EnvelopeInfo struct {

	// Ciphertext is the ciphertext from the envelope
	Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"`
	// Key is the key used in the envelope
	Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
	// IV is the initialization value used during encryption in the envelope
	IV []byte `protobuf:"bytes,3,opt,name=iv,proto3" json:"iv,omitempty"`
	// contains filtered or unexported fields
}

EnvelopeInfo contains the information necessary to perfom encryption or decryption in an envelope fashion

func (*EnvelopeInfo) Descriptor deprecated added in v0.5.11

func (*EnvelopeInfo) Descriptor() ([]byte, []int)

Deprecated: Use EnvelopeInfo.ProtoReflect.Descriptor instead.

func (*EnvelopeInfo) GetCiphertext added in v0.5.11

func (x *EnvelopeInfo) GetCiphertext() []byte

func (*EnvelopeInfo) GetIV added in v0.5.11

func (x *EnvelopeInfo) GetIV() []byte

func (*EnvelopeInfo) GetKey added in v0.5.11

func (x *EnvelopeInfo) GetKey() []byte

func (*EnvelopeInfo) ProtoMessage added in v0.5.11

func (*EnvelopeInfo) ProtoMessage()

func (*EnvelopeInfo) ProtoReflect added in v0.5.11

func (x *EnvelopeInfo) ProtoReflect() protoreflect.Message

func (*EnvelopeInfo) Reset added in v0.5.11

func (x *EnvelopeInfo) Reset()

func (*EnvelopeInfo) String added in v0.5.11

func (x *EnvelopeInfo) String() string

type EnvelopeOptions

type EnvelopeOptions struct {
	// contains filtered or unexported fields
}

EnvelopeOptions is a placeholder for future options, such as the ability to switch which algorithm is used

func (*EnvelopeOptions) Descriptor deprecated added in v0.5.11

func (*EnvelopeOptions) Descriptor() ([]byte, []int)

Deprecated: Use EnvelopeOptions.ProtoReflect.Descriptor instead.

func (*EnvelopeOptions) ProtoMessage added in v0.5.11

func (*EnvelopeOptions) ProtoMessage()

func (*EnvelopeOptions) ProtoReflect added in v0.5.11

func (x *EnvelopeOptions) ProtoReflect() protoreflect.Message

func (*EnvelopeOptions) Reset added in v0.5.11

func (x *EnvelopeOptions) Reset()

func (*EnvelopeOptions) String added in v0.5.11

func (x *EnvelopeOptions) String() string

type KeyInfo

type KeyInfo struct {

	// Mechanism is the method used by the wrapper to encrypt and sign the
	// data as defined by the wrapper.
	Mechanism     uint64 `protobuf:"varint,1,opt,name=Mechanism,proto3" json:"Mechanism,omitempty"`
	HMACMechanism uint64 `protobuf:"varint,2,opt,name=HMACMechanism,proto3" json:"HMACMechanism,omitempty"`
	// This is an opaque ID used by the wrapper to identify the specific key to
	// use as defined by the wrapper. This could be a version, key label, or
	// something else.
	KeyID     string `protobuf:"bytes,3,opt,name=KeyID,proto3" json:"KeyID,omitempty"`
	HMACKeyID string `protobuf:"bytes,4,opt,name=HMACKeyID,proto3" json:"HMACKeyID,omitempty"`
	// These value are used when generating our own data encryption keys
	// and encrypting them using the wrapper
	WrappedKey []byte `protobuf:"bytes,5,opt,name=WrappedKey,proto3" json:"WrappedKey,omitempty"`
	// Mechanism specific flags
	Flags uint64 `protobuf:"varint,6,opt,name=Flags,proto3" json:"Flags,omitempty"`
	// contains filtered or unexported fields
}

KeyInfo contains information regarding which Wrapper key was used to encrypt the entry

func (*KeyInfo) Descriptor deprecated

func (*KeyInfo) Descriptor() ([]byte, []int)

Deprecated: Use KeyInfo.ProtoReflect.Descriptor instead.

func (*KeyInfo) GetFlags

func (x *KeyInfo) GetFlags() uint64

func (*KeyInfo) GetHMACKeyID

func (x *KeyInfo) GetHMACKeyID() string

func (*KeyInfo) GetHMACMechanism

func (x *KeyInfo) GetHMACMechanism() uint64

func (*KeyInfo) GetKeyID

func (x *KeyInfo) GetKeyID() string

func (*KeyInfo) GetMechanism

func (x *KeyInfo) GetMechanism() uint64

func (*KeyInfo) GetWrappedKey

func (x *KeyInfo) GetWrappedKey() []byte

func (*KeyInfo) ProtoMessage

func (*KeyInfo) ProtoMessage()

func (*KeyInfo) ProtoReflect added in v0.5.7

func (x *KeyInfo) ProtoReflect() protoreflect.Message

func (*KeyInfo) Reset

func (x *KeyInfo) Reset()

func (*KeyInfo) String

func (x *KeyInfo) String() string

type TestWrapper

type TestWrapper struct {
	// contains filtered or unexported fields
}

TestWrapper is a wrapper that can be used for tests

func NewTestEnvelopeWrapper added in v0.5.12

func NewTestEnvelopeWrapper(secret []byte) *TestWrapper

NewTestWrapper constructs a test wrapper

func NewTestWrapper

func NewTestWrapper(secret []byte) *TestWrapper

NewTestWrapper constructs a test wrapper

func (*TestWrapper) Decrypt

func (t *TestWrapper) Decrypt(_ context.Context, dwi *EncryptedBlobInfo, _ []byte) ([]byte, error)

Decrypt allows decrypting via the test wrapper

func (*TestWrapper) Encrypt

func (t *TestWrapper) Encrypt(_ context.Context, plaintext, _ []byte) (*EncryptedBlobInfo, error)

Encrypt allows encrypting via the test wrapper

func (*TestWrapper) Finalize

func (t *TestWrapper) Finalize(_ context.Context) error

Finalize finalizes the test wrapper

func (*TestWrapper) HMACKeyID

func (t *TestWrapper) HMACKeyID() string

HMACKeyID returns the configured HMAC key ID

func (*TestWrapper) Init

func (t *TestWrapper) Init(_ context.Context) error

Init initializes the test wrapper

func (*TestWrapper) KeyID

func (t *TestWrapper) KeyID() string

KeyID returns the configured key ID

func (*TestWrapper) SetKeyID

func (t *TestWrapper) SetKeyID(k string)

SetKeyID allows setting the test wrapper's key ID

func (*TestWrapper) Type

func (t *TestWrapper) Type() string

Type returns the type of the test wrapper

type Wrapper

type Wrapper interface {
	// Type is the type of Wrapper
	Type() string

	// KeyID is the ID of the key currently used for encryption
	KeyID() string
	// HMACKeyID is the ID of the key currently used for HMACing (if any)
	HMACKeyID() string

	// Init allows performing any necessary setup calls before using this Wrapper
	Init(context.Context) error
	// Finalize should be called when all usage of this Wrapper is done
	Finalize(context.Context) error

	// Encrypt encrypts the given byte slice and puts information about the final result in the returned value. The second byte slice is to pass any additional authenticated data; this may or may not be used depending on the particular implementation.
	Encrypt(context.Context, []byte, []byte) (*EncryptedBlobInfo, error)
	// Decrypt takes in the value and decrypts it into the byte slice.  The byte slice is to pass any additional authenticated data; this may or may not be used depending on the particular implementation.
	Decrypt(context.Context, *EncryptedBlobInfo, []byte) ([]byte, error)
}

Wrapper is the embedded implementation of autoSeal that contains logic specific to encrypting and decrypting data, or in this case keys.

type WrapperOptions

type WrapperOptions struct {
	Logger hclog.Logger

	// KeyNotRequired indicates if an existing key must be
	// supplied in the configuration for a Wrapper.
	KeyNotRequired bool
}

WrapperOptions contains options used when creating a Wrapper

Directories

Path Synopsis
entropy module
extras
kms Module
kms/examples Module
internal
xor
plugin module
wrappers

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL