mdoc

package
v0.5.5 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2026 License: BSD-2-Clause Imports: 37 Imported by: 0

Documentation

Overview

Package mdoc implements ISO/IEC 18013-5:2021 Mobile Driving Licence (mDL) data model and operations.

Package mdoc implements the ISO/IEC 18013-5:2021 Mobile Driving Licence (mDL) data model.

Package mdoc provides device engagement and session establishment structures per ISO/IEC 18013-5:2021 sections 8.2 and 9.1.1.

Package mdoc provides IACA (Issuing Authority Certificate Authority) management per ISO/IEC 18013-5:2021 Annex B.

Package mdoc provides mDL issuer logic per ISO/IEC 18013-5:2021.

Package mdoc implements the ISO/IEC 18013-5:2021 Mobile Driving Licence (mDL) data model.

Package mdoc provides Mobile Security Object (MSO) generation per ISO/IEC 18013-5:2021.

Package mdoc implements the ISO/IEC 18013-5:2021 Mobile Driving Licence (mDL) data model.

Package mdoc implements the ISO/IEC 18013-5:2021 Mobile Driving Licence (mDL) data model.

Package mdoc implements the ISO/IEC 18013-5:2021 Mobile Driving Licence (mDL) data model.

Package mdoc implements the ISO/IEC 18013-5:2021 Mobile Driving Licence (mDL) data model.

Index

Examples

Constants

View Source
const (
	// TagEncodedCBOR is the CBOR tag for encoded CBOR data items (tag 24)
	TagEncodedCBOR = 24

	// TagDate is the CBOR tag for date (tag 1004 - full-date per RFC 8943)
	TagDate = 1004

	// TagDateTime is the CBOR tag for date-time (tag 0 - tdate per RFC 8949)
	TagDateTime = 0
)

CBOR tags used in ISO 18013-5

View Source
const (
	// Signing algorithms
	AlgorithmES256 int64 = -7  // ECDSA w/ SHA-256, P-256
	AlgorithmES384 int64 = -35 // ECDSA w/ SHA-384, P-384
	AlgorithmES512 int64 = -36 // ECDSA w/ SHA-512, P-521
	AlgorithmEdDSA int64 = -8  // EdDSA

	// MAC algorithms
	AlgorithmHMAC256 int64 = 5 // HMAC w/ SHA-256
	AlgorithmHMAC384 int64 = 6 // HMAC w/ SHA-384
	AlgorithmHMAC512 int64 = 7 // HMAC w/ SHA-512

	// Key types
	KeyTypeEC2 int64 = 2 // Elliptic Curve with x, y
	KeyTypeOKP int64 = 1 // Octet Key Pair (Ed25519, Ed448)

	// EC curves
	CurveP256 int64 = 1 // NIST P-256
	CurveP384 int64 = 2 // NIST P-384
	CurveP521 int64 = 3 // NIST P-521

	// OKP curves
	CurveEd25519 int64 = 6 // Ed25519
	CurveEd448   int64 = 7 // Ed448
)

COSE Algorithm identifiers per RFC 8152 and ISO 18013-5

View Source
const (
	HeaderAlgorithm   int64 = 1
	HeaderCritical    int64 = 2
	HeaderContentType int64 = 3
	HeaderKeyID       int64 = 4
	HeaderX5Chain     int64 = 33 // x5chain - certificate chain
	HeaderX5ChainAlt  int64 = 34 // Alternative x5chain label
)

COSE header labels

View Source
const (
	KeyLabelKty int64 = 1  // Key type
	KeyLabelAlg int64 = 3  // Algorithm
	KeyLabelCrv int64 = -1 // Curve
	KeyLabelX   int64 = -2 // X coordinate
	KeyLabelY   int64 = -3 // Y coordinate
)

COSE_Key labels

View Source
const (
	SessionStatusEncryptionError   uint = 10
	SessionStatusDecodingError     uint = 11
	SessionStatusSessionTerminated uint = 20
)

SessionStatus values per ISO 18013-5.

View Source
const (
	// ErrorDataNotReturned indicates data was not returned (general).
	ErrorDataNotReturned = 0
	// ErrorDataNotAvailable indicates the data element is not available.
	ErrorDataNotAvailable = 10
	// ErrorDataNotReleasable indicates the holder chose not to release the element.
	ErrorDataNotReleasable = 11
)

Error codes per ISO 18013-5:2021 Table 8

View Source
const DocType = "org.iso.18013.5.1.mDL"

DocType is the document type identifier for mDL.

View Source
const EngagementVersion = "1.0"

EngagementVersion is the device engagement version.

View Source
const Namespace = "org.iso.18013.5.1"

Namespace is the namespace for mDL data elements.

Variables

View Source
var (
	// OIDMobileDriverLicence is the extended key usage OID for mDL.
	OIDMobileDriverLicence = asn1.ObjectIdentifier{1, 0, 18013, 5, 1, 2}

	// OIDIssuerCertificate is the extended key usage for IACA certificates.
	OIDIssuerCertificate = asn1.ObjectIdentifier{1, 0, 18013, 5, 1, 6}

	// OIDMDLDocumentSigner is for Document Signer certificates.
	OIDMDLDocumentSigner = asn1.ObjectIdentifier{1, 0, 18013, 5, 1, 6}

	// OIDCRLDistributionPoints for CRL distribution.
	OIDCRLDistributionPoints = asn1.ObjectIdentifier{2, 5, 29, 31}

	// OIDAuthorityInfoAccess for OCSP.
	OIDAuthorityInfoAccess = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1}
)

OIDs defined in ISO 18013-5 Annex B.

Functions

func AlgorithmForKey

func AlgorithmForKey(key any) (int64, error)

AlgorithmForKey returns the appropriate COSE algorithm for a key. It accepts both public keys and signers (private keys).

func BuildSessionTranscript

func BuildSessionTranscript(deviceEngagement, eReaderKeyBytes, handover []byte) ([]byte, error)

BuildSessionTranscript creates the session transcript for key derivation. Per ISO 18013-5 section 9.1.5.1.

func CompareCBOR

func CompareCBOR(a, b []byte) bool

CompareCBOR compares two CBOR-encoded byte slices for equality.

Example
package main

import (
	"fmt"

	"github.com/SUNET/vc/pkg/mdoc"
)

func main() {
	enc, err := mdoc.NewCBOREncoder()
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	a, _ := enc.Marshal("test")
	b, _ := enc.Marshal("test")
	c, _ := enc.Marshal("other")

	fmt.Println("same:", mdoc.CompareCBOR(a, b))
	fmt.Println("different:", mdoc.CompareCBOR(a, c))
}
Output:
same: true
different: false

func DataElementBytes

func DataElementBytes(v DataElementValue) ([]byte, error)

DataElementBytes encodes a data element value to CBOR bytes.

func DeriveDeviceAuthenticationKey

func DeriveDeviceAuthenticationKey(sessionEncryption *SessionEncryption) ([]byte, error)

DeriveDeviceAuthenticationKey derives the key used for device MAC authentication. Per ISO 18013-5, this is derived from the session encryption keys.

func DeviceEngagementToQRCode

func DeviceEngagementToQRCode(de *DeviceEngagement) (string, error)

DeviceEngagementToQRCode generates QR code data from device engagement. The QR code contains "mdoc:" followed by the base64url-encoded device engagement.

func EncodeDeviceEngagement

func EncodeDeviceEngagement(de *DeviceEngagement) ([]byte, error)

EncodeDeviceEngagement encodes device engagement to CBOR bytes.

func EncodeDeviceResponse

func EncodeDeviceResponse(response *DeviceResponse) ([]byte, error)

EncodeDeviceResponse encodes a DeviceResponse to CBOR.

func ExportCertificateChainPEM

func ExportCertificateChainPEM(chain []*x509.Certificate) []byte

ExportCertificateChainPEM exports certificates in PEM format.

func ExtractDeviceKeyFromMSO

func ExtractDeviceKeyFromMSO(mso *MobileSecurityObject) (crypto.PublicKey, error)

ExtractDeviceKeyFromMSO extracts the device public key from the MSO.

func ExtractEDeviceKey

func ExtractEDeviceKey(de *DeviceEngagement) (*ecdsa.PublicKey, error)

ExtractEDeviceKey extracts the ephemeral device key from device engagement.

func ExtractReaderCertificate

func ExtractReaderCertificate(docRequest *DocRequest) (*x509.Certificate, error)

ExtractReaderCertificate extracts the reader certificate from a DocRequest.

func GenerateDeviceKeyPair

func GenerateDeviceKeyPair(curve elliptic.Curve) (*ecdsa.PrivateKey, error)

GenerateDeviceKeyPair generates a new device key pair for mDL holder.

func GenerateDeviceKeyPairEd25519

func GenerateDeviceKeyPairEd25519() (ed25519.PublicKey, ed25519.PrivateKey, error)

GenerateDeviceKeyPairEd25519 generates a new Ed25519 device key pair.

func GenerateRandom

func GenerateRandom(length int) ([]byte, error)

GenerateRandom generates cryptographically secure random bytes. Per ISO 18013-5, random values should be at least 16 bytes.

func GetCertificateChainFromSign1

func GetCertificateChainFromSign1(sign1 *COSESign1, ext ...*cryptoutil.Extensions) ([]*x509.Certificate, error)

GetCertificateChainFromSign1 extracts the x5chain from a COSE_Sign1. If ext is provided, certificates are parsed using extension-aware parsing (e.g. to support brainpool curves).

func GetDigestIDs

func GetDigestIDs(mso *MobileSecurityObject, namespace string) []uint

GetDigestIDs returns all digest IDs for a namespace in sorted order.

func HasReaderAuth

func HasReaderAuth(docRequest *DocRequest) bool

HasReaderAuth checks if a DocRequest contains reader authentication.

func NFCHandover

func NFCHandover() []byte

NFCHandover creates handover data for NFC engagement.

func ParseCRLDistributionPoint

