openpgp

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 29, 2023 License: Apache-2.0 Imports: 27 Imported by: 0

README

go-openpgp-card: A Go Implementation of the OpenPGP Smart Card application

GitHub Workflow Status goreportcard Codecov branch License GitHub go.mod Go version Go Reference

go-openpgp-card is a Go package providing an interface to the OpenPGP application on ISO Smart Card Operating Systems.

Features

go-openpgp-card implements the Functional Specification of the OpenPGP application in Version v3.4.1.

  • Supported commands:

    • 7.2.1 SELECT
    • 7.2.2 VERIFY
    • 7.2.3 CHANGE REFERENCE DATA
    • 7.2.4 RESET RETRY COUNTER
    • 7.2.5 SELECT DATA
    • 7.2.6 GET DATA
      • Application related
      • Security Support Template
      • Private data
      • Cardholder related
      • Password status
      • Login data
      • Public key URL
      • Cardholder certificates
      • User interaction flag
    • 7.2.7 GET NEXT DATA
    • 7.2.8 PUT DATA
      • Resetting Code
      • Name
      • Language
      • Sex
      • Public Key URL
      • Login data
      • Private data
      • User interaction flag
      • Key Import
        • RSA
        • EC
    • 7.2.9 GET RESPONSE
    • 7.2.10 PSO: COMPUTE DIGITAL SIGNATURE
      • RSA
      • ECDSA
      • Attestation
    • 7.2.11 PSO: DECIPHER
      • AES
      • RSA
      • ECDH
    • 7.2.12 PSO: ENCIPHER
      • AES Key
    • 7.2.13 INTERNAL AUTHENTICATE
    • 7.2.14 GENERATE ASYMMETRIC KEY PAIR
      • RSA
      • Elliptic Curves
    • 7.2.15 GET CHALLENGE
    • 7.2.16 TERMINATE DF
    • 7.2.17 ACTIVATE FILE
    • 7.2.18 MANAGE SECURITY ENVIRONMENT
  • Key Derivation Function (KDF) for VERIFY

YubiKey extensions
  • Set PIN Retry counters

Tested implementations

  • Yubikey
    • FW version 5.4.3

Install

When build with CGO_ENABLED, go-openpgp-card requires the following external dependencies.

apt-get install \
    libpcsclite-dev

Authors

License

go-openpgp-card is licensed under the Apache 2.0 license.

Documentation

Overview

Package openpgp implements the interface to the OpenPGP application on ISO Smart Card Operating Systems v3.4.1 See: https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.1.pdf

Index

Constants

View Source
const (
	PW1 byte = 0x81 // User PIN (PSO:CDS command only)
	RC  byte = 0x82 // Resetting code
	PW3 byte = 0x83 // Admin PIN
)
View Source
const (
	GeneralFeatureTouchscreen byte = (1 << iota)
	GeneralFeatureMicrophone
	GeneralFeatureSpeaker
	GeneralFeatureLED
	GeneralFeatureKeyPad
	GeneralFeatureButton
	GeneralFeatureBiometric
	GeneralFeatureDisplay
)

Variables

View Source
var (
	DefaultPW = map[byte]string{
		RC:  DefaultPW1,
		PW3: DefaultPW3,
	}

	DefaultPW1 = "123456"
	DefaultPW3 = "12345678"
)
View Source
var (
	ErrInvalidLength = errors.New("invalid length")
)

Functions

This section is empty.

Types

type AlgHash

type AlgHash byte
const (
	AlgHashMD5       AlgHash = iota + 1 // Message Digest 5
	AlgHashSHA1                         // SHA-1
	AlgHashRIPEMD160                    // RIPE-MD/160

	AlgHashSHA256 // SHA-256
	AlgHashSHA384 // SHA-384
	AlgHashSHA512 // SHA-512
	AlgHashSHA224 // SHA-224
)

type AlgKDF

type AlgKDF byte
const (
	AlgKDFNone          AlgKDF = 0
	AlgKDFIterSaltedS2K AlgKDF = 3
)

type AlgPubkey

