Skip to content

Commit

Permalink
Merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
n0900 committed Oct 31, 2024
2 parents ecbc657 + 2f2335a commit 6d14439
Show file tree
Hide file tree
Showing 61 changed files with 1,542 additions and 391 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,33 @@ tbd
- Refactor `AuthenticationRequestParser` to open class `RequestParser`
- New class `ExtendedRequestParser` used to also parse `SignatureRequestParametersFrom`

Release 5.2.0:
- SD-JWT: Validate confirmation claims correctly

Release 5.1.0:
- Drop ARIES protocol implementation, and the `vck-aries` artifact
- Add `credentialScheme` and `subjectPublicKey` to internal `CredentialToBeIssued`
- Refactor `issueCredential` of `Issuer` to directly get the credential-to-be-issued
- Remove now useless interface `IssuerCredentialDataProvider`
- Replace `buildIssuerCredentialDataProviderOverride` in `CredentialIssuer` with `credentialProvider` to extract user information into a credential
- Remove `dataProvider` from `IssuerAgent`s constructor, as it is not needed with the new issuing interface anyway
- Replace `relyingPartyUrl` with `clientIdScheme` on `OidcSiopVerifier`s constructor, to clarify use of `client_id` in requests
- Rename objects in `OpenIdConstants.ProofType`, `OpenIdConstants.CliendIdScheme` and `OpenIdConstants.ResponseMode`
- In all OpenID data classes, serialize strings only, and parse them to crypto data classes (from signum) in a separate property (this increases interop, as we can deserialize unsupported algorithms too)
- Add `publicKeyLookup` function to `DefaultVerifierJwsService` to provide valid keys for JWS objects out-of-band (e.g. when they're not included in the header of the JWS)
- OID4VCI:
- `WalletService` supports building multiple authorization details to request a token for more than one credential
- Remove `buildAuthorizationDetails(RequestOptions)` for `WalletService`, please migrate to `buildScope(RequestOptions)`
- Note that multiple `scope` values may be joined with a whitespace ` `
- ISO: Fix deserializing issuer signed items when element identifiers are read after the element values
- SD-JWT:
- Add implementation of JWT VC issuer metadata, see `JwtVcIssuerMetadata`
- Pass around decoded data with `SdJwtSigned` in several result classes like `VerifyPresentationResult.SuccessSdJwt`
- Rename `disclosures` to `reconstructedJsonObject` in several result classes like `AuthnResponseResult.SuccessSdJwt`
- Correctly implement confirmation claim in `VerifiableCredentialSdJwt`, migrating from `JsonWebKey` to `ConfirmationClaim`
- Change type of `claimValue` in `SelectiveDisclosureItem` from `JsonPrimitive` to `JsonElement` to be able to process nested disclosures
- Implement deserialization of complex objects, including array claims
- Add option to issue nested disclosures, by using `ClaimToBeIssued` recursively, see documentation there

Release 5.0.1:
- Update JsonPath4K to 2.4.0
Expand Down
1 change: 1 addition & 0 deletions conventions-vclib/src/main/kotlin/VcLibConventions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ inline fun KotlinDependencyHandler.commonImplementationDependencies() {
implementation(project.ktor("http"))
implementation(project.napier())
implementation(project.ktor("utils"))
implementation("net.orandja.obor:obor:${VcLibVersions.obor}")
}

/**
Expand Down
1 change: 1 addition & 0 deletions conventions-vclib/src/main/kotlin/VcLibVersions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ object VcLibVersions {
val signum get() = versionOf("signum")
val supreme get() = versionOf("supreme")
val jsonpath get() = versionOf("jsonpath")
val obor get() = versionOf("obor")
val eupidcredential get() = versionOf("eupid")
val mdl get() = versionOf("mdl")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ jvm.json=20230618
jvm.cbor=1.18
eupid=2.2.0
mdl=1.1.0
obor=2.1.3

android.compileSDK=34
android.minSDK=33
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package at.asitplus.dif

import at.asitplus.signum.indispensable.josef.JsonWebAlgorithm
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient

/**
* Data class for
* [DIF Presentation Exchange v1.0.0](https://identity.foundation/presentation-exchange/spec/v1.0.0/#presentation-definition)
*/
@Serializable
data class FormatContainerJwt(
// TODO make this a collection of Json Web Algorithms from kmp-crypto
@SerialName("alg")
val algorithms: Collection<String>? = null,
)
val algorithmStrings: Collection<String>? = null,
) {
@Transient
val algorithms: Set<JsonWebAlgorithm>? = algorithmStrings
?.mapNotNull { s -> JsonWebAlgorithm.entries.firstOrNull { it.identifier == s } }?.toSet()

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ data class FormatHolder(
val jwtVp: FormatContainerJwt? = null,
@SerialName("jwt_vc")
val jwtVc: FormatContainerJwt? = null,
/**
* Deprecated, unofficial value, please use [jwtSd]
*/
@SerialName("jwt_sd")
val jwtSdDeprecated: FormatContainerJwt? = null,
@SerialName("vc+sd-jwt")
val jwtSd: FormatContainerJwt? = null,
@SerialName("ldp")
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[versions]
kmmresult = "1.8.0!!"
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package at.asitplus.openid

import at.asitplus.KmmResult
import at.asitplus.KmmResult.Companion.wrap
import at.asitplus.signum.indispensable.josef.JsonWebKeySet
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString

/**
* Metadata about the credential issuer in
* [SD-JWT VC](https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-05.html)
*
* To be serialized into JSON and made available at `/.well-known/jwt-vc-issuer` at the credential issuer.
*/
@Serializable
data class JwtVcIssuerMetadata(
/**
* REQUIRED. The Issuer identifier, which MUST be identical to the `iss` value in the JWT.
*/
@SerialName("issuer")
val issuer: String,

/**
* OPTIONAL. Issuer's JSON Web Key Set (RFC7517) document value, which contains the Issuer's public keys.
* The value of this field MUST be a JSON object containing a valid JWK Set.
*/
@SerialName("jwks")
val jsonWebKeySet: JsonWebKeySet? = null,

/**
* OPTIONAL. URL string referencing the Issuer's JSON Web Key (JWK) Set (RFC7517) document which contains the
* Issuer's public keys. The value of this field MUST point to a valid JWK Set document.
*/
@SerialName("jwks_uri")
val jsonWebKeySetUrl: String? = null,
) {
fun serialize() = jsonSerializer.encodeToString(this)

companion object {
fun deserialize(input: String): KmmResult<JwtVcIssuerMetadata> =
runCatching { jsonSerializer.decodeFromString<JwtVcIssuerMetadata>(input) }.wrap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ object OpenIdConstants {

const val PATH_WELL_KNOWN_OPENID_CONFIGURATION = "/.well-known/openid-configuration"

const val PATH_WELL_KNOWN_JWT_VC_ISSUER_METADATA = "/.well-known/jwt-vc-issuer"

const val SCOPE_OPENID = "openid"

const val SCOPE_PROFILE = "profile"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,15 @@ import at.asitplus.wallet.lib.agent.*
import at.asitplus.wallet.lib.data.*
import at.asitplus.wallet.lib.data.ConstantIndex.supportsSdJwt
import at.asitplus.wallet.lib.data.ConstantIndex.supportsVcJwt
import at.asitplus.wallet.lib.jws.DefaultJwsService
import at.asitplus.wallet.lib.jws.DefaultVerifierJwsService
import at.asitplus.wallet.lib.jws.JwsService
import at.asitplus.wallet.lib.jws.VerifierJwsService
import at.asitplus.wallet.lib.jws.*
import at.asitplus.wallet.lib.oidvci.*
import com.benasher44.uuid.uuid4
import io.github.aakira.napier.Napier
import io.ktor.http.*
import kotlinx.datetime.Clock
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlin.coroutines.cancellation.CancellationException
import kotlin.time.DurationUnit
Expand Down Expand Up @@ -153,7 +151,7 @@ class OidcSiopVerifier private constructor(
)

private val containerJwt =
FormatContainerJwt(algorithms = verifierJwsService.supportedAlgorithms.map { it.identifier })
FormatContainerJwt(algorithmStrings = verifierJwsService.supportedAlgorithms.map { it.identifier })

val metadata by lazy {
RelyingPartyMetadata(
Expand Down Expand Up @@ -503,9 +501,12 @@ class OidcSiopVerifier private constructor(
* Successfully decoded and validated the response from the Wallet (W3C credential in SD-JWT)
*/
data class SuccessSdJwt(
val jwsSigned: JwsSigned,
val sdJwtSigned: SdJwtSigned,
val verifiableCredentialSdJwt: VerifiableCredentialSdJwt,
@Deprecated("Renamed to verifiableCredentialSdJwt", replaceWith = ReplaceWith("verifiableCredentialSdJwt"))
val sdJwt: VerifiableCredentialSdJwt,
val disclosures: List<SelectiveDisclosureItem>,
val reconstructed: JsonObject,
val disclosures: Collection<SelectiveDisclosureItem>,
val state: String?,
) : AuthnResponseResult()

Expand Down Expand Up @@ -672,6 +673,7 @@ class OidcSiopVerifier private constructor(
else -> throw IllegalArgumentException()
}

@Suppress("DEPRECATION")
private fun Verifier.VerifyPresentationResult.mapToAuthnResponseResult(state: String) = when (this) {
is Verifier.VerifyPresentationResult.InvalidStructure ->
AuthnResponseResult.Error("parse vp failed", state)
Expand All @@ -690,8 +692,14 @@ class OidcSiopVerifier private constructor(
.also { Napier.i("VP success: $this") }

is Verifier.VerifyPresentationResult.SuccessSdJwt ->
AuthnResponseResult.SuccessSdJwt(jwsSigned, sdJwt, disclosures, state)
.also { Napier.i("VP success: $this") }
AuthnResponseResult.SuccessSdJwt(
sdJwtSigned,
verifiableCredentialSdJwt,
sdJwt,
reconstructedJsonObject,
disclosures,
state
).also { Napier.i("VP success: $this") }
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ internal class PresentationFactory(

private fun FormatHolder.isMissingFormatSupport(claimFormatEnum: ClaimFormatEnum) =
when (claimFormatEnum) {
ClaimFormatEnum.JWT_VP -> jwtVp?.algorithms?.let { !it.contains(jwsService.algorithm.identifier) }
ClaimFormatEnum.JWT_VP -> jwtVp?.algorithms?.let { !it.contains(jwsService.algorithm) }
?: false

ClaimFormatEnum.JWT_SD -> jwtSd?.algorithms?.let { !it.contains(jwsService.algorithm.identifier) }
ClaimFormatEnum.JWT_SD -> jwtSd?.algorithms?.let { !it.contains(jwsService.algorithm) }
?: false

ClaimFormatEnum.MSO_MDOC -> msoMdoc?.algorithms?.let { !it.contains(jwsService.algorithm.identifier) }
ClaimFormatEnum.MSO_MDOC -> msoMdoc?.algorithms?.let { !it.contains(jwsService.algorithm) }
?: false

else -> false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import at.asitplus.signum.indispensable.CryptoPublicKey
import at.asitplus.signum.indispensable.cosef.CborWebToken
import at.asitplus.signum.indispensable.cosef.CoseSigned
import at.asitplus.signum.indispensable.io.Base64UrlStrict
import at.asitplus.signum.indispensable.josef.JsonWebKeySet
import at.asitplus.signum.indispensable.josef.JsonWebToken
import at.asitplus.signum.indispensable.josef.JwsSigned
import at.asitplus.signum.indispensable.pki.X509Certificate
Expand Down Expand Up @@ -59,6 +60,7 @@ class CredentialIssuer(
) {
/**
* Serve this result JSON-serialized under `/.well-known/openid-credential-issuer`
* (see [OpenIdConstants.PATH_WELL_KNOWN_CREDENTIAL_ISSUER])
*/
val metadata: IssuerMetadata by lazy {
IssuerMetadata(
Expand All @@ -73,6 +75,17 @@ class CredentialIssuer(
)
}

/**
* Serve this result JSON-serialized under `/.well-known/jwt-vc-issuer`
* (see [OpenIdConstants.PATH_WELL_KNOWN_JWT_VC_ISSUER_METADATA])
*/
val jwtVcMetadata: JwtVcIssuerMetadata by lazy {
JwtVcIssuerMetadata(
issuer = publicContext,
jsonWebKeySet = JsonWebKeySet(setOf(issuer.keyMaterial.jsonWebKey))
)
}

/**
* Offer all [credentialSchemes] to clients.
*
Expand Down
Loading

0 comments on commit 6d14439

Please sign in to comment.