func ParseCRLDistributionPoint(cert *x509.Certificate) (*url.URL, error)

ParseCRLDistributionPoint extracts the CRL distribution URL from a certificate.

func ParseDeviceKey

func ParseDeviceKey(data []byte, format string) (crypto.PublicKey, error)

ParseDeviceKey parses a device public key from various formats.

func QRHandover

func QRHandover() []byte

QRHandover creates handover data for QR code engagement.

func UnwrapEncodedCBOR

func UnwrapEncodedCBOR(data EncodedCBORBytes, v any) error

UnwrapEncodedCBOR extracts the value from CBOR tag 24.

func ValidateMSOValidity

func ValidateMSOValidity(mso *MobileSecurityObject) error

ValidateMSOValidity checks if the MSO is currently valid.

func ValidateReaderCertificate

func ValidateReaderCertificate(cert *x509.Certificate, profile *ReaderCertificateProfile) error

ValidateReaderCertificate validates a reader certificate against the profile.

func Verify1

func Verify1(sign1 *COSESign1, payload []byte, pubKey crypto.PublicKey, externalAAD []byte) error

Verify1 verifies a COSE_Sign1 signature.

func VerifyCOSEMac0

func VerifyCOSEMac0(mac0 *COSEMac0, key []byte, externalAAD []byte) error

VerifyCOSEMac0 verifies a COSE_Mac0 message.

func VerifyDigest

func VerifyDigest(mso *MobileSecurityObject, namespace string, item *IssuerSignedItem) error

VerifyDigest verifies that an IssuerSignedItem matches its digest in the MSO.

func WebsiteHandover

func WebsiteHandover(referrerURL *url.URL) ([]byte, error)

WebsiteHandover creates handover data for website-based engagement.

Types

type AgeOver

type AgeOver struct {
	// Over18 indicates whether the holder is 18 years or older.
	Over18 *bool `json:"age_over_18,omitempty" cbor:"age_over_18,omitempty"`

	// Over21 indicates whether the holder is 21 years or older.
	Over21 *bool `json:"age_over_21,omitempty" cbor:"age_over_21,omitempty"`

	// Over25 indicates whether the holder is 25 years or older.
	Over25 *bool `json:"age_over_25,omitempty" cbor:"age_over_25,omitempty"`

	// Over65 indicates whether the holder is 65 years or older.
	Over65 *bool `json:"age_over_65,omitempty" cbor:"age_over_65,omitempty"`
}

AgeOver contains age attestation statements for common thresholds. These are the standard age thresholds defined in ISO 18013-5.

type BLEOptions

type BLEOptions struct {
	SupportsCentralMode           bool    `cbor:"0,keyasint,omitempty"`
	SupportsPeripheralMode        bool    `cbor:"1,keyasint,omitempty"`
	PeripheralServerUUID          *string `cbor:"10,keyasint,omitempty"`
	CentralClientUUID             *string `cbor:"11,keyasint,omitempty"`
	PeripheralServerDeviceAddress *[]byte `cbor:"20,keyasint,omitempty"`
}

BLEOptions contains BLE-specific options.

type BLERole

type BLERole uint

BLERole indicates the BLE role.

const (
	// BLERoleCentral indicates the device is BLE central.
	BLERoleCentral BLERole = 0
	// BLERolePeripheral indicates the device is BLE peripheral.
	BLERolePeripheral BLERole = 1
	// BLERoleBoth indicates the device supports both roles.
	BLERoleBoth BLERole = 2
)

type BatchIssuanceRequest

type BatchIssuanceRequest struct {
	Requests []IssuanceRequest
}

BatchIssuanceRequest contains multiple mDL issuance requests.

type BatchIssuanceResult

type BatchIssuanceResult struct {
	Issued []IssuedDocument
	Errors []error
}

BatchIssuanceResult contains results from batch issuance.

type CBOREncoder

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

CBOREncoder provides CBOR encoding with ISO 18013-5 specific options.

func NewCBOREncoder

func NewCBOREncoder() (*CBOREncoder, error)

NewCBOREncoder creates a new CBOR encoder configured for ISO 18013-5.

Example
package main

import (
	"fmt"

	"github.com/SUNET/vc/pkg/mdoc"
)

func main() {
	enc, err := mdoc.NewCBOREncoder()
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Printf("%T\n", enc)
}
Output:
*mdoc.CBOREncoder

func (*CBOREncoder) Marshal

func (e *CBOREncoder) Marshal(v any) ([]byte, error)

Marshal encodes a value to CBOR.

Example
package main

import (
	"fmt"

	"github.com/SUNET/vc/pkg/mdoc"
)

func main() {
	enc, err := mdoc.NewCBOREncoder()
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	// Encode a simple map to CBOR
	original := map[string]string{"hello": "world"}
	data, err := enc.Marshal(original)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println("encoded length:", len(data))

	// Decode back
	var decoded map[string]string
	if err := enc.Unmarshal(data, &decoded); err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println("decoded:", decoded["hello"])
}
Output:
encoded length: 13
decoded: world

func (*CBOREncoder) Unmarshal

func (e *CBOREncoder) Unmarshal(data []byte, v any) error

Unmarshal decodes CBOR data into a value.

type COSEHeaders

type COSEHeaders struct {
	Protected   map[int64]any
	Unprotected map[int64]any
}

COSEHeaders contains protected and unprotected headers.

func NewCOSEHeaders

func NewCOSEHeaders() *COSEHeaders

NewCOSEHeaders creates new empty headers.

type COSEKey

type COSEKey struct {
	Kty int64  `cbor:"1,keyasint"`            // Key type
	Alg int64  `cbor:"3,keyasint,omitempty"`  // Algorithm
	Crv int64  `cbor:"-1,keyasint"`           // Curve
	X   []byte `cbor:"-2,keyasint"`           // X coordinate
	Y   []byte `cbor:"-3,keyasint,omitempty"` // Y coordinate (for EC2 keys)
}

COSEKey represents a COSE_Key structure per RFC 8152. This struct only holds public key material for security reasons. Private keys should never be serialized in COSE_Key format.

func NewCOSEKeyFromCoordinates

func NewCOSEKeyFromCoordinates(kty, crv string, x, y []byte) (*COSEKey, error)

NewCOSEKeyFromCoordinates creates a COSE_Key from raw X/Y coordinates. kty is the key type ("EC" for ECDSA, "OKP" for EdDSA). crv is the curve name ("P-256", "P-384", "P-521", "Ed25519"). x and y are the raw coordinate bytes (y should be nil for EdDSA).

func NewCOSEKeyFromECDSA

func NewCOSEKeyFromECDSA(pub *ecdsa.PublicKey) (*COSEKey, error)

NewCOSEKeyFromECDSA creates a COSE_Key from an ECDSA public key.

func NewCOSEKeyFromECDSAPublic

func NewCOSEKeyFromECDSAPublic(pub *ecdsa.PublicKey) (*COSEKey, error)

NewCOSEKeyFromECDSAPublic creates a COSE key from an ECDSA public key.

func NewCOSEKeyFromEd25519

func NewCOSEKeyFromEd25519(pub ed25519.PublicKey) *COSEKey

NewCOSEKeyFromEd25519 creates a COSE_Key from an Ed25519 public key.

func NewCOSEKeyFromEd25519Public

func NewCOSEKeyFromEd25519Public(pub ed25519.PublicKey) (*COSEKey, error)

NewCOSEKeyFromEd25519Public creates a COSE key from an Ed25519 public key.

func (*COSEKey) Bytes

func (k *COSEKey) Bytes() ([]byte, error)

Bytes encodes the COSE_Key to CBOR bytes.

func (*COSEKey) FromMap

func (k *COSEKey) FromMap(m map[int64]any) error

FromMap populates a COSEKey from a map.

func (*COSEKey) ToPublicKey

func (k *COSEKey) ToPublicKey() (crypto.PublicKey, error)

ToPublicKey converts a COSE_Key to a Go crypto public key.

type COSEMac0

type COSEMac0 struct {
	Protected   []byte      // Protected headers (CBOR encoded)
	Unprotected map[any]any // Unprotected headers
	Payload     []byte      // Payload
	Tag         []byte      // MAC tag
}

COSEMac0 represents a COSE_Mac0 structure per RFC 8152.

func Mac0

func Mac0(
	payload []byte,
	key []byte,
	algorithm int64,
	externalAAD []byte,
) (*COSEMac0, error)

Mac0 creates a COSE_Mac0 message.

func (*COSEMac0) MarshalCBOR

func (m *COSEMac0) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler for COSEMac0.

func (*COSEMac0) UnmarshalCBOR

func (m *COSEMac0) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler for COSEMac0.

type COSESign1

type COSESign1 struct {
	Protected   []byte      // Protected headers (CBOR encoded)
	Unprotected map[any]any // Unprotected headers
	Payload     []byte      // Payload (may be nil if detached)
	Signature   []byte      // Signature
}

COSESign1 represents a COSE_Sign1 structure per RFC 8152.

func Sign1

func Sign1(
	payload []byte,
	signer crypto.Signer,
	algorithm int64,
	x5chain [][]byte,
	externalAAD []byte,
) (*COSESign1, error)

Sign creates a COSE_Sign1 signature.

func Sign1Detached

func Sign1Detached(
	payload []byte,
	signer crypto.Signer,
	algorithm int64,
	x5chain [][]byte,
	externalAAD []byte,
) (*COSESign1, error)

Sign1Detached creates a COSE_Sign1 with detached payload.

func (*COSESign1) MarshalCBOR

func (s *COSESign1) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler for COSESign1.

func (*COSESign1) UnmarshalCBOR

func (s *COSESign1) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler for COSESign1.

type COSESign1Message

type COSESign1Message struct {
	Headers   *COSEHeaders
	Payload   []byte
	Signature []byte
}

COSESign1Message is a helper for creating and verifying COSE_Sign1 messages.

