nodeenrollment

package module
v0.1.13 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2022 License: MPL-2.0 Imports: 17 Imported by: 0

README

Node Enrollment

This is a library that makes it easy to set up some complicated enrollment and authentication/authorization flows for nodes, including in a proxied fashion.

It requires a minimal storage abstraction, but the functions provided can be closures to tie the storage into e.g. transactions.

It supports transparent encryption of sensitive values if a go-kms-wrapping v2 wrapper is provided. For this reason, use store and load methods on the types, rather than direct storage functions, when using this library (unless you doing your own wrapping in your storage implementation).

More information to come at a later date.

Documentation

Index

Constants

View Source
const (
	// DefaultNotBeforeClockSkewDuration is the time to subtract from NotBefore to account for
	// some clock skew
	DefaultNotBeforeClockSkewDuration = -5 * time.Minute

	// DefaultNotAfterClockSkewDuration is the time to subtract from NotBefore to account for
	// some clock skew
	DefaultNotAfterClockSkewDuration = 5 * time.Minute

	// DefaultCertificateLifetime is the default duration of a certificate, set
	// to two weeks. Rotations should happen at roughly half this.
	DefaultCertificateLifetime = time.Hour * 24 * 14

	// CommonDnsName is a name we can use in the absence of anything more
	// specific. In most cases we actually do not care about common name or DNS
	// SAN verification, and when we do we have an explicit test for it. In all
	// other cases using this allows us to not fail due to name validity checks.
	// Derived loosely from the Wizard in The Wizard of Oz.
	CommonDnsName = "pay-no-attention-to-that-pers-on-behind-the-curt-on"

	// FetchNodeCredsNextProtoV1Prefix is the ALPN NextProto used when a node is
	// trying to fetch credentials
	FetchNodeCredsNextProtoV1Prefix = "v1-nodee-fetch-node-creds-"

	// AuthenticateNodeNextProtoV1Prefix is the ALPN NextProto used when a node
	// is trying to authenticate
	AuthenticateNodeNextProtoV1Prefix = "v1-nodee-authenticate-node-"

	// NonceSize is our defined nonce size, in bytes
	NonceSize = 32

	// KeyIdNumWords is the number of words to generate from a hash of the
	// public key to serve as the key ID
	KeyIdNumWords = 8

	// The ID that will always be used for storing root certificate messages
	RootsMessageId = "roots"

	// The default amount of time for a signed fetch request validity period
	DefaultFetchCredentialsLifetime = time.Hour * 24
)

Variables

View Source
var ErrNotAuthorized = errors.New("node is not yet authorized")

ErrNotAuthorized is a common error that we can return to indicate that a node is still awaiting authentication after attempting to fetch credentials

View Source
var ErrNotFound = errors.New("value not found in storage")

ErrNotFound is a common error to use when a value is not found in storage. Depending on the storage implementation it may be a different underlying error, so this ensures we can use errors.Is as a check.

Functions

func ContainsKnownAlpnProto

func ContainsKnownAlpnProto(protos ...string) bool

ContainsKnownAlpnProto performs a simple check to see if one our defined ALPN protos is contained in the given set

func DecryptMessage

func DecryptMessage(ctx context.Context, id string, ct []byte, keySource X25519Producer, result proto.Message, _ ...Option) error

DecryptMessage takes any a value encrypted with EncryptMessage and a valid key source that implements X25519Producer and decrypts the message into the given proto.Message. Internally it uses an `aead` wrapper from go-kms-wrapping v2. No options are currently supported but in the future non-AES-GCM decryption types could be supported by the wrapper and chosen here.

ID should match what was passed into the encryption function. It is also passed as additional authenticated data to the decryption function, if supported.

func EncryptMessage

func EncryptMessage(ctx context.Context, id string, msg proto.Message, keySource X25519Producer, opt ...Option) ([]byte, error)

EncryptMessage takes any proto.Message and a valid key source that implements X25519Producer. Internally it uses an `aead` wrapper from go-kms-wrapping v2. No options are currently supported but in the future non-AES-GCM encryption types could be supported by the wrapper and chosen here.

ID is embedded into the wrapped message as the key ID. This can be useful to disambiguate either the source or target. It is also passed as additional authenticated data to the encryption function, if supported.

The resulting value from the wrapper is marshaled before being returned.

Supported options: WithRandomReader

func IsNil

func IsNil(in any) bool

func KeyIdFromPkix

func KeyIdFromPkix(pkixKey []byte) (string, error)

KeyIdFromPkix derives the library-specific key ID from the PKIX-encoed public key

func SubjectKeyInfoAndKeyIdFromPubKey

func SubjectKeyInfoAndKeyIdFromPubKey(pubKey crypto.PublicKey) ([]byte, string, error)

SubjectKeyInfoAndKeyIdFromPubKey returns the PKIX-encoded public key and the library-specific key ID derived from it

Types

type KnownId

type KnownId string
const (
	MissingId KnownId = ""

	// CurrentId is a const for when we are fetching the "current" value for
	// various purposes
	CurrentId KnownId = "current"

	// NextId is a const for when we are fetching the "next" value for various
	// purposes
	NextId KnownId = "next"
)

