Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ data class CredentialMetadata(
sealed interface CredentialConfiguration : Serializable {
val scope: String?
val cryptographicBindingMethodsSupported: List<CryptographicBindingMethod>
val credentialSigningAlgorithmsSupported: List<String>
val proofTypesSupported: ProofTypesSupported
val credentialMetadata: CredentialMetadata?
}
Expand All @@ -217,27 +216,45 @@ data class Claim(
) : Serializable
}

data class MsoMdocPolicy(val oneTimeUse: Boolean, val batchSize: Int?) : Serializable
/**
* COSE Algorithm value.
*
* @see <a href="https://www.iana.org/assignments/cose/cose.xhtml">CBOR Object Signing and Encryption (COSE)</a>
*/
@JvmInline
value class CoseAlgorithm(val value: Int) : Serializable {
override fun toString(): String = value.toString()
}

/**
* The data of a Verifiable Credentials issued as an ISO MDOC.
*/
data class MsoMdocCredential(
override val scope: String? = null,
override val cryptographicBindingMethodsSupported: List<CryptographicBindingMethod> = emptyList(),
override val credentialSigningAlgorithmsSupported: List<String> = emptyList(),
val isoCredentialSigningAlgorithmsSupported: List<CoseAlgorithm> = emptyList(),
val isoCredentialCurvesSupported: List<CoseCurve> = emptyList(),
val isoPolicy: MsoMdocPolicy?,
val credentialSigningAlgorithmsSupported: List<CoseAlgorithm> = emptyList(),
override val proofTypesSupported: ProofTypesSupported = ProofTypesSupported.Empty,
override val credentialMetadata: CredentialMetadata?,
val docType: String,
) : CredentialConfiguration

/**
* JWS Algorithm Name
*
* @see <a href="https://www.iana.org/assignments/jose/jose.xhtml">JSON Object Signing and Encryption (JOSE)</a>
*/
@JvmInline
value class JwsAlgorithm(val name: String) : Serializable {
override fun toString(): String = name
}

