-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(anoncreds): use legacy prover did #1374
Changes from 8 commits
e553b1e
d989f10
44bd6e5
b3bb7ee
5a22d86
0378ed4
32f17d7
cc03c05
5f17ee8
b8a586e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,8 +30,10 @@ import { | |
AnonCredsCredentialRecord, | ||
AnonCredsLinkSecretRepository, | ||
AnonCredsCredentialRepository, | ||
generateLegacyProverDidLikeString, | ||
legacyIndyCredentialDefinitionIdRegex, | ||
} from '@aries-framework/anoncreds' | ||
import { utils, injectable } from '@aries-framework/core' | ||
import { AriesFrameworkError, utils, injectable } from '@aries-framework/core' | ||
import { | ||
anoncreds, | ||
Credential, | ||
|
@@ -193,7 +195,7 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { | |
agentContext: AgentContext, | ||
options: CreateCredentialRequestOptions | ||
): Promise<CreateCredentialRequestReturn> { | ||
const { credentialDefinition, credentialOffer } = options | ||
const { useLegacyProverDid, credentialDefinition, credentialOffer } = options | ||
let createReturnObj: | ||
| { credentialRequest: CredentialRequest; credentialRequestMetadata: CredentialRequestMetadata } | ||
| undefined | ||
|
@@ -212,8 +214,14 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService { | |
) | ||
} | ||
|
||
const isLegacyIdentifier = credentialOffer.cred_def_id.match(legacyIndyCredentialDefinitionIdRegex) | ||
if (!isLegacyIdentifier && useLegacyProverDid) { | ||
throw new AriesFrameworkError('Cannot use legacy prover_did with non-legacy identifiers') | ||
} | ||
|
||
createReturnObj = CredentialRequest.create({ | ||
entropy: anoncreds.generateNonce(), // FIXME: find a better source of entropy | ||
entropy: !useLegacyProverDid || !isLegacyIdentifier ? anoncreds.generateNonce() : undefined, // FIXME: find a better source of entropy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another option for generating entropy can be calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels like we're misusing the generateWalletKey in that case. I think a nonce should provide enough randomness right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMHO the nonce generated by anoncreds, apart from being convenient for us, is enough for the purposes of giving some entropy in credential generation. But just trying to find an alternative that provides a true 'alphanumeric' random string as stated in the spec. |
||
proverDid: useLegacyProverDid ? generateLegacyProverDidLikeString() : undefined, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As it should be random, do wr need to make this a secure ranom generation? E.g. nonce and then encode it as base58? We could also add a getRandomBytes method to the wallet? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I copied it from anoncreds/indy-sdk package implementation, but also thought that could be a good idea to rely in anoncreds native library instead of uuid as it's being done currently in Any 22-bytes long base58 string will be good for that purpose, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As it's used for entropy, it may be needed for the string to be generated with actual secure random bytes instead of a random string? |
||
credentialDefinition: credentialDefinition as unknown as JsonObject, | ||
credentialOffer: credentialOffer as unknown as JsonObject, | ||
masterSecret: { value: { ms: linkSecretRecord.value } }, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,8 @@ import { | |
checkValidCredentialValueEncoding, | ||
encodeCredentialValue, | ||
assertNoDuplicateGroupsNamesInProofRequest, | ||
legacyIndyCredentialDefinitionIdRegex, | ||
legacyIndySchemaIdRegex, | ||
} from '../utils' | ||
|
||
const V2_INDY_PRESENTATION_PROPOSAL = 'hlindy/[email protected]' | ||
|
@@ -471,6 +473,10 @@ export class LegacyIndyProofFormatService implements ProofFormatService<LegacyIn | |
const schemas: { [key: string]: AnonCredsSchema } = {} | ||
|
||
for (const schemaId of schemaIds) { | ||
if (!schemaId.match(legacyIndySchemaIdRegex)) { | ||
throw new AriesFrameworkError(`${schemaId} is not a valid legacy indy schema id`) | ||
} | ||
|
||
const schemaRegistry = registryService.getRegistryForIdentifier(agentContext, schemaId) | ||
const schemaResult = await schemaRegistry.getSchema(agentContext, schemaId) | ||
|
||
|
@@ -499,6 +505,10 @@ export class LegacyIndyProofFormatService implements ProofFormatService<LegacyIn | |
const credentialDefinitions: { [key: string]: AnonCredsCredentialDefinition } = {} | ||
|
||
for (const credentialDefinitionId of credentialDefinitionIds) { | ||
if (!credentialDefinitionId.match(legacyIndyCredentialDefinitionIdRegex)) { | ||
Check failure Code scanning / CodeQL Polynomial regular expression used on uncontrolled data
This [regular expression](1) that depends on [library input](2) may run slow on strings with many repetitions of 'a:.:a'.
This [regular expression](1) that depends on [library input](3) may run slow on strings with many repetitions of 'a:.:a'.
|
||
throw new AriesFrameworkError(`${credentialDefinitionId} is not a valid legacy indy credential definition id`) | ||
} | ||
|
||
const credentialDefinitionRegistry = registryService.getRegistryForIdentifier( | ||
agentContext, | ||
credentialDefinitionId | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,22 +41,26 @@ export class InMemoryAnonCredsRegistry implements AnonCredsRegistry { | |
private credentialDefinitions: Record<string, AnonCredsCredentialDefinition> | ||
private revocationRegistryDefinitions: Record<string, AnonCredsRevocationRegistryDefinition> | ||
private revocationStatusLists: Record<string, Record<string, AnonCredsRevocationStatusList>> | ||
private useLegacyIdentifiers: boolean | ||
|
||
public constructor({ | ||
existingSchemas = {}, | ||
existingCredentialDefinitions = {}, | ||
existingRevocationRegistryDefinitions = {}, | ||
existingRevocationStatusLists = {}, | ||
useLegacyIdentifiers = false, | ||
}: { | ||
existingSchemas?: Record<string, AnonCredsSchema> | ||
existingCredentialDefinitions?: Record<string, AnonCredsCredentialDefinition> | ||
existingRevocationRegistryDefinitions?: Record<string, AnonCredsRevocationRegistryDefinition> | ||
existingRevocationStatusLists?: Record<string, Record<string, AnonCredsRevocationStatusList>> | ||
useLegacyIdentifiers?: boolean | ||
} = {}) { | ||
this.schemas = existingSchemas | ||
this.credentialDefinitions = existingCredentialDefinitions | ||
this.revocationRegistryDefinitions = existingRevocationRegistryDefinitions | ||
this.revocationStatusLists = existingRevocationStatusLists | ||
this.useLegacyIdentifiers = useLegacyIdentifiers | ||
} | ||
|
||
public async getSchema(agentContext: AgentContext, schemaId: string): Promise<GetSchemaReturn> { | ||
|
@@ -94,21 +98,23 @@ export class InMemoryAnonCredsRegistry implements AnonCredsRegistry { | |
agentContext: AgentContext, | ||
options: RegisterSchemaOptions | ||
): Promise<RegisterSchemaReturn> { | ||
const { namespaceIdentifier, namespace } = parseIndyDid(options.schema.issuerId) | ||
const didIndySchemaId = getDidIndySchemaId( | ||
namespace, | ||
namespaceIdentifier, | ||
options.schema.name, | ||
options.schema.version | ||
) | ||
const legacySchemaId = getLegacySchemaId(namespaceIdentifier, options.schema.name, options.schema.version) | ||
let legacyIssuerId | ||
let didIndySchemaId = '' | ||
if (this.useLegacyIdentifiers) { | ||
legacyIssuerId = options.schema.issuerId | ||
} else { | ||
const { namespace, namespaceIdentifier } = parseIndyDid(options.schema.issuerId) | ||
legacyIssuerId = namespaceIdentifier | ||
didIndySchemaId = getDidIndySchemaId(namespace, namespaceIdentifier, options.schema.name, options.schema.version) | ||
this.schemas[didIndySchemaId] = options.schema | ||
} | ||
|
||
const legacySchemaId = getLegacySchemaId(legacyIssuerId, options.schema.name, options.schema.version) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The old implementation supported both for convenience, why is this needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If schema issuerId is an unqualified did, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's for tests, so whatever works |
||
const indyLedgerSeqNo = getSeqNoFromSchemaId(legacySchemaId) | ||
|
||
this.schemas[didIndySchemaId] = options.schema | ||
this.schemas[legacySchemaId] = { | ||
...options.schema, | ||
issuerId: namespaceIdentifier, | ||
issuerId: legacyIssuerId, | ||
} | ||
|
||
return { | ||
|
@@ -121,7 +127,7 @@ export class InMemoryAnonCredsRegistry implements AnonCredsRegistry { | |
schemaState: { | ||
state: 'finished', | ||
schema: options.schema, | ||
schemaId: didIndySchemaId, | ||
schemaId: this.useLegacyIdentifiers ? legacySchemaId : didIndySchemaId, | ||
}, | ||
} | ||
} | ||
|
@@ -163,24 +169,32 @@ export class InMemoryAnonCredsRegistry implements AnonCredsRegistry { | |
) | ||
const indyLedgerSeqNo = getSeqNoFromSchemaId(legacySchemaId) | ||
|
||
const { namespaceIdentifier, namespace } = parseIndyDid(options.credentialDefinition.issuerId) | ||
let legacyIssuerId | ||
let didIndyCredentialDefinitionId = '' | ||
if (this.useLegacyIdentifiers) { | ||
legacyIssuerId = options.credentialDefinition.issuerId | ||
} else { | ||
const { namespace, namespaceIdentifier } = parseIndyDid(options.credentialDefinition.issuerId) | ||
legacyIssuerId = namespaceIdentifier | ||
didIndyCredentialDefinitionId = getDidIndyCredentialDefinitionId( | ||
namespace, | ||
namespaceIdentifier, | ||
indyLedgerSeqNo, | ||
options.credentialDefinition.tag | ||
) | ||
|
||
this.credentialDefinitions[didIndyCredentialDefinitionId] = options.credentialDefinition | ||
} | ||
|
||
const didIndyCredentialDefinitionId = getDidIndyCredentialDefinitionId( | ||
namespace, | ||
namespaceIdentifier, | ||
indyLedgerSeqNo, | ||
options.credentialDefinition.tag | ||
) | ||
const legacyCredentialDefinitionId = getLegacyCredentialDefinitionId( | ||
namespaceIdentifier, | ||
legacyIssuerId, | ||
indyLedgerSeqNo, | ||
options.credentialDefinition.tag | ||
) | ||
|
||
this.credentialDefinitions[didIndyCredentialDefinitionId] = options.credentialDefinition | ||
this.credentialDefinitions[legacyCredentialDefinitionId] = { | ||
...options.credentialDefinition, | ||
issuerId: namespaceIdentifier, | ||
issuerId: legacyIssuerId, | ||
schemaId: legacySchemaId, | ||
} | ||
|
||
|
@@ -190,7 +204,9 @@ export class InMemoryAnonCredsRegistry implements AnonCredsRegistry { | |
credentialDefinitionState: { | ||
state: 'finished', | ||
credentialDefinition: options.credentialDefinition, | ||
credentialDefinitionId: didIndyCredentialDefinitionId, | ||
credentialDefinitionId: this.useLegacyIdentifiers | ||
? legacyCredentialDefinitionId | ||
: didIndyCredentialDefinitionId, | ||
}, | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -864,23 +864,23 @@ | |
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.9": | ||
version "0.1.0-dev.9" | ||
resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-nodejs/-/anoncreds-nodejs-0.1.0-dev.9.tgz#5f09d5f147ce204abd9b3cea486c23e556cc8fdc" | ||
integrity sha512-Ht5Gt1DfnFiRIY+AlTpe8Hcdryb+jKl79hGQ3kszdct/1JFZ70A81ssfwX0VKYTdCHt5jK5cJzVaOjOVmBKZiw== | ||
"@hyperledger/anoncreds-nodejs@^0.1.0-dev.10": | ||
version "0.1.0-dev.10" | ||
resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-nodejs/-/anoncreds-nodejs-0.1.0-dev.10.tgz#80c093ecb08a277fb494399b64aad1b900c3103f" | ||
integrity sha512-ju5mJPwuyebAPziuf+eUOwxEws02G2FHEp/qG3GV3kxtlx7THW7HVB7dMSNqhRVKCsbcNnZtWJB1UiPvWqboUg== | ||
dependencies: | ||
"@hyperledger/anoncreds-shared" "0.1.0-dev.9" | ||
"@hyperledger/anoncreds-shared" "0.1.0-dev.10" | ||
"@mapbox/node-pre-gyp" "^1.0.10" | ||
ffi-napi "4.0.3" | ||
node-cache "5.1.2" | ||
ref-array-di "1.2.2" | ||
ref-napi "3.0.3" | ||
ref-struct-di "1.1.1" | ||
|
||
"@hyperledger/[email protected].9", "@hyperledger/anoncreds-shared@^0.1.0-dev.9": | ||
version "0.1.0-dev.9" | ||
resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-shared/-/anoncreds-shared-0.1.0-dev.9.tgz#7f6a033997e2641432a51ff2b609d603b3f9ab50" | ||
integrity sha512-xbWEB9Z9PwkxC2awx74xt1OULMxihbK2v7818Dtrrmun75gNBXF8Jdorn9+t+TEd62QLrJpVUJ1ZCKhXPx81zw== | ||
"@hyperledger/[email protected].10", "@hyperledger/anoncreds-shared@^0.1.0-dev.10": | ||
version "0.1.0-dev.10" | ||
resolved "https://registry.yarnpkg.com/@hyperledger/anoncreds-shared/-/anoncreds-shared-0.1.0-dev.10.tgz#9d67f64e98ff41971644c95b03dabafd741df4df" | ||
integrity sha512-POvcwQrUcPrwoZehQa38pN1dnjyeUlrQ6VlksbBRS8SUHJuyixZsD+d3XoumqaNfl9Z1DCjfuOgEiPlec01gXQ== | ||
|
||
"@hyperledger/aries-askar-nodejs@^0.1.0-dev.4": | ||
version "0.1.0-dev.4" | ||
|
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data