keystore

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 8, 2025 License: MIT Imports: 32 Imported by: 0

README

Go Reference

WARNING: In development do not use in production.

Keystore

Design principles:

  • Use structs for typed extensibility of the interfaces. Easy to wrap via a network layer if needed.
  • Storage abstract. Keystore interfaces can be implemented with memory, file, database, etc. for storage to be useable in a variety of contexts. Use write through caching to maintain synchronization between in memory keys and stored keys.
  • Only the Admin interface mutates the keystore, all other interfaces are read only. Admin interface is plural/batched to support atomic batched mutations.
  • Client side key naming. Keystore itself doesn't impose certain key algorithims/curves be used for specific contexts, it just supports a the minimum viable set of algorithms/curves for chainlink wide use cases. Clients define a name for each key which represents the context in which they wish to use it.
  • Common serialization/encryption for all storage types. Protobuf serialization (compact, versioned) for key material and then key material encrypted before persistence with a passphase.

Notes

Documentation

Index

Constants

View Source
const (
	// Maximum payload size for encrypt/decrypt operations (100kb)
	// Note just an initial limit, we may want to increase this in the future.
	MaxEncryptionPayloadSize = 100 * 1024
)

Variables

View Source
var (
	ErrKeyAlreadyExists   = fmt.Errorf("key already exists")
	ErrInvalidKeyName     = fmt.Errorf("invalid key name")
	ErrKeyNotFound        = fmt.Errorf("key not found")
	ErrUnsupportedKeyType = fmt.Errorf("unsupported key type")
)
View Source
var (
	ErrSharedSecretFailed = errors.New("shared secret derivation failed")
	ErrEncryptionFailed   = errors.New("encryption operation failed")
	ErrDecryptionFailed   = errors.New("decryption operation failed")
)

Opaque error messages to prevent information leakage

View Source
var (
	ErrInvalidSignRequest   = errors.New("invalid sign request")
	ErrInvalidVerifyRequest = errors.New("invalid verify request")
)
View Source
var AllDigitalSignatureKeyTypes = KeyTypeList{Ed25519, ECDSA_S256}
View Source
var AllEncryptionKeyTypes = KeyTypeList{X25519, ECDH_P256}
View Source
var ErrUnimplemented = errors.New("unimplemented")

Functions

func ValidKeyName

func ValidKeyName(name string) error

Types

type Admin

type Admin interface {
	// CreateKeys creates multiple keys in a single atomic operation.
	// The response preserves the order of the keys in the request.
	// Returns ErrKeyAlreadyExists if any key name already exists,
	// ErrInvalidKeyName if any key name is invalid,
	// ErrUnsupportedKeyType if any key type is not supported.
	CreateKeys(ctx context.Context, req CreateKeysRequest) (CreateKeysResponse, error)

	// DeleteKeys deletes multiple keys in a single atomic operation.
	// Returns ErrKeyNotFound if any key does not exist.
	DeleteKeys(ctx context.Context, req DeleteKeysRequest) (DeleteKeysResponse, error)

	// ImportKeys imports multiple encrypted keys in a single atomic operation.
	// Keys can be renamed during import using NewKeyName.
	// Returns ErrKeyAlreadyExists if a key with the target name exists,
	// ErrInvalidKeyName if the target name is invalid.
	ImportKeys(ctx context.Context, req ImportKeysRequest) (ImportKeysResponse, error)

	// ExportKeys exports multiple keys in encrypted format.
	// Each key is encrypted using the parameters specified in the request.
	// Returns ErrKeyNotFound if any key does not exist.
	ExportKeys(ctx context.Context, req ExportKeysRequest) (ExportKeysResponse, error)

	// SetMetadata updates metadata for multiple keys in a single atomic operation.
	// Returns ErrKeyNotFound if any key does not exist.
	SetMetadata(ctx context.Context, req SetMetadataRequest) (SetMetadataResponse, error)

	// RenameKey renames an existing key.
	// Returns ErrKeyNotFound if the old key name does not exist,
	// ErrKeyAlreadyExists if the new key name exists,
	// ErrInvalidKeyName if the new key name is invalid.
	RenameKey(ctx context.Context, req RenameKeyRequest) (RenameKeyResponse, error)
}

type CoreKeystore

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

func NewCoreKeystore

func NewCoreKeystore(ks Keystore) *CoreKeystore

func (*CoreKeystore) Accounts

func (c *CoreKeystore) Accounts(ctx context.Context) ([]string, error)

func (*CoreKeystore) Decrypt

func (c *CoreKeystore) Decrypt(ctx context.Context, account string, data []byte) ([]byte, error)

func (*CoreKeystore) Sign

func (c *CoreKeystore) Sign(ctx context.Context, account string, data []byte) ([]byte, error)

type CreateKeyRequest

type CreateKeyRequest struct {
	KeyName string
	KeyType KeyType
}

type CreateKeyResponse

type CreateKeyResponse struct {
	KeyInfo KeyInfo
}

type CreateKeysRequest

type CreateKeysRequest struct {
	Keys []CreateKeyRequest
}

type CreateKeysResponse

