eudcc

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	CBOR_Magic_ID = 55799 // Magic tag number that identifies the data as CBOR-encoded
	COSE_Sign     = 98    // COSE Signed Data Object (multiple signers)
	COSE_Sign1    = 18    // COSE Single Signer Data Object
	CWT_Tag       = 61
)

CBOR constants to assign semantic to the data structures

View Source
const (
	MT_INTEGER    = 0
	MT_NEGINTEGER = 1
	MT_BYTES      = 2
	MT_UTF8       = 3
	MT_ARRAY      = 4
	MT_MAP        = 5
	MT_TAG        = 6
	MT_FLOAT      = 7
)

Major types encoding

View Source
const (
	ValidationErrorMalformed        uint32 = 1 << iota // Token is malformed
	ValidationErrorUnverifiable                        // Token could not be verified because of signing problems
	ValidationErrorSignatureInvalid                    // Signature validation failed

	// Standard Claim validation errors
	ValidationErrorAudience      // AUD validation failed
	ValidationErrorExpired       // EXP validation failed
	ValidationErrorIssuedAt      // IAT validation failed
	ValidationErrorIssuer        // ISS validation failed
	ValidationErrorNotValidYet   // NBF validation failed
	ValidationErrorId            // JTI validation failed
	ValidationErrorClaimsInvalid // Generic claims validation error
)

The errors that might occur when parsing and validating a token

View Source
const (
	EUDCC_ISSUER     = int64(1)
	EUDCC_ISSUED_AT  = int64(6)
	EUDCC_EXPIRES_AT = int64(4)
	EUDCC_HCERT      = int64(-260)
	EUDCC_V1         = int64(1)
)
View Source
const CWT_ALG = 1

Protected headers numeric claim types

View Source
const CWT_KID = 4

Variables

View Source
var (
	ErrInvalidKey      = errors.New("key is invalid")
	ErrInvalidKeyType  = errors.New("key is of invalid type")
	ErrHashUnavailable = errors.New("the requested hash function is unavailable")

	ErrTokenMalformed        = errors.New("token is malformed")
	ErrTokenUnverifiable     = errors.New("token is unverifiable")
	ErrTokenSignatureInvalid = errors.New("token signature is invalid")

	ErrTokenInvalidAudience  = errors.New("token has invalid audience")
	ErrTokenExpired          = errors.New("token is expired")
	ErrTokenUsedBeforeIssued = errors.New("token used before issued")
	ErrTokenInvalidIssuer    = errors.New("token has invalid issuer")
	ErrTokenNotValidYet      = errors.New("token is not valid yet")
	ErrTokenInvalidId        = errors.New("token has invalid id")
	ErrTokenInvalidClaims    = errors.New("token has invalid claims")

	ErrECDSAVerification = errors.New("crypto/ecdsa: verification error")
)

Error constants

View Source
var ValidMethods = map[string]bool{
	"ES256": true,
	"ES384": true,
	"ES512": true,
}

Set the accepted validation methods. The EUDCC is very restrictive

Functions

func CBORType

func CBORType(c []byte) int

func FromQRCodeToRaw

func FromQRCodeToRaw(qrCode []byte) ([]byte, error)

FromQRCodeToRaw converts from the QR code to a clean byte array with the CWT data Strips the prefix, decodes B65 and unzips the QR code string

func GetAlgorithms

func GetAlgorithms() (algs []string)

GetAlgorithms returns a list of registered "alg" names

func PayloadAsCWT

func PayloadAsCWT(eu *EUDCCPayload) []byte

func RegisterSigner

func RegisterSigner(alg string, s Signer)

RegisterSigner registers the "alg" name and a signing method. This is typically done during init() in the method's implementation. In any case, this is NOT thread safe.

Types

type ArrayCBOR

type ArrayCBOR []byte

type CBORDecoder

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

func NewCBORDecoder

func NewCBORDecoder(b []byte) *CBORDecoder

NewCBORDecoder returns a new CBOR reading from b.

func (*CBORDecoder) DecodeBstr

func (cb *CBORDecoder) DecodeBstr() ([]byte, error)

DecodeBstr expects a CBOR bstr and gives an error otherwise

func (*CBORDecoder) DecodeItem

