From 2efa20ec6f8d5d939f20ee9af7310549d73dbca3 Mon Sep 17 00:00:00 2001 From: Michael Avoyan Date: Sun, 18 Feb 2024 12:17:01 +0200 Subject: [PATCH 1/3] Revert "v2.3.0 fix P-256 support" This reverts commit 3c6ff374ceaf11c23897ee294e260495844b34da. --- VCL/build.gradle | 4 +- .../java/io/velocitycareerlabs/api/VCL.kt | 2 +- .../api/entities/VCLDidJwk.kt | 2 - .../api/entities/VCLDidJwkDescriptor.kt | 15 ------- .../api/entities/VCLPublicJwk.kt | 2 - .../VCLCryptoServicesDescriptor.kt | 1 + .../api/keys/VCLKeyService.kt | 5 +-- .../velocitycareerlabs/impl/GlobalConfig.kt | 1 + .../io/velocitycareerlabs/impl/VCLImpl.kt | 6 ++- .../repositories/KeyServiceRepositoryImpl.kt | 5 +-- .../data/usecases/KeyServiceUseCaseImpl.kt | 5 +-- .../repositories/KeyServiceRepository.kt | 3 +- .../impl/domain/usecases/KeyServiceUseCase.kt | 4 +- .../impl/extensions/StringExtensions.kt | 10 ++--- .../jwt/local/VCLJwtSignServiceLocalImpl.kt | 17 ++++---- .../impl/keys/VCLKeyServiceLocalImpl.kt | 11 ++--- .../impl/keys/VCLKeyServiceRemoteImpl.kt | 16 ++++---- .../VCLSignatureAlgorithmTest.kt | 21 ---------- .../VCLFinalizeOffersDescriptorTest.kt | 2 +- .../jwt/local/JwtSignServiceLocalTest.kt | 3 +- .../jwt/local/JwtVerifyServiceLocalTest.kt | 2 +- .../infrastructure/keys/KeyServiceTest.kt | 15 +++++-- .../resources/valid/VCLKeyServiceMock.kt | 14 ++----- .../usecases/FinalizeOffersUseCaseTest.kt | 2 +- .../usecases/JwtServiceUseCaseTest.kt | 41 ++++++++++--------- .../usecases/KeyServiceUseCaseTest.kt | 21 ++++------ .../PresentationSubmissionUseCaseTest.kt | 5 +-- .../main/java/com/vcl/wallet/MainActivity.kt | 6 +-- 28 files changed, 89 insertions(+), 152 deletions(-) delete mode 100644 VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt delete mode 100644 VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt diff --git a/VCL/build.gradle b/VCL/build.gradle index 1e3cd688..404cc020 100644 --- a/VCL/build.gradle +++ b/VCL/build.gradle @@ -13,8 +13,8 @@ android { defaultConfig { minSdk 24 targetSdk 33 - versionName "2.3.0" - versionCode 129 + versionName "2.2.1" + versionCode 128 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" } diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt b/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt index 2cb3e0c4..922c0fa0 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt @@ -103,7 +103,7 @@ interface VCL { ) fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor = VCLDidJwkDescriptor(), + remoteCryptoServicesToken: VCLToken? = null, successHandler: (VCLDidJwk) -> Unit, errorHandler: (VCLError) -> Unit ) diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt index b58d60fb..ce4c04ae 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt @@ -29,8 +29,6 @@ data class VCLDidJwk( */ val keyId: String ) { - val curve: String get() = publicJwk.curve - companion object Utils { const val DidJwkPrefix = "did:jwk:" const val DidJwkSuffix = "#0" diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt deleted file mode 100644 index 05b25ff1..00000000 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Created by Michael Avoyan on 15/02/24. - * - * Copyright 2022 Velocity Career Labs inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.velocitycareerlabs.api.entities - -import io.velocitycareerlabs.api.VCLSignatureAlgorithm - -data class VCLDidJwkDescriptor( - val signatureAlgorithm: VCLSignatureAlgorithm = VCLSignatureAlgorithm.ES256, - val remoteCryptoServicesToken: VCLToken? = null -) \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt index b0ad8c3b..c453bdd3 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt @@ -24,8 +24,6 @@ class VCLPublicJwk { this.valueStr = this.valueJson.toString() } - val curve: String get() = valueJson.optString("crv") - internal enum class Format(val value: String) { jwk("jwk"), hex("hex"), diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt index a8aa6c08..499c7812 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt @@ -12,6 +12,7 @@ import io.velocitycareerlabs.api.VCLSignatureAlgorithm data class VCLCryptoServicesDescriptor( val cryptoServiceType: VCLCryptoServiceType = VCLCryptoServiceType.Local, + val signatureAlgorithm: VCLSignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1, val injectedCryptoServicesDescriptor: VCLInjectedCryptoServicesDescriptor? = null, val remoteCryptoServicesUrlsDescriptor: VCLRemoteCryptoServicesUrlsDescriptor? = null ) \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt b/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt index 58579e5b..8a7e9297 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt @@ -8,16 +8,14 @@ package io.velocitycareerlabs.api.keys import com.nimbusds.jose.jwk.ECKey -import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.entities.error.VCLError interface VCLKeyService { fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor = VCLDidJwkDescriptor(), + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) @@ -25,7 +23,6 @@ interface VCLKeyService { * implemented for local crypto services only */ fun generateSecret( - signatureAlgorithm: VCLSignatureAlgorithm, completionBlock: (VCLResult) -> Unit ) { completionBlock(VCLResult.Failure(VCLError(payload = "implemented for local crypto services only"))) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt index cb659efa..a36729a0 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt @@ -17,6 +17,7 @@ internal object GlobalConfig { var CurrentEnvironment = VCLEnvironment.Prod var XVnfProtocolVersion = VCLXVnfProtocolVersion.XVnfProtocolVersion1 + var SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 var IsDebugOn = false //BuildConfig.DEBUG diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt index 1524e3f4..e3f9e11a 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt @@ -215,6 +215,8 @@ internal class VCLImpl: VCL { private fun initGlobalConfigurations() { GlobalConfig.CurrentEnvironment = initializationDescriptor.environment GlobalConfig.XVnfProtocolVersion = initializationDescriptor.xVnfProtocolVersion + GlobalConfig.SignatureAlgorithm = + initializationDescriptor.cryptoServicesDescriptor.signatureAlgorithm GlobalConfig.IsDebugOn = initializationDescriptor.isDebugOn } @@ -530,11 +532,11 @@ internal class VCLImpl: VCL { } override fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, successHandler: (VCLDidJwk) -> Unit, errorHandler: (VCLError) -> Unit ) { - keyServiceUseCase.generateDidJwk(didJwkDescriptor) { didJwkResult -> + keyServiceUseCase.generateDidJwk(remoteCryptoServicesToken) { didJwkResult -> didJwkResult.handleResult( { successHandler(it) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt index d1b1e3a6..3ee7a623 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt @@ -8,7 +8,6 @@ package io.velocitycareerlabs.impl.data.repositories import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.keys.VCLKeyService @@ -18,11 +17,11 @@ internal class KeyServiceRepositoryImpl( private val keyService: VCLKeyService ): KeyServiceRepository { override fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) { keyService.generateDidJwk( - didJwkDescriptor, + remoteCryptoServicesToken, ) { completionBlock(it) } diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt index 19d888da..ca22c4b0 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt @@ -8,7 +8,6 @@ package io.velocitycareerlabs.impl.data.usecases import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.impl.domain.infrastructure.executors.Executor @@ -21,12 +20,12 @@ internal class KeyServiceUseCaseImpl( ): KeyServiceUseCase { override fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) { executor.runOnBackground { keyServiceRepository.generateDidJwk( - didJwkDescriptor, + remoteCryptoServicesToken, ) { executor.runOnMain { completionBlock(it) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt index c1f131fc..019cc77d 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt @@ -7,13 +7,12 @@ package io.velocitycareerlabs.impl.domain.repositories import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken internal interface KeyServiceRepository { fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) } \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt index 4fd2c080..77e6f834 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt @@ -8,12 +8,12 @@ package io.velocitycareerlabs.impl.domain.usecases import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult +import io.velocitycareerlabs.api.entities.VCLToken internal interface KeyServiceUseCase { fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) } \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt index 44bbb0b6..748ee0af 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt @@ -129,6 +129,9 @@ internal fun String.toJsonArray(): JSONArray? { } } +internal fun String.toPublicJwk() = + VCLPublicJwk(this.removePrefix(VCLDidJwk.DidJwkPrefix).decodeBase64()) + internal fun String.toJwtList(): List? { this.toJsonArray()?.toList()?.let { encodedCredentialList -> val jwtCredentials = mutableListOf() @@ -145,13 +148,6 @@ internal fun String.toJwtList(): List? { return null } -internal fun String.toPublicJwk() = - VCLPublicJwk( - this.removePrefix(VCLDidJwk.DidJwkPrefix) - .removeSuffix(VCLDidJwk.DidJwkSuffix) - .decodeBase64() - ) - internal fun randomString(length: Int): String = List(length) { (('a'..'z') + ('A'..'Z') + ('0'..'9')).random() diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt index d384dfd3..9075cd9a 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt @@ -8,15 +8,16 @@ package io.velocitycareerlabs.impl.jwt.local import com.nimbusds.jose.JOSEObjectType +import com.nimbusds.jose.JWSAlgorithm import com.nimbusds.jose.JWSHeader import com.nimbusds.jose.crypto.ECDSASigner import com.nimbusds.jose.jwk.ECKey import com.nimbusds.jwt.JWTClaimsSet import com.nimbusds.jwt.SignedJWT -import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk import io.velocitycareerlabs.api.entities.VCLJwt import io.velocitycareerlabs.api.entities.VCLJwtDescriptor +import io.velocitycareerlabs.api.entities.VCLPublicJwk import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.entities.error.VCLError @@ -44,9 +45,7 @@ class VCLJwtSignServiceLocalImpl( ecKeyResult.handleResult( successHandler = { ecKey -> try { - val header = JWSHeader.Builder( - VCLSignatureAlgorithm.fromString(didJwk.publicJwk.curve).jwsAlgorithm - ) + val header = JWSHeader.Builder(GlobalConfig.SignatureAlgorithm.jwsAlgorithm) .type(JOSEObjectType(GlobalConfig.TypeJwt)) // HeaderValues.XVnfProtocolVersion == VCLXVnfProtocolVersion.XVnfProtocolVersion1 .jwk(ecKey.toPublicJWK()) @@ -61,8 +60,6 @@ class VCLJwtSignServiceLocalImpl( signedJWT.sign(ECDSASigner(ecKey)) completionBlock(VCLResult.Success(VCLJwt(signedJWT))) - } catch (error: VCLError) { - completionBlock(VCLResult.Failure(error)) } catch (ex: Exception) { completionBlock(VCLResult.Failure(VCLError(ex))) } @@ -75,10 +72,14 @@ class VCLJwtSignServiceLocalImpl( } private fun getSecretReference( - keyId: String, + keyId: String?, completionBlock: (VCLResult) -> Unit ) { - keyService.retrieveSecretReference(keyId, completionBlock = completionBlock) + keyId?.let { + keyService.retrieveSecretReference(keyId = it, completionBlock = completionBlock) + } ?: run { + keyService.generateSecret(completionBlock = completionBlock) + } } private fun generateClaims( diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt index a7bb0bd6..aee2e6d8 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt @@ -8,9 +8,7 @@ import com.nimbusds.jose.jwk.Curve import com.nimbusds.jose.jwk.ECKey import com.nimbusds.jose.jwk.KeyUse import com.nimbusds.jose.jwk.gen.ECKeyGenerator -import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLPublicJwk import io.velocitycareerlabs.api.entities.error.VCLError import io.velocitycareerlabs.api.entities.VCLResult @@ -25,12 +23,10 @@ internal class VCLKeyServiceLocalImpl( private val secretStoreService: SecretStoreService, ): VCLKeyService { override fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) { - generateSecret( - signatureAlgorithm = didJwkDescriptor.signatureAlgorithm - ) { ecKeyResult -> + generateSecret { ecKeyResult -> ecKeyResult.handleResult( successHandler = { ecKey -> completionBlock( @@ -51,12 +47,11 @@ internal class VCLKeyServiceLocalImpl( } override fun generateSecret( - signatureAlgorithm: VCLSignatureAlgorithm, completionBlock: (VCLResult) -> Unit ) { try { val keyId = UUID.randomUUID().toString() - val ecKey = ECKeyGenerator(signatureAlgorithm.curve) + val ecKey = ECKeyGenerator(GlobalConfig.SignatureAlgorithm.curve) .keyUse(KeyUse.SIGNATURE) .keyID(keyId) // must be provided, otherwise ecKey.keyID is null // .keyStore(KeyStoreProvider.Instance.keyStore) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt index 9548bf2e..5a85859d 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt @@ -7,15 +7,15 @@ package io.velocitycareerlabs.impl.keys -import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLPublicJwk import io.velocitycareerlabs.api.entities.VCLResult +import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.entities.error.VCLError import io.velocitycareerlabs.api.entities.handleResult import io.velocitycareerlabs.api.entities.initialization.VCLKeyServiceUrls import io.velocitycareerlabs.api.keys.VCLKeyService +import io.velocitycareerlabs.impl.GlobalConfig import io.velocitycareerlabs.impl.data.infrastructure.network.Request import io.velocitycareerlabs.impl.data.repositories.HeaderKeys import io.velocitycareerlabs.impl.data.repositories.HeaderValues @@ -28,17 +28,17 @@ internal class VCLKeyServiceRemoteImpl( private val keyServiceUrls: VCLKeyServiceUrls ) : VCLKeyService { override fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) { networkService.sendRequest( endpoint = keyServiceUrls.createDidKeyServiceUrl, - body = generatePayloadToCreateDidJwk(didJwkDescriptor.signatureAlgorithm).toString(), + body = generatePayloadToCreateDidJwk().toString(), contentType = Request.ContentTypeApplicationJson, method = Request.HttpMethod.POST, headers = listOf( Pair(HeaderKeys.XVnfProtocolVersion, HeaderValues.XVnfProtocolVersion), - Pair(HeaderKeys.Authorization, "${HeaderKeys.Bearer} ${didJwkDescriptor.remoteCryptoServicesToken?.value}") + Pair(HeaderKeys.Authorization, "${HeaderKeys.Bearer} ${remoteCryptoServicesToken?.value}") ), completionBlock = { didJwkResult -> didJwkResult.handleResult( @@ -74,11 +74,9 @@ internal class VCLKeyServiceRemoteImpl( ) } - private fun generatePayloadToCreateDidJwk( - signatureAlgorithm: VCLSignatureAlgorithm - ): JSONObject { + private fun generatePayloadToCreateDidJwk(): JSONObject { val retVal = JSONObject() - retVal.putOpt(CodingKeys.KeyCrv, signatureAlgorithm.curve) + retVal.putOpt(CodingKeys.KeyCrv, GlobalConfig.SignatureAlgorithm.curve) return retVal } diff --git a/VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt b/VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt deleted file mode 100644 index b311d2d2..00000000 --- a/VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Created by Michael Avoyan on 08/02/2024. - * - * Copyright 2022 Velocity Career Labs inc. - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.velocitycareerlabs - -import io.velocitycareerlabs.api.VCLSignatureAlgorithm -import org.junit.Test - -class VCLSignatureAlgorithmTest { - @Test - fun fromStringTest() { - assert(VCLSignatureAlgorithm.fromString(value = "P-256") == VCLSignatureAlgorithm.ES256) - assert(VCLSignatureAlgorithm.fromString(value = "secp256k1") == VCLSignatureAlgorithm.SECP256k1) - assert(VCLSignatureAlgorithm.fromString(value = "") == VCLSignatureAlgorithm.SECP256k1) - assert(VCLSignatureAlgorithm.fromString(value = "wrong alg") == VCLSignatureAlgorithm.SECP256k1) - } -} \ No newline at end of file diff --git a/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt b/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt index bfa1302c..f627ec7e 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt @@ -59,7 +59,7 @@ class VCLFinalizeOffersDescriptorTest { @Before fun setUp() { - keyService.generateDidJwk { didJwkResult -> + keyService.generateDidJwk(null) { didJwkResult -> didJwkResult.handleResult({ didJwk = it }, { diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt index 7caf408d..aaea3b19 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt @@ -9,7 +9,6 @@ package io.velocitycareerlabs.infrastructure.jwt.local import android.os.Build import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLJwtDescriptor import io.velocitycareerlabs.api.entities.handleResult import io.velocitycareerlabs.api.jwt.VCLJwtSignService @@ -39,7 +38,7 @@ class JwtSignServiceLocalTest { @Before fun setUp() { - keyService.generateDidJwk(VCLDidJwkDescriptor()) { jwkResult -> + keyService.generateDidJwk(null) { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt index 5b244c79..cf8706b1 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt @@ -41,7 +41,7 @@ class JwtVerifyServiceLocalTest { @Before fun setUp() { - keyService.generateDidJwk { jwkResult -> + keyService.generateDidJwk(null) { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt index 5d8938b9..d6921506 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt @@ -7,7 +7,6 @@ package io.velocitycareerlabs.infrastructure.keys import android.os.Build import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.handleResult import io.velocitycareerlabs.impl.GlobalConfig import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl @@ -33,7 +32,9 @@ class KeyServiceTest { @Test fun testGenerateDidJwkES256() { - subject.generateDidJwk(VCLDidJwkDescriptor()) { didJwkResult -> + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 + + subject.generateDidJwk(null) { didJwkResult -> didJwkResult.handleResult({ didJwk -> val jwkJson = didJwk.publicJwk.valueJson @@ -45,6 +46,8 @@ class KeyServiceTest { assert(jwkJson.optString("use") == "sig") assert(jwkJson.optString("crv") == VCLSignatureAlgorithm.ES256.curve.name) assert(jwkJson.optString("use") == "sig") + assert(jwkJson.optString("x") != null) + assert(jwkJson.optString("y") != null) }, { assert(false) { "Failed to generate did:jwk $it" } }) @@ -52,8 +55,10 @@ class KeyServiceTest { } @Test - fun testGenerateDidJwkSECP256k1() { - subject.generateDidJwk(VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1)) { didJwkResult -> + fun testGenerateDidJwkSecp256k1() { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 + + subject.generateDidJwk(null) { didJwkResult -> didJwkResult.handleResult({ didJwk -> val jwkJson = didJwk.publicJwk.valueJson @@ -65,6 +70,8 @@ class KeyServiceTest { assert(jwkJson.optString("use") == "sig") assert(jwkJson.optString("crv") == VCLSignatureAlgorithm.SECP256k1.curve.name) assert(jwkJson.optString("use") == "sig") + assert(jwkJson.optString("x") != null) + assert(jwkJson.optString("y") != null) }, { assert(false) { "Failed to generate did:jwk $it" } }) diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt index 0967d300..6a5c2a38 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt @@ -8,24 +8,19 @@ package io.velocitycareerlabs.infrastructure.resources.valid import com.nimbusds.jose.jwk.ECKey -import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.keys.VCLKeyService class VCLKeyServiceMock: VCLKeyService { override fun generateDidJwk( - didJwkDescriptor: VCLDidJwkDescriptor, + remoteCryptoServicesToken: VCLToken?, completionBlock: (VCLResult) -> Unit ) { } - override fun generateSecret( - signatureAlgorithm: VCLSignatureAlgorithm, - completionBlock: (VCLResult) -> Unit - ) { + override fun generateSecret(completionBlock: (VCLResult) -> Unit) { } override fun retrieveSecretReference( @@ -34,9 +29,6 @@ class VCLKeyServiceMock: VCLKeyService { ) { } - override fun retrievePublicJwk( - ecKey: ECKey, - completionBlock: (VCLResult) -> Unit - ) { + override fun retrievePublicJwk(ecKey: ECKey, completionBlock: (VCLResult) -> Unit) { } } \ No newline at end of file diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt index 60d1561d..ea76627b 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt @@ -66,7 +66,7 @@ internal class FinalizeOffersUseCaseTest { @Before fun setUp() { - keyService.generateDidJwk { jwkResult -> + keyService.generateDidJwk(null) { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt index 29b76076..524d1cf6 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt @@ -13,6 +13,7 @@ import io.velocitycareerlabs.api.entities.* import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl import io.velocitycareerlabs.impl.data.repositories.JwtServiceRepositoryImpl import io.velocitycareerlabs.impl.data.usecases.JwtServiceUseCaseImpl +import io.velocitycareerlabs.impl.GlobalConfig import io.velocitycareerlabs.impl.domain.usecases.JwtServiceUseCase import io.velocitycareerlabs.impl.extensions.toJsonObject import io.velocitycareerlabs.impl.extensions.toPublicJwk @@ -38,9 +39,8 @@ internal class JwtServiceUseCaseTest { @Before fun setUp() { - keyService.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) - ) { jwkResult -> + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 + keyService.generateDidJwk(null) { jwkResult -> jwkResult.handleResult({ didJwkES256 = it } ,{ @@ -48,9 +48,8 @@ internal class JwtServiceUseCaseTest { }) } - keyService.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1) - ) { jwkResult -> + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 + keyService.generateDidJwk(null) { jwkResult -> jwkResult.handleResult({ didJwkSECP256k1 = it } ,{ @@ -69,6 +68,8 @@ internal class JwtServiceUseCaseTest { @Test fun testSignSECP256k1() { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 + subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( payload = JwtServiceMocks.Json.toJsonObject()!!, @@ -93,6 +94,8 @@ internal class JwtServiceUseCaseTest { @Test fun testSignES256() { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 + subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( payload = JwtServiceMocks.Json.toJsonObject()!!, @@ -117,6 +120,8 @@ internal class JwtServiceUseCaseTest { @Test fun testSignVerify() { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 + subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( payload = JwtServiceMocks.Json.toJsonObject()!!, @@ -152,9 +157,9 @@ internal class JwtServiceUseCaseTest { @Test fun testSignByExistingKeySECP256k1() { - keyService.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1) - ) { didJwkResult -> + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 + + keyService.generateDidJwk(null) { didJwkResult -> didJwkResult.handleResult({ didJwk -> subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( @@ -167,14 +172,11 @@ internal class JwtServiceUseCaseTest { ) { jwtRes -> jwtRes.handleResult( { jwt -> - val publicJwk1 = VCLPublicJwk(valueStr = jwt.header?.jwk.toString()) - val publicJwk2 = jwt.header?.toJSONObject()?.get("kid").toString().toPublicJwk() - - assert(publicJwk1.valueStr == publicJwk2.valueStr) - subject.verifyJwt( jwt = jwt, - publicJwk = publicJwk1, +// publicJwk = VCLPublicJwk(valueStr = jwt.header.jwk.toString()) + // Person binding provided did:jwk only: + publicJwk = jwt.header?.toJSONObject()?.get("kid").toString().toPublicJwk(), remoteCryptoServicesToken = null ) { isVerifiedRes -> isVerifiedRes.handleResult( @@ -197,12 +199,12 @@ internal class JwtServiceUseCaseTest { }) } } - +/* @Test fun testSignByExistingKeyES256() { - keyService.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) - ) { didJwkResult -> + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 + + keyService.generateDidJwk(null) { didJwkResult -> didJwkResult.handleResult({ didJwk -> subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( @@ -242,4 +244,5 @@ internal class JwtServiceUseCaseTest { }) } } + */ } \ No newline at end of file diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt index 4e87bfaa..f433194e 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt @@ -10,7 +10,6 @@ package io.velocitycareerlabs.usecases import android.os.Build import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk -import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.data import io.velocitycareerlabs.api.entities.handleResult @@ -47,9 +46,9 @@ class KeyServiceUseCaseTest { @Test fun testGenerateJwkES256() { - subject.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) - ) { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 + + subject.generateDidJwk(null) { it.handleResult( successHandler = { didJwk -> val jwkJsonObj = didJwk.publicJwk.valueJson @@ -72,9 +71,9 @@ class KeyServiceUseCaseTest { @Test fun testGenerateJwkSECP256k1() { - subject.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1) - ) { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 + + subject.generateDidJwk(null) { it.handleResult( successHandler = { didJwk -> val jwkJsonObj = didJwk.publicJwk.valueJson @@ -97,14 +96,10 @@ class KeyServiceUseCaseTest { @Test fun testGenerateDifferentJwks() { - subject.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) - ) { didJwk1Res -> + subject.generateDidJwk(null) { didJwk1Res -> didJwk1Res.handleResult( { didJwk1 -> - subject.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) - ) { didJwk2Res -> + subject.generateDidJwk(null) { didJwk2Res -> didJwk2Res.handleResult( { didJwk2 -> assert(didJwk1.did != didJwk2.did) diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt index 7a00a273..e30c6d94 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt @@ -8,7 +8,6 @@ package io.velocitycareerlabs.usecases import android.os.Build -import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.* import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl import io.velocitycareerlabs.impl.data.repositories.JwtServiceRepositoryImpl @@ -42,9 +41,7 @@ internal class PresentationSubmissionUseCaseTest { @Before fun setUp() { - keyService.generateDidJwk( - VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) - ) { jwkResult -> + keyService.generateDidJwk(null) { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/app/src/main/java/com/vcl/wallet/MainActivity.kt b/app/src/main/java/com/vcl/wallet/MainActivity.kt index 23175a7a..9eb173e1 100644 --- a/app/src/main/java/com/vcl/wallet/MainActivity.kt +++ b/app/src/main/java/com/vcl/wallet/MainActivity.kt @@ -33,12 +33,9 @@ class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private val environment = VCLEnvironment.Dev - private lateinit var vcl: VCL private lateinit var didJwk: VCLDidJwk - private val didJwkDescriptor = VCLDidJwkDescriptor(signatureAlgorithm = VCLSignatureAlgorithm.ES256) - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -80,6 +77,7 @@ class MainActivity : AppCompatActivity() { environment = environment, xVnfProtocolVersion = VCLXVnfProtocolVersion.XVnfProtocolVersion2, cryptoServicesDescriptor = VCLCryptoServicesDescriptor( + signatureAlgorithm = VCLSignatureAlgorithm.ES256, cryptoServiceType = VCLCryptoServiceType.Remote, remoteCryptoServicesUrlsDescriptor = VCLRemoteCryptoServicesUrlsDescriptor( keyServiceUrls = VCLKeyServiceUrls( @@ -96,7 +94,6 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "VCL Initialization succeed!") vcl.generateDidJwk( - didJwkDescriptor = didJwkDescriptor, successHandler = { didJwk -> this.didJwk = didJwk Log.d( @@ -418,7 +415,6 @@ class MainActivity : AppCompatActivity() { private fun generateDidJwk() { vcl.generateDidJwk( - didJwkDescriptor = didJwkDescriptor, successHandler = { didJwk -> this.didJwk = didJwk Log.d( From dbf41dbf11f1a4adba0752f8e5925c2d33226a6e Mon Sep 17 00:00:00 2001 From: Michael Avoyan Date: Sun, 18 Feb 2024 12:17:01 +0200 Subject: [PATCH 2/3] Revert "v2.3.0 fix P-256 support" This reverts commit 3c6ff374ceaf11c23897ee294e260495844b34da. From e41b6f0f63c730e8da622630b4206ef130524e6a Mon Sep 17 00:00:00 2001 From: Michael Avoyan Date: Sun, 18 Feb 2024 12:12:46 +0200 Subject: [PATCH 3/3] v2.3.0 fix P-256 support --- VCL/build.gradle | 4 +- .../java/io/velocitycareerlabs/api/VCL.kt | 2 +- .../api/entities/VCLDidJwk.kt | 2 + .../api/entities/VCLDidJwkDescriptor.kt | 15 +++++++ .../api/entities/VCLPublicJwk.kt | 2 + .../VCLCryptoServicesDescriptor.kt | 1 - .../api/keys/VCLKeyService.kt | 5 ++- .../velocitycareerlabs/impl/GlobalConfig.kt | 1 - .../io/velocitycareerlabs/impl/VCLImpl.kt | 6 +-- .../repositories/KeyServiceRepositoryImpl.kt | 5 ++- .../data/usecases/KeyServiceUseCaseImpl.kt | 5 ++- .../repositories/KeyServiceRepository.kt | 3 +- .../impl/domain/usecases/KeyServiceUseCase.kt | 4 +- .../impl/extensions/StringExtensions.kt | 10 +++-- .../jwt/local/VCLJwtSignServiceLocalImpl.kt | 17 ++++---- .../impl/keys/VCLKeyServiceLocalImpl.kt | 11 +++-- .../impl/keys/VCLKeyServiceRemoteImpl.kt | 16 ++++---- .../VCLSignatureAlgorithmTest.kt | 21 ++++++++++ .../VCLFinalizeOffersDescriptorTest.kt | 2 +- .../jwt/local/JwtSignServiceLocalTest.kt | 3 +- .../jwt/local/JwtVerifyServiceLocalTest.kt | 2 +- .../infrastructure/keys/KeyServiceTest.kt | 15 ++----- .../resources/valid/VCLKeyServiceMock.kt | 14 +++++-- .../usecases/FinalizeOffersUseCaseTest.kt | 2 +- .../usecases/JwtServiceUseCaseTest.kt | 41 +++++++++---------- .../usecases/KeyServiceUseCaseTest.kt | 21 ++++++---- .../PresentationSubmissionUseCaseTest.kt | 5 ++- .../main/java/com/vcl/wallet/MainActivity.kt | 6 ++- 28 files changed, 152 insertions(+), 89 deletions(-) create mode 100644 VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt create mode 100644 VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt diff --git a/VCL/build.gradle b/VCL/build.gradle index 404cc020..1e3cd688 100644 --- a/VCL/build.gradle +++ b/VCL/build.gradle @@ -13,8 +13,8 @@ android { defaultConfig { minSdk 24 targetSdk 33 - versionName "2.2.1" - versionCode 128 + versionName "2.3.0" + versionCode 129 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" } diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt b/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt index 922c0fa0..2cb3e0c4 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/VCL.kt @@ -103,7 +103,7 @@ interface VCL { ) fun generateDidJwk( - remoteCryptoServicesToken: VCLToken? = null, + didJwkDescriptor: VCLDidJwkDescriptor = VCLDidJwkDescriptor(), successHandler: (VCLDidJwk) -> Unit, errorHandler: (VCLError) -> Unit ) diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt index ce4c04ae..b58d60fb 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwk.kt @@ -29,6 +29,8 @@ data class VCLDidJwk( */ val keyId: String ) { + val curve: String get() = publicJwk.curve + companion object Utils { const val DidJwkPrefix = "did:jwk:" const val DidJwkSuffix = "#0" diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt new file mode 100644 index 00000000..05b25ff1 --- /dev/null +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLDidJwkDescriptor.kt @@ -0,0 +1,15 @@ +/** + * Created by Michael Avoyan on 15/02/24. + * + * Copyright 2022 Velocity Career Labs inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.velocitycareerlabs.api.entities + +import io.velocitycareerlabs.api.VCLSignatureAlgorithm + +data class VCLDidJwkDescriptor( + val signatureAlgorithm: VCLSignatureAlgorithm = VCLSignatureAlgorithm.ES256, + val remoteCryptoServicesToken: VCLToken? = null +) \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt index c453bdd3..b0ad8c3b 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLPublicJwk.kt @@ -24,6 +24,8 @@ class VCLPublicJwk { this.valueStr = this.valueJson.toString() } + val curve: String get() = valueJson.optString("crv") + internal enum class Format(val value: String) { jwk("jwk"), hex("hex"), diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt index 499c7812..a8aa6c08 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/initialization/VCLCryptoServicesDescriptor.kt @@ -12,7 +12,6 @@ import io.velocitycareerlabs.api.VCLSignatureAlgorithm data class VCLCryptoServicesDescriptor( val cryptoServiceType: VCLCryptoServiceType = VCLCryptoServiceType.Local, - val signatureAlgorithm: VCLSignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1, val injectedCryptoServicesDescriptor: VCLInjectedCryptoServicesDescriptor? = null, val remoteCryptoServicesUrlsDescriptor: VCLRemoteCryptoServicesUrlsDescriptor? = null ) \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt b/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt index 8a7e9297..58579e5b 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/keys/VCLKeyService.kt @@ -8,14 +8,16 @@ package io.velocitycareerlabs.api.keys import com.nimbusds.jose.jwk.ECKey +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.entities.error.VCLError interface VCLKeyService { fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor = VCLDidJwkDescriptor(), completionBlock: (VCLResult) -> Unit ) @@ -23,6 +25,7 @@ interface VCLKeyService { * implemented for local crypto services only */ fun generateSecret( + signatureAlgorithm: VCLSignatureAlgorithm, completionBlock: (VCLResult) -> Unit ) { completionBlock(VCLResult.Failure(VCLError(payload = "implemented for local crypto services only"))) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt index a36729a0..cb659efa 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt @@ -17,7 +17,6 @@ internal object GlobalConfig { var CurrentEnvironment = VCLEnvironment.Prod var XVnfProtocolVersion = VCLXVnfProtocolVersion.XVnfProtocolVersion1 - var SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 var IsDebugOn = false //BuildConfig.DEBUG diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt index e3f9e11a..1524e3f4 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt @@ -215,8 +215,6 @@ internal class VCLImpl: VCL { private fun initGlobalConfigurations() { GlobalConfig.CurrentEnvironment = initializationDescriptor.environment GlobalConfig.XVnfProtocolVersion = initializationDescriptor.xVnfProtocolVersion - GlobalConfig.SignatureAlgorithm = - initializationDescriptor.cryptoServicesDescriptor.signatureAlgorithm GlobalConfig.IsDebugOn = initializationDescriptor.isDebugOn } @@ -532,11 +530,11 @@ internal class VCLImpl: VCL { } override fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, successHandler: (VCLDidJwk) -> Unit, errorHandler: (VCLError) -> Unit ) { - keyServiceUseCase.generateDidJwk(remoteCryptoServicesToken) { didJwkResult -> + keyServiceUseCase.generateDidJwk(didJwkDescriptor) { didJwkResult -> didJwkResult.handleResult( { successHandler(it) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt index 3ee7a623..d1b1e3a6 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/KeyServiceRepositoryImpl.kt @@ -8,6 +8,7 @@ package io.velocitycareerlabs.impl.data.repositories import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.keys.VCLKeyService @@ -17,11 +18,11 @@ internal class KeyServiceRepositoryImpl( private val keyService: VCLKeyService ): KeyServiceRepository { override fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, completionBlock: (VCLResult) -> Unit ) { keyService.generateDidJwk( - remoteCryptoServicesToken, + didJwkDescriptor, ) { completionBlock(it) } diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt index ca22c4b0..19d888da 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/KeyServiceUseCaseImpl.kt @@ -8,6 +8,7 @@ package io.velocitycareerlabs.impl.data.usecases import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.impl.domain.infrastructure.executors.Executor @@ -20,12 +21,12 @@ internal class KeyServiceUseCaseImpl( ): KeyServiceUseCase { override fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, completionBlock: (VCLResult) -> Unit ) { executor.runOnBackground { keyServiceRepository.generateDidJwk( - remoteCryptoServicesToken, + didJwkDescriptor, ) { executor.runOnMain { completionBlock(it) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt index 019cc77d..c1f131fc 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/KeyServiceRepository.kt @@ -7,12 +7,13 @@ package io.velocitycareerlabs.impl.domain.repositories import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken internal interface KeyServiceRepository { fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, completionBlock: (VCLResult) -> Unit ) } \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt index 77e6f834..4fd2c080 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/usecases/KeyServiceUseCase.kt @@ -8,12 +8,12 @@ package io.velocitycareerlabs.impl.domain.usecases import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult -import io.velocitycareerlabs.api.entities.VCLToken internal interface KeyServiceUseCase { fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, completionBlock: (VCLResult) -> Unit ) } \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt index 748ee0af..44bbb0b6 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/extensions/StringExtensions.kt @@ -129,9 +129,6 @@ internal fun String.toJsonArray(): JSONArray? { } } -internal fun String.toPublicJwk() = - VCLPublicJwk(this.removePrefix(VCLDidJwk.DidJwkPrefix).decodeBase64()) - internal fun String.toJwtList(): List? { this.toJsonArray()?.toList()?.let { encodedCredentialList -> val jwtCredentials = mutableListOf() @@ -148,6 +145,13 @@ internal fun String.toJwtList(): List? { return null } +internal fun String.toPublicJwk() = + VCLPublicJwk( + this.removePrefix(VCLDidJwk.DidJwkPrefix) + .removeSuffix(VCLDidJwk.DidJwkSuffix) + .decodeBase64() + ) + internal fun randomString(length: Int): String = List(length) { (('a'..'z') + ('A'..'Z') + ('0'..'9')).random() diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt index 9075cd9a..d384dfd3 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/jwt/local/VCLJwtSignServiceLocalImpl.kt @@ -8,16 +8,15 @@ package io.velocitycareerlabs.impl.jwt.local import com.nimbusds.jose.JOSEObjectType -import com.nimbusds.jose.JWSAlgorithm import com.nimbusds.jose.JWSHeader import com.nimbusds.jose.crypto.ECDSASigner import com.nimbusds.jose.jwk.ECKey import com.nimbusds.jwt.JWTClaimsSet import com.nimbusds.jwt.SignedJWT +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk import io.velocitycareerlabs.api.entities.VCLJwt import io.velocitycareerlabs.api.entities.VCLJwtDescriptor -import io.velocitycareerlabs.api.entities.VCLPublicJwk import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.entities.error.VCLError @@ -45,7 +44,9 @@ class VCLJwtSignServiceLocalImpl( ecKeyResult.handleResult( successHandler = { ecKey -> try { - val header = JWSHeader.Builder(GlobalConfig.SignatureAlgorithm.jwsAlgorithm) + val header = JWSHeader.Builder( + VCLSignatureAlgorithm.fromString(didJwk.publicJwk.curve).jwsAlgorithm + ) .type(JOSEObjectType(GlobalConfig.TypeJwt)) // HeaderValues.XVnfProtocolVersion == VCLXVnfProtocolVersion.XVnfProtocolVersion1 .jwk(ecKey.toPublicJWK()) @@ -60,6 +61,8 @@ class VCLJwtSignServiceLocalImpl( signedJWT.sign(ECDSASigner(ecKey)) completionBlock(VCLResult.Success(VCLJwt(signedJWT))) + } catch (error: VCLError) { + completionBlock(VCLResult.Failure(error)) } catch (ex: Exception) { completionBlock(VCLResult.Failure(VCLError(ex))) } @@ -72,14 +75,10 @@ class VCLJwtSignServiceLocalImpl( } private fun getSecretReference( - keyId: String?, + keyId: String, completionBlock: (VCLResult) -> Unit ) { - keyId?.let { - keyService.retrieveSecretReference(keyId = it, completionBlock = completionBlock) - } ?: run { - keyService.generateSecret(completionBlock = completionBlock) - } + keyService.retrieveSecretReference(keyId, completionBlock = completionBlock) } private fun generateClaims( diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt index aee2e6d8..a7bb0bd6 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt @@ -8,7 +8,9 @@ import com.nimbusds.jose.jwk.Curve import com.nimbusds.jose.jwk.ECKey import com.nimbusds.jose.jwk.KeyUse import com.nimbusds.jose.jwk.gen.ECKeyGenerator +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLPublicJwk import io.velocitycareerlabs.api.entities.error.VCLError import io.velocitycareerlabs.api.entities.VCLResult @@ -23,10 +25,12 @@ internal class VCLKeyServiceLocalImpl( private val secretStoreService: SecretStoreService, ): VCLKeyService { override fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, completionBlock: (VCLResult) -> Unit ) { - generateSecret { ecKeyResult -> + generateSecret( + signatureAlgorithm = didJwkDescriptor.signatureAlgorithm + ) { ecKeyResult -> ecKeyResult.handleResult( successHandler = { ecKey -> completionBlock( @@ -47,11 +51,12 @@ internal class VCLKeyServiceLocalImpl( } override fun generateSecret( + signatureAlgorithm: VCLSignatureAlgorithm, completionBlock: (VCLResult) -> Unit ) { try { val keyId = UUID.randomUUID().toString() - val ecKey = ECKeyGenerator(GlobalConfig.SignatureAlgorithm.curve) + val ecKey = ECKeyGenerator(signatureAlgorithm.curve) .keyUse(KeyUse.SIGNATURE) .keyID(keyId) // must be provided, otherwise ecKey.keyID is null // .keyStore(KeyStoreProvider.Instance.keyStore) diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt index 5a85859d..9548bf2e 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt @@ -7,15 +7,15 @@ package io.velocitycareerlabs.impl.keys +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLPublicJwk import io.velocitycareerlabs.api.entities.VCLResult -import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.entities.error.VCLError import io.velocitycareerlabs.api.entities.handleResult import io.velocitycareerlabs.api.entities.initialization.VCLKeyServiceUrls import io.velocitycareerlabs.api.keys.VCLKeyService -import io.velocitycareerlabs.impl.GlobalConfig import io.velocitycareerlabs.impl.data.infrastructure.network.Request import io.velocitycareerlabs.impl.data.repositories.HeaderKeys import io.velocitycareerlabs.impl.data.repositories.HeaderValues @@ -28,17 +28,17 @@ internal class VCLKeyServiceRemoteImpl( private val keyServiceUrls: VCLKeyServiceUrls ) : VCLKeyService { override fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, completionBlock: (VCLResult) -> Unit ) { networkService.sendRequest( endpoint = keyServiceUrls.createDidKeyServiceUrl, - body = generatePayloadToCreateDidJwk().toString(), + body = generatePayloadToCreateDidJwk(didJwkDescriptor.signatureAlgorithm).toString(), contentType = Request.ContentTypeApplicationJson, method = Request.HttpMethod.POST, headers = listOf( Pair(HeaderKeys.XVnfProtocolVersion, HeaderValues.XVnfProtocolVersion), - Pair(HeaderKeys.Authorization, "${HeaderKeys.Bearer} ${remoteCryptoServicesToken?.value}") + Pair(HeaderKeys.Authorization, "${HeaderKeys.Bearer} ${didJwkDescriptor.remoteCryptoServicesToken?.value}") ), completionBlock = { didJwkResult -> didJwkResult.handleResult( @@ -74,9 +74,11 @@ internal class VCLKeyServiceRemoteImpl( ) } - private fun generatePayloadToCreateDidJwk(): JSONObject { + private fun generatePayloadToCreateDidJwk( + signatureAlgorithm: VCLSignatureAlgorithm + ): JSONObject { val retVal = JSONObject() - retVal.putOpt(CodingKeys.KeyCrv, GlobalConfig.SignatureAlgorithm.curve) + retVal.putOpt(CodingKeys.KeyCrv, signatureAlgorithm.curve) return retVal } diff --git a/VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt b/VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt new file mode 100644 index 00000000..b311d2d2 --- /dev/null +++ b/VCL/src/test/java/io/velocitycareerlabs/VCLSignatureAlgorithmTest.kt @@ -0,0 +1,21 @@ +/** + * Created by Michael Avoyan on 08/02/2024. + * + * Copyright 2022 Velocity Career Labs inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.velocitycareerlabs + +import io.velocitycareerlabs.api.VCLSignatureAlgorithm +import org.junit.Test + +class VCLSignatureAlgorithmTest { + @Test + fun fromStringTest() { + assert(VCLSignatureAlgorithm.fromString(value = "P-256") == VCLSignatureAlgorithm.ES256) + assert(VCLSignatureAlgorithm.fromString(value = "secp256k1") == VCLSignatureAlgorithm.SECP256k1) + assert(VCLSignatureAlgorithm.fromString(value = "") == VCLSignatureAlgorithm.SECP256k1) + assert(VCLSignatureAlgorithm.fromString(value = "wrong alg") == VCLSignatureAlgorithm.SECP256k1) + } +} \ No newline at end of file diff --git a/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt b/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt index f627ec7e..bfa1302c 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt @@ -59,7 +59,7 @@ class VCLFinalizeOffersDescriptorTest { @Before fun setUp() { - keyService.generateDidJwk(null) { didJwkResult -> + keyService.generateDidJwk { didJwkResult -> didJwkResult.handleResult({ didJwk = it }, { diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt index aaea3b19..7caf408d 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtSignServiceLocalTest.kt @@ -9,6 +9,7 @@ package io.velocitycareerlabs.infrastructure.jwt.local import android.os.Build import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLJwtDescriptor import io.velocitycareerlabs.api.entities.handleResult import io.velocitycareerlabs.api.jwt.VCLJwtSignService @@ -38,7 +39,7 @@ class JwtSignServiceLocalTest { @Before fun setUp() { - keyService.generateDidJwk(null) { jwkResult -> + keyService.generateDidJwk(VCLDidJwkDescriptor()) { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt index cf8706b1..5b244c79 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/jwt/local/JwtVerifyServiceLocalTest.kt @@ -41,7 +41,7 @@ class JwtVerifyServiceLocalTest { @Before fun setUp() { - keyService.generateDidJwk(null) { jwkResult -> + keyService.generateDidJwk { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt index d6921506..5d8938b9 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt @@ -7,6 +7,7 @@ package io.velocitycareerlabs.infrastructure.keys import android.os.Build import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.handleResult import io.velocitycareerlabs.impl.GlobalConfig import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl @@ -32,9 +33,7 @@ class KeyServiceTest { @Test fun testGenerateDidJwkES256() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 - - subject.generateDidJwk(null) { didJwkResult -> + subject.generateDidJwk(VCLDidJwkDescriptor()) { didJwkResult -> didJwkResult.handleResult({ didJwk -> val jwkJson = didJwk.publicJwk.valueJson @@ -46,8 +45,6 @@ class KeyServiceTest { assert(jwkJson.optString("use") == "sig") assert(jwkJson.optString("crv") == VCLSignatureAlgorithm.ES256.curve.name) assert(jwkJson.optString("use") == "sig") - assert(jwkJson.optString("x") != null) - assert(jwkJson.optString("y") != null) }, { assert(false) { "Failed to generate did:jwk $it" } }) @@ -55,10 +52,8 @@ class KeyServiceTest { } @Test - fun testGenerateDidJwkSecp256k1() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 - - subject.generateDidJwk(null) { didJwkResult -> + fun testGenerateDidJwkSECP256k1() { + subject.generateDidJwk(VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1)) { didJwkResult -> didJwkResult.handleResult({ didJwk -> val jwkJson = didJwk.publicJwk.valueJson @@ -70,8 +65,6 @@ class KeyServiceTest { assert(jwkJson.optString("use") == "sig") assert(jwkJson.optString("crv") == VCLSignatureAlgorithm.SECP256k1.curve.name) assert(jwkJson.optString("use") == "sig") - assert(jwkJson.optString("x") != null) - assert(jwkJson.optString("y") != null) }, { assert(false) { "Failed to generate did:jwk $it" } }) diff --git a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt index 6a5c2a38..0967d300 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/resources/valid/VCLKeyServiceMock.kt @@ -8,19 +8,24 @@ package io.velocitycareerlabs.infrastructure.resources.valid import com.nimbusds.jose.jwk.ECKey +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.keys.VCLKeyService class VCLKeyServiceMock: VCLKeyService { override fun generateDidJwk( - remoteCryptoServicesToken: VCLToken?, + didJwkDescriptor: VCLDidJwkDescriptor, completionBlock: (VCLResult) -> Unit ) { } - override fun generateSecret(completionBlock: (VCLResult) -> Unit) { + override fun generateSecret( + signatureAlgorithm: VCLSignatureAlgorithm, + completionBlock: (VCLResult) -> Unit + ) { } override fun retrieveSecretReference( @@ -29,6 +34,9 @@ class VCLKeyServiceMock: VCLKeyService { ) { } - override fun retrievePublicJwk(ecKey: ECKey, completionBlock: (VCLResult) -> Unit) { + override fun retrievePublicJwk( + ecKey: ECKey, + completionBlock: (VCLResult) -> Unit + ) { } } \ No newline at end of file diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt index ea76627b..60d1561d 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/FinalizeOffersUseCaseTest.kt @@ -66,7 +66,7 @@ internal class FinalizeOffersUseCaseTest { @Before fun setUp() { - keyService.generateDidJwk(null) { jwkResult -> + keyService.generateDidJwk { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt index 524d1cf6..29b76076 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/JwtServiceUseCaseTest.kt @@ -13,7 +13,6 @@ import io.velocitycareerlabs.api.entities.* import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl import io.velocitycareerlabs.impl.data.repositories.JwtServiceRepositoryImpl import io.velocitycareerlabs.impl.data.usecases.JwtServiceUseCaseImpl -import io.velocitycareerlabs.impl.GlobalConfig import io.velocitycareerlabs.impl.domain.usecases.JwtServiceUseCase import io.velocitycareerlabs.impl.extensions.toJsonObject import io.velocitycareerlabs.impl.extensions.toPublicJwk @@ -39,8 +38,9 @@ internal class JwtServiceUseCaseTest { @Before fun setUp() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 - keyService.generateDidJwk(null) { jwkResult -> + keyService.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) + ) { jwkResult -> jwkResult.handleResult({ didJwkES256 = it } ,{ @@ -48,8 +48,9 @@ internal class JwtServiceUseCaseTest { }) } - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 - keyService.generateDidJwk(null) { jwkResult -> + keyService.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1) + ) { jwkResult -> jwkResult.handleResult({ didJwkSECP256k1 = it } ,{ @@ -68,8 +69,6 @@ internal class JwtServiceUseCaseTest { @Test fun testSignSECP256k1() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 - subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( payload = JwtServiceMocks.Json.toJsonObject()!!, @@ -94,8 +93,6 @@ internal class JwtServiceUseCaseTest { @Test fun testSignES256() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 - subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( payload = JwtServiceMocks.Json.toJsonObject()!!, @@ -120,8 +117,6 @@ internal class JwtServiceUseCaseTest { @Test fun testSignVerify() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 - subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( payload = JwtServiceMocks.Json.toJsonObject()!!, @@ -157,9 +152,9 @@ internal class JwtServiceUseCaseTest { @Test fun testSignByExistingKeySECP256k1() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 - - keyService.generateDidJwk(null) { didJwkResult -> + keyService.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1) + ) { didJwkResult -> didJwkResult.handleResult({ didJwk -> subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( @@ -172,11 +167,14 @@ internal class JwtServiceUseCaseTest { ) { jwtRes -> jwtRes.handleResult( { jwt -> + val publicJwk1 = VCLPublicJwk(valueStr = jwt.header?.jwk.toString()) + val publicJwk2 = jwt.header?.toJSONObject()?.get("kid").toString().toPublicJwk() + + assert(publicJwk1.valueStr == publicJwk2.valueStr) + subject.verifyJwt( jwt = jwt, -// publicJwk = VCLPublicJwk(valueStr = jwt.header.jwk.toString()) - // Person binding provided did:jwk only: - publicJwk = jwt.header?.toJSONObject()?.get("kid").toString().toPublicJwk(), + publicJwk = publicJwk1, remoteCryptoServicesToken = null ) { isVerifiedRes -> isVerifiedRes.handleResult( @@ -199,12 +197,12 @@ internal class JwtServiceUseCaseTest { }) } } -/* + @Test fun testSignByExistingKeyES256() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 - - keyService.generateDidJwk(null) { didJwkResult -> + keyService.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) + ) { didJwkResult -> didJwkResult.handleResult({ didJwk -> subject.generateSignedJwt( jwtDescriptor = VCLJwtDescriptor( @@ -244,5 +242,4 @@ internal class JwtServiceUseCaseTest { }) } } - */ } \ No newline at end of file diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt index f433194e..4e87bfaa 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/KeyServiceUseCaseTest.kt @@ -10,6 +10,7 @@ package io.velocitycareerlabs.usecases import android.os.Build import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.VCLDidJwk +import io.velocitycareerlabs.api.entities.VCLDidJwkDescriptor import io.velocitycareerlabs.api.entities.VCLResult import io.velocitycareerlabs.api.entities.data import io.velocitycareerlabs.api.entities.handleResult @@ -46,9 +47,9 @@ class KeyServiceUseCaseTest { @Test fun testGenerateJwkES256() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 - - subject.generateDidJwk(null) { + subject.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) + ) { it.handleResult( successHandler = { didJwk -> val jwkJsonObj = didJwk.publicJwk.valueJson @@ -71,9 +72,9 @@ class KeyServiceUseCaseTest { @Test fun testGenerateJwkSECP256k1() { - GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 - - subject.generateDidJwk(null) { + subject.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.SECP256k1) + ) { it.handleResult( successHandler = { didJwk -> val jwkJsonObj = didJwk.publicJwk.valueJson @@ -96,10 +97,14 @@ class KeyServiceUseCaseTest { @Test fun testGenerateDifferentJwks() { - subject.generateDidJwk(null) { didJwk1Res -> + subject.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) + ) { didJwk1Res -> didJwk1Res.handleResult( { didJwk1 -> - subject.generateDidJwk(null) { didJwk2Res -> + subject.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) + ) { didJwk2Res -> didJwk2Res.handleResult( { didJwk2 -> assert(didJwk1.did != didJwk2.did) diff --git a/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt b/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt index e30c6d94..7a00a273 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/usecases/PresentationSubmissionUseCaseTest.kt @@ -8,6 +8,7 @@ package io.velocitycareerlabs.usecases import android.os.Build +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.entities.* import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl import io.velocitycareerlabs.impl.data.repositories.JwtServiceRepositoryImpl @@ -41,7 +42,9 @@ internal class PresentationSubmissionUseCaseTest { @Before fun setUp() { - keyService.generateDidJwk(null) { jwkResult -> + keyService.generateDidJwk( + VCLDidJwkDescriptor(VCLSignatureAlgorithm.ES256) + ) { jwkResult -> jwkResult.handleResult({ didJwk = it } ,{ diff --git a/app/src/main/java/com/vcl/wallet/MainActivity.kt b/app/src/main/java/com/vcl/wallet/MainActivity.kt index 9eb173e1..23175a7a 100644 --- a/app/src/main/java/com/vcl/wallet/MainActivity.kt +++ b/app/src/main/java/com/vcl/wallet/MainActivity.kt @@ -33,9 +33,12 @@ class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private val environment = VCLEnvironment.Dev + private lateinit var vcl: VCL private lateinit var didJwk: VCLDidJwk + private val didJwkDescriptor = VCLDidJwkDescriptor(signatureAlgorithm = VCLSignatureAlgorithm.ES256) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -77,7 +80,6 @@ class MainActivity : AppCompatActivity() { environment = environment, xVnfProtocolVersion = VCLXVnfProtocolVersion.XVnfProtocolVersion2, cryptoServicesDescriptor = VCLCryptoServicesDescriptor( - signatureAlgorithm = VCLSignatureAlgorithm.ES256, cryptoServiceType = VCLCryptoServiceType.Remote, remoteCryptoServicesUrlsDescriptor = VCLRemoteCryptoServicesUrlsDescriptor( keyServiceUrls = VCLKeyServiceUrls( @@ -94,6 +96,7 @@ class MainActivity : AppCompatActivity() { Log.d(TAG, "VCL Initialization succeed!") vcl.generateDidJwk( + didJwkDescriptor = didJwkDescriptor, successHandler = { didJwk -> this.didJwk = didJwk Log.d( @@ -415,6 +418,7 @@ class MainActivity : AppCompatActivity() { private fun generateDidJwk() { vcl.generateDidJwk( + didJwkDescriptor = didJwkDescriptor, successHandler = { didJwk -> this.didJwk = didJwk Log.d(