From 7300956eff8cb3e20642a2fd23434e43086ad9d2 Mon Sep 17 00:00:00 2001 From: Michael Avoyan Date: Tue, 13 Feb 2024 22:25:39 +0200 Subject: [PATCH] sdk v2.2.0 P-256 --- VCL/build.gradle | 4 +- .../api/VCLSignatureAlgorithm.kt | 35 +++++ .../entities/VCLFinalizeOffersDescriptor.kt | 12 +- .../api/entities/VCLOffers.kt | 2 +- .../VCLCryptoServicesDescriptor.kt | 2 + .../velocitycareerlabs/impl/GlobalConfig.kt | 2 + .../io/velocitycareerlabs/impl/VCLImpl.kt | 64 ++++----- .../FinalizeOffersRepositoryImpl.kt | 4 +- .../GenerateOffersRepositoryImpl.kt | 6 +- .../usecases/FinalizeOffersUseCaseImpl.kt | 134 ++++++++++-------- .../repositories/FinalizeOffersRepository.kt | 2 +- .../jwt/local/VCLJwtSignServiceLocalImpl.kt | 2 +- .../impl/keys/VCLKeyServiceLocalImpl.kt | 3 +- .../impl/keys/VCLKeyServiceRemoteImpl.kt | 14 +- .../VCLFinalizeOffersDescriptorTest.kt | 2 +- .../infrastructure/keys/KeyServiceTest.kt | 33 ++++- .../main/java/com/vcl/wallet/MainActivity.kt | 26 ++-- 17 files changed, 218 insertions(+), 129 deletions(-) create mode 100644 VCL/src/main/java/io/velocitycareerlabs/api/VCLSignatureAlgorithm.kt diff --git a/VCL/build.gradle b/VCL/build.gradle index b2d2d153..a63c396e 100644 --- a/VCL/build.gradle +++ b/VCL/build.gradle @@ -13,8 +13,8 @@ android { defaultConfig { minSdk 24 targetSdk 33 - versionName "2.1.0" - versionCode 126 + versionName "2.2.0" + versionCode 127 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" } diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/VCLSignatureAlgorithm.kt b/VCL/src/main/java/io/velocitycareerlabs/api/VCLSignatureAlgorithm.kt new file mode 100644 index 00000000..2aa5abef --- /dev/null +++ b/VCL/src/main/java/io/velocitycareerlabs/api/VCLSignatureAlgorithm.kt @@ -0,0 +1,35 @@ +/** + * Created by Michael Avoyan on 08/02/2024. + * + * Copyright 2022 Velocity Career Labs inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.velocitycareerlabs.api + +import com.nimbusds.jose.JWSAlgorithm +import com.nimbusds.jose.jwk.Curve + +enum class VCLSignatureAlgorithm(val value: String) { + ES256("P-256"), + SECP256k1("secp256k1"); + + val curve: Curve get() = when(this) { + ES256 -> Curve.P_256 + SECP256k1 -> Curve.SECP256K1 + } + + val jwsAlgorithm: JWSAlgorithm get() = when(this) { + ES256 -> JWSAlgorithm.ES256 + SECP256k1 -> JWSAlgorithm.ES256K + } + + companion object { + fun fromString(value: String) = + when (value) { + ES256.value -> ES256 + SECP256k1.value -> SECP256k1 + else -> ES256 + } + } +} \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLFinalizeOffersDescriptor.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLFinalizeOffersDescriptor.kt index 25cd3a79..5cb91bcc 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLFinalizeOffersDescriptor.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLFinalizeOffersDescriptor.kt @@ -29,12 +29,14 @@ data class VCLFinalizeOffersDescriptor( val finalizeOffersUri: String get() = credentialManifest.finalizeOffersUri val serviceTypes: VCLServiceTypes get() = credentialManifest.verifiedProfile.serviceTypes - fun generateRequestBody(jwt: VCLJwt): JSONObject { + fun generateRequestBody(proof: VCLJwt?): JSONObject { val retVal = JSONObject(this.payload.toString()) - val proof = JSONObject() - proof.put(CodingKeys.KeyProofType, CodingKeys.KeyJwt) - proof.put(CodingKeys.KeyJwt, jwt.encodedJwt) - retVal.put(CodingKeys.KeyProof, proof) + proof?.let { + val proofJson = JSONObject() + proofJson.put(CodingKeys.KeyProofType, CodingKeys.KeyJwt) + proofJson.put(CodingKeys.KeyJwt, it.encodedJwt) + retVal.put(CodingKeys.KeyProof, proofJson) + } return retVal } diff --git a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLOffers.kt b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLOffers.kt index 89ea8295..f800ad90 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLOffers.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/api/entities/VCLOffers.kt @@ -15,7 +15,7 @@ data class VCLOffers ( val all: List, val responseCode: Int, val sessionToken: VCLToken, - val challenge: String, + val challenge: String? = null, ) { companion object CodingKeys { const val KeyOffers = "offers" 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 46a8a5d1..c3edd0e9 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 @@ -8,9 +8,11 @@ package io.velocitycareerlabs.api.entities.initialization import io.velocitycareerlabs.api.VCLCryptoServiceType +import io.velocitycareerlabs.api.VCLSignatureAlgorithm data class VCLCryptoServicesDescriptor( val cryptoServiceType: VCLCryptoServiceType = VCLCryptoServiceType.Local, + val signatureAlgorithm: VCLSignatureAlgorithm = VCLSignatureAlgorithm.ES256, val injectedCryptoServicesDescriptor: VCLInjectedCryptoServicesDescriptor? = null, val remoteCryptoServicesUrlsDescriptor: VCLRemoteCryptoServicesUrlsDescriptor? = null ) \ No newline at end of file diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt index 2b1fba2a..882012b9 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/GlobalConfig.kt @@ -9,6 +9,7 @@ package io.velocitycareerlabs.impl import io.velocitycareerlabs.BuildConfig import io.velocitycareerlabs.api.VCLEnvironment +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.VCLXVnfProtocolVersion internal object GlobalConfig { @@ -16,6 +17,7 @@ internal object GlobalConfig { var CurrentEnvironment = VCLEnvironment.Prod var XVnfProtocolVersion = VCLXVnfProtocolVersion.XVnfProtocolVersion1 + var SignatureAlgorithm = VCLSignatureAlgorithm.ES256 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 11053093..e3f9e11a 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/VCLImpl.kt @@ -39,6 +39,7 @@ internal class VCLImpl: VCL { private const val ModelsToInitializeAmount = 3 } + private lateinit var initializationDescriptor: VCLInitializationDescriptor private lateinit var credentialTypesModel: CredentialTypesModel @@ -214,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 } @@ -266,14 +269,12 @@ internal class VCLImpl: VCL { presentationSubmissionUseCase.submit( submission = presentationSubmission ) { presentationSubmissionResult -> - presentationSubmissionResult.handleResult( - { - successHandler(it) - }, - { - logError("submit presentation", it) - errorHandler(it) - } + presentationSubmissionResult.handleResult({ + successHandler(it) + }, { + logError("submit presentation", it) + errorHandler(it) + } ) } } @@ -284,14 +285,12 @@ internal class VCLImpl: VCL { errorHandler: (VCLError) -> Unit ) { exchangeProgressUseCase.getExchangeProgress(exchangeDescriptor) { presentationSubmissionResult -> - presentationSubmissionResult.handleResult( - { - successHandler(it) - }, - { - logError("getExchangeProgress", it) - errorHandler(it) - } + presentationSubmissionResult.handleResult({ + successHandler(it) + }, { + logError("getExchangeProgress", it) + errorHandler(it) + } ) } } @@ -302,14 +301,12 @@ internal class VCLImpl: VCL { errorHandler: (VCLError) -> Unit ) { organizationsUseCase.searchForOrganizations(organizationsSearchDescriptor) { organization -> - organization.handleResult( - { - successHandler(it) - }, - { - logError("searchForOrganizations", it) - errorHandler(it) - } + organization.handleResult({ + successHandler(it) + }, { + logError("searchForOrganizations", it) + errorHandler(it) + } ) } } @@ -319,7 +316,10 @@ internal class VCLImpl: VCL { successHandler: (VCLCredentialManifest) -> Unit, errorHandler: (VCLError) -> Unit ) { - VCLLog.d(TAG, "credentialManifestDescriptor: ${credentialManifestDescriptor.toPropsString()}") + VCLLog.d( + TAG, + "credentialManifestDescriptor: ${credentialManifestDescriptor.toPropsString()}" + ) credentialManifestDescriptor.did?.let { did -> profileServiceTypeVerifier.verifyServiceTypeOfVerifiedProfile( verifiedProfileDescriptor = VCLVerifiedProfileDescriptor(did = did), @@ -329,14 +329,12 @@ internal class VCLImpl: VCL { credentialManifestDescriptor, verifiedProfile ) { credentialManifest -> - credentialManifest.handleResult( - { - successHandler(it) - }, - { - logError("getCredentialManifest", it) - errorHandler(it) - } + credentialManifest.handleResult({ + successHandler(it) + }, { + logError("getCredentialManifest", it) + errorHandler(it) + } ) } }, diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/FinalizeOffersRepositoryImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/FinalizeOffersRepositoryImpl.kt index 41541665..332a09ee 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/FinalizeOffersRepositoryImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/FinalizeOffersRepositoryImpl.kt @@ -27,7 +27,7 @@ internal class FinalizeOffersRepositoryImpl( override fun finalizeOffers( finalizeOffersDescriptor: VCLFinalizeOffersDescriptor, sessionToken: VCLToken, - proof: VCLJwt, + proof: VCLJwt?, completionBlock: (VCLResult>) -> Unit ) { networkService.sendRequest( @@ -36,7 +36,7 @@ internal class FinalizeOffersRepositoryImpl( Pair(HeaderKeys.Authorization, "${HeaderKeys.Bearer} ${sessionToken.value}"), Pair(HeaderKeys.XVnfProtocolVersion, HeaderValues.XVnfProtocolVersion) ), - body = finalizeOffersDescriptor.generateRequestBody(jwt = proof).toString(), + body = finalizeOffersDescriptor.generateRequestBody(proof = proof).toString(), method = Request.HttpMethod.POST, contentType = Request.ContentTypeApplicationJson, completionBlock = { result -> diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/GenerateOffersRepositoryImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/GenerateOffersRepositoryImpl.kt index 8dd2de4d..101bcf50 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/GenerateOffersRepositoryImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/data/repositories/GenerateOffersRepositoryImpl.kt @@ -70,7 +70,7 @@ internal class GenerateOffersRepositoryImpl( ), responseCode = offersResponse.code, sessionToken = sessionToken, - challenge = payload.optString(VCLOffers.CodingKeys.KeyChallenge) ?: "" + challenge = payload.optString(VCLOffers.CodingKeys.KeyChallenge) ) } ?: run { // VCLXVnfProtocolVersion.XVnfProtocolVersion1 @@ -80,7 +80,6 @@ internal class GenerateOffersRepositoryImpl( all = Utils.offersFromJsonArray(offersJsonArray), responseCode = offersResponse.code, sessionToken = sessionToken, - challenge = "" ) } ?: run { // No offers @@ -89,8 +88,7 @@ internal class GenerateOffersRepositoryImpl( all = listOf(), responseCode = offersResponse.code, sessionToken = sessionToken, - challenge = "" - ) + ) } } } diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/FinalizeOffersUseCaseImpl.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/FinalizeOffersUseCaseImpl.kt index b7334773..bdd92927 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/FinalizeOffersUseCaseImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/data/usecases/FinalizeOffersUseCaseImpl.kt @@ -17,7 +17,6 @@ import io.velocitycareerlabs.impl.domain.usecases.FinalizeOffersUseCase import io.velocitycareerlabs.impl.domain.verifiers.CredentialIssuerVerifier import io.velocitycareerlabs.impl.domain.verifiers.CredentialsByDeepLinkVerifier import io.velocitycareerlabs.impl.utils.VCLLog -import java.util.UUID internal class FinalizeOffersUseCaseImpl( private val finalizeOffersRepository: FinalizeOffersRepository, @@ -35,66 +34,89 @@ internal class FinalizeOffersUseCaseImpl( completionBlock: (VCLResult) -> Unit ) { executor.runOnBackground { - this.jwtServiceRepository.generateSignedJwt( - jwtDescriptor = VCLJwtDescriptor( - iss = finalizeOffersDescriptor.didJwk?.did ?: UUID.randomUUID().toString(), - aud = finalizeOffersDescriptor.aud - ), - nonce = finalizeOffersDescriptor.offers.challenge, - didJwk = finalizeOffersDescriptor.didJwk, - ) { proofJwtResult -> - proofJwtResult.handleResult( - successHandler = { proof -> - this.finalizeOffersRepository.finalizeOffers( - sessionToken = sessionToken, - proof = proof, - finalizeOffersDescriptor = finalizeOffersDescriptor - ) { jwtCredentialsListResult -> - jwtCredentialsListResult.handleResult( - successHandler = { jwtCredentials -> - verifyCredentialsByDeepLink( - jwtCredentials, - finalizeOffersDescriptor - ) { verifyCredentialsByDeepLinkResult -> - verifyCredentialsByDeepLinkResult.handleResult( - successHandler = { - verifyCredentialsByIssuer( - jwtCredentials, - finalizeOffersDescriptor - ) { verifyCredentialsByIssuerResult -> - verifyCredentialsByIssuerResult.handleResult({ - verifyCredentialByDid( - jwtCredentials, - finalizeOffersDescriptor - ) { jwtVerifiableCredentialsResult -> - executor.runOnMain { - completionBlock( - jwtVerifiableCredentialsResult - ) - } - } - }, { error -> - onError(error, completionBlock) - }) - } - }, - errorHandler = { error -> - onError(error, completionBlock) - }) - } - }, - errorHandler = { error -> - onError(error, completionBlock) - }) + finalizeOffersDescriptor.offers.challenge?.let { challenge -> + this.jwtServiceRepository.generateSignedJwt( + jwtDescriptor = VCLJwtDescriptor( + iss = finalizeOffersDescriptor.didJwk.did, + aud = finalizeOffersDescriptor.aud + ), + nonce = challenge, + didJwk = finalizeOffersDescriptor.didJwk, + remoteCryptoServicesToken = finalizeOffersDescriptor.remoteCryptoServicesToken + ) { proofJwtResult -> + proofJwtResult.handleResult( + successHandler = { proof -> + finalizeOffersInvoke( + finalizeOffersDescriptor = finalizeOffersDescriptor, + sessionToken = sessionToken, + proof = proof, + completionBlock = completionBlock + ) + }, + errorHandler = { error -> + onError(error, completionBlock) } - }, - errorHandler = { error -> - onError(error, completionBlock) - } + ) + } + } ?: run { + finalizeOffersInvoke( + finalizeOffersDescriptor = finalizeOffersDescriptor, + sessionToken = sessionToken, + completionBlock = completionBlock ) } } } + + private fun finalizeOffersInvoke( + finalizeOffersDescriptor: VCLFinalizeOffersDescriptor, + sessionToken: VCLToken, + proof: VCLJwt? = null, + completionBlock: (VCLResult) -> Unit + ) { + this.finalizeOffersRepository.finalizeOffers( + sessionToken = sessionToken, + proof = proof, + finalizeOffersDescriptor = finalizeOffersDescriptor + ) { jwtCredentialsListResult -> + jwtCredentialsListResult.handleResult( + successHandler = { jwtCredentials -> + verifyCredentialsByDeepLink( + jwtCredentials, + finalizeOffersDescriptor + ) { verifyCredentialsByDeepLinkResult -> + verifyCredentialsByDeepLinkResult.handleResult( + successHandler = { + verifyCredentialsByIssuer( + jwtCredentials, + finalizeOffersDescriptor + ) { verifyCredentialsByIssuerResult -> + verifyCredentialsByIssuerResult.handleResult({ + verifyCredentialByDid( + jwtCredentials, + finalizeOffersDescriptor + ) { jwtVerifiableCredentialsResult -> + executor.runOnMain { + completionBlock( + jwtVerifiableCredentialsResult + ) + } + } + }, { error -> + onError(error, completionBlock) + }) + } + }, + errorHandler = { error -> + onError(error, completionBlock) + }) + } + }, + errorHandler = { error -> + onError(error, completionBlock) + }) + } + } private fun verifyCredentialsByDeepLink( jwtCredentials: List, diff --git a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/FinalizeOffersRepository.kt b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/FinalizeOffersRepository.kt index 997512a9..c40a5621 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/FinalizeOffersRepository.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/domain/repositories/FinalizeOffersRepository.kt @@ -16,7 +16,7 @@ internal interface FinalizeOffersRepository { fun finalizeOffers( finalizeOffersDescriptor: VCLFinalizeOffersDescriptor, sessionToken: VCLToken, - proof: VCLJwt, + proof: VCLJwt? = null, completionBlock: (VCLResult>) -> Unit ) } \ No newline at end of file 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 107ee046..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 @@ -45,7 +45,7 @@ class VCLJwtSignServiceLocalImpl( ecKeyResult.handleResult( successHandler = { ecKey -> try { - val header = JWSHeader.Builder(JWSAlgorithm.ES256K) + val header = JWSHeader.Builder(GlobalConfig.SignatureAlgorithm.jwsAlgorithm) .type(JOSEObjectType(GlobalConfig.TypeJwt)) // HeaderValues.XVnfProtocolVersion == VCLXVnfProtocolVersion.XVnfProtocolVersion1 .jwk(ecKey.toPublicJWK()) 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 15213bbc..aee2e6d8 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceLocalImpl.kt @@ -16,6 +16,7 @@ import io.velocitycareerlabs.api.entities.VCLToken import io.velocitycareerlabs.api.entities.handleResult import io.velocitycareerlabs.impl.domain.infrastructure.db.SecretStoreService import io.velocitycareerlabs.api.keys.VCLKeyService +import io.velocitycareerlabs.impl.GlobalConfig import java.util.UUID internal class VCLKeyServiceLocalImpl( @@ -50,7 +51,7 @@ internal class VCLKeyServiceLocalImpl( ) { try { val keyId = UUID.randomUUID().toString() - val ecKey = ECKeyGenerator(Curve.SECP256K1) + 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 a1b16fbd..5a85859d 100644 --- a/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt +++ b/VCL/src/main/java/io/velocitycareerlabs/impl/keys/VCLKeyServiceRemoteImpl.kt @@ -15,6 +15,7 @@ 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 @@ -75,17 +76,16 @@ internal class VCLKeyServiceRemoteImpl( private fun generatePayloadToCreateDidJwk(): JSONObject { val retVal = JSONObject() - retVal.putOpt(CodingKeys.KeyCrv, CodingKeys.ValueCrv) + retVal.putOpt(CodingKeys.KeyCrv, GlobalConfig.SignatureAlgorithm.curve) return retVal } companion object CodingKeys { - val KeyCrv = "crv" - val ValueCrv = "secp256k1" + const val KeyCrv = "crv" - val KeyDid = "did" - val KeyKid = "kid" - val KeyKeyId = "keyId" - val KeyPublicJwk = "publicJwk" + const val KeyDid = "did" + const val KeyKid = "kid" + const val KeyKeyId = "keyId" + const val KeyPublicJwk = "publicJwk" } } \ 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 b26da020..f627ec7e 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/entities/VCLFinalizeOffersDescriptorTest.kt @@ -96,7 +96,7 @@ class VCLFinalizeOffersDescriptorTest { didJwk = didJwk ) { jwtResult -> jwtResult.handleResult({ jwt -> - val requestBody = subject.generateRequestBody(jwt = jwt) + val requestBody = subject.generateRequestBody(proof = jwt) assert((requestBody["exchangeId"] as? String) == "645e315309237c760ac022b1") assert(requestBody["approvedOfferIds"] as? JSONArray == approvedOfferIds.toJsonArray()) 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 df799b48..d6921506 100644 --- a/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt +++ b/VCL/src/test/java/io/velocitycareerlabs/infrastructure/keys/KeyServiceTest.kt @@ -5,8 +5,10 @@ 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.handleResult +import io.velocitycareerlabs.impl.GlobalConfig import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl import io.velocitycareerlabs.impl.extensions.decodeBase64 import io.velocitycareerlabs.impl.extensions.toJsonObject @@ -29,7 +31,33 @@ class KeyServiceTest { } @Test - fun testGenerateDidJwk() { + fun testGenerateDidJwkES256() { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.ES256 + + subject.generateDidJwk(null) { didJwkResult -> + didJwkResult.handleResult({ didJwk -> + val jwkJson = didJwk.publicJwk.valueJson + + assert(didJwk.did.startsWith(VCLDidJwk.DidJwkPrefix)) + assert(didJwk.kid.startsWith(VCLDidJwk.DidJwkPrefix)) + assert(didJwk.kid.endsWith(VCLDidJwk.DidJwkSuffix)) + + assert(jwkJson.optString("kty") == "EC") + 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" } + }) + } + } + + @Test + fun testGenerateDidJwkSecp256k1() { + GlobalConfig.SignatureAlgorithm = VCLSignatureAlgorithm.SECP256k1 + subject.generateDidJwk(null) { didJwkResult -> didJwkResult.handleResult({ didJwk -> val jwkJson = didJwk.publicJwk.valueJson @@ -40,8 +68,7 @@ class KeyServiceTest { assert(jwkJson.optString("kty") == "EC") assert(jwkJson.optString("use") == "sig") - assert(jwkJson.optString("crv") == "secp256k1") -// assert(jwkJson?.optString("alg") == "ES256K") + assert(jwkJson.optString("crv") == VCLSignatureAlgorithm.SECP256k1.curve.name) assert(jwkJson.optString("use") == "sig") assert(jwkJson.optString("x") != null) assert(jwkJson.optString("y") != null) diff --git a/app/src/main/java/com/vcl/wallet/MainActivity.kt b/app/src/main/java/com/vcl/wallet/MainActivity.kt index db748d3c..9eb173e1 100644 --- a/app/src/main/java/com/vcl/wallet/MainActivity.kt +++ b/app/src/main/java/com/vcl/wallet/MainActivity.kt @@ -15,6 +15,7 @@ import io.velocitycareerlabs.api.VCL import io.velocitycareerlabs.api.VCLCryptoServiceType import io.velocitycareerlabs.api.VCLEnvironment import io.velocitycareerlabs.api.VCLProvider +import io.velocitycareerlabs.api.VCLSignatureAlgorithm import io.velocitycareerlabs.api.VCLXVnfProtocolVersion import io.velocitycareerlabs.api.entities.* import io.velocitycareerlabs.api.entities.error.VCLError @@ -75,18 +76,19 @@ class MainActivity : AppCompatActivity() { initializationDescriptor = VCLInitializationDescriptor( environment = environment, xVnfProtocolVersion = VCLXVnfProtocolVersion.XVnfProtocolVersion2, -// cryptoServicesDescriptor = VCLCryptoServicesDescriptor( -// cryptoServiceType = VCLCryptoServiceType.Remote, -// remoteCryptoServicesUrlsDescriptor = VCLRemoteCryptoServicesUrlsDescriptor( -// keyServiceUrls = VCLKeyServiceUrls( -// createDidKeyServiceUrl = Constants.getCreateDidKeyServiceUrl(environment = environment) -// ), -// jwtServiceUrls = VCLJwtServiceUrls( -// jwtSignServiceUrl = Constants.getJwtSignServiceUrl(environment = environment), -// jwtVerifyServiceUrl = Constants.getJwtVerifyServiceUrl(environment = environment) -// ) -// ) -// ) + cryptoServicesDescriptor = VCLCryptoServicesDescriptor( + signatureAlgorithm = VCLSignatureAlgorithm.ES256, + cryptoServiceType = VCLCryptoServiceType.Remote, + remoteCryptoServicesUrlsDescriptor = VCLRemoteCryptoServicesUrlsDescriptor( + keyServiceUrls = VCLKeyServiceUrls( + createDidKeyServiceUrl = Constants.getCreateDidKeyServiceUrl(environment = environment) + ), + jwtServiceUrls = VCLJwtServiceUrls( + jwtSignServiceUrl = Constants.getJwtSignServiceUrl(environment = environment), + jwtVerifyServiceUrl = Constants.getJwtVerifyServiceUrl(environment = environment) + ) + ) + ) ), successHandler = { Log.d(TAG, "VCL Initialization succeed!")