func (cb *CBORDecoder) DecodeItem() (any, error)

DecodeItem decodes a CBOR item of unknown data type. We look at the first byte to determine type and length of the object. It returns any and the caller should use type casting to determine the actual type

func (*CBORDecoder) DecodeMap

func (cb *CBORDecoder) DecodeMap() (map[any]any, error)

DecodeMap expects a CBOR Map and gives an error otherwise

func (*CBORDecoder) Len

func (r *CBORDecoder) Len() int

Len returns the number of bytes of the unread portion of the internal slice.

func (*CBORDecoder) PeekByte

func (r *CBORDecoder) PeekByte() (byte, error)

PeekByte returns one byte without consuming it.

func (*CBORDecoder) Read

func (r *CBORDecoder) Read(b []byte) (n int, err error)

Read implements the io.Reader interface.

func (*CBORDecoder) ReadAt

func (r *CBORDecoder) ReadAt(b []byte, off int64) (n int, err error)

ReadAt implements the io.ReaderAt interface.

func (*CBORDecoder) ReadByte

func (r *CBORDecoder) ReadByte() (byte, error)

ReadByte implements the io.ByteReader interface.

func (*CBORDecoder) ReadLength

func (cb *CBORDecoder) ReadLength() (int64, error)

ReadLength decodes the length field of the CBOR data element Uses a variable-size encoding schema

func (*CBORDecoder) ReadRune

func (r *CBORDecoder) ReadRune() (ch rune, size int, err error)

ReadRune implements the io.RuneReader interface.

func (*CBORDecoder) ReadSlice

func (r *CBORDecoder) ReadSlice(n int) (s []byte, err error)

ReadSlice does not copy. Must be used only if original buffer is immutable.

func (*CBORDecoder) ReadUint16

func (cb *CBORDecoder) ReadUint16() (int64, error)

ReadUint16 reads 2 bytes (big-endian) and returns a int64

func (*CBORDecoder) ReadUint32

func (cb *CBORDecoder) ReadUint32() (int64, error)

ReadUint32 reads 4 bytes (big-endian) and returns a int64

func (*CBORDecoder) ReadUint64

func (cb *CBORDecoder) ReadUint64() (int64, error)

ReadUint64 reads 8 bytes (big-endian) and returns a int64

func (*CBORDecoder) ReadUint8

func (cb *CBORDecoder) ReadUint8() (int64, error)

ReadUint8 reads one byte and returns it as a int64

func (*CBORDecoder) Reset

func (r *CBORDecoder) Reset(b []byte)

Reset resets the Reader to be reading from b (no allocations in reset)

func (*CBORDecoder) Seek

func (r *CBORDecoder) Seek(offset int64, whence int) (int64, error)

Seek implements the io.Seeker interface.

func (*CBORDecoder) Size

func (r *CBORDecoder) Size() int64

Size returns the original length of the underlying byte slice. Size is the number of bytes available for reading via ReadAt. The returned value is always the same and is not affected by calls to any other method.

func (*CBORDecoder) UnreadByte

func (r *CBORDecoder) UnreadByte() error

UnreadByte complements ReadByte in implementing the io.ByteScanner interface.

func (*CBORDecoder) UnreadRune

func (r *CBORDecoder) UnreadRune() error

UnreadRune complements ReadRune in implementing the io.RuneScanner interface.

func (*CBORDecoder) WriteTo

func (r *CBORDecoder) WriteTo(w io.Writer) (n int64, err error)

WriteTo implements the io.WriterTo interface.

type CBOREncoder

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

func NewCBOREncoder

func NewCBOREncoder() *CBOREncoder

func (*CBOREncoder) Bytes

func (ce *CBOREncoder) Bytes() []byte

func (*CBOREncoder) EncodeAny

func (ce *CBOREncoder) EncodeAny(item any) *CBOREncoder

func (*CBOREncoder) EncodeArray

func (ce *CBOREncoder) EncodeArray(sourceArray []any) *CBOREncoder

func (*CBOREncoder) EncodeBytes

func (ce *CBOREncoder) EncodeBytes(sourceBstr []byte) *CBOREncoder

func (*CBOREncoder) EncodeInteger

func (ce *CBOREncoder) EncodeInteger(val int64) *CBOREncoder