type MessageWithId

type MessageWithId interface {
	proto.Message
	GetId() string
}

MessageWithId is a proto message that is required to implement a GetId function, which will be immediately satisfied by any message with an `string id = X;` parameter.

type Option

type Option func(*Options) error

Option is a function that takes in an options struct and sets values or returns an error

func WithAlpnProtoPrefix

func WithAlpnProtoPrefix(with string) Option

WithAlpnProtoPrefix is used to convey information about which proto is being used to handle a connection

func WithCertificateLifetime

func WithCertificateLifetime(with time.Duration) Option

WithCertificateLifetime allows overriding a default duration for certificate creation

func WithExpectedPublicKey

func WithExpectedPublicKey(with []byte) Option

WithExpectedPublicKey allows indicating a public key that we expect to be the key signed by a certificate

func WithExtraAlpnProtos added in v0.1.5

func WithExtraAlpnProtos(with []string) Option

WithExtraAlpnProtos is used to allow passing additional ALPN protos in via a ClientHello message, e.g. via the Dial function in the protocol package. This can allow users of the library to perform an extra switch on the desired protocol post-authentication.

func WithNonce

func WithNonce(with string) Option

WithNonce is used at various points for encoding nonces in certs or expecting them there

func WithNotAfterClockSkew

func WithNotAfterClockSkew(with time.Duration) Option

WithNotAfterClockSkew allows overriding a default duration for certificate NotAfter clock skew handling

func WithNotBeforeClockSkew

func WithNotBeforeClockSkew(with time.Duration) Option

WithNotBeforeClockSkew allows overriding a default duration for certificate NotBefore clock skew handling

func WithRandomReader

func WithRandomReader(with io.Reader) Option

WithRandomReader allows specifying a reader to use in place of the default (crypto/rand.Reader)

func WithServerName added in v0.1.2

func WithServerName(with string) Option

WithServerName is used to pass a server name to include in a TLS config

func WithSkipStorage

func WithSkipStorage(with bool) Option

WithSkipStorage allows indicating that the newly generated resource should not be stored in storage, but simply returned in-memory only, useful for tests or cases where the storage implementation wants to manage storage lifecycle (e.g. with transactions)

func WithState

func WithState(with *structpb.Struct) Option

WithState allows passing state in to some registration functions to round trip to NodeInformation storage

func WithTlsVerifyOptionsFunc

func WithTlsVerifyOptionsFunc(with func(*x509.CertPool) x509.VerifyOptions) Option

WithTlsVerifyOptionsFunc allows specifying a custom TLS certificate VerifyFunc, useful for testing

func WithWrapper

func WithWrapper(with wrapping.Wrapper) Option

WithWrapper will cause the library to wrap any sensitive information (private keys, nonces, etc.) with the given wrapper prior to writing to storage, and to unwrap when reading from storage

type Options

type Options struct {
	WithCertificateLifetime  time.Duration
	WithNotBeforeClockSkew   time.Duration
	WithNotAfterClockSkew    time.Duration
	WithRandomReader         io.Reader
	WithNonce                string
	WithTlsVerifyOptionsFunc func(*x509.CertPool) x509.VerifyOptions
	WithWrapper              wrapping.Wrapper
	WithSkipStorage          bool
	WithExpectedPublicKey    []byte
	WithState                *structpb.Struct
	WithAlpnProtoPrefix      string
	WithServerName           string
	WithExtraAlpnProtos      []string
}

Options contains various options. The values are exported since the options are parsed in various other packages.

func GetOpts

func GetOpts(opt ...Option) (*Options, error)

GetOpts iterates the inbound Options and returns a struct and any errors

type Storage

type Storage interface {
	// Store stores the given message
	Store(context.Context, MessageWithId) error

	// Load loads values into the given message. The message must be populated
	// with the ID of the value to load. If not found, the returned error should
	// be ErrNotFound.
	Load(context.Context, MessageWithId) error

	// Remove removes the given message. The ID field of the message must be
	// populated, and only the ID field of the message is considered.
	Remove(context.Context, MessageWithId) error

	// List returns a list of IDs; the type of the message is used to
	// disambiguate what to list, and can be a nil pointer to the type.
	List(context.Context, proto.Message) ([]string, error)
}

Storage is an interface for to store values. The interface operates on proto.Message or MessageWithId (which embeds a proto.Message but requires a GetId() function), which is satisifed by all types in this library and provides some type safety vs. any.

The interface can be used for multiple types of message via a type switch on, allowing various implementations to then read or write the correct data from e.g. separate storage locations.

type X25519Producer

type X25519Producer interface {
	X25519EncryptionKey() ([]byte, error)
}

X25519Producer is an interface that can be satisfied by an underlying type that produces an encryption key via X25519.

Directories

Path Synopsis
Protocol provides a listener and dial function that can be used to easily integrate this library into other applications.
Protocol provides a listener and dial function that can be used to easily integrate this library into other applications.
storage
util

Jump to

Keyboard shortcuts

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