type CreateKeysResponse struct {
	Keys []CreateKeyResponse
}

type DecryptRequest

type DecryptRequest struct {
	KeyName       string
	EncryptedData []byte
}

type DecryptResponse

type DecryptResponse struct {
	Data []byte
}

type DeleteKeysRequest

type DeleteKeysRequest struct {
	KeyNames []string
}

type DeleteKeysResponse

type DeleteKeysResponse struct{}

type DeriveSharedSecretRequest

type DeriveSharedSecretRequest struct {
	KeyName      string
	RemotePubKey []byte
}

type DeriveSharedSecretResponse

type DeriveSharedSecretResponse struct {
	SharedSecret []byte
}

type EncryptRequest

type EncryptRequest struct {
	RemoteKeyType KeyType
	RemotePubKey  []byte
	Data          []byte
}

type EncryptResponse

type EncryptResponse struct {
	EncryptedData []byte
}

type EncryptionParams

type EncryptionParams struct {
	Password     string
	ScryptParams ScryptParams
}

EncryptionParams controls password-based encryption. Password is the secret used to derive the encryption key. ScryptParams control CPU/memory cost.

type Encryptor

type Encryptor interface {
	Encrypt(ctx context.Context, req EncryptRequest) (EncryptResponse, error)
	Decrypt(ctx context.Context, req DecryptRequest) (DecryptResponse, error)
	// DeriveSharedSecret: Derives a shared secret between the key specified
	// and the remote public key. WARNING: Using the shared secret should only be used directly in
	// cases where very custom encryption schemes are needed and you know
	// exactly what you are doing.
	DeriveSharedSecret(ctx context.Context, req DeriveSharedSecretRequest) (DeriveSharedSecretResponse, error)
}

Encryptor is an interfaces for hybrid encryption (key exchange + encryption) operations.

type ExportKeyParam

type ExportKeyParam struct {
	KeyName string
	Enc     EncryptionParams
}

type ExportKeyResponse

type ExportKeyResponse struct {
	KeyName string
	Data    []byte
}

type ExportKeysRequest

type ExportKeysRequest struct {
	Keys []ExportKeyParam
}

type ExportKeysResponse

type ExportKeysResponse struct {
	Keys []ExportKeyResponse
}

type FileStorage

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

FileStorage implements Storage using a file

func NewFileStorage

func NewFileStorage(name string) *FileStorage

func (*FileStorage) GetEncryptedKeystore

func (f *FileStorage) GetEncryptedKeystore(ctx context.Context) ([]byte, error)

func (*FileStorage) PutEncryptedKeystore

func (f *FileStorage) PutEncryptedKeystore(ctx context.Context, encryptedKeystore []byte) error

type GetKeyRequest

type GetKeyRequest struct {
	KeyName string
}

type GetKeyResponse

type GetKeyResponse struct {
	KeyInfo KeyInfo
}

type GetKeysRequest

type GetKeysRequest struct {
	KeyNames []string
}

type GetKeysResponse

type GetKeysResponse struct {
	Keys []GetKeyResponse
}

type ImportKeyRequest

type ImportKeyRequest struct {
	NewKeyName string
	Data       []byte
	Password   string
}

type ImportKeysRequest

type ImportKeysRequest struct {
	Keys []ImportKeyRequest
}

type ImportKeysResponse

type ImportKeysResponse struct{}

type KeyInfo

type KeyInfo struct {
	Name      string
	KeyType   KeyType
	CreatedAt time.Time
	PublicKey []byte
	Metadata  []byte
}

KeyInfo is the information about a key in the keystore. Public key may be empty for non-asymmetric key types.

type KeyPath

type KeyPath []string

func NewKeyPath

func NewKeyPath(segments ...string) KeyPath

func NewKeyPathFromString

func NewKeyPathFromString(fullName string) KeyPath

func (KeyPath) Base

func (k KeyPath) Base() string

func (KeyPath) String

func (k KeyPath) String() string

type KeyType

type KeyType string
const (
	// Hybrid encryption (key exchange + encryption) key types.
	// Naming schema is generally <key exchange algorithm><encryption algorithm>.
	// Except for widely used/commonly paired encryption algorithms, we
	// omit the encryption algorithm. So for example X25519 with ChaCha20Poly1305
	// (via box) is specified just as X25519.
	// X25519:
	// - X25519 for ECDH key exchange.
	// - Box for encryption (ChaCha20Poly1305)
	X25519 KeyType = "X25519"
	// ECDH_P256:
	// - ECDH on P-256
	// - Encryption with AES-GCM and HKDF-SHA256
	ECDH_P256 KeyType = "ECDH_P256"

	// Digital signature key types.
	// Ed25519:
	// - Ed25519 for digital signatures.
	// - Supports arbitrary messages sizes, no hashing required.
	Ed25519 KeyType = "Ed25519"
	// ECDSA_S256:
	// - ECDSA on secp256k1 for digital signatures.
	// - Only signs 32 byte digests. Caller must hash the data before signing.
	ECDSA_S256 KeyType = "ECDSA_S256"
)

func (KeyType) IsDigitalSignatureKeyType

