hardwarekey

package
v0.0.0-...-bd075a3 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2025 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package hardwarekey defines types and interfaces for hardware private keys.

Package hardwarekey defines types and interfaces for hardware private keys.

Index

Constants

This section is empty.

Variables

View Source
var (
	// DefaultPIN for the PIV applet. The PIN is used to change the Management Key,
	// and slots can optionally require it to perform signing operations.
	DefaultPIN = "123456"
	// DefaultPUK for the PIV applet. The PUK is only used to reset the PIN when
	// the card's PIN retries have been exhausted.
	DefaultPUK = "12345678"
)
View Source
var (
	// PromptPolicyNone does not require touch or pin.
	PromptPolicyNone = PromptPolicy{TouchRequired: false, PINRequired: false}
	// PromptPolicyTouch requires touch.
	PromptPolicyTouch = PromptPolicy{TouchRequired: true, PINRequired: false}
	// PromptPolicyPIN requires pin.
	PromptPolicyPIN = PromptPolicy{TouchRequired: false, PINRequired: true}
	// PromptPolicyTouchAndPIN requires touch and pin.
	PromptPolicyTouchAndPIN = PromptPolicy{TouchRequired: true, PINRequired: true}
)

Functions

func EncodeSigner

func EncodeSigner(p *Signer) ([]byte, error)

EncodeSigner encodes the hardware key signer a format understood by other Teleport clients.

func NewCLIPrompt

func NewCLIPrompt(w io.Writer, r prompt.StdinReader) *cliPrompt

NewStdCLIPrompt returns a new CLIPrompt with the given writer and reader. Used in tests.

func NewStdCLIPrompt

func NewStdCLIPrompt() *cliPrompt

NewStdCLIPrompt returns a new CLIPrompt with stderr and stdout.

func PIVSlotKeyToProto

func PIVSlotKeyToProto(slotKey PIVSlotKey) (hardwarekeyagentv1.PIVSlotKey, error)

PIVSlotKeyFromProto convert the piv slot key to proto.

Types

type AgentKeyInfo

type AgentKeyInfo struct {
	// UnknownAgentKey indicates whether this hardware private key is known to the hardware key agent
	// process, usually based on whether a matching key is found in the process's client key store.
	//
	// For unknown agent keys, the hardware key service will check that the certificate in the same
	// slot as the key matches a Teleport client metadata certificate in order to ensure the agent
	// doesn't provide access to non teleport client PIV keys.
	UnknownAgentKey bool
	// Command is the command reported by the agent client which this agent key is being utilized to
	// complete, e.g. `tsh ssh server01`.
	Command string
}

AgentKeyInfo contains info associated with an hardware key agent signature request.

type AttestationStatement

type AttestationStatement attestationv1.AttestationStatement

AttestationStatement is an attestation statement for a hardware private key that supports json marshaling through the standard json/encoding package.

func AttestationStatementFromProto

func AttestationStatementFromProto(att *attestationv1.AttestationStatement) *AttestationStatement

AttestationStatementFromProto converts an AttestationStatement from its protobuf form.

func (*AttestationStatement) MarshalJSON

func (a *AttestationStatement) MarshalJSON() ([]byte, error)

MarshalJSON implements custom protobuf json marshaling.

func (*AttestationStatement) ToProto

ToProto converts this AttestationStatement to its protobuf form.

func (*AttestationStatement) UnmarshalJSON

func (a *AttestationStatement) UnmarshalJSON(buf []byte) error

UnmarshalJSON implements custom protobuf json unmarshaling.

type ContextualKeyInfo

type ContextualKeyInfo struct {
	// ProxyHost is the root proxy hostname that the key is associated with.
	ProxyHost string
	// Username is a Teleport username that the key is associated with.
	Username string
	// ClusterName is a Teleport cluster name that the key is associated with.
	ClusterName string
	// AgentKeyInfo contains info associated with an hardware key agent signature request.
	AgentKeyInfo AgentKeyInfo
}

ContextualKeyInfo contains contextual information associated with a hardware [PrivateKey].

type MockHardwareKeyService

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

func NewMockHardwareKeyService

func NewMockHardwareKeyService(prompt Prompt) *MockHardwareKeyService

NewMockHardwareKeyService returns a [mockHardwareKeyService] for use in tests. If prompt is provided, the service will also mock PIN and touch prompts.

func (*MockHardwareKeyService) AddUnknownAgentKey

func (s *MockHardwareKeyService) AddUnknownAgentKey(ref *PrivateKeyRef)

func (*MockHardwareKeyService) GetFullKeyRef

func (s *MockHardwareKeyService) GetFullKeyRef(serialNumber uint32, slotKey PIVSlotKey) (*PrivateKeyRef, error)