type AlgPubkey byte
const (
	AlgPubkeyRSA                AlgPubkey = 1  // RSA (Encrypt or Sign)
	AlgPubkeyRSAEncOnly         AlgPubkey = 2  // RSA Encrypt-Only (legacy)
	AlgPubkeyRSASignOnly        AlgPubkey = 3  // RSA Sign-Only (legacy)
	AlgPubkeyElgamalEncOnly     AlgPubkey = 16 // Elgamal (Encrypt-Only)
	AlgPubkeyDSA                AlgPubkey = 17 // DSA (Digital Signature Algorithm)
	AlgPubkeyECDH               AlgPubkey = 18 // RFC-6637
	AlgPubkeyECDSA              AlgPubkey = 19 // RFC-6637
	AlgPubkeyElgamalEncSignOnly AlgPubkey = 20 // Elgamal encrypt+sign, reserved by OpenPGP (legacy)
	AlgPubkeyEdDSA              AlgPubkey = 22 // EdDSA
	AlgPubkeyKy768_25519        AlgPubkey = 29 // Kyber768 + X25519
	AlgPubkeyKy1024_448         AlgPubkey = 30 // Kyber1024 + X448
	AlgPubkeyDil3_25519         AlgPubkey = 35 // Dilithium3 + Ed25519
	AlgPubkeyDil5_448           AlgPubkey = 36 // Dilithium5 + Ed448
	AlgPubkeySPHINXSHA2         AlgPubkey = 41 // SPHINX+-simple-SHA2
)

func (AlgPubkey) String

func (a AlgPubkey) String() string

type AlgSymmetric

type AlgSymmetric byte
const (
	AlgSymPlaintext AlgSymmetric = iota // Plaintext or unencrypted data
	AlgSymIDEA                          // IDEA
	AlgSymTripleDES                     // TripleDES (DES-EDE, - 168 bit key derived from 192)
	AlgSymCAST5                         // CAST5 (128 bit key, as per RFC2144)
	AlgSymBlowfish                      // Blowfish (128 bit key, 16 rounds)

	AlgSymAES128  // AES with 128-bit key
	AlgSymAES192  // AES with 192-bit key
	AlgSymAES256  // AES with 256-bit key
	AlgSymTwofish // Twofish with 256-bit key
)

type AlgorithmAttributes

type AlgorithmAttributes struct {
	Algorithm AlgPubkey

	// Relevant for RSA
	LengthModulus  uint16
	LengthExponent uint16

	// Relevant for ECDSA/ECDH
	OID []byte

	ImportFormat ImportFormat
}

func EC

func EC(curve Curve) AlgorithmAttributes

func RSA

func RSA(bits int) AlgorithmAttributes

func (AlgorithmAttributes) Curve

func (a AlgorithmAttributes) Curve() Curve

func (*AlgorithmAttributes) Decode

func (a *AlgorithmAttributes) Decode(b []byte) error

func (AlgorithmAttributes) Encode

func (a AlgorithmAttributes) Encode() (b []byte)

func (AlgorithmAttributes) Equal

func (AlgorithmAttributes) String

func (a AlgorithmAttributes) String() string

type ApplicationIdentifier

type ApplicationIdentifier struct {
	RID          iso.RID
	Application  byte
	Version      iso.Version
	Serial       [4]byte
	Manufacturer Manufacturer
}

func (*ApplicationIdentifier) Decode

func (aid *ApplicationIdentifier) Decode(b []byte) error

type ApplicationRelated

type ApplicationRelated struct {
	AID             ApplicationIdentifier
	HistoricalBytes iso.HistoricalBytes

	LengthInfo     ExtendedLengthInfo
	Capabilities   ExtendedCapabilities
	Features       GeneralFeatures
	PasswordStatus PasswordStatus

	Keys [4]KeyInfo
}

func (*ApplicationRelated) Decode

func (ar *ApplicationRelated) Decode(b []byte) (err error)

type AuthError

type AuthError struct {
	// Retries is the number of retries remaining if this error resulted from a retry-able
	// authentication attempt.  If the authentication method is blocked or does not support
	// retries, this will be 0.
	Retries int
}

AuthError is an error indicating an authentication error occurred (wrong PIN or blocked).

func (AuthError) Error

func (v AuthError) Error() string

type Card

type Card struct {
	Rand  io.Reader
	Clock func() time.Time

	*ApplicationRelated
	*Cardholder
	*SecuritySupportTemplate
	// contains filtered or unexported fields
}

func NewCard

func NewCard(sc *iso.Card) (c *Card, err error)

NewCard creates a new OpenPGP card handle.

func (*Card) AlgorithmAttributes

func (c *Card) AlgorithmAttributes(slot Slot) (attrs AlgorithmAttributes, err error)

func (*Card) Challenge

