mdoc

package
v0.5.9 Latest Latest
Warning

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

Go to latest
Published: May 21, 2026 License: BSD-2-Clause Imports: 39 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.

View Source
var MDocClaimMapping = map[string]string{

	"family_name":                    "family_name",
	"given_name":                     "given_name",
	"birth_date":                     "birthdate",
	"portrait":                       "picture",
	"issue_date":                     "iat",
	"expiry_date":                    "exp",
	"issuing_country":                "issuing_country",
	"issuing_authority":              "issuing_authority",
	"document_number":                "document_number",
	"driving_privileges":             "driving_privileges",
	"un_distinguishing_sign":         "un_distinguishing_sign",
	"administrative_number":          "administrative_number",
	"sex":                            "gender",
	"height":                         "height",
	"weight":                         "weight",
	"eye_colour":                     "eye_color",
	"hair_colour":                    "hair_color",
	"birth_place":                    "place_of_birth",
	"resident_address":               "address",
	"resident_city":                  "locality",
	"resident_state":                 "region",
	"resident_postal_code":           "postal_code",
	"resident_country":               "country",
	"age_in_years":                   "age",
	"age_birth_year":                 "birth_year",
	"age_over_18":                    "age_over_18",
	"age_over_21":                    "age_over_21",
	"issuing_jurisdiction":           "issuing_jurisdiction",
	"nationality":                    "nationality",
	"family_name_national_character": "family_name_native",
	"given_name_national_character":  "given_name_native",
}

MDocClaimMapping provides standard mappings from mdoc claims to OIDC claims.

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 ExtractMDocClaims added in v0.5.7

func ExtractMDocClaims(vpToken string) (map[string]any, error)

ExtractMDocClaims extracts claims from an mdoc VP token without full verification. Use this for testing or when verification is handled separately.

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 IsMDocFormat added in v0.5.7

func IsMDocFormat(vpToken string) bool

IsMDocFormat checks if the VP token appears to be in mdoc format. It tries to decode and check for CBOR structure.

func MapMDocToOIDC added in v0.5.7

func MapMDocToOIDC(mdocClaims map[string]any) map[string]any

MapMDocToOIDC maps mdoc claims to OIDC claims using the standard mapping.

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 MDocDocumentClaims added in v0.5.7

type MDocDocumentClaims struct {
	DocType    string
	Namespaces map[string]map[string]any
}

MDocDocumentClaims contains the claims from a single mdoc document.

func (*MDocDocumentClaims) GetClaims added in v0.5.7

func (dc *MDocDocumentClaims) GetClaims() map[string]any

GetClaims returns a flat map of all claims from all namespaces.

type MDocHandler added in v0.5.7

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

MDocHandler handles mdoc format credentials in OpenID4VP flows.

func NewMDocHandler added in v0.5.7

func NewMDocHandler(opts ...MDocHandlerOption) (*MDocHandler, error)

NewMDocHandler creates a new mdoc handler for OpenID4VP. Either WithMDocTrustEvaluator or WithMDocVerifier must be provided.

func (*MDocHandler) VerifyAndExtract added in v0.5.7

func (h *MDocHandler) VerifyAndExtract(ctx context.Context, vpToken string) (*MDocVerificationResult, error)

VerifyAndExtract verifies an mdoc VP token and extracts the disclosed claims. The vpToken should be the base64url-encoded DeviceResponse.

type MDocHandlerOption added in v0.5.7

type MDocHandlerOption func(*MDocHandler)

MDocHandlerOption configures an MDocHandler.

func WithMDocTrustEvaluator added in v0.5.7

func WithMDocTrustEvaluator(te trust.TrustEvaluator) MDocHandlerOption

WithMDocTrustEvaluator sets the trust evaluator for mdoc verification. This is the preferred way to configure trust - it delegates to go-trust which can use mdociaca, ETSI TSL, OpenID Federation, etc.

func WithMDocVerifier added in v0.5.7

func WithMDocVerifier(v *Verifier) MDocHandlerOption

WithMDocVerifier sets a pre-configured verifier.

type MDocVerificationResult added in v0.5.7

type MDocVerificationResult struct {
	Valid     bool
	Documents map[string]*MDocDocumentClaims
}

MDocVerificationResult contains the result of mdoc verification and claim extraction.

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, error)

NewStatusChecker creates a new StatusChecker. A cache must be provided via WithStatusCache. TODO(masv): wire into the verifier so status checking is actually performed at presentation time.

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.

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.

func WithStatusCache added in v0.5.7

func WithStatusCache(c cache.Cache[[]uint8]) StatusCheckerOption

WithStatusCache sets an external cache implementation (e.g. MongoCache for HA).

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