Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ Release 6.0.0 (unreleased):
- Credential definitions:
- Move `CredentialScheme` out of `ConstantIndex`
- Provide type alias for `CredentialRepresentation`
- Introudce typed sub-interfaces of `CredentialScheme`: `VcJwtCredentialScheme`, `SdJwtCredentialScheme` and `IsoMdocCredentialScheme`
- Introduce typed sub-interfaces of `CredentialScheme`: `VcJwtCredentialScheme`, `SdJwtCredentialScheme` and `IsoMdocCredentialScheme`
- That implies changes to `CredentialToBeIssued`, `IssuedCredential`, `StoreCredentialInput` and methods in `SubjectCredentialStore`
- In `CredentialScheme` deprecate `claimNames` (list of strings), to be replaced with `claimDescriptions` (set of typed descriptions)
- In `StoreEntry` deprecate property `scheme` and add suspending function `resolveScheme()` to replace it
- Add `UnknownCredentialScheme` so that the `scheme` property of several classes is never null
- Import data classes and data element strings from credentials into this library for [EU PID](https://github.com/a-sit-plus/eu-pid-credential), [EU PID in SD-JWT](https://github.com/a-sit-plus/eu-pid-credential-sdjwt/) and [Mobile Driving Licence](https://github.com/a-sit-plus/mobile-driving-licence-credential/)
- Document usage of remote metadata retrieval
- New modules:
- `etsi-data-classes` implements list of trusted entities from [ETSI TS 119 602](https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf)
- `sd-jwt-type-metadata` implements SD-JWT VC Type Metadata from [draft-ietf-oauth-sd-jwt-vc-16](https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/):
Expand All @@ -57,7 +58,7 @@ Release 6.0.0 (unreleased):
- Update to [Signum 3.23.0](https://github.com/a-sit-plus/signum/releases/tag/3.23.0)
- Update to Ktor 3.5.0
- Update Bouncy Castle 1.84
- Update to kotlinx.coroutines 1.11.0
- Update to `kotlinx.coroutines` 1.11.0
- Matrix testing

Release 5.12.0:
Expand All @@ -79,7 +80,7 @@ Release 5.12.0:
- Change: Update DCQLClaimsQuery and DCQLCredentialQuery to OpenID4VP 1.0
- Change: Do not fail when only matching credentials without submitting a presentation
- Allow issuance and verification of `IdentifierList` Revocation Mechanism
- Change: Don't send response on user initiated signature cancellation
- Change: Don't send response on user-initiated signature cancellation
- BREAKING CHANGE: The result type from `verifyAuthnResponse`, `AuthnResponseResult` has been reworked to a data class
- DCQL: Add custom credential types and proper satisfaction evaluation
- Add: DCQL submission requirements validation
Expand Down Expand Up @@ -207,7 +208,7 @@ Release 5.10.0:
- Drop single `proof` in credential request
- Support credential response encryption correctly, see changed API in `CredentialIssuer.credential()`
- Correctly verify credential request regarding `credential_configuration_id` and `credential_identifiers`
- Support credential request encryption correctly, if metadata is set at Issuer
- Support credential request encryption correctly if metadata is set at Issuer
- OpenID for Verifiable Presentations:
- Update implementation to 1.0 from 2025-07-09
- Remove code elements deprecated in 5.9.0
Expand Down Expand Up @@ -376,11 +377,11 @@ Release 5.8.0:
- In `SimpleAuthorizationService` deprecate constructor parameter `dataProvider`, use `authorize()` with `OAuth2LoadUserFun` instead
- In `AuthorizationService` deprecate `authorize()` methods, adding `authorize()` with `OAuth2LoadUserFun`
- Credential schemes:
- Provide fallback credential schemes, to be used when no matching scheme is registered with this library:
- Provide fallback credential schemes to be used when no matching scheme is registered with this library:
- `SdJwtFallbackCredentialScheme`
- `VcFallbackCredentialScheme`
- `IsoMdocFallbackCredentialScheme`
- Note that these schemes are not resolved automatically, and need to be used explicitly in client applications
- Note that these schemes are not resolved automatically and need to be used explicitly in client applications
- SD-JWT:
- Add data class for [SD-JWT VC Type metadata](https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-10.html#name-sd-jwt-vc-type-metadata) in `SdJwtTypeMetadata`
- Update signum to provide SD-JWT VC Type metadata in `vctm` in the header of a SD-JWT
Expand Down Expand Up @@ -440,7 +441,7 @@ Release 5.7.0:
- Replace type aliases with functional interfaces (providing named parameters in implementations)
- Make cryptographic verification functions suspending
- Fully integrated crypto functionality based on Signum 3.16.2. This carries over breaking changes:
- All debug-only kotlinx.serialization for cryptographic datatypes like certificates, public keys, etc. was removed
- All debug-only `kotlinx.serialization` for cryptographic datatypes like certificates, public keys, etc. was removed
- This finally cleans up the RSAorHMAC
- `SignatureAlgorithm.RSAorHMAC` is now properly split into `SignatureAlgorithm` and `MessageAuthenticationCode`. Both implement `DataIntegrityAlgorithm`.
- This split also affects `JwsAlgorithm`, which now has subtypes: `Signature` and `MAC`. Hence, `JwsAlgorithm.ES256` -> `JwsAlgorithm.Signature.ES256`
Expand All @@ -458,15 +459,15 @@ Release 5.7.0:
- Remove `Validator.checkRevocationStatus` in favor of `Validator.checkCredentialFreshness`
- Remove `Holder.StoredCredential.status`
- Remove `Verifier.VerifyCredentialResult.Revoked`
- Add constructor parameter `Validator.acceptedTokenStatuses` to allow library client to define token statuses deemed valid
- Add constructor parameter `Validator.acceptedTokenStatuses` to allow library clients to define token statuses deemed valid
- Add support for Digital Credentials API as defined in OID4VP draft 28 and ISO 18013-7 Annex C:
- Implement `DCAPIRequest` for requests received via the Digital Credentials API, with implementations for OID4VP (`Oid4vpDCAPIRequest`), ISO 18013-7 Annex C (`IsoMdocRequest`) and a non-standardised preview protocol (`PreviewDCAPIRequest`)
- New property of type `Oid4vpDCAPIRequest` for requests originating from the Digital Credentials API in `AuthorizationResponsePreparationState`
- New parameter of type `Oid4vpDCAPIRequest` for requests originating from the Digital Credentials API in `OpenId4VpHolder.parseAuthenticationRequestParameters`, `RequestParameters.extractAudience` `PresentationFactory.createPresentation` `PresentationFactory.calcDeviceSignature` `RequestParser.parseRequestParameters` `RequestParser.extractRequestObject` `RequestParser.parseRequestObjectJws` `RequestParser.matchRequestParameterCases` `HolderAgent.getValidCredentialsByPriority`
- New optional parameter `filterById` of type `String` in `Holder.matchInputDescriptorsAgainstCredentialStore`, `HolderAgent.getValidCredentialsByPriority` `HolderAgent.matchInputDescriptorsAgainstCredentialStore` `HolderAgent.matchDCQLQueryAgainstCredentialStore` to filter credentials by id
- New method `SubjectCredentialStore.getDcApiId` to generate an id of type `String` for a credential
- New optional property of type `DCAPIHandover` for `SessionTranscript`
- Return member of interface `AuthenticationResult` instead of `AuthenticationSuccess` as authorization response in `OpenId4VpWallet`. Can either be
- Return member of interface `AuthenticationResult` instead of `AuthenticationSuccess` as authorization response in `OpenId4VpWallet`:
- `AuthenticationSuccess`: contains a `redirectUri` (same behaviour as in 5.6.x)
- `AuthenticationForward`: contains the `authenticationResponseResult` for responses via the Digital Credentials API
- Refactoring of ISO data classes:
Expand Down Expand Up @@ -837,7 +838,7 @@ Release 5.2.0:
- Remove `scopePresentationDefinitionRetriever` from `OidcSiopWallet` to keep implementation simple
- Dependency Updates:
- Signum 3.11.1
- Kotlin 2.1.0 through Conventions 2.1.0+20241204
- Kotlin 2.1.0 through Conventions 2.1.0+20241204

Release 5.1.0:
- Drop ARIES protocol implementation, and the `vck-aries` artifact
Expand Down Expand Up @@ -906,7 +907,7 @@ Release 5.0.0:
- Remove binding method for `did:key`, as it was never completely implemented, but add binding method `jwk` for JSON Web Keys.
- Rework interface of `WalletService` to make selecting the credential configuration by its ID more explicit
- Support requesting issuance of credential using scope values
- Introudce `OAuth2Client` to extract creating authentication requests and token requests from OID4VCI `WalletService`
- Introduce `OAuth2Client` to extract creating authentication requests and token requests from OID4VCI `WalletService`
- Refactor `SimpleAuthorizationService` to extract actual authentication and authorization into `AuthorizationServiceStrategy`
- Implement JWE encryption with AES-CBC-HMAC algorithms
- SIOPv2/OpenID4VP: Support requesting and receiving claims from different credentials, i.e. a combined presentation
Expand Down
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,53 @@ As discovered in [#226](https://github.com/a-sit-plus/vck/issues/226), using the
The actual credentials are provided as discrete artefacts and are maintained separately [over here](https://github.com/a-sit-plus/credentials-collection).
It is fine to add credentials **and** VC-K to as project dependencies, e. g., to use a version of VC-K that is more recent than the one a certain credentials depends on.

### Registering credential schemes

Credential schemes are derived from [SD-JWT Type Metadata](https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/)
documents and resolved through `AttributeIndex`. Register one or more `CredentialMetadataRegistry` instances once at
startup; on a lookup miss `AttributeIndex` consults them, builds the scheme, and caches it. Two registries coexist:
a `StaticCredentialMetadataRegistry` for documents **bundled in code** (offline, authoritative; preloaded so they win
on lookup), and a `RemoteCredentialMetadataRegistry` that **fetches documents over HTTP** for everything else. The
documents are hosted in [credentials-collection](https://github.com/a-sit-plus/credentials-collection).

```kotlin
val base = "https://raw.githubusercontent.com/a-sit-plus/credentials-collection/main"
Comment thread
nodh marked this conversation as resolved.

// Bundled in code: EU PID (ISO), EU PID SD-JWT, mDL. The URL is the document's hosted copy (becomes schemaUri).
LibraryInitializer.registerCredentialMetadataRegistry(
StaticCredentialMetadataRegistry(
documentRegistry = SdJwtTypeMetadataDocumentRegistry(
EuPidSdJwtMetadataDocument, EuPidMetadataDocument, MobileDrivingLicenceMetadataDocument,
),
documentUrls = mapOf(
EuPidSdJwtMetadataDocument.first to EU_PID_SD_JWT_METADATA_URL,
EuPidMetadataDocument.first to EU_PID_METADATA_URL,
MobileDrivingLicenceMetadataDocument.first to MDL_METADATA_URL,
),
)
)

// Fetched on demand: add one `vct -> URL` entry per published document. SD-JWT resolves directly (identifier == vct);
// ISO mDoc has no direct vct fallback, so its docType must be aliased to the document's vct.
LibraryInitializer.registerCredentialMetadataRegistry(
RemoteCredentialMetadataRegistry(
httpClient = httpClient, // your app's Ktor HttpClient
clock = Clock.System,
documentUrls = mutableMapOf(
SdJwtVcType("urn:eudi:ehic:1") to "$base/ehic.json",
SdJwtVcType("eu.europa.ec.av.1") to "$base/age-verification.json",
),
aliases = mapOf(
CredentialMetadataLookup(ISO_MDOC, "eu.europa.ec.av.1") to SdJwtVcType("eu.europa.ec.av.1"),
),
)
)
```

ISO mDoc credentials with non-primitive values additionally need their CBOR/JSON value serializers registered from
code (e.g. `LibraryInitializer.registerCredentialSerializers(EuPidJsonValueEncoder, EuPidItemValueSerializerMap)`);
schemes whose values are all primitive (such as the all-boolean age verification) need none.

## Limitations

- Several parts of the W3C VC Data Model have not been fully implemented, i.e. everything around resolving cryptographic key material.
Expand Down
10 changes: 6 additions & 4 deletions vck-openid-ktor/src/commonTest/kotlin/TestConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import at.asitplus.testballoon.matrix.MatrixTestDefaults
import at.asitplus.wallet.eupid.EuPidItemValueSerializerMap
import at.asitplus.wallet.eupid.EuPidJsonValueEncoder
import at.asitplus.wallet.eupid.EuPidMetadataDocument
import at.asitplus.wallet.eupid.EU_PID_METADATA_URL
import at.asitplus.wallet.eupidsdjwt.EuPidSdJwtMetadataDocument
import at.asitplus.wallet.eupidsdjwt.EU_PID_SD_JWT_METADATA_URL
import at.asitplus.wallet.mdl.MDL_METADATA_URL
import at.asitplus.wallet.lib.LibraryInitializer
import at.asitplus.wallet.lib.data.StaticCredentialMetadataRegistry
import at.asitplus.wallet.mdl.MobileDrivingLicenceItemValueSerializerMap
import at.asitplus.wallet.mdl.MobileDrivingLicenceJsonValueEncoder
import at.asitplus.wallet.mdl.MobileDrivingLicenceMetadataDocument
import at.asitplus.wallet.sdjwt.SdJwtTypeMetadataDocumentRegistry
import at.asitplus.wallet.sdjwt.SdJwtVcType
import de.infix.testBalloon.framework.core.TestSession
import io.github.aakira.napier.DebugAntilog
import io.github.aakira.napier.Napier
Expand All @@ -30,9 +32,9 @@ class TestConfig : TestSession(
MobileDrivingLicenceMetadataDocument,
),
documentUrls = mapOf(
SdJwtVcType(EuPidSdJwtMetadataDocument.first.string) to "https://example.com",
SdJwtVcType(EuPidMetadataDocument.first.string) to "https://example.com",
SdJwtVcType(MobileDrivingLicenceMetadataDocument.first.string) to "https://example.com",
EuPidSdJwtMetadataDocument.first to EU_PID_SD_JWT_METADATA_URL,
EuPidMetadataDocument.first to EU_PID_METADATA_URL,
MobileDrivingLicenceMetadataDocument.first to MDL_METADATA_URL,
)
)
)
Expand Down
Loading
Loading