func (c *Card) Challenge(cnt int) ([]byte, error)

Challenge generates a random number of cnt bytes.

See: OpenPGP Smart Card Application - Section 7.2.15 GET CHALLENGE

func (*Card) ChangePassword

func (c *Card) ChangePassword(pwType byte, pwCurrent, pwNew string) error

ChangePassword changes the user or admin password.

Access condition: Always Access level: None (current password must be provided) See: OpenPGP Smart Card Application - Section 7.2.3 CHANGE REFERENCE DATA

func (*Card) ChangeResettingCode

func (c *Card) ChangeResettingCode(rc string) error

ChangeResettingCode sets the resetting code of the cards.

Access condition: Admin/PW3 See: OpenPGP Smart Card Application - Section 4.3.4 Resetting Code

func (*Card) ClearPasswordState

func (c *Card) ClearPasswordState(pwType byte) error

ClearPasswordState clears the passwort unlock state from the card.

Access condition: Always Note: Appears to be broken on YubiKey 5 See: OpenPGP Smart Card Application - Section 7.2.2 VERIFY

func (*Card) ClearResettingCode

func (c *Card) ClearResettingCode() error

func (*Card) Close

func (c *Card) Close() error

Close closes the OpenPGP card handle.

func (*Card) DecryptAES

func (c *Card) DecryptAES(pt []byte) (ct []byte, err error)

DecryptAES encrypts a plain text with an AES-key stored in a special DO (D5).

See: OpenPGP Smart Card Application - Section 7.2.12 PSO: ENCIPHER

func (*Card) EncryptAES

func (c *Card) EncryptAES(pt []byte) (ct []byte, err error)

EncryptAES encrypts a plain text with an AES-key stored in a special DO (D5).

See: OpenPGP Smart Card Application - Section 7.2.12 PSO: ENCIPHER

func (*Card) FactoryReset

func (c *Card) FactoryReset() error

FactoryReset resets the applet to its original state

Access condition: Admin/PW3

Alternatively, we will try to block the Admin PIN by repeatedly calling VerifyPassword()
with a wrong password to enable TERMINATE DF without Admin PIN.

See: OpenPGP Smart Card Application - Section 7.2.16 TERMINATE DF & 7.2.17 ACTIVATE FILE

func (*Card) GenerateKey

func (c *Card) GenerateKey(slot Slot, attrs AlgorithmAttributes) (crypto.PrivateKey, error)

func (*Card) GetApplicationRelatedData

func (c *Card) GetApplicationRelatedData() (ar *ApplicationRelated, err error)

GetApplicationRelatedData fetches the application related data from the card.

func (*Card) GetCardholder

func (c *Card) GetCardholder() (ch *Cardholder, err error)

GetCardholder fetches the card holder information from the card.

func (*Card) GetCardholderCertificate

func (c *Card) GetCardholderCertificate(slot Slot) ([]byte, error)

func (*Card) GetCardholderCertificates

func (c *Card) GetCardholderCertificates() ([][]byte, error)

func (*Card) GetKDF

func (c *Card) GetKDF() (k *KDF, err error)

func (*Card) GetLoginData

func (c *Card) GetLoginData() (string, error)

func (*Card) GetPasswordStatus

func (c *Card) GetPasswordStatus() (*PasswordStatus, error)

func (*Card) GetPublicKeyURL

func (c *Card) GetPublicKeyURL() (*url.URL, error)

func (*Card) GetSecuritySupportTemplate

func (c *Card) GetSecuritySupportTemplate() (sst *SecuritySupportTemplate, err error)

GetSecuritySupportTemplate fetches the the security template from the card.

func (*Card) GetSignatureCounter

func (c *Card) GetSignatureCounter() (int, error)

func (*Card) ImportKey

func (c *Card) ImportKey(_ Slot, _ crypto.PrivateKey) error

func (*Card) ManageSecurityEnvironment

func (c *Card) ManageSecurityEnvironment(op SecurityOperation, slot Slot) error

See: OpenPGP Smart Card Application - Section 7.2.18 MANAGE SECURITY ENVIRONMENT

func (*Card) PasswordState

func (c *Card) PasswordState(pwType byte) (bool, error)

PasswordState returns true if the given password is unlocked.

Access condition: Always Note: Appears to be broken on YubiKey 5 See: OpenPGP Smart Card Application - Section 7.2.2 VERIFY

func (*Card) PrivateData

func (c *Card) PrivateData(index int) ([]byte, error)