TODO(Joerger): DELETE IN v19.0.0

func (*MockHardwareKeyService) MockTouch

func (s *MockHardwareKeyService) MockTouch()

func (*MockHardwareKeyService) NewPrivateKey

func (s *MockHardwareKeyService) NewPrivateKey(ctx context.Context, config PrivateKeyConfig) (*Signer, error)

func (*MockHardwareKeyService) Reset

func (s *MockHardwareKeyService) Reset()

func (*MockHardwareKeyService) SetPrompt

func (s *MockHardwareKeyService) SetPrompt(prompt Prompt)

func (*MockHardwareKeyService) Sign

func (s *MockHardwareKeyService) Sign(ctx context.Context, ref *PrivateKeyRef, keyInfo ContextualKeyInfo, rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)

Sign performs a cryptographic signature using the specified hardware private key and provided signature parameters.

type PINAndPUK

type PINAndPUK struct {
	// New PIN set by the user.
	PIN string
	// PUK used to change the PIN.
	// This is a new PUK if it has not been changed (from the default PUK).
	PUK string
	// PUKChanged is true if the user changed the default PUK.
	PUKChanged bool
}

PINAndPUK describes a response returned from Prompt.ChangePIN.

func (PINAndPUK) Validate

func (p PINAndPUK) Validate() error

Validate the user-provided PIN and PUK.

type PINPromptRequirement

type PINPromptRequirement int

PINPromptRequirement specifies whether a PIN is required.

const (
	// PINOptional allows the user to proceed without entering a PIN.
	PINOptional PINPromptRequirement = iota
	// PINRequired enforces that a PIN must be entered to proceed.
	PINRequired
)

type PIVSlotKey

type PIVSlotKey uint32

PIVSlotKey is the key reference for a specific PIV slot.

See: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=32

func GetDefaultSlotKey

func GetDefaultSlotKey(policy PromptPolicy) (PIVSlotKey, error)

GetDefaultSlotKey gets the default PIV slot key for the given [policy].

  • 9A for PromptPolicyNone
  • 9C for PromptPolicyTouch
  • 9D for PromptPolicyTouchAndPIN
  • 9E for PromptPolicyPIN

func PIVSlotKeyFromProto

func PIVSlotKeyFromProto(pivSlot hardwarekeyagentv1.PIVSlotKey) (PIVSlotKey, error)

PIVSlotKeyFromProto convert the piv slot key from proto.

func (PIVSlotKey) Validate

func (k PIVSlotKey) Validate() error

Validate the slot key value.

type PIVSlotKeyString

type PIVSlotKeyString string

PIVSlotKeyString is the string representation of a PIVSlotKey.

func (PIVSlotKeyString) Parse

func (s PIVSlotKeyString) Parse() (PIVSlotKey, error)

Parse [s] into a PIVSlotKey.

func (PIVSlotKeyString) Validate

func (s PIVSlotKeyString) Validate() error

Validate that [s] parses into a valid PIVSlotKey.

type PrivateKeyConfig

type PrivateKeyConfig struct {
	// Policy is a prompt policy to require for the hardware private key.
	Policy PromptPolicy
	// CustomSlot is a specific PIV slot to generate the hardware private key in.
	// If unset, the default slot for the given policy will be used.
	//   - !touch & !pin -> 9a
	//   - !touch & pin  -> 9c
	//   - touch & pin   -> 9d
	//   - touch & !pin  -> 9e
	CustomSlot PIVSlotKeyString
	// Algorithm is the key algorithm to use. Defaults to [AlgorithmEC256].
	// [AlgorithmEd25519] is not supported by all hardware keys.
	Algorithm SignatureAlgorithm
	// ContextualKeyInfo contains additional info to associate with the key.
	ContextualKeyInfo ContextualKeyInfo
	// PINCacheTTL is an option to enable PIN caching for this key with the specified TTL.
	PINCacheTTL time.Duration
}

PrivateKeyConfig contains config for creating a new hardware private key.

type PrivateKeyRef

type PrivateKeyRef struct {
	// SerialNumber is the hardware key's serial number.
	SerialNumber uint32 `json:"serial_number"`
	// SlotKey is the key name for the hardware key PIV slot, e.g. "9a".
	SlotKey PIVSlotKey `json:"slot_key"`
	// PublicKey is the public key paired with the hardware private key.
	PublicKey crypto.PublicKey `json:"-"` // uses custom JSON marshaling in PKIX, ASN.1 DER form
	// Policy specifies the hardware private key's PIN/touch prompt policies.
	Policy PromptPolicy `json:"policy"`
	// AttestationStatement contains the hardware private key's attestation statement, which is
	// to attest the touch and pin requirements for this hardware private key during login.
	AttestationStatement *AttestationStatement `json:"attestation_statement"`
	// PINCacheTTL is how long hardware key prompts should cache the PIN for this key, if at all.
	PINCacheTTL time.Duration `json:"pin_cache_ttl"`
}