func (*CBOREncoder) EncodeMap

func (ce *CBOREncoder) EncodeMap(sourceMap map[any]any) *CBOREncoder

func (*CBOREncoder) EncodeString

func (ce *CBOREncoder) EncodeString(sourceString string) *CBOREncoder

func (*CBOREncoder) Reset

func (ce *CBOREncoder) Reset() *CBOREncoder

type CWT

type CWT struct {

	// The raw token.  Populated when you Parse a token
	Raw []byte `json:"-"`

	// These are the 4 components of a CWT, as per the specification
	CBORProtectedHeaders   MapCBOR       `json:"-"` // The headers as a CBOR bstr
	CBORUnprotectedHeaders map[any]any   `json:"-"` // The unprotected headers as a map
	CBORPayload            MapCBOR       `json:"-"` // The payload as a bstr
	CBORSignature          SignatureCBOR `json:"-"` // The signature as a bstr

	// The headers as a JWT-style map, once they are decoded from CBOR binary
	// ProtectedHeaders map[string]string
	ProtectedHeaders *ProtectedHeaders

	// The signing method, both for verifying and signing
	Method Signer

	// Is the token valid?  Populated when you Parse/Verify a token
	Valid bool // Is the token valid?  Populated when you Parse/Verify a token
}

CWT is the basic structure for CWT functionality. It can be used by embedding it in a struct defining the additional claims required by the application.

func (*CWT) Dump

func (cwt *CWT) Dump() string

func (*CWT) Sign

func (cwt *CWT) Sign(key *crypto.PrivateKey) ([]byte, error)

Sign signs the CWT with the provided PrivateKey and stores the signature

func (*CWT) SigningBytes

func (cwt *CWT) SigningBytes() []byte

SigningBytes generates the signing byte array.

func (*CWT) Verify

func (cwt *CWT) Verify(key *crypto.PublicKey) (bool, error)

Verify checks the signature of the CWT against the provided PublicKey

type EUDCC

type EUDCC struct {
	CWT
	ValidMethods map[string]bool
	Payload      *EUDCCPayload
}

func DecodeEU_DCC_QR

func DecodeEU_DCC_QR(qrCode []byte) (*EUDCC, error)

DecodeEU_DCC_QR converts a raw string in QR format to a EUDCC native Go structure

func EUDCCFromSerializedCWT

func EUDCCFromSerializedCWT(raw []byte) (*EUDCC, error)

EUDCCFromSerializedCWT decodes a raw EUDCC certificate into a Go structure. It does NOT perform signature validation.

func NewEUDCC

func NewEUDCC(payload *EUDCCPayload, alg string) (*EUDCC, error)

func (*EUDCC) DecodeUntaggedCOSE

func (eu *EUDCC) DecodeUntaggedCOSE() error

DecodeUntaggedCOSE decodes a raw EUDCC certificate into a Go structure. It dos not perform validation of the signature.

func (*EUDCC) Dump

func (eu *EUDCC) Dump() string

func (*EUDCC) EncodeAndSign

func (eu *EUDCC) EncodeAndSign(privateKeyFunc PrivateKeyResolution) ([]byte, error)

func (*EUDCC) VerifyWith

func (eu *EUDCC) VerifyWith(publicKeyFunc PublicKeyResolution) (bool, error)

VerifyWith uses the public key provided by the keyFunc argument to verify the signature of a previously decoded EUDCC structure

type EUDCCPayload

type EUDCCPayload struct {
	Issuer                 string
	IssuedAt               int64
	ExpiresAt              int64
	Version                string
	DateOfBirth            string
	Surname                string
	SurnameTransliterated  string
	Forename               string
	ForenameTransliterated string
	VaccinationCert        *VaccinationCert `json:"v,omitempty"`
}

func PayloadAsJWT

func PayloadAsJWT(p map[any]any) *EUDCCPayload

type EUDCCPayload_

type EUDCCPayload_ struct {
	Issuer                 string
	IssuedAt               int64
	ExpiresAt              int64
	Version                string
	DateOfBirth            string
	Surname                string
	SurnameTransliterated  string
	Forename               string
	ForenameTransliterated string
	VaccinationCert        *VaccinationCert `json:"v,omitempty"`
}

type MapCBOR