type CRLInfo

type CRLInfo struct {
	Issuer          string
	ThisUpdate      time.Time
	NextUpdate      time.Time
	RevokedCount    int
	DistributionURL string
}

CRLInfo contains information about a Certificate Revocation List.

type CredentialStatus

type CredentialStatus int

CredentialStatus represents the status of a credential.

const (
	// CredentialStatusValid indicates the credential is valid.
	CredentialStatusValid CredentialStatus = iota
	// CredentialStatusInvalid indicates the credential has been revoked.
	CredentialStatusInvalid
	// CredentialStatusSuspended indicates the credential is temporarily suspended.
	CredentialStatusSuspended
	// CredentialStatusUnknown indicates the status could not be determined.
	CredentialStatusUnknown
)

func (CredentialStatus) String

func (s CredentialStatus) String() string

String returns a string representation of the credential status.

type DataElementValue

type DataElementValue any

DataElementValue represents any valid data element value in an mDL.

type DeviceAuth

type DeviceAuth struct {
	// DeviceSignature is the COSE_Sign1 device signature (mutually exclusive with DeviceMac).
	DeviceSignature []byte `json:"deviceSignature,omitempty" cbor:"deviceSignature,omitempty"`

	// DeviceMac is the COSE_Mac0 device MAC (mutually exclusive with DeviceSignature).
	DeviceMac []byte `json:"deviceMac,omitempty" cbor:"deviceMac,omitempty"`
}

DeviceAuth contains either a device signature or MAC.

type DeviceAuthBuilder

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

DeviceAuthBuilder builds the DeviceSigned structure for mdoc authentication.

func NewDeviceAuthBuilder

func NewDeviceAuthBuilder(docType string) *DeviceAuthBuilder

NewDeviceAuthBuilder creates a new DeviceAuthBuilder.

func (*DeviceAuthBuilder) AddDeviceNameSpace

func (b *DeviceAuthBuilder) AddDeviceNameSpace(namespace string, elements map[string]any) *DeviceAuthBuilder

AddDeviceNameSpace adds device-signed data elements.

func (*DeviceAuthBuilder) Build

func (b *DeviceAuthBuilder) Build() (*DeviceSigned, error)

Build creates the DeviceSigned structure.

func (*DeviceAuthBuilder) WithDeviceKey

func (b *DeviceAuthBuilder) WithDeviceKey(key crypto.Signer) *DeviceAuthBuilder

WithDeviceKey sets the device private key for signature-based authentication.

func (*DeviceAuthBuilder) WithSessionKey

func (b *DeviceAuthBuilder) WithSessionKey(key []byte) *DeviceAuthBuilder

WithSessionKey sets the session key for MAC-based authentication. This is typically derived from the session encryption keys.

func (*DeviceAuthBuilder) WithSessionTranscript

func (b *DeviceAuthBuilder) WithSessionTranscript(transcript []byte) *DeviceAuthBuilder

WithSessionTranscript sets the session transcript.

type DeviceAuthVerifier

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

DeviceAuthVerifier verifies device authentication.

func NewDeviceAuthVerifier

func NewDeviceAuthVerifier(sessionTranscript []byte, docType string) *DeviceAuthVerifier

NewDeviceAuthVerifier creates a new DeviceAuthVerifier.

func (*DeviceAuthVerifier) VerifyMAC

func (v *DeviceAuthVerifier) VerifyMAC(deviceSigned *DeviceSigned, sessionKey []byte) error

VerifyMAC verifies a MAC-based device authentication.

func (*DeviceAuthVerifier) VerifySignature

func (v *DeviceAuthVerifier) VerifySignature(deviceSigned *DeviceSigned, deviceKey crypto.PublicKey) error

VerifySignature verifies a signature-based device authentication.

type DeviceAuthentication

type DeviceAuthentication struct {
	// SessionTranscript is the session transcript bytes
	SessionTranscript []byte
	// DocType is the document type being authenticated
	DocType string
	// DeviceNameSpacesBytes is the CBOR-encoded device-signed namespaces
	DeviceNameSpacesBytes []byte
}

DeviceAuthentication represents the structure to be signed/MACed for device authentication. Per ISO 18013-5:2021 section 9.1.3.

type DeviceEngagement

type DeviceEngagement struct {
	Version                string            `cbor:"0,keyasint"`
	Security               Security          `cbor:"1,keyasint"`
	DeviceRetrievalMethods []RetrievalMethod `cbor:"2,keyasint,omitempty"`
	ServerRetrievalMethods *ServerRetrieval  `cbor:"3,keyasint,omitempty"`
	ProtocolInfo           any               `cbor:"4,keyasint,omitempty"`
	OriginInfos            []OriginInfo      `cbor:"5,keyasint,omitempty"`
}

DeviceEngagement is the structure for device engagement. Per ISO 18013-5 section 8.2.1.

func DecodeDeviceEngagement

func DecodeDeviceEngagement(data []byte) (*DeviceEngagement, error)

DecodeDeviceEngagement decodes device engagement from CBOR bytes.

func ParseQRCode

func ParseQRCode(qrData string) (*DeviceEngagement, error)

ParseQRCode parses a device engagement QR code.

type DeviceKeyInfo

type DeviceKeyInfo struct {
	// DeviceKey is the public key of the device (COSE_Key format).
	DeviceKey []byte `json:"deviceKey" cbor:"deviceKey" validate:"required"`

	// KeyAuthorizations contains authorized namespaces and data elements.
	KeyAuthorizations *KeyAuthorizations `json:"keyAuthorizations,omitempty" cbor:"keyAuthorizations,omitempty"`

	// KeyInfo contains additional key information.
	KeyInfo map[string]any `json:"keyInfo,omitempty" cbor:"keyInfo,omitempty"`
}

DeviceKeyInfo contains information about the device key used for mdoc authentication.

type DeviceRequest

type DeviceRequest struct {
	// Version is the request version (e.g., "1.0").
	Version string `json:"version" cbor:"version" validate:"required"`

	// DocRequests contains the document requests.
	DocRequests []DocRequest `json:"docRequests" cbor:"docRequests" validate:"required,dive"`
}

DeviceRequest represents a request for mdoc data.

type DeviceResponse

type DeviceResponse struct {
	// Version is the response version (e.g., "1.0").
	Version string `json:"version" cbor:"version" validate:"required"`

	// Documents contains the returned documents.
	Documents []Document `json:"documents,omitempty" cbor:"documents,omitempty"`

	// DocumentErrors contains errors for documents that could not be returned.
	DocumentErrors []map[string]int `json:"documentErrors,omitempty" cbor:"documentErrors,omitempty"`

	// Status is the overall status code (0 = OK).
	Status uint `json:"status" cbor:"status"`
}

DeviceResponse represents a complete device response.

func DecodeDeviceResponse

func DecodeDeviceResponse(data []byte) (*DeviceResponse, error)

DecodeDeviceResponse decodes a DeviceResponse from CBOR.

type DeviceResponseBuilder

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

DeviceResponseBuilder builds a DeviceResponse with selective disclosure.

func NewDeviceResponseBuilder

func NewDeviceResponseBuilder(docType string) *DeviceResponseBuilder

NewDeviceResponseBuilder creates a new DeviceResponseBuilder.

func (*DeviceResponseBuilder) AddError

func (b *DeviceResponseBuilder) AddError(namespace, element string, errorCode int) *DeviceResponseBuilder

AddError adds an error for a specific element. Error codes per ISO 18013-5:2021: 0 = data not returned (general) 10 = data element not available 11 = data element not releasable by holder

func (*DeviceResponseBuilder) Build

Build creates the DeviceResponse.

func (*DeviceResponseBuilder) WithDeviceKey

WithDeviceKey sets the device key for signing.

func (*DeviceResponseBuilder) WithIssuerSigned

func (b *DeviceResponseBuilder) WithIssuerSigned(issuerSigned *IssuerSigned) *DeviceResponseBuilder

WithIssuerSigned sets the issuer-signed data.

func (*DeviceResponseBuilder) WithMACKey

func (b *DeviceResponseBuilder) WithMACKey(key []byte) *DeviceResponseBuilder

WithMACKey sets the MAC key for device authentication.

func (*DeviceResponseBuilder) WithRequest

func (b *DeviceResponseBuilder) WithRequest(request *ItemsRequest) *DeviceResponseBuilder

WithRequest sets the items request for selective disclosure.

func (*DeviceResponseBuilder) WithSessionTranscript

func (b *DeviceResponseBuilder) WithSessionTranscript(transcript []byte) *DeviceResponseBuilder

WithSessionTranscript sets the session transcript for device authentication.

type DeviceRetrievalMethod

type DeviceRetrievalMethod uint

DeviceRetrievalMethod identifies how the mdoc reader connects to the device.

const (
	// RetrievalMethodNFC indicates NFC connection.
	RetrievalMethodNFC DeviceRetrievalMethod = 1
	// RetrievalMethodBLE indicates Bluetooth Low Energy.
	RetrievalMethodBLE DeviceRetrievalMethod = 2
	// RetrievalMethodWiFiAware indicates Wi-Fi Aware.
	RetrievalMethodWiFiAware DeviceRetrievalMethod = 3
)

type DeviceSigned

type DeviceSigned struct {
	// NameSpaces contains device-signed name spaces (CBOR encoded).
	NameSpaces []byte `json:"nameSpaces" cbor:"nameSpaces"`

	// DeviceAuth contains the device authentication (MAC or signature).
	DeviceAuth DeviceAuth `json:"deviceAuth" cbor:"deviceAuth" validate:"required"`
}

DeviceSigned contains the device-signed data.

type DigestAlgorithm

type DigestAlgorithm string

DigestAlgorithm represents the hash algorithm used for digests.

