ocicrypt

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Jan 9, 2024 License: Apache-2.0 Imports: 27 Imported by: 0

README

OCIcrypt Library

The ocicrypt library is the OCI image spec implementation of container image encryption. More details of the spec can be seen in the OCI repository. The purpose of this library is to encode spec structures and consts in code, as well as provide a consistent implementation of image encryption across container runtimes and build tools.

Consumers of OCIcrypt:

Usage

There are various levels of usage for this library. The main consumers of these would be runtime/build tools, and a more specific use would be in the ability to extend cryptographic function.

Runtime/Build tool usage

The general exposed interface a runtime/build tool would use, would be to perform encryption or decryption of layers:

package "github.com/containers/ocicrypt"
func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, desc ocispec.Descriptor) (io.Reader, EncryptLayerFinalizer, error)
func DecryptLayer(dc *config.DecryptConfig, encLayerReader io.Reader, desc ocispec.Descriptor, unwrapOnly bool) (io.Reader, digest.Digest, error)

The settings/parameters to these functions can be specified via creation of an encryption config with the github.com/containers/ocicrypt/config package. We note that because setting of annotations and other fields of the layer descriptor is done through various means in different runtimes/build tools, it is the responsibility of the caller to still ensure that the layer descriptor follows the OCI specification (i.e. encoding, setting annotations, etc.).

Crypto Agility and Extensibility

The implementation for both symmetric and asymmetric encryption used in this library are behind 2 main interfaces, which users can extend if need be. These are in the following packages:

  • github.com/containers/ocicrypt/blockcipher - LayerBlockCipher interface for block ciphers
  • github.com/containers/ocicrypt/keywrap - KeyWrapper interface for key wrapping

We note that adding interfaces here is risky outside the OCI spec is not recommended, unless for very specialized and confined usecases. Please open an issue or PR if there is a general usecase that could be added to the OCI spec.

Keyprovider interface

As part of the keywrap interface, there is a keyprovider implementation that allows one to call out to a binary or service.

Security Issues

We consider security issues related to this library critical. Please report and security related issues by emailing maintainers in the MAINTAINERS file.

Ocicrypt Pkcs11 Support

Ocicrypt Pkcs11 support is currently experiemental. For more details, please refer to the this document.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecryptLayer

func DecryptLayer(dc *config.DecryptConfig, encLayerReader io.Reader, desc ocispec.Descriptor, unwrapOnly bool) (io.Reader, digest.Digest, error)

DecryptLayer decrypts a layer trying one keywrap.KeyWrapper after the other to see whether it can apply the provided private key If unwrapOnly is set we will only try to decrypt the layer encryption key and return

func FilterOutAnnotations

func FilterOutAnnotations(annotations map[string]string) map[string]string

FilterOutAnnotations filters out the annotations belonging to the image encryption 'namespace' and returns a map with those taken out

func GPGGetPrivateKey

func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault GPGVault, mustFindKey bool) (gpgPrivKeys [][]byte, gpgPrivKeysPwds [][]byte, err error)

GPGGetPrivateKey walks the list of layerInfos and tries to decrypt the wrapped symmetric keys. For this it determines whether a private key is in the GPGVault or on this system and prompts for the passwords for those that are available. If we do not find a private key on the system for getting to the symmetric key of a layer then an error is generated.

func GetKeyWrapper

func GetKeyWrapper(scheme string) keywrap.KeyWrapper

GetKeyWrapper looks up the encryptor interface given an encryption scheme (gpg, jwe)

func GetWrappedKeysMap

func GetWrappedKeysMap(desc ocispec.Descriptor) map[string]string

GetWrappedKeysMap returns a map of wrappedKeys as values in a map with the encryption scheme(s) as the key(s)

func ReaderFromReaderAt

func ReaderFromReaderAt(r io.ReaderAt) io.Reader

ReaderFromReaderAt takes an io.ReaderAt and returns an io.Reader

func RegisterKeyWrapper

func RegisterKeyWrapper(scheme string, iface keywrap.KeyWrapper)

RegisterKeyWrapper allows to register key wrappers by their encryption scheme

Types

type EncryptLayerFinalizer

type EncryptLayerFinalizer func() (map[string]string, error)

EncryptLayerFinalizer is a finalizer run to return the annotations to set for the encrypted layer

func EncryptLayer

func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, desc ocispec.Descriptor) (io.Reader, EncryptLayerFinalizer, error)

EncryptLayer encrypts the layer by running one encryptor after the other

type GPGClient

type GPGClient interface {
	// ReadGPGPubRingFile gets the byte sequence of the gpg public keyring
	ReadGPGPubRingFile() ([]byte, error)
	// GetGPGPrivateKey gets the private key bytes of a keyid given a passphrase
	GetGPGPrivateKey(keyid uint64, passphrase string) ([]byte, error)
	// GetSecretKeyDetails gets the details of a secret key
	GetSecretKeyDetails(keyid uint64) ([]byte, bool, error)
	// GetKeyDetails gets the details of a public key
	GetKeyDetails(keyid uint64) ([]byte, bool, error)
	// ResolveRecipients resolves PGP key ids to user names
	ResolveRecipients([]string) []string
}

GPGClient defines an interface for wrapping the gpg command line tools

func NewGPGClient

func NewGPGClient(gpgVersion, gpgHomeDir string) (GPGClient, error)

NewGPGClient creates a new GPGClient object representing the given version and using the given home directory

type GPGVault

type GPGVault interface {
	// AddSecretKeyRingData adds a secret keyring via its raw byte array
	AddSecretKeyRingData(gpgSecretKeyRingData []byte) error
	// AddSecretKeyRingDataArray adds secret keyring via its raw byte arrays
	AddSecretKeyRingDataArray(gpgSecretKeyRingDataArray [][]byte) error
	// AddSecretKeyRingFiles adds secret keyrings given their filenames
	AddSecretKeyRingFiles(filenames []string) error
	// GetGPGPrivateKey gets the private key bytes of a keyid given a passphrase
	GetGPGPrivateKey(keyid uint64) ([]openpgp.Key, []byte)
}

GPGVault defines an interface for wrapping multiple secret key rings

func NewGPGVault

func NewGPGVault() GPGVault

NewGPGVault creates an empty GPGVault

type GPGVersion

type GPGVersion int

GPGVersion enum representing the GPG client version to use.

const (
	// GPGv2 signifies gpgv2+
	GPGv2 GPGVersion = iota
	// GPGv1 signifies gpgv1+
	GPGv1
	// GPGVersionUndetermined signifies gpg client version undetermined
	GPGVersionUndetermined
)

func GuessGPGVersion

func GuessGPGVersion() GPGVersion

GuessGPGVersion guesses the version of gpg. Defaults to gpg2 if exists, if not defaults to regular gpg.

Jump to

Keyboard shortcuts

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