func (*Card) PrivateKey

func (c *Card) PrivateKey(slot Slot) (crypto.PrivateKey, error)

func (*Card) ResetRetryCounter

func (c *Card) ResetRetryCounter(newPw string) error

ResetRetryCounter reset the PIN retry counter and a new password.

Access condition: Admin/PW3 See: OpenPGP Smart Card Application - Section 7.2.4 RESET RETRY COUNTER

func (*Card) ResetRetryCounterWithResettingCode

func (c *Card) ResetRetryCounterWithResettingCode(rc, newPw string) error

ResetRetryCounterWithResettingCode resets the PIN retry counter using a reset code.

Access condition: None (reset code is required) See: OpenPGP Smart Card Application - Section 7.2.4 RESET RETRY COUNTER

func (*Card) Select

func (c *Card) Select() error

Select selects the OpenPGP applet.

See: OpenPGP Smart Card Application - Section 7.2.1 SELECT

func (*Card) SetCardholder

func (c *Card) SetCardholder(ch Cardholder) error

func (*Card) SetLanguage

func (c *Card) SetLanguage(lang string) error

func (*Card) SetLoginData

func (c *Card) SetLoginData(login string) error

func (*Card) SetName

func (c *Card) SetName(name string) error

func (*Card) SetPrivateData

func (c *Card) SetPrivateData(index int, b []byte) error

func (*Card) SetPublicKeyURL

func (c *Card) SetPublicKeyURL(url *url.URL) error

func (*Card) SetRetryCounters

func (c *Card) SetRetryCounters(pw1, rc, pw3 byte) error

SetRetryCounters sets the number of PIN attempts to allow before blocking.

Access condition: Admin/PW3 Note: This is a YubiKey extensions Warning: On YubiKey NEO this will reset the PINs to their default values.

func (*Card) SetSex

func (c *Card) SetSex(sex Sex) error

func (*Card) SetupKDF

func (c *Card) SetupKDF(alg AlgKDF, iterations int, pw1, pw3 string) (err error)

SetupKDF initialize the KDF data object and updates passwords to work with it.

Resetting code must be set again. User/PW1 and Admin/PW3 are unchanged.

Access condition: Admin/PW3 (User/PW1 and AdminPW3 must be passed as arguments) See: OpenPGP Smart Card Application - Section 4.3.2 Key derived format

func (*Card) SupportedAlgorithms

func (c *Card) SupportedAlgorithms() (map[Slot][]AlgorithmAttributes, error)

func (*Card) VerifyPassword

func (c *Card) VerifyPassword(pwType byte, pw string) (err error)

VerifyPassword attempts to unlock a given password.

Access condition: Always See: OpenPGP Smart Card Application - Section 7.2.2 VERIFY

type Cardholder

type Cardholder struct {
	Name     string
	Language string
	Sex      Sex
}

func (*Cardholder) Decode

func (ch *Cardholder) Decode(b []byte) (err error)

type Curve

type Curve byte
const (
	CurveUnknown Curve = iota

	CurveANSIx9p256r1
	CurveANSIx9p384r1
	CurveANSIx9p521r1

	CurveBrainpoolP256r1
	CurveBrainpoolP384r1
	CurveBrainpoolP512r1

	CurveX25519
	CurveX448

	CurveEd25519
	CurveEd448

	CurveSecp256k1
)

func (Curve) String

func (c Curve) String() string

type ECDHKey

type ECDHKey interface {
	SharedKey(peer ECPublicKey) ([]byte, error)
}

type ECPublicKey

type ECPublicKey interface {
	Curve() Curve
	Bytes() []byte
	Equal(x crypto.PublicKey) bool
}

type ExtendedCapabilities

type ExtendedCapabilities struct {
	Flags                ExtendedCapabilitiesFlag
	AlgSM                byte
	MaxLenChallenge      uint16
	MaxLenCardholderCert uint16
	MaxLenSpecialDO      uint16
	Pin2BlockFormat      byte
	CommandMSE           byte
}

func (*ExtendedCapabilities) Decode

func (ec *ExtendedCapabilities) Decode(b []byte) error

type ExtendedCapabilitiesFlag

type ExtendedCapabilitiesFlag byte
const (
	CapKDF ExtendedCapabilitiesFlag = (1 << iota)
	CapAES
	CapAlgAttrsChangeable
	CapPrivateDO
	CapPasswordStatusChangeable
	CapKeyImport
	CapGetChallenge
	CapSecureMessaging
)

