Skip to content

8.0.0

Choose a tag to compare

@nodh nodh released this 01 Oct 08:43

New features:

  • Generate holder-side ISO mDoc zero-knowledge proofs through pluggable backends, including the new vck-longfellow module.
  • Present mDocs through direct ISO 18013-5 Device Retrieval, including matching and multi-document responses.
  • Use encrypted OpenID4VP authorization requests and request-specific keys for encrypted presentation responses.
  • Encrypt OpenID4VCI credential requests and responses with keys bound to each credential request.
  • Configure trust for credential issuers and relying parties, including WRPAC and WRPRC validation for EU wallet presentations.
  • Filter EU Lists of Trusted Entities by profile and provide trust anchors for issuers and status list signers.
  • Use OAuth 2.0 attestation-based client authentication Draft 10, combined DPoP proofs, and transaction codes in pre-authorized issuance flows.

Technical changes and migration notes:

  • Build:
    • Upgrade the Android JVM target to 17 for compatibility with vck-longfellow
    • Upgrade to the 20260828 conventions plugin and AGP 9
    • Migrate Android library targets to the new Kotlin Multiplatform Android library plugin API
    • Remove the conventions plugin submodule and version catalog workarounds
    • Remove obsolete build hacks
  • ETSI data classes:
    • Normalize decoded RFC 5646 language tags to lowercase instead of rejecting non-lowercase input
    • Add WalletRelyingParty ETSI data classes for WRPAC and WRPRC validation
  • ISO mdoc data classes:
    • BREAKING: Update ZkDocumentData.timestamp type to Instant instead of DateTime to conform to upcoming ISO-18013-5 draft
    • Add support for correctly (de-)serializing RFC9360-conformant single-chain cbor-encoded ZkDocumentData
    • Add missing equality overrides for ZkDocumentData, ZkSignedItem
  • Openid data classes:
    • Add fields eUWrprc and euWrpRegistrarInfo to data class DocRequestInfo
  • ISO mDoc Zero-Knowledge Proofs:
    • Add the ZkRequest-based ISO mDoc ZK presentation path and convert DCQL ZK metadata into ZkRequest for holder-side proof generation
    • Add the IsoMdocZkBackend, IsoMdocZkBackendRegistry, IsoMdocZkEngine, and IsoMdocZkProof extension layer
      for application- and library-provided proving systems
    • Add holder-side ZK proof generation and optional plain-mDoc fallback through VerifiablePresentationFactory
    • Add backend routing for ISO mDoc ZK system specifications, including application-defined proving systems and
      backend-specific parameter serializers
    • BREAKING: Rename ZkSystemSpec.zkSystemId to id while retaining zkSystemId on the wire
    • Rename ZkMetadata.IsoMdocZk.zkInfo to zkRequest, change DCQL ZK numeric parameters from Int to Long,
      and update the ZK integration APIs to use ZkSystemSpec
    • Remove the unused ZkInfo and ZkSystem preparation abstractions
    • Add vck-longfellow module containing an implementation of a registerable Longfellow-ZK backend
  • Credentials:
    • In SubjectCredentialStore.StoreEntry make the schemeIdentifier non-nullable. Deserialization of old previously stored entries need to be handled by calling applications.
    • Derive SD-JWT Digital Credentials API identifiers from the JWT ID or serialized credential instead of the subject
    • Preserve and validate every status mechanism when a credential's status object contains both status_list and identifier_list; combined values are exposed through StatusListInfo.tokenStatusInfo while the 7.0.1 RevocationListInfo properties and singleton behavior remain compatible
  • Verifiable Presentations:
    • Compute ISO mDoc DeviceAuthentication signatures automatically using the calcIsoSessionTranscript callback instead of requiring calcIsoDeviceSignaturePlain
    • Replace PresentationRequestParameters.calcIsoDeviceSignaturePlain with the PresentationRequestParameters.calcIsoSessionTranscript callback to return a nullable SessionTranscript. DeviceSignature and DeviceAuth is now calculated based on the Transcript.
    • Add optional signDeviceAuthDetached parameter to HolderAgent and VerifiablePresentationFactory to centralize ISO mDoc device authentication within the holder
  • OpenID for Verifiable Presentations:
    • Deprecate Presentation Exchange APIs in favor of DCQL, since OpenID4VP 1.0 only supports DCQL
    • Implement direct presentation requests and responses according to ISO 18013-5 Device Retrieval with new subtypes CredentialPresentationRequest.IsoDeviceRetrieval, CredentialPresentation.IsoDeviceRetrievalPresentation, IsoDeviceRetrievalMatchingResult for CredentialMatchingResult, HolderIsoDeviceRetrievalQueryMatchingResult for HolderPresentationRequestMatchingResult, and PresentationResponseParameters.DeviceRetrievalParameters
    • Add DeviceRequestCredentialDisclosure, IsoDeviceRetrievalQueryMatchingResult, IsoDeviceRetrievalCredentialMatch, and IsoDeviceRetrievalClaimMatch for ISO submission and matching details
    • Match every DocRequest against stored mdocs, requiring all requested data elements while preserving repeated docTypes and multiple matching credentials; validate explicit submissions and create a single, possibly multi-document DeviceResponse
    • Keep direct ISO Device Retrieval responses separate from OpenID4VP vp_token responses, and fix JSON round trips for ISO presentation requests
    • Migrate ISO/IEC 18013-7 Annex C holder and iOS pre-request matching from Presentation Exchange to ISO Device Retrieval; replace IosDcApiMdocPreRequestSummary.toDifInputDescriptors() with toDeviceRequest()
    • Add Holder.matchPresentationRequestAgainstCredentialStore() as a protocol-neutral matching entry point and move CredentialMatchingResult with its DCQLMatchingResult, IsoDeviceRetrievalMatchingResult, and deprecated PresentationExchangeMatchingResult subtypes from vck-openid to vck
    • Use correct digest for validating KB JWT of SD-JWT VC
    • Extract format-specific submission resolution, validation, and response creation from HolderAgent into an internal presentation response coordinator
    • Deprecate format specific methods in Holder, all to be replaced with matchPresentationRequestAgainstCredentialStore(): matchInputDescriptorsAgainstCredentialStoreV2(), matchDeviceRetrievalAgainstCredentialStore(), evaluateInputDescriptorAgainstCredential(), matchDCQLQueryAgainstCredentialStoreV2()
    • Match non-fully specified COSE algorithms with fully specified ones
    • Reject credential presentations containing any invalid issuer signed items according to ISO 18013-5 9.3.1 Inspection procedure for issuer data authentication
    • Correctly validate credential submissions for DCQL queries
    • Add VerifierInfo to OpenId4VpRequestOptions
    • Do not accept responses for the same state twice for OpenID4VP flows
    • Do not accept responses for the same externalId twice for DCAPI flows
    • Supply an ephemeral response encryption key specific to each authentication request in its client metadata, as required by OpenID4VP 1.0, Section 8.3, and OpenID4VC HAIP. Keys are identified by the kid of the JWE, and also used as the HPKE recipient key for ISO/IEC 18013-7 Annex C requests, where they are identified by the request's state
    • Add EphemeralEncryptionKeyService holding these keys in a MapStore<String, String>, PKCS#8 PEM encoded, so that applications running several instances can synchronize them, along with the parameter ephemeralEncryptionKeyService on OpenId4VpVerifier and DcApiVerifier. Every key decrypts at most one response
    • Add DecryptJweWithEphemeralKey, resolving the decryption key from the kid header of the JWE
    • In OpenId4VpVerifier and DcApiVerifier the decryptionKeyMaterial is now nullable and defaults to null: it is only advertised in metadataWithEncryption, i.e. for client identifier schemes that distribute it out-of-band, which is not conformant to HAIP. metadata carries no key to encrypt responses to at all
    • In OpenId4VpVerifier and DcApiVerifier remove the decryptJwe function from the list of constructor arguments
    • Consume the request's nonce when validating an authentication response, regardless of the validation result, i.e. authentication responses are not retryable
    • Support requesting and serving encrypted authorization requests as per OpenID4VP 1.0, Section 5.10
    • Add jwks, request_object_encryption_alg_values_supported and request_object_encryption_enc_values_supported to OAuth2AuthorizationServerMetadata
    • Fix decoding of form-encoded parameters whose value is a JSON string, e.g. wallet_metadata posted to the request URI endpoint
    • Send wallet_metadata and wallet_nonce only when fetching the request object with request_uri_method=post
    • Terminate request processing if the request object does not carry back the wallet_nonce we sent, as required by OpenID4VP 1.0, Section 5.10.1
    • Reject a JAR request whose request object can not be retrieved from request_uri, that carries neither request nor request_uri, or whose request object nests another request/request_uri (RFC 9101, Section 6.2), with invalid_request in RequestParser
    • Retain the underlying payload deserialization failure as the cause of invalid_request when parsing a structurally valid signed request object
    • In OpenId4VpHolder reject requests that are not authorization requests, e.g. RQES signature requests, with invalid_request instead of failing with a ClassCastException during request validation
    • Pass requireEncryptedRequests = true to OpenId4VpHolder to reject a plain request object served at a request_uri fetched with POST
    • Add decryptedFrom to RequestParametersFrom.Jws and RequestParametersFrom.Json, holding the header of the JWE a request was decrypted from, and requestWasEncrypted to AuthorizationResponsePreparationState
    • Reject request objects that are not a JWS (and optionally encrypted) per RFC 9101, Section 4
    • Reject request objects that do not carry typ: oauth-authz-req+jwt as required by OpenID4VP 1.0, Section 5, also for signed and multi-signed requests over the DC API
    • Deprecate CreationOptions.RequestByReference at error level: it serves an unsigned request object by reference, which OpenID4VP 1.0, Section 5.10.1 forbids, instead use CreationOptions.SignedRequestByReference
  • OpenID for Verifiable Credential Issuance:
    • Preserve credential-offer retrieval failures instead of masking them with a JSON parsing error
    • Rework validation of key attestation statements
    • In ProofValidator replace the unreleased keyAttestationIssuer with verifyKeyAttestationSignature to accept key attestations of trusted wallet providers, e.g. with VerifyJwsObjectTrustedCertificate; key attestations are rejected unless a trusted verifier is configured
    • Sign metadata in CredentialIssuer.signedMetadata() as per OpenID4VCI 1.0, Section 12.2.3, i.e. with typ set to openidvci-issuer-metadata+jwt and the claims sub and iat, added as subject, issuedAt and expiration to IssuerMetadata
    • Add displayProperties to CredentialIssuer, to include them in both metadata and signedMetadata()
    • Make sure a nonce provided by the credential issuer can only be used for one request to the credential endpoint
    • Security fix: encrypt the credential request whenever it carries credential_response_encryption, as required by OpenID4VCI 1.0, i.e. "Credential Request encryption MUST be used if the credential_response_encryption parameter is included, to prevent it being substituted by an attacker". WalletEncryptionService previously sent its response encryption key in a plain request unless request encryption was required by either side, and CredentialIssuer accepted such requests
    • In WalletEncryptionService, if the issuer publishes no key to encrypt the request with, credential_response_encryption is omitted, or the request fails if the issuer requires response encryption
    • Announce a response encryption key specific to each credential request, with a kid for the issuer to echo in the JWE header. Replace WalletEncryptionService.decryptionKeyMaterial with ephemeralEncryptionKeyService, which may hold a MapStore to synchronize these keys between the wallet component creating the request and the one receiving the response
    • Bind encrypted credential responses to their originating CredentialRequest, reject encryption downgrades and response/request key swaps, and consume a response key only after authenticated decryption. Parsing an encrypted response now requires passing the originating request to WalletService.parseCredentialResponse
    • Negotiate credential response alg and enc strictly against issuer metadata: omit optional encryption when no combination is shared, fail when encryption is required, and reject algorithms the issuer did not advertise
    • IssuerEncryptionService advertises credential_response_encryption whenever it can encrypt responses, and credential_request_encryption whenever it can decrypt requests, instead of only when some encryption is required, so that clients can opt into encryption. Requiring response encryption now also declares credential_request_encryption.encryption_required, since the client's key may only be sent in an encrypted request
    • Select the issuer's credential request encryption key by its intended use instead of taking the first key of the set, and use the alg of the client's response encryption key for the JWE, as required by OpenID4VCI 1.0
  • Signature verification:
    • VerifyJwsObject and VerifyCoseSignature now only ever use the key material asserted by the JWS header resp. the COSE headers, and make no trust decision
    • Add VerifyJwsObjectTrusted and VerifyCoseSignatureTrusted, where the supplied keys are the only accepted signers
    • Note that neither builds a certificate path to a trust anchor, they compare public keys
    • In ValidatorSdJwt.verifyVpSdJwt() reject presentations whose SD-JWT carries no cnf: the key binding JWT used to be verified against a key asserted in its own header in that case, which proves nothing about the holder
    • Delegate ISO mDoc device authentication calculation directly to the holder during OpenID4VP and DCAPI presentation creation
  • Trusted issuers:
    • Accept an exactly listed, CA-issued end-entity certificate as a direct credential signer, without requiring it to be self-signed
    • Add TrustedCertificates, supplying the certificates of the parties to trust, e.g. extracted from an ETSI trust list with LoTEFilterService
    • Add VerifyJwsObjectTrustedCertificate and VerifyCoseSignatureTrustedCertificate, requiring the certificate transported with a credential to be signed by one of the trusted issuer certificates.
    • The certificate of the trust anchor must be known out-of-band, so no trusted certificate may be transported with the credential, and the signing certificate must not be self-signed.
    • Add a trustedIssuers parameter to VerifierAgent and HolderAgent, which builds validators enforcing it for issuer signatures on SD-JWT, VC-JWS and mdoc credentials.
    • Use issuerJwsVerifier() and issuerCoseVerifier() to wire it into validators directly, and pass VerifyJwsObjectTrustedCertificate as verifyJwsObjectIntegrity of TokenStatusResolverImpl resp. as verifyJwsObject of ClientAuthenticationService for status list tokens and client attestations, which are separate trust domains
    • In VerifyStatusListTokenHAIP implement the certificate checks. Replace trustStoreLookup with trustedIssuers, and deprecate the now unused TrustStoreLookup.
    • In VerifyStatusListTokenHAIP fix the check that the signing certificate must not be self-signed
  • Trusted relying parties:
    • Add RelyingPartyTrust, a sealed interface with one subtype per client identifier scheme, configuring how a wallet establishes trust in the relying party sending an authorization request, and a relyingPartyTrust parameter taking a Set of them on OpenId4VpHolder and on OpenId4VpWallet. Several sources of the same kind form a union, i.e. trust established by any one of them is enough, so e.g. a trust list may sit next to a locally pinned certificate. Passing null trusts every relying party, an empty set trusts none
    • AuthorizationRequestValidator now verifies the signature of a signed request object, for JwsCompact as well as for multi-signed JwsGeneral requests.
    • For x509_san_dns and x509_hash, validate the x5c chain against RelyingPartyTrust.Certificates
    • Implement the verifier_attestation client identifier scheme
    • Enforce the pre-registered client identifier scheme against RelyingPartyTrust.PreRegisteredClients
    • Requests using a scheme for which no trust material is configured are rejected. This includes entity_id and did, which are handed to RelyingPartyTrust.Custom and rejected when none is configured, so that a relying party cannot bypass the configured trust anchors by naming itself with a scheme this library does not evaluate natively. Only redirect_uri is not covered, as it forbids signed requests anyway
    • RequestParser no longer verifies anything and lost its requestObjectJwsVerifier parameter, so parsing a request is purely parsing. Consequently RequestParametersSigned.verified is removed, with the verified property of Jws, OpenId4VpDcApiSigned and OpenId4VpDcApiMultiSigned and its serialized form. Stored JSON still carrying "verified" deserializes fine, as unknown keys are ignored
    • Add WrprcValidator, WrpacValidator, WrpAuthenticationRequestValidator and WrpChainValidator to validate WRPAC and WRPRC during presentation.
    • Verify ISO mdoc readerAuth/readerAuthAll against the session transcript before accepting a WRPAC from the request. ISO mdoc validation now uses a suspend WrpAuthenticationRequestValidator.invoke overload requiring a SessionTranscript; IsoMdocDcApi.validateWrpAuthenticationRequest() calculates it from the DC API request. Remove the unauthenticated DeviceRequest.extractCertificateChain() helper.
    • DcApiVerifier signs readerAuth of every ISO 18013-7 Annex C document request with its key material, when that has a certificate, transporting the chain of the certificate-based client identifier scheme. Pass the CBOR-encoded WRPRC in the new OpenId4VpRequestOptions.euWrprc to set it in the DocRequestInfo of every document request.
  • Trust List filtering:
    • Replace LoTEServiceType/LoTEFilterCriteria with LoteProfile, a sealed class defining PID, mDL, WRPAC, WALLET, and EAA profiles with built-in matching against scheme type, status approach, community rules URIs, and country code
    • Add support for LoTEs with issuance and revocation certificates
    • Add LoTEStage, enumerating the base URLs of the European Commission's development, acceptance, and production trust infrastructure, so that applications can fetch the lists of any stage
    • Replace the hardcoded acceptance URL in LoteProfile.fetchUrl with the relative LoteProfile.fileName, resolved against a base URL by LoteProfile.fetchUrl(baseUrl) or LoteProfile.fetchUrl(stage)
    • Replace LoteProfile.defaultUrls with LoteProfile.entries and LoteProfile.fetchUrls(), which take the stages or the base URL to fetch from
    • Add TrustAnchorProvider which lets apps supply trust anchors per credential type (vct/doctype) or per LoteProfile, for issuers as well as for status list signers (JWT and CWT)
  • Form-url-encoded parameters:
    • Preserve opaque string parameters when decoding polymorphic requests, and ignore unknown object parameters before parsing their values as JSON
    • Use RequestParametersSerializer.decodeFormParameters() to decode form parameters whose concrete request type is determined by their parameter names
    • Extract the sketch in SerializerSketch.kt of vck-openid into a documented API in FormUrlEncoding.kt, covered by FormUrlEncodingTest
    • Move it from at.asitplus.wallet.lib.oidvci in vck-openid to at.asitplus.openid in openid-data-classes, next to the parameter classes it encodes, since it is specific to neither issuance nor presentation. The previous declarations remain as deprecated forwarders
    • Rename Parameters to FormParameters, to disambiguate it from io.ktor.http.Parameters
    • Replace String.decodeFromPostBody() and String.decodeFromUrlQuery(), which were two names for the same thing, with String.decodeFromFormUrlEncoded()
    • Add Url.decodeFromQuery(), Url.decodeFromFragment() and Url.decodeFromFragmentOrQuery(), which read the parameters off a URL instead of leaving that to callers
    • Add T.encodeToFormUrlEncoded() and String.toFormParameters()
    • Deprecate FormParameters.decodeFromUrlQuery(): its receiver is already decoded in nearly all call sites, so it decoded percent-encoding a second time and mangled every value containing a percent sign. This fixes parsing credential offers, authentication requests and authentication responses carrying such values
    • Split the payload with io.ktor.http.parseQueryString() instead of by hand, which drops names without a value instead of throwing, and reads + as a space in URL queries too
  • OAuth 2.0:
    • Update implementation of OAuth 2.0 Attestation-Based Client Authentication to Draft 10 from 2026-07-06
    • Support DPoP combined mode, advertised with dpop_combined in client_attestation_pop_methods_supported to combine client authentication with DPoP proofs from RFC 9449
    • Support DPoP combined mode on the client side in OAuth2KtorClient
    • Add method attestationChallenge() to SimpleAuthorizationService to deliver challenges for Attestation-Based Client Authentication
    • Support use_client_attestation errors and parse challenges from OAuth-Client-Attestation-Challenge in OAuth2KtorClient
    • Strengthen validation of DPoP proofs from OAuth 2.0 Demonstrating Proof of Possession (DPoP)
    • Validate the access token in SimpleAuthorizationService.getUserInfo() before returning any user info, i.e. it now behaves the same as userInfo(). Previously the token was only parsed, so neither its signature, nor its expiration, nor the DPoP proof were verified
    • Compare scopes as space-delimited values instead of substrings, when issuing access tokens in SimpleAuthorizationService and when authorizing credential requests in CredentialIssuer
    • Authorize several credential requests with a single JWT access token
    • Add TokenService.validateAccessToken(), which validates the access token and resolves the user info stored at issuance
    • Bind client authentication to internal state to prevent client mismatches in subsequent requests
    • Add dpopKeyMaterial as explicit constructor argument to OAuth2KtorClient
    • Enforce require_pushed_authorization_requests in SimpleAuthorizationService.authorize() as mandated by RFC 9126, Section 4
    • Require PKCE with code_challenge_method=S256 on every authorization request, as mandated by OpenID4VC HAIP, and advertise it in code_challenge_methods_supported
    • Make CodeService.provideCode() and CodeService.verifyAndRemove() suspending functions, and implement DefaultCodeService on top of NonceService, so codes are stored thread-safely and expire.
    • Keep authorization codes, pre-authorized codes and issuer_state values in separate stores in SimpleAuthorizationService
    • Make OAuth 2.0 Token Exchange opt-in with the new supportTokenExchange constructor argument of SimpleAuthorizationService, defaulting to false, and only advertise the grant in grant_types_supported when it is enabled.
    • Add OAuth2Exception.UnsupportedGrantType for the unsupported_grant_type error of RFC 6749
    • Restrict pre-authorized codes to the credential configuration IDs of the offer they belong to, tracked in the new ClientAuthRequest.configurationIds.
    • Support OID4VCI transaction codes for the pre-authorized code flow, with the new transactionCode parameters of SimpleAuthorizationService.offerWithPreAuthnForUserForSchemes() and providePreAuthorizedCode().
    • Return null from CredentialAuthorizationServiceStrategy.filterScope() when no requested scope is supported to trigger invalid_scope error
    • Grant only the scopes the authorization server accepted: SimpleAuthorizationService keeps the filtered scope with the authorization code
    • Implement validScopes() and filterScope() in QtspAuthorizationServiceStrategy for the CSC scopes service and credential, which the delegate CredentialAuthorizationServiceStrategy does not know
  • Deprecations:
    • Remove code deprecated in 7.0.0, e.g. various Iso180137AnnexC* and related classes
    • Deprecate all classes used for Presentation Exchange requests and so on, e.g., CredentialPresentationRequest.PresentationExchangeRequest or PresentationExchangeCredentialDisclosure or CredentialPresentation.PresentationExchangePresentation
    • Deprecate member invalidItems in IsoDocumentParsed, method ValidatorMdoc.verifyDocument() will throw instead of filling invalid items
    • In ProofValidator deprecate constructor argument verifyAttestationProof, replace with statusListTokenResolver and verifyKeyAttestationSignature
    • In NonceChallengeVerifier deprecate verifyPresentationSdJwt(), verifyPresentationVcJwt() and verifyPresentationIsoMdoc(), which take the challenge from the presentation itself, to be replaced with consumeChallenge() and the returned ChallengeSession
    • NonceChallengeVerifier does not implement Verifier and NonceService anymore, so a presentation cannot be verified without accounting for the challenge it answers; use the ChallengeSession from consumeChallenge(), or the properties verifier for challenge-free verification and nonceService for raw nonce access
    • Deprecate passing publicKeyLookup to VerifyJwsObject and VerifyCoseSignature, callers are rerouted to the trusted variants, use VerifyJwsObjectTrusted resp. VerifyCoseSignatureTrusted explicitly, or drop the parameter to keep verifying against the asserted key
    • Deprecate PresentationRequestParameters.calcIsoDeviceSignaturePlain in favor of computing device signatures automatically via calcIsoSessionTranscript
    • Deprecate the NonceChallengeVerifier.createPresentationRequest() overload accepting calcIsoDeviceSignaturePlain
    • Deprecate signDeviceAuthDetached parameter in buildEncryptedResponse(), OpenId4VpHolder, and Iso180137AnnexCHolder, as device authentication signature functions are now managed internally by the holder
    • Deprecate TrustStoreLookup, as trusted certificates are not selected per signed object, replaced by TrustedCertificates
    • Deprecate RequestObjectJwsVerifier and the requestObjectJwsVerifier parameter of OpenId4VpHolder, superseded by RelyingPartyTrust. It is no longer invoked: verifying a request object needs to know where to load the relying party's key from, which depends on the client identifier scheme, so it moved to AuthorizationRequestValidator. Supplying one now logs a warning and has no effect, so migrate to relyingPartyTrust — RelyingPartyTrust.PreRegisteredClients for the pre-registered case, RelyingPartyTrust.Custom for schemes this library does not evaluate natively. To be removed in 9.0.0
    • Deprecate ClientAuthenticationService.verifyClientAttestationJwt, which never validated the x5c it required; pass VerifyJwsObjectTrustedCertificate with the trusted wallet provider certificates as verifyJwsObject instead
    • Deprecate constructor in RequestInfo taking single values for some HTTP headers, replace with constructor taking in all HTTP headers
    • Deprecate constructor parameter enforceClientAuthentication in AttestationBasedClientAuthenticationService as the new default is true. Callers might use a NoopClientAuthenticationService
    • Deprecate TokenService.readUserInfo(), since it does not prove possession of the key the access token is bound to. Replace with TokenService.validateAccessToken(), which validates the access token including the DPoP proof and returns the user info in ValidatedAccessToken.userInfoExtended
    • Deprecate constructor parameter signDpop in OAuth2KtorClient, replace by setting dpopKeyMaterial
    • Deprecate LoTEFilterCriteria and LoTEServiceType, replace by LoteProfile
    • Deprecate LoTEFilterService.extractTrustedCertificates(), replace by LoTEFilterService.extractIssuanceCertificates() and LoTEFilterService.extractRevocationCertificates()
  • Refactorings:
    • In MdocInputValidator and ValidatorMdoc replace verifyCoseSignatureWithKey with a VerifyCoseSignatureFun<MobileSecurityObject>, which resolves the issuer key from the COSE headers itself. Consequently MdocInputValidator.invoke() and ValidatorMdoc.verifyIsoCred() lose their issuerKey parameter, MdocInputValidationSummary.IntegrityValidationSummary.IntegrityValidationResult loses its issuerKey property, and IntegrityNotValidated is removed
    • ValidatorMdoc.verifyDocument() no longer extracts the issuer certificate itself, but delegates to MdocInputValidator like the credential path does
    • Remove requestObjectVerified from AuthorizationResponsePreparationState: request verification is enforced in AuthorizationRequestValidator, which every holder flow passes through, so the flag had no remaining job. It could never be satisfied for signed DC API requests anyway, since nothing ever set it
    • In ISO data classes like DeviceResponse, DeviceRequest, MobileSecurityObject replace the String version with a typed parsedVersion from kotlin-semver
    • In ISO data class MobileSecurityObject replace the String digestAlgorithm with a typed digest from Signum
    • In CredentialToBeIssued.Iso add a property to specify the digest algorithm to be used in the MSO
    • Add method getCertificateChain to class KeyStoreMaterial
    • In NonceChallengeVerifier add consumeChallenge(), which consumes the challenge of the request an authentication response refers to and returns a NonceChallengeVerifier.ChallengeSession to verify all presentations of that response with, as used by OpenId4VpVerifier and DcApiVerifier
    • Add main constructor to RequestInfo that takes in all HTTP headers for future extensions to client authentication methods
    • Rename existing ClientAuthenticationService to AttestationBasedClientAuthenticationService and extract an interface
    • Return the validated token from validateAccessToken() in TokenVerificationService and OAuth2AuthorizationServerAdapter as ValidatedAccessToken, and move validCredentialIdentifiers from TokenInfo to ValidatedAccessToken
    • Authorize credential requests in CredentialIssuer from the ValidatedAccessToken
    • In EncryptJwe remove keyMaterial as it always relies on ephemeral keys embedded in the JWE header
    • Add SingleClaimReference (moved from Valera)
    • Additional Java-Safe APIs for IssuerMetadata, ClaimDescrption, StatusIssuer, ReferencedTokenStore
  • Dependencies:
    • Update to Signum 3.26.0 for HPKE support
    • Add etsi-data-classes as api dependency to openid-data-classes
    • Bouncy Castle 1.86 on the JVM
    • JsonPath4K 4.0.0