/**
* The data of a Verifiable Credentials issued as an SD-JWT VC.
*/
data class SdJwtVcCredential(
override val scope: String? = null,
override val cryptographicBindingMethodsSupported: List<CryptographicBindingMethod> = emptyList(),
override val credentialSigningAlgorithmsSupported: List<String> = emptyList(),
val credentialSigningAlgorithmsSupported: List<JwsAlgorithm> = emptyList(),
override val proofTypesSupported: ProofTypesSupported = ProofTypesSupported.Empty,
override val credentialMetadata: CredentialMetadata?,
val type: String,
Expand All @@ -249,12 +266,22 @@ data class W3CJsonLdCredentialDefinition(
)

/**
* The data of a W3C Verifiable Credential issued as using Data Integrity and JSON-LD.
* Linked Data Algorithm Identifier
*
* @see <a href="https://w3c-ccg.github.io/ld-cryptosuite-registry/">Linked Data Cryptographic Suite Registry</a>
*/
@JvmInline
value class LinkedDataAlgorithm(val identifier: String) : Serializable {
override fun toString(): String = identifier
}

/**
* The data of a W3C Verifiable Credential issued using Data Integrity and JSON-LD.
*/
data class W3CJsonLdDataIntegrityCredential(
override val scope: String? = null,
override val cryptographicBindingMethodsSupported: List<CryptographicBindingMethod> = emptyList(),
override val credentialSigningAlgorithmsSupported: List<String> = emptyList(),
val credentialSigningAlgorithmsSupported: List<LinkedDataAlgorithm> = emptyList(),
override val proofTypesSupported: ProofTypesSupported = ProofTypesSupported.Empty,
override val credentialMetadata: CredentialMetadata?,
val credentialDefinition: W3CJsonLdCredentialDefinition,
Expand All @@ -266,7 +293,7 @@ data class W3CJsonLdDataIntegrityCredential(
data class W3CJsonLdSignedJwtCredential(
override val scope: String? = null,
override val cryptographicBindingMethodsSupported: List<CryptographicBindingMethod> = emptyList(),
override val credentialSigningAlgorithmsSupported: List<String> = emptyList(),
val credentialSigningAlgorithmsSupported: List<LinkedDataAlgorithm> = emptyList(),
override val proofTypesSupported: ProofTypesSupported = ProofTypesSupported.Empty,
override val credentialMetadata: CredentialMetadata?,
val credentialDefinition: W3CJsonLdCredentialDefinition,
Expand All @@ -278,7 +305,7 @@ data class W3CJsonLdSignedJwtCredential(
data class W3CSignedJwtCredential(
override val scope: String? = null,
override val cryptographicBindingMethodsSupported: List<CryptographicBindingMethod> = emptyList(),
override val credentialSigningAlgorithmsSupported: List<String> = emptyList(),
val credentialSigningAlgorithmsSupported: List<JwsAlgorithm> = emptyList(),
override val proofTypesSupported: ProofTypesSupported = ProofTypesSupported.Empty,
override val credentialMetadata: CredentialMetadata?,
val credentialDefinition: CredentialDefinition,
Expand Down
34 changes: 0 additions & 34 deletions src/main/kotlin/eu/europa/ec/eudi/openid4vci/Types.kt
Original file line number Diff line number Diff line change
Expand Up @@ -343,40 +343,6 @@ val CIAuthorizationServerMetadata.clientAttestationPOPJWSAlgs: List<JWSAlgorithm
)
?.mapNotNull { JWSAlgorithm.parse(it) }

@JvmInline
value class CoseAlgorithm(val value: Int) {

companion object {

val ES256 = CoseAlgorithm(-7)
val ES384 = CoseAlgorithm(-35)
val ES512 = CoseAlgorithm(-36)

internal val Names: Map<CoseAlgorithm, String> = mapOf(
ES256 to "ES256",
ES384 to "ES384",
ES512 to "ES512",
)

internal fun byName(name: String): CoseAlgorithm? =
Names.firstNotNullOfOrNull { (alg, knownName) ->
alg.takeIf { knownName == name }
}
}
}

internal fun CoseAlgorithm.name(): String? = CoseAlgorithm.Names[this]

@JvmInline
value class CoseCurve(val value: Int) {

companion object {
val P_256 = CoseCurve(1)
val P_384 = CoseCurve(2)
val P_521 = CoseCurve(3)
}
}

/**
* Nonce (single use) value provided either by the Authorization or Resource server.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ private data class KeyAttestationRequirementTO(
@SerialName("user_authentication") val userAuthentication: List<String>? = null,
)

@Serializable
private data class PolicyTO(
@SerialName("one_time_use") val oneTimeUse: Boolean,
@SerialName("batch_size") val batchSize: Int? = null,
)

/**
* The data of a Verifiable Credentials issued as an ISO mDL.
*/
Expand All @@ -102,10 +96,7 @@ private data class MsdMdocCredentialTO(
@SerialName("cryptographic_binding_methods_supported")
override val cryptographicBindingMethodsSupported: List<String>? = null,
@SerialName("credential_signing_alg_values_supported")
val credentialSigningAlgorithmsSupported: List<JsonPrimitive>? = null,
@SerialName("credential_alg_values_supported") val isoCredentialSigningAlgorithmsSupported: List<JsonPrimitive>? = null,
@SerialName("credential_crv_values_supported") val isoCredentialCurvesSupported: List<Int>? = null,
@SerialName("policy") val isoPolicy: PolicyTO? = null,
val credentialSigningAlgorithmsSupported: List<Int>? = null,
@SerialName("proof_types_supported")
override val proofTypesSupported: Map<String, ProofTypeSupportedMetaTO>? = null,
@SerialName("doctype") @Required val docType: String,
Expand All @@ -120,13 +111,7 @@ private data class MsdMdocCredentialTO(
.map { cryptographicBindingMethodOf(it) }

val proofTypesSupported = proofTypesSupported.toProofTypes()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported
.orEmpty().mapNotNull { it.toCoseAlgorithm()?.name() }
val coseAlgs = isoCredentialSigningAlgorithmsSupported.orEmpty().map {
requireNotNull(it.toCoseAlgorithm()) { "Expecting COSE algorithm, yet got $it" }
}
val coseCurves = isoCredentialCurvesSupported.orEmpty().map { CoseCurve(it) }
val policy = isoPolicy?.let { policy -> MsoMdocPolicy(policy.oneTimeUse, policy.batchSize) }
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty().map { CoseAlgorithm(it) }

if (bindingMethods.isNotEmpty()) {
require(proofTypesSupported.values.isNotEmpty()) {
Expand All @@ -142,9 +127,6 @@ private data class MsdMdocCredentialTO(
scope,
bindingMethods,
cryptographicSuitesSupported,
coseAlgs,
coseCurves,
policy,
proofTypesSupported,
credentialMetadata?.toDomain(),
docType,
Expand Down Expand Up @@ -176,7 +158,7 @@ private data class SdJwtVcCredentialTO(
.map { cryptographicBindingMethodOf(it) }

val proofTypesSupported = proofTypesSupported.toProofTypes()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty().map { JwsAlgorithm(it) }

if (bindingMethods.isNotEmpty()) {
require(proofTypesSupported.values.isNotEmpty()) {
Expand Down Expand Up @@ -237,7 +219,7 @@ private data class W3CJsonLdDataIntegrityCredentialTO(
val bindingMethods = cryptographicBindingMethodsSupported.orEmpty()
.map { cryptographicBindingMethodOf(it) }
val proofTypesSupported = proofTypesSupported.toProofTypes()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty().map { LinkedDataAlgorithm(it) }

if (bindingMethods.isNotEmpty()) {
require(proofTypesSupported.values.isNotEmpty()) {
Expand Down Expand Up @@ -287,7 +269,7 @@ private data class W3CJsonLdSignedJwtCredentialTO(
.map { cryptographicBindingMethodOf(it) }

val proofTypesSupported = proofTypesSupported.toProofTypes()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty().map { LinkedDataAlgorithm(it) }

if (bindingMethods.isNotEmpty()) {
require(proofTypesSupported.values.isNotEmpty()) {
Expand Down Expand Up @@ -348,7 +330,7 @@ private data class W3CSignedJwtCredentialTO(
.map { cryptographicBindingMethodOf(it) }

val proofTypesSupported = proofTypesSupported.toProofTypes()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty()
val cryptographicSuitesSupported = credentialSigningAlgorithmsSupported.orEmpty().map { JwsAlgorithm(it) }

if (bindingMethods.isNotEmpty()) {
require(proofTypesSupported.values.isNotEmpty()) {
Expand Down Expand Up @@ -633,14 +615,6 @@ private fun cryptographicBindingMethodOf(s: String): CryptographicBindingMethod
else -> CryptographicBindingMethod.Other(s)
}

private fun JsonPrimitive.toCoseAlgorithm(): CoseAlgorithm? {
fun Int.toCose() = CoseAlgorithm(this)
fun String.toCoseByName() = CoseAlgorithm.byName(this)
fun String.toCodeByValue() = toIntOrNull()?.toCose()
val strOrNull by lazy { contentOrNull }
return intOrNull?.toCose() ?: strOrNull?.toCodeByValue() ?: strOrNull?.toCoseByName()
}

/**
* Converts and validates [CredentialIssuerMetadataTO] as [CredentialIssuerMetadata] instance.
*/
Expand Down
11 changes: 4 additions & 7 deletions src/test/kotlin/eu/europa/ec/eudi/openid4vci/MockData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ internal fun CredentialIssuerId.metaDataUrl() = HttpsUrl(
internal fun universityDegreeJwt() = W3CSignedJwtCredential(
"UniversityDegree_JWT",
listOf(CryptographicBindingMethod.DID("did:example")),
listOf("ES256K"),
listOf(JwsAlgorithm("ES256K")),
ProofTypesSupported(
setOf(
ProofTypeMeta.Jwt(
Expand Down Expand Up @@ -122,7 +122,7 @@ internal fun universityDegreeJwt() = W3CSignedJwtCredential(
internal fun universityDegreeLdpVc() = W3CJsonLdDataIntegrityCredential(
"UniversityDegree_LDP_VC",
listOf(CryptographicBindingMethod.DID("did:example")),
listOf("Ed25519Signature2018"),
listOf(LinkedDataAlgorithm("Ed25519Signature2018")),
ProofTypesSupported(
setOf(
ProofTypeMeta.Jwt(
Expand Down Expand Up @@ -183,7 +183,7 @@ internal fun universityDegreeLdpVc() = W3CJsonLdDataIntegrityCredential(
internal fun universityDegreeJwtVcJsonLD() = W3CJsonLdSignedJwtCredential(
"UniversityDegree_JWT_VC_JSON-LD",
listOf(CryptographicBindingMethod.DID("did:example")),
listOf("Ed25519Signature2018"),
listOf(LinkedDataAlgorithm("Ed25519Signature2018")),
ProofTypesSupported(
setOf(
ProofTypeMeta.Jwt(
Expand Down Expand Up @@ -247,10 +247,7 @@ internal fun universityDegreeJwtVcJsonLD() = W3CJsonLdSignedJwtCredential(
internal fun mobileDrivingLicense() = MsoMdocCredential(
"MobileDrivingLicense_msoMdoc",
emptyList(),
listOf("ES256", "ES384", "ES512"),
emptyList(),
emptyList(),
null,
listOf(CoseAlgorithm(-7), CoseAlgorithm(-35), CoseAlgorithm(-36)),
ProofTypesSupported.Empty,
CredentialMetadata(
listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@
"cose_key"
],
"credential_signing_alg_values_supported": [
"ES256",
"ES384",
"ES512"
-7,
-35,
-36
],
"proof_types_supported": {
"jwt": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@
"scope": "MobileDrivingLicense_msoMdoc",
"doctype": "org.iso.18013.5.1.mDL",
"credential_signing_alg_values_supported": [
"ES256",
"ES384",
"ES512"
-7,
-35,
-36
],
"credential_metadata": {
"display": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@
"scope": "MobileDrivingLicense_msoMdoc",
"doctype": "org.iso.18013.5.1.mDL",
"credential_signing_alg_values_supported": [
"ES256",
"ES384",
"ES512"
-7,
-35,
-36
],
"credential_metadata": {
"display": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@
"scope": "MobileDrivingLicense_msoMdoc",
"doctype": "org.iso.18013.5.1.mDL",
"credential_signing_alg_values_supported": [
"ES256",
"ES384",
"ES512"
-7,
-35,
-36
],
"credential_metadata": {
"display": [
Expand Down
Loading
Loading