piv

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2020 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package piv implements management functionality for the YubiKey PIV applet.

Index

Constants

View Source
const (
	FormfactorUSBAKeychain = iota + 1
	FormfactorUSBANano
	FormfactorUSBCKeychain
	FormfactorUSBCNano
)

Formfactors recognized by this package.

Variables

View Source
var (
	SlotAuthentication     = Slot{0x9a, 0x5fc101}
	SlotSignature          = Slot{0x9c, 0x5fc10a}
	SlotCardAuthentication = Slot{0x9e, 0x5fc10b}
)

Slot combinations pre-defined by this package.

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"
	// DefaultManagementKey for the PIV applet. The Management Key is a Triple-DES
	// key required for slot actions such as generating keys, setting certificates,
	// and signing.
	DefaultManagementKey = [24]byte{
		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
	}
)

Functions

func Cards

func Cards() ([]string, error)

Cards lists all smart cards available via PC/SC interface. Card names are strings describing the key, such as "Yubico Yubikey NEO OTP+U2F+CCID 00 00".

Card names depend on the operating system and what port a card is plugged into. To uniquely identify a card, use its serial number.

See: https://ludovicrousseau.blogspot.com/2010/05/what-is-in-pcsc-reader-name.html

Types

type Algorithm

type Algorithm int

Algorithm represents a specific algorithm and bit size supported by the PIV specification.

const (
	AlgorithmEC256 Algorithm = iota + 1
	AlgorithmEC384
	AlgorithmRSA1024
	AlgorithmRSA2048
)

Algorithms supported by this package. Note that not all cards will support every algorithm.

For algorithm discovery, see: https://github.com/ericchiang/piv-go/issues/1

type Attestation

type Attestation struct {
	// Version of the YubiKey's firmware.
	Version Version
	// Serial is the YubiKey's serial number.
	Serial uint32
	// Formfactor indicates the physical type of the YubiKey.
	//
	// Formfactor may be empty Formfactor(0) for some YubiKeys.
	Formfactor Formfactor

	// PINPolicy set on the slot.
	PINPolicy PINPolicy
	// TouchPolicy set on the slot.
	TouchPolicy TouchPolicy
}

Attestation returns additional information about a key attested to be on a card.

func Verify

func Verify(attestationCert, slotCert *x509.Certificate) (*Attestation, error)

Verify proves that a key was generated on a YubiKey. It ensures the slot and YubiKey certificate chains up to the Yubico CA, parsing additional information out of the slot certificate, such as the touch and PIN policies of a key.

type Formfactor

type Formfactor int

Formfactor enumerates the physical set of forms a key can take. USB-A vs. USB-C and Keychain vs. Nano.

type Key

type Key struct {
	// Algorithm to use when generating the key.
	Algorithm Algorithm
	// PINPolicy for the key.
	PINPolicy PINPolicy
	// TouchPolicy for the key.
	TouchPolicy TouchPolicy
}

Key is used for key generation and holds different options for the key.

While keys can have default PIN and touch policies, this package currently doesn't support this option, and all fields must be provided.

type KeyAuth

type KeyAuth struct {
	// PIN, if provided, is a static PIN used to authenticate against the key.
	// If provided, PINPrompt is ignored.
	PIN string
	// PINPrompt should be used to interactively request the PIN from the user.
	PINPrompt func() (pin string, err error)
}

KeyAuth is used to authenticate against the YubiKey on each signing and decryption request.

type Metadata

type Metadata struct {
	// ManagementKey is the management key stored directly on the YubiKey.
	ManagementKey *[24]byte
	// contains filtered or unexported fields
}

Metadata holds protected metadata. This is primarily used by YubiKey manager to implement PIN protect management keys, storing management keys on the card guarded by the PIN.

type PINPolicy

type PINPolicy int

PINPolicy represents PIN requirements when signing or decrypting with an asymmetric key in a given slot.

const (
	PINPolicyNever PINPolicy = iota + 1
	PINPolicyOnce
	PINPolicyAlways
)

PIN policies supported by this package.

type Slot

type Slot struct {
	// Key is a reference for a key type.
	//
	// See: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=32
	Key uint32
	// Object is a reference for data object.
	//
	// See: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=30
	Object uint32
}

Slot is a private key and certificate combination managed by the security key.

type TouchPolicy

type TouchPolicy int

TouchPolicy represents proof-of-presence requirements when signing or decrypting with asymmetric key in a given slot.

const (
	TouchPolicyNever TouchPolicy = iota + 1
	TouchPolicyCached
	TouchPolicyAlways
)

Touch policies supported by this package.

type Version

type Version struct {
	Major int
	Minor int
	Patch int
}

Version encodes a major, minor, and patch version.

type YubiKey

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