const (
	// DigestAlgorithmSHA256 uses SHA-256 for digest computation.
	DigestAlgorithmSHA256 DigestAlgorithm = "SHA-256"
	// DigestAlgorithmSHA384 uses SHA-384 for digest computation.
	DigestAlgorithmSHA384 DigestAlgorithm = "SHA-384"
	// DigestAlgorithmSHA512 uses SHA-512 for digest computation.
	DigestAlgorithmSHA512 DigestAlgorithm = "SHA-512"
)

type DigestIDMapping

type DigestIDMapping map[string]ValueDigests

DigestIDMapping maps namespace to ValueDigests.

type DisclosurePolicy

type DisclosurePolicy struct {
	// AlwaysDisclose contains elements that should always be disclosed if requested.
	AlwaysDisclose map[string][]string
	// NeverDisclose contains elements that should never be disclosed.
	NeverDisclose map[string][]string
	// RequireConfirmation contains elements requiring explicit user confirmation.
	RequireConfirmation map[string][]string
}

DisclosurePolicy defines rules for automatic element disclosure decisions.

func DefaultMDLDisclosurePolicy

func DefaultMDLDisclosurePolicy() *DisclosurePolicy

DefaultMDLDisclosurePolicy returns a sensible default policy for mDL.

func NewDisclosurePolicy

func NewDisclosurePolicy() *DisclosurePolicy

NewDisclosurePolicy creates a new DisclosurePolicy.

func (*DisclosurePolicy) CanAutoDisclose

func (p *DisclosurePolicy) CanAutoDisclose(request *ItemsRequest) bool

CanAutoDisclose checks if all requested elements can be auto-disclosed.

func (*DisclosurePolicy) FilterRequest

func (p *DisclosurePolicy) FilterRequest(request *ItemsRequest) (*ItemsRequest, map[string][]string)

FilterRequest filters an ItemsRequest based on the disclosure policy. Returns the filtered request and elements that were blocked.

func (*DisclosurePolicy) RequiresConfirmation

func (p *DisclosurePolicy) RequiresConfirmation(request *ItemsRequest) map[string][]string

RequiresConfirmation returns elements from the request that need user confirmation.

type DocRequest

type DocRequest struct {
	// ItemsRequest is the CBOR-encoded items request.
	ItemsRequest []byte `json:"itemsRequest" cbor:"itemsRequest" validate:"required"`

	// ReaderAuth is the optional COSE_Sign1 reader authentication.
	ReaderAuth []byte `json:"readerAuth,omitempty" cbor:"readerAuth,omitempty"`
}

DocRequest represents a request for a specific document type.

type Document

type Document struct {
	// DocType is the document type identifier.
	DocType string `json:"docType" cbor:"docType" validate:"required"`

	// IssuerSigned contains issuer-signed data.
	IssuerSigned IssuerSigned `json:"issuerSigned" cbor:"issuerSigned" validate:"required"`

	// DeviceSigned contains device-signed data.
	DeviceSigned DeviceSigned `json:"deviceSigned" cbor:"deviceSigned" validate:"required"`

	// Errors contains any errors for specific data elements.
	Errors map[string]map[string]int `json:"errors,omitempty" cbor:"errors,omitempty"`
}

Document represents a complete mdoc document in a response.

type DocumentVerificationResult

type DocumentVerificationResult struct {
	// DocType is the document type identifier.
	DocType string

	// Valid indicates whether this document passed verification.
	Valid bool

	// MSO is the parsed Mobile Security Object.
	MSO *MobileSecurityObject

	// IssuerCertificate is the Document Signer certificate.
	IssuerCertificate *x509.Certificate

	// VerifiedElements contains successfully verified data elements.
	VerifiedElements map[string]map[string]any

	// Errors contains any errors for this document.
	Errors []error
}

DocumentVerificationResult contains the verification result for a single document.

type DrivingPrivilege

type DrivingPrivilege struct {
	// VehicleCategoryCode is the vehicle category code per ISO 18013-5 / Vienna Convention.
	// Valid values: AM, A1, A2, A, B1, B, BE, C1, C1E, C, CE, D1, D1E, D, DE, T.
	VehicleCategoryCode string `` /* 128-byte string literal not displayed */

	// IssueDate is the date when this privilege was issued.
	IssueDate *string `json:"issue_date,omitempty" cbor:"issue_date,omitempty"`

	// ExpiryDate is the date when this privilege expires.
	ExpiryDate *string `json:"expiry_date,omitempty" cbor:"expiry_date,omitempty"`

	// Codes contains additional restriction or condition codes.
	Codes []DrivingPrivilegeCode `json:"codes,omitempty" cbor:"codes,omitempty" validate:"omitempty,dive"`
}

DrivingPrivilege represents a single driving privilege category.

type DrivingPrivilegeCode

type DrivingPrivilegeCode struct {
	// Code is the restriction or condition code.
	Code string `json:"code" cbor:"code" validate:"required"`

	// Sign is the sign of the code (e.g., "=", "<", ">").
	Sign *string `json:"sign,omitempty" cbor:"sign,omitempty"`

	// Value is the value associated with the code.
	Value *string `json:"value,omitempty" cbor:"value,omitempty"`
}

DrivingPrivilegeCode represents a restriction or condition code for a driving privilege.

type EncodedCBORBytes

type EncodedCBORBytes []byte

EncodedCBORBytes represents CBOR-encoded bytes wrapped with tag 24. This is used for IssuerSignedItem and other structures that need to be independently verifiable.

func WrapInEncodedCBOR

func WrapInEncodedCBOR(v any) (EncodedCBORBytes, error)

WrapInEncodedCBOR wraps a value in CBOR tag 24 (encoded CBOR).

func (EncodedCBORBytes) MarshalCBOR

func (e EncodedCBORBytes) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler for EncodedCBORBytes.

func (*EncodedCBORBytes) UnmarshalCBOR

func (e *EncodedCBORBytes) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler for EncodedCBORBytes.

type EngagementBuilder

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

EngagementBuilder builds a DeviceEngagement structure.

func NewEngagementBuilder

func NewEngagementBuilder() *EngagementBuilder

NewEngagementBuilder creates a new engagement builder.

func (*EngagementBuilder) Build

Build creates the DeviceEngagement and returns it along with the private key.

func (*EngagementBuilder) GenerateEphemeralKey

func (b *EngagementBuilder) GenerateEphemeralKey() (*EngagementBuilder, error)

GenerateEphemeralKey generates a new ephemeral P-256 key.

func (*EngagementBuilder) WithBLE

WithBLE adds BLE as a device retrieval method.

func (*EngagementBuilder) WithEphemeralKey

func (b *EngagementBuilder) WithEphemeralKey(key *ecdsa.PrivateKey) (*EngagementBuilder, error)

WithEphemeralKey sets the ephemeral device key.

func (*EngagementBuilder) WithNFC

func (b *EngagementBuilder) WithNFC(maxCommand, maxResponse uint) *EngagementBuilder

WithNFC adds NFC as a device retrieval method.

func (*EngagementBuilder) WithOriginInfo

func (b *EngagementBuilder) WithOriginInfo(cat, typ uint, details string) *EngagementBuilder

WithOriginInfo adds origin information.

func (*EngagementBuilder) WithWiFiAware

func (b *EngagementBuilder) WithWiFiAware(opts WiFiAwareOptions) *EngagementBuilder

WithWiFiAware adds Wi-Fi Aware as a device retrieval method.

type FullDate

type FullDate string

FullDate represents a full-date (YYYY-MM-DD) with CBOR tag 1004.

Example
package main

import (
	"fmt"

	"github.com/SUNET/vc/pkg/mdoc"
)

func main() {
	enc, err := mdoc.NewCBOREncoder()
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	date := mdoc.FullDate("2024-01-15")
	data, err := enc.Marshal(date)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	var decoded mdoc.FullDate
	if err := enc.Unmarshal(data, &decoded); err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println(string(decoded))
}
Output:
2024-01-15

func (FullDate) MarshalCBOR

func (f FullDate) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler for FullDate.

func (*FullDate) UnmarshalCBOR

func (f *FullDate) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler for FullDate.

type IACACertManager

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

IACACertManager manages IACA and Document Signer certificates.

func NewIACACertManager

func NewIACACertManager() *IACACertManager

NewIACACertManager creates a new certificate manager.

func (*IACACertManager) GenerateIACACertificate

func (m *IACACertManager) GenerateIACACertificate(req *IACACertRequest) (*x509.Certificate, crypto.Signer, error)

GenerateIACACertificate generates a self-signed IACA root certificate. Per ISO 18013-5 Annex B.1.2.

func (*IACACertManager) GetCertificateChain

func (m *IACACertManager) GetCertificateChain(dsCert *x509.Certificate) []*x509.Certificate

GetCertificateChain returns the DS certificate chain including IACA.

func (*IACACertManager) GetIACACertificate

func (m *IACACertManager) GetIACACertificate() *x509.Certificate

GetIACACertificate returns the IACA certificate.

func (*IACACertManager) IssueDSCertificate

func (m *IACACertManager) IssueDSCertificate(req *IACACertRequest) (*x509.Certificate, error)

IssueDSCertificate issues a Document Signer certificate. Per ISO 18013-5 Annex B.1.3.

func (*IACACertManager) LoadIACA

func (m *IACACertManager) LoadIACA(cert *x509.Certificate, key crypto.Signer) error

LoadIACA loads an existing IACA certificate and key.

func (*IACACertManager) ValidateDSCertificate

func (m *IACACertManager) ValidateDSCertificate(dsCert *x509.Certificate) error

ValidateDSCertificate validates a DS certificate against the IACA.

type IACACertProfile

type IACACertProfile string

IACACertProfile represents the certificate profile requirements.

const (
	// ProfileIACA is for the root IACA certificate.
	ProfileIACA IACACertProfile = "IACA"
	// ProfileDS is for Document Signer certificates.
	ProfileDS IACACertProfile = "DS"
)

type IACACertRequest

