From 8bc8dbcb53776cde8e495905adb7518b01c3c446 Mon Sep 17 00:00:00 2001 From: Ariel Gentile Date: Sat, 1 Apr 2023 11:16:59 -0300 Subject: [PATCH] refactor(anoncreds): master secret to link secret (#1415) Signed-off-by: Ariel Gentile --- demo/package.json | 2 +- packages/anoncreds-rs/package.json | 4 +-- .../src/services/AnonCredsRsHolderService.ts | 36 +++++++++---------- .../src/services/__tests__/helpers.ts | 11 +++--- .../anoncreds-rs/tests/anoncreds-flow.test.ts | 4 +-- packages/anoncreds-rs/tests/indy-flow.test.ts | 4 +-- packages/anoncreds/package.json | 2 +- .../legacy-indy-format-services.test.ts | 4 +-- packages/anoncreds/src/models/internal.ts | 12 ++++--- .../credentialExchangeRecord.test.ts | 8 ++--- .../0.3.1-0.4/credentialExchangeRecord.ts | 7 ++-- .../__tests__/__snapshots__/0.3.test.ts.snap | 4 +-- .../services/IndySdkHolderService.ts | 9 +++-- .../indy-sdk/src/anoncreds/utils/transform.ts | 24 ++++++++++++- yarn.lock | 18 +++++----- 15 files changed, 85 insertions(+), 64 deletions(-) diff --git a/demo/package.json b/demo/package.json index 45b43f4a7f..81f6d992d5 100644 --- a/demo/package.json +++ b/demo/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@hyperledger/indy-vdr-nodejs": "0.1.0-dev.12", - "@hyperledger/anoncreds-nodejs": "^0.1.0-dev.11", + "@hyperledger/anoncreds-nodejs": "^0.1.0-dev.13", "@hyperledger/aries-askar-nodejs": "^0.1.0-dev.6", "inquirer": "^8.2.5" }, diff --git a/packages/anoncreds-rs/package.json b/packages/anoncreds-rs/package.json index 9e74c5ae66..d69a68df0d 100644 --- a/packages/anoncreds-rs/package.json +++ b/packages/anoncreds-rs/package.json @@ -26,14 +26,14 @@ "dependencies": { "@aries-framework/core": "0.3.3", "@aries-framework/anoncreds": "0.3.3", - "@hyperledger/anoncreds-shared": "^0.1.0-dev.11", + "@hyperledger/anoncreds-shared": "^0.1.0-dev.13", "class-transformer": "^0.5.1", "class-validator": "0.14.0", "rxjs": "^7.2.0", "tsyringe": "^4.7.0" }, "devDependencies": { - "@hyperledger/anoncreds-nodejs": "^0.1.0-dev.11", + "@hyperledger/anoncreds-nodejs": "^0.1.0-dev.13", "reflect-metadata": "^0.1.13", "rimraf": "^4.4.0", "typescript": "~4.9.5" diff --git a/packages/anoncreds-rs/src/services/AnonCredsRsHolderService.ts b/packages/anoncreds-rs/src/services/AnonCredsRsHolderService.ts index e543fd32b7..e5f9f1ef39 100644 --- a/packages/anoncreds-rs/src/services/AnonCredsRsHolderService.ts +++ b/packages/anoncreds-rs/src/services/AnonCredsRsHolderService.ts @@ -40,7 +40,7 @@ import { Credential, CredentialRequest, CredentialRevocationState, - MasterSecret, + LinkSecret, Presentation, RevocationRegistryDefinition, RevocationStatusList, @@ -55,19 +55,9 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { agentContext: AgentContext, options?: CreateLinkSecretOptions ): Promise { - let masterSecret: MasterSecret | undefined - try { - masterSecret = MasterSecret.create() - - // FIXME: This is a very specific format of anoncreds-rs. I think it should be simply a string - const linkSecretJson = masterSecret.toJson() as { value: { ms: string } } - - return { - linkSecretId: options?.linkSecretId ?? utils.uuid(), - linkSecretValue: linkSecretJson.value.ms, - } - } finally { - masterSecret?.handle.clear() + return { + linkSecretId: options?.linkSecretId ?? utils.uuid(), + linkSecretValue: LinkSecret.create(), } } @@ -184,7 +174,7 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { credentials: credentials.map((entry) => entry.credentialEntry), credentialsProve, selfAttest: selectedCredentials.selfAttestedAttributes, - masterSecret: { value: { ms: linkSecretRecord.value } }, + linkSecret: linkSecretRecord.value, }) return presentation.toJson() as unknown as AnonCredsProof @@ -216,6 +206,10 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { ) } + if (!linkSecretRecord.value) { + throw new AnonCredsRsError('Link Secret value not stored') + } + const isLegacyIdentifier = credentialOffer.cred_def_id.match(legacyIndyCredentialDefinitionIdRegex) if (!isLegacyIdentifier && useLegacyProverDid) { throw new AriesFrameworkError('Cannot use legacy prover_did with non-legacy identifiers') @@ -227,8 +221,8 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { : undefined, credentialDefinition: credentialDefinition as unknown as JsonObject, credentialOffer: credentialOffer as unknown as JsonObject, - masterSecret: { value: { ms: linkSecretRecord.value } }, - masterSecretId: linkSecretRecord.linkSecretId, + linkSecret: linkSecretRecord.value, + linkSecretId: linkSecretRecord.linkSecretId, }) return { @@ -247,7 +241,11 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { const linkSecretRecord = await agentContext.dependencyManager .resolve(AnonCredsLinkSecretRepository) - .getByLinkSecretId(agentContext, credentialRequestMetadata.master_secret_name) + .getByLinkSecretId(agentContext, credentialRequestMetadata.link_secret_name) + + if (!linkSecretRecord.value) { + throw new AnonCredsRsError('Link Secret value not stored') + } const revocationRegistryDefinition = revocationRegistry?.definition as unknown as JsonObject @@ -260,7 +258,7 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { processedCredential = credentialObj.process({ credentialDefinition: credentialDefinition as unknown as JsonObject, credentialRequestMetadata: credentialRequestMetadata as unknown as JsonObject, - masterSecret: { value: { ms: linkSecretRecord.value } }, + linkSecret: linkSecretRecord.value, revocationRegistryDefinition, }) diff --git a/packages/anoncreds-rs/src/services/__tests__/helpers.ts b/packages/anoncreds-rs/src/services/__tests__/helpers.ts index a6d97632f1..fefc63d9c1 100644 --- a/packages/anoncreds-rs/src/services/__tests__/helpers.ts +++ b/packages/anoncreds-rs/src/services/__tests__/helpers.ts @@ -13,7 +13,7 @@ import { CredentialOffer, CredentialRequest, CredentialRevocationConfig, - MasterSecret, + LinkSecret, RevocationRegistryDefinition, RevocationRegistryDefinitionPrivate, RevocationStatusList, @@ -77,10 +77,7 @@ export function createCredentialOffer(keyCorrectnessProof: Record { credentialDefinitionId: legacyCredentialDefinitionId, }, '_anoncreds/credentialRequest': { - master_secret_blinding_data: expect.any(Object), - master_secret_name: expect.any(String), + link_secret_blinding_data: expect.any(Object), + link_secret_name: expect.any(String), nonce: expect.any(String), }, }) diff --git a/packages/anoncreds/src/models/internal.ts b/packages/anoncreds/src/models/internal.ts index 4693e02859..8aacc72a52 100644 --- a/packages/anoncreds/src/models/internal.ts +++ b/packages/anoncreds/src/models/internal.ts @@ -31,11 +31,13 @@ export interface AnonCredsSelectedCredentials { selfAttestedAttributes: Record } +export interface AnonCredsLinkSecretBlindingData { + v_prime: string + vr_prime: string | null +} + export interface AnonCredsCredentialRequestMetadata { - master_secret_blinding_data: { - v_prime: string - vr_prime: string | null - } - master_secret_name: string + link_secret_blinding_data: AnonCredsLinkSecretBlindingData + link_secret_name: string nonce: string } diff --git a/packages/anoncreds/src/updates/0.3.1-0.4/__tests__/credentialExchangeRecord.test.ts b/packages/anoncreds/src/updates/0.3.1-0.4/__tests__/credentialExchangeRecord.test.ts index 74af775b10..80e5a596c9 100644 --- a/packages/anoncreds/src/updates/0.3.1-0.4/__tests__/credentialExchangeRecord.test.ts +++ b/packages/anoncreds/src/updates/0.3.1-0.4/__tests__/credentialExchangeRecord.test.ts @@ -45,7 +45,7 @@ describe('0.3.1-0.4.0 | AnonCreds Migration | Credential Exchange Record', () => getCredentialRecord({ metadata: { '_internal/indyCredential': { some: 'value' }, - '_internal/indyRequest': { another: 'value' }, + '_internal/indyRequest': { nonce: 'nonce', master_secret_name: 'ms', master_secret_blinding_data: 'msbd' }, }, credentials: [ { @@ -71,7 +71,7 @@ describe('0.3.1-0.4.0 | AnonCreds Migration | Credential Exchange Record', () => expect(credentialRecord.toJSON()).toMatchObject({ metadata: { '_anoncreds/credential': { some: 'value' }, - '_anoncreds/credentialRequest': { another: 'value' }, + '_anoncreds/credentialRequest': { nonce: 'nonce', link_secret_name: 'ms', link_secret_blinding_data: 'msbd' }, }, credentials: [ { @@ -92,7 +92,7 @@ describe('0.3.1-0.4.0 | AnonCreds Migration | Credential Exchange Record', () => const record = getCredentialRecord({ metadata: { '_internal/indyCredential': { some: 'value' }, - '_internal/indyRequest': { another: 'value' }, + '_internal/indyRequest': { nonce: 'nonce', master_secret_name: 'ms', master_secret_blinding_data: 'msbd' }, }, }) @@ -101,7 +101,7 @@ describe('0.3.1-0.4.0 | AnonCreds Migration | Credential Exchange Record', () => expect(record.toJSON()).toMatchObject({ metadata: { '_anoncreds/credential': { some: 'value' }, - '_anoncreds/credentialRequest': { another: 'value' }, + '_anoncreds/credentialRequest': { nonce: 'nonce', link_secret_name: 'ms', link_secret_blinding_data: 'msbd' }, }, }) }) diff --git a/packages/anoncreds/src/updates/0.3.1-0.4/credentialExchangeRecord.ts b/packages/anoncreds/src/updates/0.3.1-0.4/credentialExchangeRecord.ts index 526270d81f..b181f42a61 100644 --- a/packages/anoncreds/src/updates/0.3.1-0.4/credentialExchangeRecord.ts +++ b/packages/anoncreds/src/updates/0.3.1-0.4/credentialExchangeRecord.ts @@ -131,8 +131,11 @@ export function migrateIndyCredentialMetadataToAnonCredsMetadata in the indy-sdk, but the anoncreds package contains the correct type - options.credentialRequestMetadata as unknown as CredReqMetadata, + indySdkCredentialRequestMetadataFromAnonCreds(options.credentialRequestMetadata), options.credential, indySdkCredentialDefinitionFromAnonCreds(options.credentialDefinitionId, options.credentialDefinition), indyRevocationRegistryDefinition @@ -277,7 +276,7 @@ export class IndySdkHolderService implements AnonCredsHolderService { return { credentialRequest: result[0], // The type is typed as a Record in the indy-sdk, but the anoncreds package contains the correct type - credentialRequestMetadata: result[1] as unknown as AnonCredsCredentialRequestMetadata, + credentialRequestMetadata: anonCredsCredentialRequestMetadataFromIndySdk(result[1]), } } catch (error) { agentContext.config.logger.error(`Error creating Indy Credential Request`, { diff --git a/packages/indy-sdk/src/anoncreds/utils/transform.ts b/packages/indy-sdk/src/anoncreds/utils/transform.ts index a993475349..06b4b16698 100644 --- a/packages/indy-sdk/src/anoncreds/utils/transform.ts +++ b/packages/indy-sdk/src/anoncreds/utils/transform.ts @@ -3,8 +3,10 @@ import type { AnonCredsRevocationStatusList, AnonCredsRevocationRegistryDefinition, AnonCredsSchema, + AnonCredsCredentialRequestMetadata, + AnonCredsLinkSecretBlindingData, } from '@aries-framework/anoncreds' -import type { CredDef, RevocReg, RevocRegDef, RevocRegDelta, Schema } from 'indy-sdk' +import type { CredDef, CredReqMetadata, RevocReg, RevocRegDef, RevocRegDelta, Schema } from 'indy-sdk' import { parseCredentialDefinitionId, parseSchemaId } from './identifiers' @@ -136,3 +138,23 @@ export function indySdkRevocationDeltaFromAnonCreds( ver: '1.0', } } + +export function anonCredsCredentialRequestMetadataFromIndySdk( + credentialRequestMetadata: CredReqMetadata +): AnonCredsCredentialRequestMetadata { + return { + link_secret_blinding_data: credentialRequestMetadata.master_secret_blinding_data as AnonCredsLinkSecretBlindingData, + link_secret_name: credentialRequestMetadata.master_secret_name as string, + nonce: credentialRequestMetadata.nonce as string, + } +} + +export function indySdkCredentialRequestMetadataFromAnonCreds( + credentialRequestMetadata: AnonCredsCredentialRequestMetadata +): CredReqMetadata { + return { + master_secret_blinding_data: credentialRequestMetadata.link_secret_blinding_data, + master_secret_name: credentialRequestMetadata.link_secret_name, + nonce: credentialRequestMetadata.nonce, + } +} diff --git a/yarn.lock b/yarn.lock index 10600e83b5..93024b56e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -881,12 +881,12 @@ resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== -"@hyperledger/anoncreds-nodejs@^0.1.0-dev.11": - version "0.1.0-dev.11" - resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-nodejs/-/anoncreds-nodejs-0.1.0-dev.11.tgz#301b9bc5a4bb0235212ac48da2bf41118b407cdd" - integrity sha512-4BSHOGOdXjF4pyJuEjwk0iaSHeqt5UdXRXNv+u9VJ7yYhqM/aJZNhtUAgHXu8KGZwimFcFsp2e0FoLqwO0vLHQ== +"@hyperledger/anoncreds-nodejs@^0.1.0-dev.13": + version "0.1.0-dev.13" + resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-nodejs/-/anoncreds-nodejs-0.1.0-dev.13.tgz#65b60be1c5ff077457ccd2f8298e71f198a8984f" + integrity sha512-W6Hoxp4lzcdv6yIQruK0CJDH52n79yQ8XCekFNmkUsXxpycB8Ts2M1o3KKRPa68AYM3CzmcN2Nw8pE7XqqEMyQ== dependencies: - "@hyperledger/anoncreds-shared" "0.1.0-dev.11" + "@hyperledger/anoncreds-shared" "0.1.0-dev.13" "@mapbox/node-pre-gyp" "^1.0.10" ffi-napi "4.0.3" node-cache "5.1.2" @@ -894,10 +894,10 @@ ref-napi "3.0.3" ref-struct-di "1.1.1" -"@hyperledger/anoncreds-shared@0.1.0-dev.11", "@hyperledger/anoncreds-shared@^0.1.0-dev.11": - version "0.1.0-dev.11" - resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-shared/-/anoncreds-shared-0.1.0-dev.11.tgz#206328cabcd855ef20c863ab5c2615a3a4c2502c" - integrity sha512-nK05y/qNtI3P+hnkVZW/d5oduMa7slZfEh2gQ+ZmAEmwHEcSU8iJ+QTkKS3nRE+6igXUvVAztlGS7JZHf21KKw== +"@hyperledger/anoncreds-shared@0.1.0-dev.13", "@hyperledger/anoncreds-shared@^0.1.0-dev.13": + version "0.1.0-dev.13" + resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-shared/-/anoncreds-shared-0.1.0-dev.13.tgz#e78768366e6d7dd6e65839b769b857fbd828bce7" + integrity sha512-UtR2zCrugTa/Mu6LqAiEX1NJw1bdaf65wqcdS/k9efcq0iY1slQb+qg/KWEf+pZZFVa6NmkjAwmdyrzVbu9WTQ== "@hyperledger/aries-askar-nodejs@^0.1.0-dev.6": version "0.1.0-dev.6"