PrivateKeyRef references a specific hardware private key.

func (PrivateKeyRef) MarshalJSON

func (r PrivateKeyRef) MarshalJSON() ([]byte, error)

MarshalJSON marshals PrivateKeyRef with custom logic for the public key.

func (*PrivateKeyRef) UnmarshalJSON

func (r *PrivateKeyRef) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals PrivateKeyRef with custom logic for the public key.

func (*PrivateKeyRef) Validate

func (r *PrivateKeyRef) Validate() error

type Prompt

type Prompt interface {
	// AskPIN prompts the user for a PIN.
	// The requirement tells if the PIN is required or optional.
	AskPIN(ctx context.Context, requirement PINPromptRequirement, keyInfo ContextualKeyInfo) (string, error)
	// Touch prompts the user to touch the hardware key.
	Touch(ctx context.Context, keyInfo ContextualKeyInfo) error
	// ChangePIN asks for a new PIN.
	// If the PUK has a default value, it should ask for the new value for it.
	// It is up to the implementer how the validation is handled.
	// For example, CLI prompt can ask for a valid PIN/PUK in a loop, a GUI
	// prompt can use the frontend validation.
	ChangePIN(ctx context.Context, keyInfo ContextualKeyInfo) (*PINAndPUK, error)
	// ConfirmSlotOverwrite asks the user if the slot's private key and certificate can be overridden.
	ConfirmSlotOverwrite(ctx context.Context, message string, keyInfo ContextualKeyInfo) (bool, error)
}

Prompt provides methods to interact with a hardware Signer.

type PromptPolicy

type PromptPolicy struct {
	// TouchRequired means that touch is required for signatures.
	TouchRequired bool
	// PINRequired means that PIN is required for signatures.
	PINRequired bool
}

PromptPolicy specifies a hardware private key's PIN/touch prompt policies.

type Service

type Service interface {
	// NewPrivateKey creates a hardware private key that satisfies the provided [config],
	// if one does not already exist, and returns a corresponding [hardwarekey.Signer].
	NewPrivateKey(ctx context.Context, config PrivateKeyConfig) (*Signer, error)
	// Sign performs a cryptographic signature using the specified hardware
	// private key and provided signature parameters.
	Sign(ctx context.Context, ref *PrivateKeyRef, keyInfo ContextualKeyInfo, rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)
	// TODO(Joerger): DELETE IN v19.0.0
	// GetFullKeyRef gets the full [PrivateKeyRef] for an existing hardware private
	// key in the given slot of the hardware key with the given serial number.
	GetFullKeyRef(serialNumber uint32, slotKey PIVSlotKey) (*PrivateKeyRef, error)
}

Service for interfacing with hardware private keys.

type SignatureAlgorithm

type SignatureAlgorithm int

SignatureAlgorithm is a signature key algorithm option.

const (
	SignatureAlgorithmEC256 SignatureAlgorithm = iota + 1
	SignatureAlgorithmEd25519
	SignatureAlgorithmRSA2048
)

type Signer

type Signer struct {
	Ref     *PrivateKeyRef
	KeyInfo ContextualKeyInfo
	// contains filtered or unexported fields
}

Signer is a hardware key implementation of crypto.Signer.

func DecodeSigner

func DecodeSigner(encodedKey []byte, s Service, keyInfo ContextualKeyInfo) (*Signer, error)

DecodeSigner decodes an encoded hardware key signer for the given service.

func NewSigner

func NewSigner(s Service, ref *PrivateKeyRef, keyInfo ContextualKeyInfo) *Signer

NewSigner returns a Signer for the given service and ref. keyInfo is an optional argument to supply additional contextual info used to add additional context to prompts, e.g. ProxyHost.

func (*Signer) GetAttestationStatement

func (h *Signer) GetAttestationStatement() *AttestationStatement

GetAttestation returns the hardware private key attestation details.

func (*Signer) GetPromptPolicy

func (h *Signer) GetPromptPolicy() PromptPolicy

GetPrivateKeyPolicy returns the PrivateKeyPolicy satisfied by this key.

func (*Signer) Public

func (h *Signer) Public() crypto.PublicKey

Public implements crypto.Signer.

func (*Signer) Sign

func (h *Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

Sign implements crypto.Signer.

func (*Signer) WarmupHardwareKey

func (h *Signer) WarmupHardwareKey(ctx context.Context) error

WarmupHardwareKey performs a bogus sign() call to prompt the user for PIN/touch (if needed).

Jump to

Keyboard shortcuts

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