type IACACertRequest struct {
	// Profile specifies IACA (root) or DS (document signer)
	Profile IACACertProfile

	// Subject information
	Country            string // ISO 3166-1 alpha-2
	Organization       string
	OrganizationalUnit string
	CommonName         string

	// Validity period
	NotBefore time.Time
	NotAfter  time.Time

	// Key to certify (public key)
	PublicKey crypto.PublicKey

	// For DS certificates, the issuing IACA
	IssuerCert *x509.Certificate
	IssuerKey  crypto.Signer

	// CRL distribution point URL
	CRLDistributionURL string

	// OCSP responder URL
	OCSPResponderURL string

	// Serial number (optional, generated if not provided)
	SerialNumber *big.Int
}

IACACertRequest contains the parameters for generating an IACA or DS certificate.

type IACATrustInfo

type IACATrustInfo struct {
	Country      string
	Organization string
	CommonName   string
	NotBefore    time.Time
	NotAfter     time.Time
	KeyAlgorithm string
	IsValid      bool
}

IACATrustInfo contains information about a trusted IACA.

type IACATrustList

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

IACATrustList manages a list of trusted IACA certificates.

func NewIACATrustList

func NewIACATrustList() *IACATrustList

NewIACATrustList creates a new trust list.

func (*IACATrustList) AddTrustedIACA

func (t *IACATrustList) AddTrustedIACA(cert *x509.Certificate) error

AddTrustedIACA adds an IACA certificate to the trust list.

func (*IACATrustList) GetTrustInfo

func (t *IACATrustList) GetTrustInfo() []IACATrustInfo

GetTrustInfo returns information about all trusted IACAs.

func (*IACATrustList) GetTrustedIssuers

func (t *IACATrustList) GetTrustedIssuers() []*x509.Certificate

GetTrustedIssuers returns all trusted IACA certificates.

func (*IACATrustList) IsTrusted

func (t *IACATrustList) IsTrusted(chain []*x509.Certificate) error

IsTrusted checks if a certificate chain is trusted.

type IssuanceRequest

type IssuanceRequest struct {
	// Holder's device public key
	DevicePublicKey crypto.PublicKey
	// mDL data elements
	MDoc *MDoc
	// Custom validity period (optional)
	ValidFrom  *time.Time
	ValidUntil *time.Time
}

IssuanceRequest contains the data for issuing an mDL.

type IssuedDocument

type IssuedDocument struct {
	// The complete Document structure ready for transmission
	Document *Document
	// The signed MSO
	SignedMSO *COSESign1
	// Validity information
	ValidFrom  time.Time
	ValidUntil time.Time
}

IssuedDocument contains the issued mDL document.

type Issuer

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

Issuer handles the creation and signing of mDL documents.

func NewIssuer

func NewIssuer(config IssuerConfig) (*Issuer, error)

NewIssuer creates a new mDL issuer.

func (*Issuer) GetInfo

func (i *Issuer) GetInfo() IssuerInfo

GetInfo returns information about the issuer.

func (*Issuer) Issue

func (i *Issuer) Issue(req *IssuanceRequest) (*IssuedDocument, error)

Issue creates a signed mDL document from the request.

func (*Issuer) IssueBatch

func (i *Issuer) IssueBatch(batch BatchIssuanceRequest) *BatchIssuanceResult

IssueBatch issues multiple mDL documents.

func (*Issuer) RevokeDocument

func (i *Issuer) RevokeDocument(documentNumber string) error

RevokeDocument marks a document for revocation (placeholder for status list integration).

type IssuerConfig

type IssuerConfig struct {
	SignerKey        crypto.Signer
	CertificateChain []*x509.Certificate
	DefaultValidity  time.Duration
	DigestAlgorithm  DigestAlgorithm
}

IssuerConfig contains configuration for creating an Issuer.

type IssuerInfo

type IssuerInfo struct {
	SubjectDN       string
	IssuerDN        string
	NotBefore       time.Time
	NotAfter        time.Time
	KeyAlgorithm    string
	DigestAlgorithm DigestAlgorithm
	CertChainLength int
}

GetIssuerInfo returns information about the issuer configuration.

type IssuerNameSpaces

type IssuerNameSpaces map[string][]TaggedCBOR

IssuerNameSpaces maps namespace to a list of IssuerSignedItem (as tagged CBOR).

type IssuerSigned

type IssuerSigned struct {
	// NameSpaces maps namespaces to arrays of IssuerSignedItem.
	NameSpaces map[string][]IssuerSignedItem `json:"nameSpaces" cbor:"nameSpaces"`

	// IssuerAuth is the COSE_Sign1 structure containing the MSO.
	IssuerAuth []byte `json:"issuerAuth" cbor:"issuerAuth" validate:"required"`
}

IssuerSigned contains the issuer-signed data.

type IssuerSignedItem

type IssuerSignedItem struct {
	// DigestID is the digest identifier matching the MSO.
	DigestID uint `json:"digestID" cbor:"digestID" validate:"required"`

	// Random is random bytes for digest computation.
	Random []byte `json:"random" cbor:"random" validate:"required,min=16"`

	// ElementIdentifier is the data element identifier.
	ElementIdentifier string `json:"elementIdentifier" cbor:"elementIdentifier" validate:"required"`

	// ElementValue is the data element value.
	ElementValue any `json:"elementValue" cbor:"elementValue" validate:"required"`
}

IssuerSignedItem represents a single signed data element.

type ItemsRequest

type ItemsRequest struct {
	// DocType is the requested document type.
	DocType string `json:"docType" cbor:"docType" validate:"required"`

	// NameSpaces maps namespaces to requested data elements with intent to retain.
	NameSpaces map[string]map[string]bool `json:"nameSpaces" cbor:"nameSpaces" validate:"required"`

	// RequestInfo contains optional additional request information.
	RequestInfo map[string]any `json:"requestInfo,omitempty" cbor:"requestInfo,omitempty"`
}

ItemsRequest represents the decoded items request.

type KeyAuthorizations

type KeyAuthorizations struct {
	// NameSpaces lists authorized namespaces.
	NameSpaces []string `json:"nameSpaces,omitempty" cbor:"nameSpaces,omitempty"`

	// DataElements maps namespaces to authorized data element identifiers.
	DataElements map[string][]string `json:"dataElements,omitempty" cbor:"dataElements,omitempty"`
}

KeyAuthorizations specifies what namespaces and data elements the device key is authorized to access.

type MDoc

type MDoc struct {

	// FamilyName is the last name, surname, or primary identifier of the mDL holder.
	// Maximum 150 characters, Latin1 encoding.
	FamilyName string `json:"family_name" cbor:"family_name" validate:"required,max=150"`

	// GivenName is the first name(s), other name(s), or secondary identifier of the mDL holder.
	// Maximum 150 characters, Latin1 encoding.
	GivenName string `json:"given_name" cbor:"given_name" validate:"required,max=150"`

	// BirthDate is the date of birth of the mDL holder.
	BirthDate string `json:"birth_date" cbor:"birth_date" validate:"required"`

	// IssueDate is the date when the mDL was issued.
	IssueDate string `json:"issue_date" cbor:"issue_date" validate:"required"`

	// ExpiryDate is the date when the mDL expires.
	ExpiryDate string `json:"expiry_date" cbor:"expiry_date" validate:"required"`

	// IssuingCountry is the Alpha-2 country code (ISO 3166-1) of the issuing authority's country.
	IssuingCountry string `json:"issuing_country" cbor:"issuing_country" validate:"required,len=2,iso3166_1_alpha2"`

	// IssuingAuthority is the name of the issuing authority.
	// Maximum 150 characters, Latin1 encoding.
	IssuingAuthority string `json:"issuing_authority" cbor:"issuing_authority" validate:"required,max=150"`

	// DocumentNumber is the licence number assigned by the issuing authority.
	// Maximum 150 characters, Latin1 encoding.
	DocumentNumber string `json:"document_number" cbor:"document_number" validate:"required,max=150"`

	// Portrait is the portrait image of the mDL holder (JPEG or JPEG2000).
	Portrait []byte `json:"portrait" cbor:"portrait" validate:"required"`

	// DrivingPrivileges contains the driving privileges of the mDL holder.
	DrivingPrivileges []DrivingPrivilege `json:"driving_privileges" cbor:"driving_privileges" validate:"required,dive"`

	// UNDistinguishingSign is the distinguishing sign according to ISO/IEC 18013-1:2018, Annex F.
	UNDistinguishingSign string `json:"un_distinguishing_sign" cbor:"un_distinguishing_sign" validate:"required"`

	// AdministrativeNumber is an audit control number assigned by the issuing authority.
	// Maximum 150 characters, Latin1 encoding.
	AdministrativeNumber *string `json:"administrative_number,omitempty" cbor:"administrative_number,omitempty" validate:"omitempty,max=150"`

	// Sex is the mDL holder's sex using values as defined in ISO/IEC 5218.
	// 0 = not known, 1 = male, 2 = female, 9 = not applicable
	Sex *uint `json:"sex,omitempty" cbor:"sex,omitempty" validate:"omitempty,oneof=0 1 2 9"`

	// Height is the mDL holder's height in centimetres.
	Height *uint `json:"height,omitempty" cbor:"height,omitempty" validate:"omitempty,min=1,max=300"`

	// Weight is the mDL holder's weight in kilograms.
	Weight *uint `json:"weight,omitempty" cbor:"weight,omitempty" validate:"omitempty,min=1,max=500"`

	// EyeColour is the mDL holder's eye colour.
	EyeColour *string `` /* 148-byte string literal not displayed */

	// HairColour is the mDL holder's hair colour.
	HairColour *string `` /* 143-byte string literal not displayed */

	// BirthPlace is the country and municipality or state/province where the mDL holder was born.
	// Maximum 150 characters, Latin1 encoding.
	BirthPlace *string `json:"birth_place,omitempty" cbor:"birth_place,omitempty" validate:"omitempty,max=150"`

	// ResidentAddress is the place where the mDL holder resides.
	// Maximum 150 characters, Latin1 encoding.
	ResidentAddress *string `json:"resident_address,omitempty" cbor:"resident_address,omitempty" validate:"omitempty,max=150"`

	// PortraitCaptureDate is the date when the portrait was taken.
	PortraitCaptureDate *time.Time `json:"portrait_capture_date,omitempty" cbor:"portrait_capture_date,omitempty"`

	// AgeInYears is the age of the mDL holder in years.
	AgeInYears *uint `json:"age_in_years,omitempty" cbor:"age_in_years,omitempty" validate:"omitempty,min=0,max=150"`

	// AgeBirthYear is the year when the mDL holder was born.
	AgeBirthYear *uint `json:"age_birth_year,omitempty" cbor:"age_birth_year,omitempty" validate:"omitempty,min=1900,max=2100"`

	// AgeOver contains age attestation statements for common thresholds.
	AgeOver *AgeOver `json:"age_over,omitempty" cbor:"age_over,omitempty"`

	// IssuingJurisdiction is the country subdivision code (ISO 3166-2) of the issuing jurisdiction.
	IssuingJurisdiction *string `json:"issuing_jurisdiction,omitempty" cbor:"issuing_jurisdiction,omitempty" validate:"omitempty"`

	// Nationality is the nationality of the mDL holder (ISO 3166-1 alpha-2).
	Nationality *string `json:"nationality,omitempty" cbor:"nationality,omitempty" validate:"omitempty,len=2"`

	// ResidentCity is the city where the mDL holder lives.
	// Maximum 150 characters, Latin1 encoding.
	ResidentCity *string `json:"resident_city,omitempty" cbor:"resident_city,omitempty" validate:"omitempty,max=150"`

	// ResidentState is the state/province/district where the mDL holder lives.
	// Maximum 150 characters, Latin1 encoding.
	ResidentState *string `json:"resident_state,omitempty" cbor:"resident_state,omitempty" validate:"omitempty,max=150"`

	// ResidentPostalCode is the postal code of the mDL holder.
	// Maximum 150 characters, Latin1 encoding.
	ResidentPostalCode *string `json:"resident_postal_code,omitempty" cbor:"resident_postal_code,omitempty" validate:"omitempty,max=150"`

	// ResidentCountry is the country where the mDL holder lives (ISO 3166-1 alpha-2).
	ResidentCountry *string `json:"resident_country,omitempty" cbor:"resident_country,omitempty" validate:"omitempty,len=2"`

	// BiometricTemplateFace is a biometric template for face recognition.
	BiometricTemplateFace []byte `json:"biometric_template_face,omitempty" cbor:"biometric_template_face,omitempty"`

	// BiometricTemplateFingerprint is a biometric template for fingerprint recognition.
	BiometricTemplateFingerprint []byte `json:"biometric_template_finger,omitempty" cbor:"biometric_template_finger,omitempty"`

	// BiometricTemplateSignature is a biometric template for signature recognition.
	BiometricTemplateSignature []byte `json:"biometric_template_signature,omitempty" cbor:"biometric_template_signature,omitempty"`

	// FamilyNameNationalCharacter is the family name using full UTF-8 character set.
	FamilyNameNationalCharacter *string `json:"family_name_national_character,omitempty" cbor:"family_name_national_character,omitempty"`

	// GivenNameNationalCharacter is the given name using full UTF-8 character set.
	GivenNameNationalCharacter *string `json:"given_name_national_character,omitempty" cbor:"given_name_national_character,omitempty"`

	// SignatureUsualMark is an image of the signature or usual mark of the mDL holder.
	SignatureUsualMark []byte `json:"signature_usual_mark,omitempty" cbor:"signature_usual_mark,omitempty"`
}

