Documentation
¶
Overview ¶
Package integrity defines the integrity-checking interface of tt: a repository for reading verified files, signing, and the hashers and verifiers used by storage-backed readers and writers.
A Provider implements the interface. The disabled provider, returned by NewDisabledProvider, performs no checks, and the package-level functions delegate to it. tt runs with the provider its distribution chooses (core.WithIntegrity in github.com/tarantool/tt/v3/core) and with the disabled one when it chooses none; a module does not choose.
The RSA provider, returned by NewRSAProvider, signs with an RSA private key and checks with its public key. Its Signer writes hashes files that list the SHA-256 digests of the files of a tree, each with an RSASSA-PSS signature next to it: for the tree of a package, hashes.json lists what Tarantool loads and env_hashes.json everything else, so that every file is listed once; for a runtime a package bundles, env_hashes.json lists the files under the paths they are installed at. Its check verifies the signatures and the digests of the hashes files of every root it is given - an application and the runtimes it runs on - and its Repository hashes a file again every time it reads it. VerifyTree checks that a whole tree is signed, before it is installed. Data published to a configuration storage carries a digest and a signature of the same kind.
A signature of RSASSA-PSS has a random salt: signing the same tree twice gives the same hashes files and different signatures.
The API of this package is alpha and may change incompatibly.
Index ¶
- Constants
- Variables
- func GetCheckFunction(ctx IntegrityCtx) (func(data []byte, hashes map[string][]byte, sign []byte) error, error)
- func GetSignFunction(privateKeyPath string) (func(data []byte) (map[string][]byte, []byte, error), error)
- func GetStorageSigners(privateKeyPath string) ([]ghasher.Hasher, []gcrypto.SignerVerifier, error)
- func GetStorageVerifiers(ctx IntegrityCtx) ([]ghasher.Hasher, []gcrypto.Verifier, error)
- func RegisterIntegrityCheckFlag(flagset *pflag.FlagSet, dst *string)
- func RegisterIntegrityCheckPeriodFlag(flagset *pflag.FlagSet, dst *int)
- func RegisterWithIntegrityFlag(flagset *pflag.FlagSet, dst *string)
- func VerifyTree(publicKeyPath, dir string) error
- type IntegrityCtx
- type Provider
- type Repository
- type SignOptions
- type SignedFile
- type Signer
Constants ¶
const HashesFileName = ""
HashesFileName is a name of a file containing file hashes that require checking.
Variables ¶
Functions ¶
func GetCheckFunction ¶
func GetCheckFunction(ctx IntegrityCtx) ( func(data []byte, hashes map[string][]byte, sign []byte) error, error, )
GetCheckFunction returns a function that checks a map of hashes and a signature of a data.
func GetSignFunction ¶
func GetSignFunction(privateKeyPath string) ( func(data []byte) (map[string][]byte, []byte, error), error, )
GetSignFunction returns a function that creates a map of hashes and a signature for a data for the private key in the path.
func GetStorageSigners ¶
func GetStorageSigners( privateKeyPath string, ) ([]ghasher.Hasher, []gcrypto.SignerVerifier, error)
GetStorageSigners returns integrity primitives for storage-backed writers.
func GetStorageVerifiers ¶
GetStorageVerifiers returns integrity primitives for storage-backed readers.
func RegisterIntegrityCheckFlag ¶
RegisterIntegrityCheckFlag is a noop function that is intended to add root flag enabling integrity checks.
func RegisterIntegrityCheckPeriodFlag ¶
RegisterIntegrityCheckPeriodFlag is a noop function that is intended to add flag specifying how often should integrity checks run in watchdog.
func RegisterWithIntegrityFlag ¶
RegisterWithIntegrityFlag is a noop function that is intended to add integrity flags to commands that publish signed data.
func VerifyTree ¶
VerifyTree refuses to check a tree: the disabled provider checks nothing.
Types ¶
type IntegrityCtx ¶
type IntegrityCtx struct {
// Repository is a repository used to check integrity of files.
Repository Repository
// contains filtered or unexported fields
}
IntegrityCtx is context required for integrity checks.
func InitializeIntegrityCheck ¶
func InitializeIntegrityCheck( publicKeyPath string, roots ...string, ) (IntegrityCtx, error)
InitializeIntegrityCheck is a noop setup of integrity checking of the files rooted at roots.
type Provider ¶
type Provider interface {
// RegisterWithIntegrityFlag adds the flag naming the private key used
// to sign published data.
RegisterWithIntegrityFlag(flags *pflag.FlagSet, dst *string)
// RegisterIntegrityCheckFlag adds the root flag naming the public key
// that enables integrity checks.
RegisterIntegrityCheckFlag(flags *pflag.FlagSet, dst *string)
// RegisterIntegrityCheckPeriodFlag adds the flag setting how often the
// watchdog re-checks integrity.
RegisterIntegrityCheckPeriodFlag(flags *pflag.FlagSet, dst *int)
// HashesFileName is the name of the file with the hashes of an
// application's files.
HashesFileName() string
// InitializeIntegrityCheck sets up integrity checking of the files the
// signed hashes files in the directories roots list, with the public
// key at publicKeyPath; a root without hashes files lists nothing. tt
// passes the directory of the application it works on - the project,
// or an installed version - and the directories of the runtimes it
// runs, tarantool, tt and tcm. An empty publicKeyPath disables the
// checks.
InitializeIntegrityCheck(publicKeyPath string, roots ...string) (IntegrityCtx, error)
// VerifyTree checks the tree rooted at dir with the public key at
// publicKeyPath: it must be signed, every file its hashes files list
// must match, and every file of the tree must be listed. A symbolic
// link to a directory, or one that leads nowhere, holds no file and is
// passed over. It is the check of what is about to be installed.
VerifyTree(publicKeyPath, dir string) error
// NewSigner creates a Signer for the private key at privateKeyPath.
NewSigner(privateKeyPath string) (Signer, error)
// GetCheckFunction returns a function that checks a map of hashes and
// a signature of a data.
GetCheckFunction(ctx IntegrityCtx) (
func(data []byte, hashes map[string][]byte, sign []byte) error, error,
)
// GetSignFunction returns a function that creates a map of hashes and a
// signature for a data for the private key at privateKeyPath.
GetSignFunction(privateKeyPath string) (
func(data []byte) (map[string][]byte, []byte, error), error,
)
// GetStorageVerifiers returns integrity primitives for storage-backed
// readers.
GetStorageVerifiers(ctx IntegrityCtx) ([]ghasher.Hasher, []gcrypto.Verifier, error)
// GetStorageSigners returns integrity primitives for storage-backed
// writers for the private key at privateKeyPath.
GetStorageSigners(
privateKeyPath string,
) ([]ghasher.Hasher, []gcrypto.SignerVerifier, error)
}
Provider is an implementation of integrity checking. Each method matches the package-level function of the same name; the package-level functions are the disabled provider.
A caller selects the provider once and passes it to everything that registers integrity flags, initializes integrity checking or builds signers and verifiers. An IntegrityCtx is only meaningful to the provider that created it.
func NewDisabledProvider ¶
func NewDisabledProvider() Provider
NewDisabledProvider returns the provider that performs no integrity checks: it registers no flags, reads files as they are, and refuses to sign or to verify with a key.
func NewRSAProvider ¶
func NewRSAProvider() Provider
NewRSAProvider returns the provider that signs with an RSA private key and checks with its public key. A signed environment carries hashes files that list the SHA-256 digests of its files, each signed with RSASSA-PSS; data published to a configuration storage carries its digest and signature.
type Repository ¶
type Repository interface {
// Read checks the file at path and returns it opened for reading.
//
// The content of the file matched its digest when Read opened it. The
// returned file is the live file: a write to it after Read returns
// reaches the reader undetected, and only a later ValidateAll reports
// it. Meant for large files and for callers that need a file rather
// than bytes.
Read(path string) (io.ReadCloser, error)
// ReadFile checks the file at path and returns its content.
//
// The file is read into memory once and those bytes are checked, so
// the returned bytes are exactly the ones that matched the digest,
// whatever happens to the file afterwards. The cost is memory
// proportional to the file. Meant for configuration and script files.
ReadFile(path string) ([]byte, error)
// ValidateAll checks that all the files stored in the repository
// were not modified.
ValidateAll() error
}
Repository provides utilities for working with files and ensuring that they were not compromised.
The guarantees below hold while integrity checking is on. The repository of the disabled provider, and of a check initialized without a public key, checks nothing: Read and ReadFile return files as they are and ValidateAll reports nothing.
type SignOptions ¶
type SignOptions struct {
// Skip are directories of the tree, as slash-separated paths relative
// to its root, that are not listed: what is installed apart from the
// package, such as the runtime it bundles.
Skip []string
// Loaded are files of the tree, as slash-separated paths relative to its
// root, that Tarantool loads whatever their names, such as the scripts
// the instance records run. Each must be a file of the tree.
Loaded []string
}
SignOptions tune what Signer.Sign lists.
type SignedFile ¶
type SignedFile struct {
// Path is the path the file is listed under: relative to the directory
// of the hashes file, slash-separated, without "." or "..".
Path string
// Source is the file whose content is listed.
Source string
}
SignedFile is a file Signer.SignFiles lists.
type Signer ¶
type Signer interface {
// Sign signs the tree of a package rooted at dir. It writes two hashes
// files in dir, each with its signature: hashes.json lists the files
// Tarantool loads - Lua sources, shared libraries, cluster configs, the
// files opts.Loaded names - and is what tt hands Tarantool to check
// them; env_hashes.json lists every other file of the tree, the ones tt
// reads and runs itself. Every file of the tree is listed exactly once,
// but for the directories opts.Skip names and the hashes files and
// signatures themselves, wherever they are.
Sign(dir string, opts SignOptions) error
// SignFiles writes the environment hashes file of dir, env_hashes.json,
// listing files under the paths they are to have there, and its
// signature. It signs a tree that is laid out after it is signed, such
// as the runtime a package bundles, which is installed apart from it.
SignFiles(dir string, files []SignedFile) error
}
Signer writes signed hashes files: the lists of the files of a tree with their digests that a check rooted at the tree knows them by.