iso7816

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2023 License: Apache-2.0 Imports: 2 Imported by: 4

README

go-iso7816: Go implementation of the ISO 7816 standard for smart card communication

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

go-iso7816 implements several helpers and utilities to communicate with ISO7816 compliant smart cards.

This includes:

  • Abstract interface for smart card communication

  • APDU parsing and serialization

    • Extended-length support
    • TLV en- & decoding variants
      • ASN.1 BER-TLV
      • Simple TLVs
      • Compact TLVs
  • Constants of

    • Inter-industry instructions and status codes
    • Application Identifiers (AIDs)
  • Basic card management and query support for:

  • Card enumeration and filters

  • Testing utilities

    • Smartcard Mock Object
    • Tracing Wrapper

In the future we might want to add support for:

  • More device support for existing cards
  • Global Platform's Secure Channel Protocol (SCP03)
  • Cross-platform transport implementations
    • Direct CCID
    • Apples CryptoTokenKit
    • CGo-less pcscd / libpcsc-lite

Authors

License

go-iso7816 is licensed under the Apache 2.0 license.

Documentation

Index

Constants

View Source
const (
	LenHeader          = 4 // LenHeader defines the length of the header of an APDU.
	LenLCStandard      = 1 // LenLCStandard defines the length of the LC of a standard length APDU.
	LenLCExtended      = 3 // LenLCExtended defines the length of the LC of an extended length APDU.
	LenResponseTrailer = 2 // LenResponseTrailer defines the length of the trailer of a RAPDU.

	MaxLenCommandDataStandard  = (1 << 8) - 1  // MaxLenCommandDataStandard defines the maximum command data length of a standard length CAPDU.
	MaxLenResponseDataStandard = (1 << 8)      // MaxLenResponseDataStandard defines the maximum response data length of a standard length RAPDU.
	MaxLenCommandDataExtended  = (1 << 16) - 1 // MaxLenCommandDataExtended defines the maximum command data length of an extended length CAPDU.
	MaxLenResponseDataExtended = (1 << 16)     // MaxLenResponseDataExtended defines the maximum response data length of an extended length RAPDU.
)
View Source
const (
	// MaxLenCmdDataStandard defines the maximum command data length of a standard length command APDU.
	MaxLenCmdDataStandard = 255

	// MaxLenRespDataStandard defines the maximum response data length of a standard length response APDU.
	MaxLenRespDataStandard = 256

	// MaxLenCmdDataExtended defines the maximum command data length of an extended length command APDU.
	MaxLenCmdDataExtended = 65535

	// MaxLenRespDataExtended defines the maximum response data length of an extended length response APDU.
	MaxLenRespDataExtended = 65536
)

Variables