MDoc represents a Mobile Driving Licence document according to ISO/IEC 18013-5:2021.

type MSOBuilder

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

MSOBuilder builds a Mobile Security Object.

func NewMSOBuilder

func NewMSOBuilder(docType string) *MSOBuilder

NewMSOBuilder creates a new MSO builder.

Example
package main

import (
	"fmt"

	"github.com/SUNET/vc/pkg/mdoc"
)

func main() {
	builder := mdoc.NewMSOBuilder(mdoc.DocType)
	fmt.Printf("%T\n", builder)
}
Output:
*mdoc.MSOBuilder

func (*MSOBuilder) AddDataElement

func (b *MSOBuilder) AddDataElement(namespace, elementID string, value any) error

AddDataElement adds a data element to the MSO.

func (*MSOBuilder) AddDataElementWithRandom

func (b *MSOBuilder) AddDataElementWithRandom(namespace, elementID string, value any, random []byte) error

AddDataElementWithRandom adds a data element with a specific random value (for testing).

func (*MSOBuilder) Build

func (b *MSOBuilder) Build() (*COSESign1, IssuerNameSpaces, error)

Build creates the signed MSO and IssuerNameSpaces.

func (*MSOBuilder) WithDeviceKey

func (b *MSOBuilder) WithDeviceKey(key *COSEKey) *MSOBuilder