YubiKey is an open connection to a YubiKey smart card.

func Open

func Open(card string) (*YubiKey, error)

Open connects to a YubiKey smart card.

func (*YubiKey) Attest

func (yk *YubiKey) Attest(slot Slot) (*x509.Certificate, error)

Attest generates a certificate for a key, signed by the YubiKey's attestation certificate. This can be used to prove a key was generate on a specific YubiKey.

func (*YubiKey) AttestationCertificate

func (yk *YubiKey) AttestationCertificate() (*x509.Certificate, error)

AttestationCertificate returns the YubiKey's attestation certificate, which is unique to the key and signed by Yubico.

func (*YubiKey) Certificate

func (yk *YubiKey) Certificate(slot Slot) (*x509.Certificate, error)

Certificate returns the certifiate object stored in a given slot.

func (*YubiKey) Close

func (yk *YubiKey) Close() error

Close releases the connection to the smart card.

func (*YubiKey) GenerateKey

func (yk *YubiKey) GenerateKey(key [24]byte, slot Slot, opts Key) (crypto.PublicKey, error)

GenerateKey generates an asymmetric key on the card, returning the key's public key.

func (*YubiKey) Metadata

func (yk *YubiKey) Metadata(pin string) (*Metadata, error)

Metadata returns protected data stored on the card. This can be used to retrieve PIN protected management keys.

func (*YubiKey) PrivateKey

func (yk *YubiKey) PrivateKey(slot Slot, public crypto.PublicKey, auth KeyAuth) (crypto.PrivateKey, error)

PrivateKey is used to access signing and decryption options for the key stored in the slot. The returned key implements crypto.Signer and/or crypto.Decrypter depending on the key type.

func (*YubiKey) Reset

func (yk *YubiKey) Reset() error

Reset resets the YubiKey PIV applet to its factory settings, wiping all slots and resetting the PIN, PUK, and Management Key to their default values. This does NOT affect data on other applets, such as GPG or U2F.

func (*YubiKey) Retries

func (yk *YubiKey) Retries() (int, error)

Retries returns the number of attempts remaining to enter the correct PIN.

func (*YubiKey) Serial

func (yk *YubiKey) Serial() (uint32, error)

Serial returns the YubiKey's serial number.

func (*YubiKey) SetCertificate

func (yk *YubiKey) SetCertificate(key [24]byte, slot Slot, cert *x509.Certificate) error

SetCertificate stores a certificate object in the provided slot. Setting a certificate isn't required to use the associated key for signing or decryption.

func (*YubiKey) SetManagementKey

func (yk *YubiKey) SetManagementKey(oldKey, newKey [24]byte) error

SetManagementKey updates the management key to a new key. Management keys are triple-des keys, however padding isn't verified. To generate a new key, generate 24 random bytes.

var newKey [24]byte
if _, err := io.ReadFull(rand.Reader, newKey[:]); err != nil {
	// ...
}
if err := yk.SetManagementKey(piv.DefaultManagementKey, newKey); err != nil {
	// ...
}

func (*YubiKey) SetMetadata

func (yk *YubiKey) SetMetadata(key [24]byte, m *Metadata) error

SetMetadata sets PIN protected metadata on the key. This is primarily to store the management key on the smart card instead of managing the PIN and management key seperately.

func (*YubiKey) SetPIN

func (yk *YubiKey) SetPIN(oldPIN, newPIN string) error

SetPIN updates the PIN to a new value. For compatibility, PINs should be 1-8 numeric characters.

To generate a new PIN, use the crypto/rand package.

// Generate a 6 character PIN.
newPINInt, err := rand.Int(rand.Reader, bit.NewInt(1_000_000))
if err != nil {
	// ...
}
// Format with leading zeros.
newPIN := fmt.Sprintf("%06d", newPINInt)
if err := yk.SetPIN(piv.DefaultPIN, newPIN); err != nil {
	// ...
}

func (*YubiKey) SetPUK

func (yk *YubiKey) SetPUK(oldPUK, newPUK string) error

SetPUK updates the PUK to a new value. For compatibility, PUKs should be 1-8 numeric characters.

To generate a new PUK, use the crypto/rand package.

// Generate a 8 character PUK.
newPUKInt, err := rand.Int(rand.Reader, bit.NewInt(100_000_000))
if err != nil {
	// ...
}
// Format with leading zeros.
newPUK := fmt.Sprintf("%08d", newPUKInt)
if err := yk.SetPIN(piv.DefaultPUK, newPUK); err != nil {
	// ...
}

func (*YubiKey) Unblock

func (yk *YubiKey) Unblock(puk, newPIN string) error

Unblock unblocks the PIN, setting it to a new value.

Jump to

Keyboard shortcuts

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