View Source
var (
	// https://www.eftlab.com/knowledge-base/complete-list-of-registered-application-provider-identifiers-rid
	RidNIST           = []byte{0xa0, 0x00, 0x00, 0x03, 0x08}
	RidFSFE           = []byte{0xd2, 0x76, 0x00, 0x01, 0x24}
	RidYubico         = []byte{0xa0, 0x00, 0x00, 0x05, 0x27}
	RidFIDO           = []byte{0xa0, 0x00, 0x00, 0x06, 0x47}
	RidSolokeys       = []byte{0xA0, 0x00, 0x00, 0x08, 0x47}
	RidGlobalPlatform = []byte{0xa0, 0x00, 0x00, 0x01, 0x51}
	RidNXPNFC         = []byte{0xD2, 0x76, 0x00, 0x00, 0x85}

	// https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-73-4.pdf
	AidPIV = concat(RidNIST, 0x00, 0x00, 0x10, 0x00)

	// https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.1.pdf
	AidOpenPGP = concat(RidFSFE, 0x01)

	// https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#nfc-applet-selection
	AidFIDO = concat(RidFIDO, 0x2f, 0x00, 0x01)

	// https://github.com/Yubico/yubikey-manager/blob/6496393f9269e86fb7b4b67907b397db33b50c2d/yubikit/core/smartcard.py#L66
	AidYubicoOTP           = concat(RidYubico, 0x20, 0x01)
	AidYubicoManagement    = concat(RidYubico, 0x47, 0x11, 0x17)
	AidYubicoOATH          = concat(RidYubico, 0x21, 0x01)
	AidYubicoHSMAuth       = concat(RidYubico, 0x21, 0x07, 0x01)
	AidSolokeysAdmin       = concat(RidSolokeys, 0x00, 0x00, 0x00, 0x01)
	AidSolokeysProvisioner = concat(RidSolokeys, 0x01, 0x00, 0x00, 0x01)
	AidCardManager         = concat(RidGlobalPlatform, 0x00, 0x00, 0x00)
	AidNDEF                = concat(RidNXPNFC, 0x01, 0x01)
)
View Source
var (
	// General or unspecified warnings & errors
	ErrSuccess                    = Code{0x90, 0x00}
	ErrUnspecifiedWarning         = Code{0x62, 0x00} // No information given (warning)
	ErrUnspecifiedWarningModified = Code{0x63, 0x00} // No information given (warning), on-volatile memory has changed
	ErrUnspecifiedError           = Code{0x64, 0x00} // No information given (error)
	ErrUnspecifiedErrorModified   = Code{0x65, 0x00} // No information given (error), on-volatile memory has changed
	ErrWrongLength                = Code{0x67, 0x00} // Wrong length; no further indication
	ErrUnsupportedFunction        = Code{0x68, 0x00} // Function in CLA not supported
	ErrCommandNotAllowed          = Code{0x69, 0x00} // Command not allowed
	ErrWrongParamsNoInfo          = Code{0x6A, 0x00} // No information given (error)
	ErrWrongParams                = Code{0x6B, 0x00} // Wrong parameters P1-P2
	ErrUnsupportedInstruction     = Code{0x6D, 0x00} // Instruction code not supported or invalid
	ErrUnsupportedClass           = Code{0x6E, 0x00} // Class not supported
	ErrNoDiag                     = Code{0x6F, 0x00} // No precise diagnosis

	// Specific warnings & errors
	ErrResponseMayBeCorrupted              = Code{0x62, 0x81} // Part of returned data may be corrupted
	ErrEOF                                 = Code{0x62, 0x82} // End of file or record reached before reading Ne bytes
	ErrSelectedFileDeactivated             = Code{0x62, 0x83} // Selected file deactivated
	ErrInvalidFileControlInfo              = Code{0x62, 0x84} // File control information not formatted according to 5.3.3
	ErrSelectedFileInTermination           = Code{0x62, 0x85} // Selected file in termination state
	ErrNoSensorData                        = Code{0x62, 0x86} // No input data available from a sensor on the card
	ErrFileFilledUp                        = Code{0x63, 0x81} // File filled up by the last write
	ErrImmediateResponseRequired           = Code{0x64, 0x01} // Immediate response required by the card
	ErrMemory                              = Code{0x65, 0x81} // Memory failure
	ErrLogicalChannelNotSupported          = Code{0x68, 0x81} // Logical channel not supported
	ErrSecureMessagingNotSupported         = Code{0x68, 0x82} // Secure messaging not supported
	ErrExpectedLastCommand                 = Code{0x68, 0x83} // Last command of the chain expected
	ErrCommandChainingNotSupported         = Code{0x68, 0x84} // Command chaining not supported
	ErrCommandIncompatibleWithFile         = Code{0x69, 0x81} // Command incompatible with file structure
	ErrSecurityStatusNotSatisfied          = Code{0x69, 0x82} // Security status not satisfied
	ErrAuthenticationMethodBlocked         = Code{0x69, 0x83} // Authentication method blocked
	ErrReferenceDataNotUsable              = Code{0x69, 0x84} // Reference data not usable
	ErrConditionsOfUseNotSatisfied         = Code{0x69, 0x85} // Conditions of use not satisfied
	ErrCommandNotAllowedNoCurrentEF        = Code{0x69, 0x86} // Command not allowed (no current EF)
	ErrExpectedSecureMessaging             = Code{0x69, 0x87} // Expected secure messaging data objects missing
	ErrIncorrectSecureMessagingDataObjects = Code{0x69, 0x88} // Incorrect secure messaging data objects
	ErrIncorrectData                       = Code{0x6A, 0x80} // Incorrect parameters in the command data field
	ErrFunctionNotSupported                = Code{0x6A, 0x81} // Function not supported
	ErrFileOrAppNotFound                   = Code{0x6A, 0x82} // File or application not found
	ErrRecordNotFound                      = Code{0x6A, 0x83} // Record not found
	ErrNoSpace                             = Code{0x6A, 0x84} // Not enough memory space in the file
	ErrInvalidNcWithTLV                    = Code{0x6A, 0x85} // Nc inconsistent with TLV structure
	ErrIncorrectParams                     = Code{0x6A, 0x86} // Incorrect parameters P1-P2
	ErrInvalidNcWithParams                 = Code{0x6A, 0x87} // Nc inconsistent with parameters P1-P2
	ErrReferenceNotFound                   = Code{0x6A, 0x88} // Referenced data or reference data not found (exact meaning depending on the command)
	ErrFileAlreadyExists                   = Code{0x6A, 0x89} // File already exists
	ErrNameAlreadyExists                   = Code{0x6A, 0x8A} // DF name already exists
)