WithDeviceKey sets the device key (holder's key).

func (*MSOBuilder) WithDigestAlgorithm

func (b *MSOBuilder) WithDigestAlgorithm(alg DigestAlgorithm) *MSOBuilder

WithDigestAlgorithm sets the digest algorithm.

func (*MSOBuilder) WithSigner

func (b *MSOBuilder) WithSigner(key crypto.Signer, certChain []*x509.Certificate) *MSOBuilder

WithSigner sets the document signer key and certificate chain.

func (*MSOBuilder) WithValidity

func (b *MSOBuilder) WithValidity(from, until time.Time) *MSOBuilder

WithValidity sets the validity period.

type MSOInfo

type MSOInfo struct {
	Version         string
	DigestAlgorithm string
	DocType         string
	Signed          time.Time
	ValidFrom       time.Time
	ValidUntil      time.Time
	Namespaces      []string
	DigestCount     int
}

MSOInfo contains parsed information from an MSO for display purposes.

func GetMSOInfo

func GetMSOInfo(mso *MobileSecurityObject) MSOInfo

GetMSOInfo extracts display information from an MSO.

type MSOIssuerSignedItem

type MSOIssuerSignedItem struct {
	DigestID     uint   `cbor:"digestID"`
	Random       []byte `cbor:"random"`
	ElementID    string `cbor:"elementIdentifier"`
	ElementValue any    `cbor:"elementValue"`
}

MSOIssuerSignedItem represents a single data element with its digest ID and random salt. Per ISO 18013-5 section 9.1.2.4, this is the structure that gets hashed. This is internal to MSO generation; the canonical IssuerSignedItem is in mdoc.go.

type MobileSecurityObject

type MobileSecurityObject struct {
	// Version is the MSO version (e.g., "1.0").
	Version string `json:"version" cbor:"version" validate:"required"`

	// DigestAlgorithm is the algorithm used for digests (e.g., "SHA-256", "SHA-512").
	DigestAlgorithm string `json:"digestAlgorithm" cbor:"digestAlgorithm" validate:"required,oneof=SHA-256 SHA-512"`

	// ValueDigests maps namespaces to digest ID → digest value mappings.
	ValueDigests map[string]map[uint][]byte `json:"valueDigests" cbor:"valueDigests" validate:"required"`

	// DeviceKeyInfo contains the device key information.
	DeviceKeyInfo DeviceKeyInfo `json:"deviceKeyInfo" cbor:"deviceKeyInfo" validate:"required"`

	// DocType is the document type (e.g., "org.iso.18013.5.1.mDL").
	DocType string `json:"docType" cbor:"docType" validate:"required"`

	// ValidityInfo contains validity timestamps.
	ValidityInfo ValidityInfo `json:"validityInfo" cbor:"validityInfo" validate:"required"`
}

MobileSecurityObject (MSO) contains the signed digest values and metadata.

func VerifyMSO

func VerifyMSO(signedMSO *COSESign1, issuerCert *x509.Certificate) (*MobileSecurityObject, error)

VerifyMSO verifies a signed MSO against the issuer certificate.

type NFCOptions

type NFCOptions struct {
	MaxLenCommandData  uint `cbor:"0,keyasint"`
	MaxLenResponseData uint `cbor:"1,keyasint"`
}

NFCOptions contains NFC-specific options.

type OIDCRetrieval

type OIDCRetrieval struct {
	Version uint   `cbor:"0,keyasint"`
	URL     string `cbor:"1,keyasint"`
	Token   string `cbor:"2,keyasint,omitempty"`
}

OIDCRetrieval contains OIDC retrieval info.

type OriginInfo

type OriginInfo struct {
	Cat     uint   `cbor:"0,keyasint"` // 0=Delivery, 1=Receive
	Type    uint   `cbor:"1,keyasint"` // 1=Website
	Details string `cbor:"2,keyasint"` // e.g., referrer URL
}

OriginInfo contains origin information.

type ReaderAuthBuilder

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

ReaderAuthBuilder builds the ReaderAuth COSE_Sign1 structure.

func NewReaderAuthBuilder

func NewReaderAuthBuilder() *ReaderAuthBuilder

NewReaderAuthBuilder creates a new ReaderAuthBuilder.

func (*ReaderAuthBuilder) Build

func (b *ReaderAuthBuilder) Build() ([]byte, error)

Build creates the ReaderAuth COSE_Sign1 structure.

func (*ReaderAuthBuilder) BuildDocRequest

func (b *ReaderAuthBuilder) BuildDocRequest() (*DocRequest, error)

BuildDocRequest creates a complete DocRequest with reader authentication.

func (*ReaderAuthBuilder) WithItemsRequest

func (b *ReaderAuthBuilder) WithItemsRequest(request *ItemsRequest) *ReaderAuthBuilder

WithItemsRequest sets the items request to be signed.

func (*ReaderAuthBuilder) WithReaderKey

func (b *ReaderAuthBuilder) WithReaderKey(key crypto.Signer, certChain []*x509.Certificate) *ReaderAuthBuilder

WithReaderKey sets the reader's private key and certificate chain.

func (*ReaderAuthBuilder) WithSessionTranscript

func (b *ReaderAuthBuilder) WithSessionTranscript(transcript []byte) *ReaderAuthBuilder

WithSessionTranscript sets the session transcript.

type ReaderAuthVerifier

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

ReaderAuthVerifier verifies reader authentication on the device side.

func NewReaderAuthVerifier

func NewReaderAuthVerifier(sessionTranscript []byte, trustedReaders *ReaderTrustList) *ReaderAuthVerifier

NewReaderAuthVerifier creates a new ReaderAuthVerifier.

func (*ReaderAuthVerifier) FilterRequestByIntent

func (v *ReaderAuthVerifier) FilterRequestByIntent(request *ItemsRequest, readerCert *x509.Certificate) *ItemsRequest

FilterRequestByIntent filters an items request based on reader's allowed intents.

func (*ReaderAuthVerifier) VerifyAndFilterRequest

func (v *ReaderAuthVerifier) VerifyAndFilterRequest(readerAuthBytes []byte, itemsRequestBytes []byte) (*ItemsRequest, *x509.Certificate, error)

VerifyAndFilterRequest verifies reader auth and filters the request by intent.

func (*ReaderAuthVerifier) VerifyReaderAuth

func (v *ReaderAuthVerifier) VerifyReaderAuth(readerAuthBytes []byte, itemsRequestBytes []byte) (*ItemsRequest, *x509.Certificate, error)

VerifyReaderAuth verifies reader authentication and returns the verified items request.

type ReaderAuthentication

type ReaderAuthentication struct {
	// SessionTranscript is the session transcript bytes
	SessionTranscript []byte
	// ItemsRequestBytes is the CBOR-encoded items request
	ItemsRequestBytes []byte
}

ReaderAuthentication represents the structure to be signed for reader authentication. Per ISO 18013-5:2021 section 9.1.4.

type ReaderCertificateProfile

type ReaderCertificateProfile struct {
	// Extended key usage OID for mdoc reader authentication
	ExtKeyUsageOID string
}

ReaderCertificateProfile defines the expected profile for reader authentication certificates. Per ISO 18013-5:2021 Annex B.1.7.

func DefaultReaderCertProfile

func DefaultReaderCertProfile() *ReaderCertificateProfile

DefaultReaderCertProfile returns the default reader certificate profile.

type ReaderEngagement

type ReaderEngagement struct {
	Version     string       `cbor:"0,keyasint"`
	Security    Security     `cbor:"1,keyasint"`
	OriginInfos []OriginInfo `cbor:"5,keyasint,omitempty"`
}

ReaderEngagement is the structure for reader engagement (mdoc reader to device). Per ISO 18013-5 section 8.2.2.

type ReaderTrustList

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

ReaderTrustList maintains a list of trusted reader certificates or CAs.

func NewReaderTrustList

func NewReaderTrustList() *ReaderTrustList

NewReaderTrustList creates a new ReaderTrustList.

func (*ReaderTrustList) AddTrustedCA

func (t *ReaderTrustList) AddTrustedCA(cert *x509.Certificate)

AddTrustedCA adds a trusted CA that can issue reader certificates.

func (*ReaderTrustList) AddTrustedCertificate

func (t *ReaderTrustList) AddTrustedCertificate(cert *x509.Certificate)

AddTrustedCertificate adds a directly trusted reader certificate.

func (*ReaderTrustList) GetAllowedNamespaces

func (t *ReaderTrustList) GetAllowedNamespaces(cert *x509.Certificate) []string

GetAllowedNamespaces returns the namespaces a reader is allowed to access.

func (*ReaderTrustList) IsTrusted

func (t *ReaderTrustList) IsTrusted(chain []*x509.Certificate) error

IsTrusted checks if a reader certificate chain is trusted.

func (*ReaderTrustList) SetIntentMapping

func (t *ReaderTrustList) SetIntentMapping(subject string, allowedNamespaces []string)

SetIntentMapping sets the allowed namespaces/elements for a reader identified by subject.

type RequestBuilder

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

RequestBuilder builds an ItemsRequest for requesting specific data elements.

func NewRequestBuilder

func NewRequestBuilder(docType string) *RequestBuilder

NewRequestBuilder creates a new RequestBuilder for the specified document type.

func (*RequestBuilder) AddAgeVerification

func (b *RequestBuilder) AddAgeVerification(ages ...uint) *RequestBuilder

AddAgeVerification adds age verification elements to the request.

func (*RequestBuilder) AddElement

func (b *RequestBuilder) AddElement(namespace, elementID string, intentToRetain bool) *RequestBuilder

AddElement adds a data element to the request. intentToRetain indicates whether the verifier intends to retain the data.

func (*RequestBuilder) AddMandatoryElements

func (b *RequestBuilder) AddMandatoryElements(intentToRetain bool) *RequestBuilder

AddMandatoryElements adds all mandatory mDL elements to the request.

func (*RequestBuilder) Build

func (b *RequestBuilder) Build() *ItemsRequest

Build creates the ItemsRequest.

func (*RequestBuilder) BuildDeviceRequest

func (b *RequestBuilder) BuildDeviceRequest() (*DeviceRequest, error)

BuildDeviceRequest creates a complete DeviceRequest with this items request.

func (*RequestBuilder) BuildEncoded

func (b *RequestBuilder) BuildEncoded() ([]byte, error)

BuildEncoded creates the CBOR-encoded ItemsRequest.

func (*RequestBuilder) WithRequestInfo

func (b *RequestBuilder) WithRequestInfo(key string, value any) *RequestBuilder

WithRequestInfo adds additional request information.

type RetrievalMethod

type RetrievalMethod struct {
	Type    DeviceRetrievalMethod
	Version uint
	Options any // BLEOptions, NFCOptions, or WiFiAwareOptions
	// contains filtered or unexported fields
}

RetrievalMethod describes a device retrieval method.

type Security

type Security struct {
	CipherSuiteID   int    // 1 = ECDH with AES-256-GCM
	EDeviceKeyBytes []byte // Tagged CBOR-encoded COSE_Key
	// contains filtered or unexported fields
}

Security contains the security information for device engagement.

type SelectiveDisclosure

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

SelectiveDisclosure provides methods for selectively disclosing mDL data elements. Per ISO 18013-5:2021 section 8.3.2.1.2.2, the mdoc holder can choose which data elements to release from the requested elements.

func NewSelectiveDisclosure

func NewSelectiveDisclosure(issuerSigned *IssuerSigned) (*SelectiveDisclosure, error)

NewSelectiveDisclosure creates a new SelectiveDisclosure handler from issuer-signed data.

func (*SelectiveDisclosure) Disclose

func (sd *SelectiveDisclosure) Disclose(request map[string][]string) (*IssuerSigned, error)

Disclose creates a new IssuerSigned containing only the specified elements. The request maps namespaces to element identifiers to disclose.

func (*SelectiveDisclosure) DiscloseFromItemsRequest

func (sd *SelectiveDisclosure) DiscloseFromItemsRequest(request *ItemsRequest) (*IssuerSigned, error)

DiscloseFromItemsRequest creates a new IssuerSigned from an ItemsRequest.

func (*SelectiveDisclosure) GetAvailableElements

func (sd *SelectiveDisclosure) GetAvailableElements() map[string][]string

GetAvailableElements returns all available elements grouped by namespace.

func (*SelectiveDisclosure) HasElement

func (sd *SelectiveDisclosure) HasElement(namespace, element string) bool

HasElement checks if a specific element is available for disclosure.

type ServerRetrieval

type ServerRetrieval struct {
	WebAPI *WebAPIRetrieval `cbor:"0,keyasint,omitempty"`
	OIDC   *OIDCRetrieval   `cbor:"1,keyasint,omitempty"`
}

ServerRetrieval contains server retrieval information.

type SessionData

type SessionData struct {
	Data   []byte `cbor:"data,omitempty"`
	Status *uint  `cbor:"status,omitempty"`
}

SessionData contains encrypted session data.

type SessionEncryption

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

SessionEncryption handles the encryption/decryption for mdoc sessions. Per ISO 18013-5 section 9.1.1.5.

func NewSessionEncryptionDevice

func NewSessionEncryptionDevice(eDevicePriv *ecdsa.PrivateKey, eReaderPub *ecdsa.PublicKey, sessionTranscript []byte) (*SessionEncryption, error)

NewSessionEncryptionDevice creates session encryption from the device's perspective.

func NewSessionEncryptionReader

func NewSessionEncryptionReader(eReaderPriv *ecdsa.PrivateKey, eDevicePub *ecdsa.PublicKey, sessionTranscript []byte) (*SessionEncryption, error)

NewSessionEncryptionReader creates session encryption from the reader's perspective.

func (*SessionEncryption) Decrypt

func (s *SessionEncryption) Decrypt(ciphertext []byte) ([]byte, error)

Decrypt decrypts received data.

func (*SessionEncryption) Encrypt

func (s *SessionEncryption) Encrypt(plaintext []byte) ([]byte, error)

Encrypt encrypts data for transmission.

type SessionEstablishment

type SessionEstablishment struct {
	EReaderKeyBytes []byte // Tagged CBOR-encoded COSE_Key
	Data            []byte // Encrypted mdoc request (when sent by reader)
	// contains filtered or unexported fields
}

SessionEstablishment is used to establish a secure session. Per ISO 18013-5 section 9.1.1.4.

type StatusCheckResult

type StatusCheckResult struct {
	// Status is the credential status (valid, invalid, suspended).
	Status CredentialStatus
	// StatusCode is the raw status code from the status list.
	StatusCode uint8
	// CheckedAt is the timestamp when the status was checked.
	CheckedAt time.Time
	// StatusListURI is the URI of the status list that was checked.
	StatusListURI string
	// Index is the index in the status list.
	Index int64
}

StatusCheckResult contains the result of a credential status check.

type StatusChecker

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

StatusChecker checks the revocation status of mDL credentials.

func NewStatusChecker

func NewStatusChecker(opts ...StatusCheckerOption) *StatusChecker

NewStatusChecker creates a new StatusChecker.

func (*StatusChecker) CheckStatus

func (sc *StatusChecker) CheckStatus(ctx context.Context, ref *StatusReference) (*StatusCheckResult, error)

CheckStatus checks the status of a credential using its status reference.

func (*StatusChecker) ClearCache

func (sc *StatusChecker) ClearCache()

ClearCache clears the status list cache.

type StatusCheckerOption

type StatusCheckerOption func(*StatusChecker)

StatusCheckerOption configures the StatusChecker.

func WithCacheExpiry

func WithCacheExpiry(expiry time.Duration) StatusCheckerOption

WithCacheExpiry sets the cache expiry duration.

func WithHTTPClient

func WithHTTPClient(client *http.Client) StatusCheckerOption

WithHTTPClient sets a custom HTTP client.

func WithKeyFunc

func WithKeyFunc(keyFunc jwt.Keyfunc) StatusCheckerOption

WithKeyFunc sets the key function for JWT verification.

type StatusManager

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

StatusManager manages credential status for an issuer.

func NewStatusManager

func NewStatusManager(uri string, initialSize int) *StatusManager

NewStatusManager creates a new StatusManager for issuing credentials with status.

func (*StatusManager) AllocateIndex

func (sm *StatusManager) AllocateIndex() (int64, error)

AllocateIndex allocates the next available index for a new credential.

func (*StatusManager) GetStatus

func (sm *StatusManager) GetStatus(index int64) (CredentialStatus, error)

GetStatus returns the current status of a credential.

func (*StatusManager) GetStatusReference

func (sm *StatusManager) GetStatusReference(index int64) *StatusReference

GetStatusReference returns a StatusReference for a credential at the given index.

func (*StatusManager) Reinstate

func (sm *StatusManager) Reinstate(index int64) error

Reinstate marks a suspended credential as valid again.

func (*StatusManager) Revoke

func (sm *StatusManager) Revoke(index int64) error

Revoke marks a credential as revoked (invalid).

func (*StatusManager) StatusList

func (sm *StatusManager) StatusList() *tokenstatuslist.StatusList

StatusList returns the underlying status list for token generation.

func (*StatusManager) Suspend

func (sm *StatusManager) Suspend(index int64) error

Suspend marks a credential as suspended.

type StatusReference

type StatusReference struct {
	// URI is the URI of the Status List Token.
	URI string `json:"uri" cbor:"uri"`
	// Index is the index within the status list for this credential.
	Index int64 `json:"idx" cbor:"idx"`
}

StatusReference contains the status list reference embedded in an mDL. This follows the draft-ietf-oauth-status-list specification.

func ExtractStatusReference

func ExtractStatusReference(doc *Document) (*StatusReference, error)

ExtractStatusReference extracts the status reference from a Document. Returns nil if no status reference is present.

type TDate

type TDate string

TDate represents a date-time with CBOR tag 0.

func (TDate) MarshalCBOR

func (t TDate) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler for TDate.

func (*TDate) UnmarshalCBOR

func (t *TDate) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler for TDate.

type TaggedCBOR

type TaggedCBOR struct {
	Data []byte
	// contains filtered or unexported fields
}

TaggedCBOR represents CBOR data wrapped with tag 24 (encoded CBOR data item).

type TaggedValue

type TaggedValue struct {
	Tag   uint64
	Value any
}

TaggedValue wraps a value with a CBOR tag.

func (TaggedValue) MarshalCBOR

func (t TaggedValue) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler for TaggedValue.

type ValidityInfo

type ValidityInfo struct {
	// Signed is the timestamp when the MSO was signed.
	Signed time.Time `json:"signed" cbor:"signed" validate:"required"`

	// ValidFrom is the timestamp from which the MSO is valid.
	ValidFrom time.Time `json:"validFrom" cbor:"validFrom" validate:"required"`

	// ValidUntil is the timestamp until which the MSO is valid.
	ValidUntil time.Time `json:"validUntil" cbor:"validUntil" validate:"required"`

	// ExpectedUpdate is the expected timestamp for the next update (optional).
	ExpectedUpdate *time.Time `json:"expectedUpdate,omitempty" cbor:"expectedUpdate,omitempty"`
}

ValidityInfo contains validity information for the mDL.

type ValueDigests

type ValueDigests map[uint][]byte

ValueDigests maps digest ID to the actual digest bytes.

type VerificationResult

type VerificationResult struct {
	// Valid indicates whether the overall verification succeeded.
	Valid bool

	// Documents contains the verification results for each document.
	Documents []DocumentVerificationResult

	// Errors contains any errors encountered during verification.
	Errors []error
}

VerificationResult contains the result of verifying a DeviceResponse.

func (*VerificationResult) ExtractElements

func (r *VerificationResult) ExtractElements() map[string]map[string]any

ExtractElements extracts data elements from a VerificationResult. Returns a map of namespace -> element identifier -> value for all verified elements.

func (*VerificationResult) GetElement

func (r *VerificationResult) GetElement(namespace, elementID string) (any, bool)

GetElement retrieves a specific verified element from the result.

func (*VerificationResult) GetMDocElements

func (r *VerificationResult) GetMDocElements() map[string]any

GetMDocElements retrieves the standard mDL elements from the result.

func (*VerificationResult) VerifyAgeOver

func (r *VerificationResult) VerifyAgeOver(age uint) (bool, bool)

VerifyAgeOver checks if the holder is over a specific age. Returns (true, true) if verified over age, (false, true) if verified under age, and (false, false) if the age attestation is not present.

type Verifier

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

Verifier verifies mDL documents according to ISO/IEC 18013-5:2021.

func NewVerifier

func NewVerifier(config VerifierConfig) (*Verifier, error)

NewVerifier creates a new Verifier with the given configuration. TrustEvaluator is required - use go-trust with appropriate registries (mdociaca for dynamic IACA, ETSI TSL, OpenID Federation, etc.).

func (*Verifier) VerifyDeviceAuth

func (v *Verifier) VerifyDeviceAuth(doc *Document, mso *MobileSecurityObject, sessionTranscript []byte) error

VerifyDeviceAuth verifies device authentication as part of document verification. This should be called after verifying the issuer signature.

func (*Verifier) VerifyDeviceAuthWithSessionKey

func (v *Verifier) VerifyDeviceAuthWithSessionKey(doc *Document, sessionTranscript []byte, sessionKey []byte) error

VerifyDeviceAuthWithSessionKey verifies MAC-based device authentication.

func (*Verifier) VerifyDeviceResponse

func (v *Verifier) VerifyDeviceResponse(response *DeviceResponse) *VerificationResult

VerifyDeviceResponse verifies a complete DeviceResponse.

func (*Verifier) VerifyDeviceResponseWithContext

func (v *Verifier) VerifyDeviceResponseWithContext(ctx context.Context, response *DeviceResponse) *VerificationResult

VerifyDeviceResponseWithContext verifies a complete DeviceResponse with a context. The context is used for external trust evaluation when TrustEvaluator is configured.

func (*Verifier) VerifyDocument

func (v *Verifier) VerifyDocument(doc *Document) DocumentVerificationResult

VerifyDocument verifies a single Document.

func (*Verifier) VerifyIssuerSigned

func (v *Verifier) VerifyIssuerSigned(issuerSigned *IssuerSigned, docType string) (*MobileSecurityObject, map[string]map[string]any, error)

VerifyIssuerSigned verifies IssuerSigned data and returns verified elements. This is a convenience method for verifying just the issuer-signed portion.

type VerifierConfig

type VerifierConfig struct {
	// TrustEvaluator is required for validating certificate chains using an external
	// trust framework (e.g., go-trust with mdociaca, ETSI TSL, or OpenID Federation).
	// This replaces the deprecated local TrustList approach - all trust decisions
	// should go through TrustEvaluator for consistent policy enforcement.
	TrustEvaluator trust.TrustEvaluator

	// SkipRevocationCheck skips CRL/OCSP revocation checking if true.
	SkipRevocationCheck bool

	// Clock is an optional function that returns the current time.
	// If nil, time.Now() is used.
	Clock func() time.Time

	// CryptoExt provides extended algorithm and certificate support
	// (e.g. brainpool curves).
	CryptoExt *cryptoutil.Extensions
}

VerifierConfig contains configuration options for the Verifier.

type VerifierStatusCheck

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

VerifierStatusCheck integrates status checking into the verification flow.

func NewVerifierStatusCheck

func NewVerifierStatusCheck(checker *StatusChecker) *VerifierStatusCheck

NewVerifierStatusCheck creates a new VerifierStatusCheck.

func (*VerifierStatusCheck) CheckDocumentStatus

func (vsc *VerifierStatusCheck) CheckDocumentStatus(ctx context.Context, doc *Document) (*StatusCheckResult, error)

CheckDocumentStatus checks the status of a document if it has a status reference.

func (*VerifierStatusCheck) SetEnabled

func (vsc *VerifierStatusCheck) SetEnabled(enabled bool)

SetEnabled enables or disables status checking.

type WebAPIRetrieval

type WebAPIRetrieval struct {
	Version uint   `cbor:"0,keyasint"`
	URL     string `cbor:"1,keyasint"`
	Token   string `cbor:"2,keyasint,omitempty"`
}

WebAPIRetrieval contains Web API retrieval info.

type WiFiAwareOptions

type WiFiAwareOptions struct {
	PassphraseInfo *string `cbor:"0,keyasint,omitempty"`
	ChannelInfo    *uint   `cbor:"1,keyasint,omitempty"`
	BandInfo       *uint   `cbor:"2,keyasint,omitempty"`
}

WiFiAwareOptions contains Wi-Fi Aware options.

Jump to

Keyboard shortcuts

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