func (k KeyType) IsDigitalSignatureKeyType() bool

func (KeyType) IsEncryptionKeyType

func (k KeyType) IsEncryptionKeyType() bool

func (KeyType) String

func (k KeyType) String() string

type KeyTypeList

type KeyTypeList []KeyType

func (KeyTypeList) String

func (k KeyTypeList) String() string

type Keystore

type Keystore interface {
	Admin
	Reader
	Signer
	Encryptor
}

func LoadKeystore

func LoadKeystore(ctx context.Context, storage Storage, password string, opts ...Option) (Keystore, error)

LoadKeystore constructs a keystore with required args (ctx, storage, password) and optional settings via functional options. Default logger is a discard logger and default scrypt params are the standard scrypt params.

type MemoryStorage

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

MemoryStorage implements Storage using in-memory storage

func NewMemoryStorage

func NewMemoryStorage() *MemoryStorage

func (*MemoryStorage) GetEncryptedKeystore

func (m *MemoryStorage) GetEncryptedKeystore(ctx context.Context) ([]byte, error)

func (*MemoryStorage) PutEncryptedKeystore

func (m *MemoryStorage) PutEncryptedKeystore(ctx context.Context, data []byte) error

type Option

type Option func(*keystore)

func WithLogger

func WithLogger(l *slog.Logger) Option

func WithScryptParams

func WithScryptParams(sp ScryptParams) Option

type Reader

type Reader interface {
	GetKeys(ctx context.Context, req GetKeysRequest) (GetKeysResponse, error)
}

Reader is the interface for reading keys from the keystore. GetKeys returns all keys in the keystore if no names are provided, or the keys with the given names. Keys are sorted by name in lexicographic order.

type RenameKeyRequest

type RenameKeyRequest struct {
	OldName string
	NewName string
}

type RenameKeyResponse

type RenameKeyResponse struct{}

type ScryptParams

type ScryptParams struct {
	N int
	P int
}
var (
	DefaultScryptParams = ScryptParams{
		N: gethkeystore.StandardScryptN,
		P: gethkeystore.StandardScryptP,
	}
	FastScryptParams ScryptParams = ScryptParams{
		N: 1 << 14,
		P: 1,
	}
)

type SetMetadataRequest

type SetMetadataRequest struct {
	Updates []SetMetadataUpdate
}

type SetMetadataResponse

type SetMetadataResponse struct{}

type SetMetadataUpdate

type SetMetadataUpdate struct {
	KeyName  string
	Metadata []byte
}

type SignRequest

type SignRequest struct {
	KeyName string
	Data    []byte
}

type SignResponse

type SignResponse struct {
	Signature []byte
}

type Signer

type Signer interface {
	Sign(ctx context.Context, req SignRequest) (SignResponse, error)
	Verify(ctx context.Context, req VerifyRequest) (VerifyResponse, error)
}

type Storage

type Storage interface {
	GetEncryptedKeystore(ctx context.Context) ([]byte, error)
	// PutEncryptedKeystore must atomically replace the entire encrypted keystore.
	PutEncryptedKeystore(ctx context.Context, encryptedKeystore []byte) error
}

Storage is where we store the encrypted key material.

type UnimplementedAdmin

type UnimplementedAdmin struct{}

UnimplementedAdmin returns ErrUnimplemented for all Admin methods.

func (UnimplementedAdmin) CreateKeys

func (UnimplementedAdmin) DeleteKeys

func (UnimplementedAdmin) ExportKeys

func (UnimplementedAdmin) ImportKeys

func (UnimplementedAdmin) RenameKey

func (UnimplementedAdmin) SetMetadata

type UnimplementedEncryptor

type UnimplementedEncryptor struct{}

UnimplementedEncryptor returns ErrUnimplemented for all Encryptor methods. Clients should embed this struct to ensure forward compatibility with changes to the Encryptor interface.

func (UnimplementedEncryptor) Decrypt

func (UnimplementedEncryptor) DeriveSharedSecret

func (UnimplementedEncryptor) Encrypt

type UnimplementedKeystore

UnimplementedKeystore provides a no-op implementation of Keystore. It composes the specific unimplemented stubs for each interface. Clients should embed this struct to ensure forward compatibility with changes to the Keystore interface.

type UnimplementedReader

type UnimplementedReader struct{}

UnimplementedReader returns ErrUnimplemented for all Reader methods.

func (UnimplementedReader) GetKeys

type UnimplementedSigner

type UnimplementedSigner struct{}

UnimplementedSigner returns ErrUnimplemented for all Signer methods.

func (UnimplementedSigner) Sign

func (UnimplementedSigner) Verify

type VerifyRequest

type VerifyRequest struct {
	KeyType   KeyType
	PublicKey []byte
	Data      []byte
	Signature []byte
}

type VerifyResponse

type VerifyResponse struct {
	Valid bool
}

Directories

Path Synopsis
cmd
keystore command
Package internal declares a Raw private key type, only available for use in the keystore sub-tree.
Package internal declares a Raw private key type, only available for use in the keystore sub-tree.

Jump to

Keyboard shortcuts

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