Functions

func DecodeResponse

func DecodeResponse(resp []byte) (data []byte, sw1 byte, sw2 byte)

Types

type CAPDU

type CAPDU struct {
	Cla    byte        // Cla is the class byte.
	Ins    Instruction // Ins is the instruction byte.
	P1, P2 byte        // P1, P2 is the p1, p2 byte.
	Data   []byte      // Data is the data field.
	Ne     int         // Ne is the total number of expected response data byte (not LE encoded).
}

func (*CAPDU) Bytes

func (c *CAPDU) Bytes() ([]byte, error)

type Card

type Card struct {
	PCSCCard

	InsGetRemaining Instruction
}

func NewCard

func NewCard(c PCSCCard) *Card

func (*Card) NewTransaction

func (c *Card) NewTransaction() (*Transaction, error)

func (*Card) Select

func (c *Card) Select(aid []byte) (respBuf []byte, err error)

func (*Card) Send

func (c *Card) Send(cmd *CAPDU) (respBuf []byte, err error)

Send sends a command APDU to the card nolint: unparam

type Code

type Code [2]byte

Code encapsulates (some) response codes from the spec See: ISO 7816-4 Section 5.1.3 Status Bytes

func (Code) Error

func (c Code) Error() string

Error return the encapsulated error string

func (Code) HasMore

func (c Code) HasMore() bool

HasMore indicates more data that needs to be fetched

func (Code) IsAborted

func (c Code) IsAborted() bool

func (Code) IsCompleted

func (c Code) IsCompleted() bool

func (Code) IsSuccess

func (c Code) IsSuccess() bool

IsSuccess indicates that all data has been successfully fetched

type Instruction