type ExtendedLengthInfo

type ExtendedLengthInfo struct {
	MaxCommandLength  uint16
	MaxResponseLength uint16
}

func (*ExtendedLengthInfo) Decode

func (li *ExtendedLengthInfo) Decode(b []byte) error

type Fingerprint

type Fingerprint [20]byte

type GeneralFeatures

type GeneralFeatures byte

func (*GeneralFeatures) Decode

func (gf *GeneralFeatures) Decode(b []byte) error

type ImportFormat

type ImportFormat byte
const (
	ImportFormatRSAStd ImportFormat = iota
	ImportFormatRSAStdWithModulus
	ImportFormatRSACRT
	ImportFormatRSACRTWithModulus

	ImportFormatECDSAStdWithPublicKey ImportFormat = 0xff
)

type KDF

type KDF struct {
	Algorithm      AlgKDF
	HashAlgorithm  AlgHash
	Iterations     int
	SaltPW1        [8]byte
	SaltPW3        [8]byte
	SaltRC         [8]byte
	InitialHashPW1 []byte
	InitialHashPW3 []byte
}

func (*KDF) Decode

func (k *KDF) Decode(b []byte) (err error)

func (*KDF) DerivePassword

func (k *KDF) DerivePassword(pwType byte, pw string) ([]byte, error)

func (*KDF) Encode

func (k *KDF) Encode() ([]byte, error)

type KeyInfo

type KeyInfo struct {
	Reference      byte
	Status         Status
	AlgAttrs       AlgorithmAttributes
	Fingerprint    []byte
	FingerprintCA  []byte
	GenerationTime time.Time
	UIF            UserInteractionFlag
}

type LifeCycleStatus

type LifeCycleStatus byte

See: OpenPGP Smart Card Application - Section 6 Historical Bytes

const (
	LifeCycleStatusNoInfo      LifeCycleStatus = 0x00
	LifeCycleStatusInitialized LifeCycleStatus = 0x03
	LifeCycleStatusOperational LifeCycleStatus = 0x05
)

type Manufacturer

type Manufacturer uint16

func (Manufacturer) String

func (m Manufacturer) String() string

type PasswordStatus

type PasswordStatus struct {
	ValidityPW1 uint8

	LengthPW1 uint8
	LengthRC  uint8
	LengthPW3 uint8

	AttemptsPW1 uint8
	AttemptsRC  uint8
	AttemptsPW3 uint8
}

func (*PasswordStatus) Decode

func (ps *PasswordStatus) Decode(b []byte) error

type SecurityOperation

type SecurityOperation byte
const (
	SecurityOperationSign         SecurityOperation = iota
	SecurityOperationAuthenticate                   // Authentication
	SecurityOperationDecrypt                        // Confidentiality
)

type SecuritySupportTemplate

type SecuritySupportTemplate struct {
	SignatureCounter int
	CardHolderCerts  [3][]byte
}

func (*SecuritySupportTemplate) Decode

func (sst *SecuritySupportTemplate) Decode(b []byte) (err error)

type Sex

type Sex byte
const (
	SexUnknown       Sex = '0'
	SexMale          Sex = '1'
	SexFemale        Sex = '2'
	SexNotApplicable Sex = '9'
)

func (Sex) String

func (s Sex) String() string

type Slot

type Slot byte
const (
	SlotSign Slot = iota
	SlotDecrypt
	SlotAuthn
	SlotAttest
)

func (Slot) String

func (s Slot) String() string

type Status

type Status byte
const (
	StatusKeyNotPresent Status = iota // Not generated or imported
	StatusKeyGenerated                // On the the card
	StatusKeyImported                 // Into the card (insecure)
)

type UserInteractionFlag

type UserInteractionFlag struct {
	Mode    UserInteractionMode
	Feature byte
}

func (*UserInteractionFlag) Decode

func (uif *UserInteractionFlag) Decode(b []byte) error

type UserInteractionMode

type UserInteractionMode byte
const (
	UserInteractionDisabled     UserInteractionMode = 0x00
	UserInteractionEnabled      UserInteractionMode = 0x01
	UserInteractionEnabledFixed UserInteractionMode = 0x02
	UserInteractionCached       UserInteractionMode = 0x03
	UserInteractionCachedFixed  UserInteractionMode = 0x04
)

Directories

Path Synopsis
internal
s2k

Jump to

Keyboard shortcuts

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