type MapCBOR []byte

type PrivateKeyResolution

type PrivateKeyResolution func(*EUDCC) (*jwt.JWK, error)

type ProtectedHeaders

type ProtectedHeaders struct {
	Alg string
	Kid string
	// The signing method, both for verifying and signing
	Method Signer
}

func ProtectedHeadersFromCBOR

func ProtectedHeadersFromCBOR(CBORProtectedHeaders MapCBOR) (ph *ProtectedHeaders)

func (*ProtectedHeaders) ToCBOR

func (ph *ProtectedHeaders) ToCBOR() MapCBOR

type PublicKeyResolution

type PublicKeyResolution func(*EUDCC) (*jwt.JWK, error)

type SigStructure

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

SigStructure is used to sign a CWT or verify its signature It is here just for documentation, it is not actually used

type SignatureCBOR

type SignatureCBOR []byte

type Signer

type Signer interface {
	Available() bool                                                          // Returns true if the crypto functions are available
	Verify(signingBytes, signature []byte, publicKey *crypto.PublicKey) error // Returns nil if signature is valid
	Sign(signingBytes []byte, privateKey *crypto.PrivateKey) ([]byte, error)  // Returns encoded signature or error
	Alg() string                                                              // returns the alg identifier for this method (example: 'HS256')
}

Signer can be used add new methods for signing or verifying tokens.

func GetSigner

func GetSigner(alg string) (s Signer)

GetSigner retrieves a signing method from an "alg" string

type SignerECDSA

type SignerECDSA struct {
	Name      string
	Hash      crypto.Hash
	Hasher    hash.Hash
	KeySize   int
	CurveBits int
}

SignerECDSA implements the ECDSA family of signing methods. Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification

var (
	SignerES256 *SignerECDSA
	SignerES384 *SignerECDSA
	SignerES512 *SignerECDSA
)

Specific instances for EC256 and company

func (*SignerECDSA) Alg

func (m *SignerECDSA) Alg() string

func (*SignerECDSA) Available

func (m *SignerECDSA) Available() bool

func (*SignerECDSA) Sign

func (m *SignerECDSA) Sign(signingBytes []byte, key *crypto.PrivateKey) ([]byte, error)

Sign implements token signing for the SigningMethod. For this signing method, key must be an ecdsa.PrivateKey struct

func (*SignerECDSA) Verify

func (m *SignerECDSA) Verify(signingBytes, signature []byte, key *crypto.PublicKey) error

Verify implements token verification for the SigningMethod. For this verify method, key must be an ecdsa.PublicKey struct

type VaccinationCert

type VaccinationCert struct {
	DiseaseAgentTargeted    string // "tg"
	VaccineProphylaxis      string // "vp"
	VaccineMedicinalProduct string // "mp"
	VaccineMahManf          string // "ma"
	DoseNumber              int64  // "dn"
	DoseTotal               int64  // "sd"
	DateVaccination         string // "dt"
	CountryCode             string // "co"
	CertificateIssuer       string // "is"
	CertificateIdentifier   string // "ci"
}

func FromIntermediateCBOR

func FromIntermediateCBOR(vdata any) *VaccinationCert

func (*VaccinationCert) ToIntermediateCBOR

func (vc *VaccinationCert) ToIntermediateCBOR() []any

type ValidationError

type ValidationError struct {
	Inner  error  // stores the error returned by external dependencies, i.e.: KeyFunc
	Errors uint32 // bitfield.  see ValidationError... constants
	// contains filtered or unexported fields
}

ValidationError represents an error from Parse if token is not valid

func NewValidationError

func NewValidationError(errorText string, errorFlags uint32) *ValidationError

NewValidationError is a helper for constructing a ValidationError with a string error message

func (ValidationError) Error

func (e ValidationError) Error() string

Error is the implementation of the err interface.

func (*ValidationError) Is

func (e *ValidationError) Is(err error) bool

Is checks if this ValidationError is of the supplied error. We are first checking for the exact error message by comparing the inner error message. If that fails, we compare using the error flags. This way we can use custom error messages (mainly for backwards compatability) and still leverage errors.Is using the global error variables.

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Unwrap gives errors.Is and errors.As access to the inner error.

Jump to

Keyboard shortcuts

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