type Instruction byte
const (
	InsDeactivateFile                 Instruction = 0x04 // Part 9
	InsEraseRecord                    Instruction = 0x0c // Section 7.3.8
	InsEraseBinary                    Instruction = 0x0e // Section 7.2.7
	InsEraseBinaryEven                Instruction = 0x0f // Section 7.2.7
	InsPerformSCQLOperation           Instruction = 0x10 // Part 7
	InsPerformTransactionOperation    Instruction = 0x12 // Part 7
	InsPerformUserOperation           Instruction = 0x14 // Part 7
	InsVerify                         Instruction = 0x20 // Section 7.5.6
	InsVerifyOdd                      Instruction = 0x21 // Section 7.5.6
	InsManageSecurityEnvironment      Instruction = 0x22 // Section 7.5.11
	InsChangeReferenceData            Instruction = 0x24 // Section 7.5.7
	InsDisableVerificationRequirement Instruction = 0x26 // Section 7.5.9
	InsEnableVerificationRequirement  Instruction = 0x28 // Section 7.5.8
	InsPerformSecurityOperation       Instruction = 0x2a // Part 8
	InsResetRetryCounter              Instruction = 0x2c // Section 7.5.10
	InsActivateFile                   Instruction = 0x44 // Part 9
	InsGenerateAsymmetricKeyPair      Instruction = 0x46 // Part 8
	InsManageChannel                  Instruction = 0x70 // Section 7.1.2
	InsExternalOrMutualAuthenticate   Instruction = 0x82 // Section 7.5.4
	InsGetChallenge                   Instruction = 0x84 // Section 7.5.3
	InsGeneralAuthenticate            Instruction = 0x87 // Section 7.5.5
	InsInternalAuthenticate           Instruction = 0x88 // Section 7.5.2
	InsSearchBinary                   Instruction = 0xa0 // Section 7.2.6
	InsSearchBinaryOdd                Instruction = 0xa1 // Section 7.2.6
	InsSearchRecord                   Instruction = 0xa2 // Section 7.3.7
	InsSelect                         Instruction = 0xa4 // Section 7.1.1
	InsReadBinary                     Instruction = 0xb0 // Section 7.2.3
	InsReadBinaryOdd                  Instruction = 0xb1 // Section 7.2.3
	InsReadRecord                     Instruction = 0xb3 // Section 7.3.3
	InsGetResponse                    Instruction = 0xc0 // Section 7.6.1
	InsEnvelope                       Instruction = 0xc2 // Section 7.6.2
	InsEnvelopeOdd                    Instruction = 0xc3 // Section 7.6.2
	InsGetData                        Instruction = 0xca // Section 7.4.2
	InsGetDataOdd                     Instruction = 0xcb // Section 7.4.2
	InsWriteBinary                    Instruction = 0xd0 // Section 7.2.6
	InsWriteBinaryOdd                 Instruction = 0xd1 // Section 7.2.6
	InsWriteRecord                    Instruction = 0xd2 // Section 7.3.4
	InsUpdateBinary                   Instruction = 0xd7 // Section 7.2.5
	InsPutData                        Instruction = 0xda // Section 7.4.3
	InsPutDataOdd                     Instruction = 0xdb // Section 7.4.3
	InsUpdateRecord                   Instruction = 0xdc // Section 7.3.5
	InsUpdateRecordOdd                Instruction = 0xdd // Section 7.3.5
	InsCreateFile                     Instruction = 0xe0 // Part 9
	InsAppendRecord                   Instruction = 0xe2 // Section 7.3.6
	InsDeleteFile                     Instruction = 0xe4 // Part 9
	InsTerminateDF                    Instruction = 0xe6 // Part 9
	InsTerminateEF                    Instruction = 0xe8 // Part 9
	InsTerminateCardUsage             Instruction = 0xfe // Part 9
)

type PCSCCard

type PCSCCard interface {
	Transmit([]byte) ([]byte, error)
	BeginTransaction() error
	EndTransaction() error
	Close() error
}

type RAPDU

type RAPDU struct {
	Data     []byte
	SW1, SW2 byte
}

func ParseRAPDU

func ParseRAPDU(b []byte) (*RAPDU, error)

ParseRAPDU parses a Response APDU and returns a RAPDU.

func (*RAPDU) Code

func (r *RAPDU) Code() Code

func (*RAPDU) IsError

func (r *RAPDU) IsError() bool

IsError returns true if the RAPDU indicates an error during the execution of a command ('0x64xx', '0x65xx' or from '0x67xx' to 0x6Fxx'), otherwise false.

func (*RAPDU) IsSuccess

func (r *RAPDU) IsSuccess() bool

IsSuccess returns true if the RAPDU indicates the successful execution of a command ('0x61xx' or '0x9000'), otherwise false.

func (*RAPDU) IsWarning

func (r *RAPDU) IsWarning() bool

IsWarning returns true if the RAPDU indicates the execution of a command with a warning ('0x62xx' or '0x63xx'), otherwise false.

type ResettableCard

type ResettableCard interface {
	Reset() error
}

type Transaction

type Transaction struct {
	*Card
}

func (*Transaction) Close

func (tx *Transaction) Close() error

Directories

Path Synopsis
devices
nitrokey
Package nitrokey implements basic support for getting status and details about Nitrokey 3 tokens.
Package nitrokey implements basic support for getting status and details about Nitrokey 3 tokens.
yubikey
Package yubikey implements basic support for getting status and details about YubiKey tokens.
Package yubikey implements basic support for getting status and details about YubiKey tokens.
drivers
encoding
tlv
Package tlv implements various version (ASN.1 BER, Simple, Compact) TLV encoding using in ISO 7816-4.
Package tlv implements various version (ASN.1 BER, Simple, Compact) TLV encoding using in ISO 7816-4.

Jump to

Keyboard shortcuts

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