Skip to content
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: indy revocation (prover & verifier) #592

Merged
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
c2e15d3
Added recepientRevocation for createProof
TheTreek Jul 16, 2021
14173a4
Initial revocation functions for getRequestedCredentialsForProofRequest
TheTreek Jul 16, 2021
2353f36
Added option to check for revocation status in getRequestedCredentials
TheTreek Jul 19, 2021
3316e0d
sorted transports
burdettadam Jul 22, 2021
20ba447
broken message sender tests
burdettadam Jul 24, 2021
af6431d
structure fix
burdettadam Jul 26, 2021
a8a3fb3
lint import ordering
burdettadam Jul 26, 2021
9d732c8
if(0) does not work.
burdettadam Jul 28, 2021
4db4da6
utf-8 decode ws event.data
burdettadam Jul 28, 2021
178bd6c
indy wallet friendly bits
burdettadam Jul 28, 2021
cfd7ece
correct protocal type
burdettadam Jul 28, 2021
23fe187
check invite during init
burdettadam Jul 28, 2021
d67710c
id check
burdettadam Jul 28, 2021
bc4762d
keep sockets with mediators open
burdettadam Jul 28, 2021
dccb596
recursive backoff
burdettadam Jul 28, 2021
12de34e
timeout
burdettadam Jul 28, 2021
8bcd966
timeout time
burdettadam Jul 28, 2021
6814600
logger
burdettadam Jul 28, 2021
3e6640f
propper recursive backoff
burdettadam Jul 28, 2021
27b4818
multiple socket timeout support
burdettadam Jul 28, 2021
1210bc6
Code cleanup
TheTreek Aug 3, 2021
b515b49
Fix tests and types
TheTreek Aug 3, 2021
6dab351
Formatting and type fixes
TheTreek Aug 3, 2021
67410d3
Recipient revocation functional
TheTreek Aug 6, 2021
27e8425
revocation fixes
TheTreek Aug 6, 2021
4b54f75
ran prettier
TheTreek Aug 6, 2021
9cb1881
chore: add ts ignore until types are updated
JamesKEbert Aug 11, 2021
5f6026a
feat: updated tails download to utilize axios and added inline docs
JamesKEbert Aug 13, 2021
edd6f63
chore: fixed formatting
JamesKEbert Aug 13, 2021
1d45c30
Merge branch 'main' into feature/revocationCleanup
JamesKEbert Aug 21, 2021
0262fd0
chore: removed husky
JamesKEbert Aug 21, 2021
57a6b15
fix: add back husky pre-push
JamesKEbert Aug 21, 2021
0ea5112
chore: formatting
JamesKEbert Aug 21, 2021
ee7934e
chore: merge main
JamesKEbert Oct 15, 2021
1d1a640
fix: fixed error imports
JamesKEbert Oct 19, 2021
59ff98c
chore: resolve dependency loop issues
JamesKEbert Oct 26, 2021
7eceb62
chore: formatting
JamesKEbert Oct 26, 2021
8c34125
chore: merged main
JamesKEbert Dec 7, 2021
b6c8a3f
feature: revocation ledger methods & proof get requested credentials …
JamesKEbert Jan 6, 2022
ab0e433
feature: added revocation state creation
JamesKEbert Jan 6, 2022
64930c3
fix: small tweaks and fixes for revocation
JamesKEbert Jan 6, 2022
11c2a13
feature: takes into account referent revocation intervals
JamesKEbert Jan 6, 2022
3e354a7
chore: cleanup & prettier
JamesKEbert Jan 6, 2022
271c3ad
chore: merge main
JamesKEbert Jan 6, 2022
31a0cd3
fix: fixed createrevocationstate types & initial rev reg def caching
JamesKEbert Jan 6, 2022
4c05c62
chore: formatting
JamesKEbert Jan 6, 2022
f6ea9dd
fix: fixed proofservice test mock
JamesKEbert Jan 6, 2022
264cb57
chore: minor cleanup
JamesKEbert Jan 6, 2022
e8913d9
chore: rename indyutilitiesservice
JamesKEbert Jan 7, 2022
2044f19
chore: troubleshooting revocation, added ledger methods for verifying…
JamesKEbert Jan 27, 2022
1cee54b
chore: cleanup & credential storage w/revocation
JamesKEbert Jan 28, 2022
a89ef94
feat: add download to file method to file system
TimoGlastra Jan 30, 2022
542c0c3
refactor: use rnfs for react native
TimoGlastra Jan 31, 2022
ddb770e
Merge pull request #19 from TimoGlastra/feat/download-to-file-rnfs
JamesKEbert Feb 1, 2022
1240acc
chore: cleanup & log adjustments
JamesKEbert Feb 1, 2022
4f15765
chore: formatting
JamesKEbert Feb 1, 2022
72eff05
feat: verify proofs containing proof of non_revocation
JamesKEbert Feb 1, 2022
02108ae
chore: formatting
JamesKEbert Feb 1, 2022
1a06ae5
Merge branch 'main' into feature/revocationCleanup
JamesKEbert Feb 1, 2022
115c2c8
chore: update indy-sdk-react-native & indy-sdk types
JamesKEbert Feb 1, 2022
b5273c9
chore: resolve yarn.lock conflicts
JamesKEbert Feb 2, 2022
c1d44d0
chore: adjusts names to be consistent & removing abbreviations
JamesKEbert Feb 8, 2022
698ed49
chore: updated indy-sdk types to fix proof identifier types
JamesKEbert Feb 8, 2022
1067f94
fix: indyverifierservice prototype pollution
JamesKEbert Feb 9, 2022
164e2ba
Merge branch 'main' into feature/revocationCleanup
JamesKEbert Feb 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@multiformats/base-x": "^4.0.1",
"@stablelib/ed25519": "^1.0.2",
"@stablelib/sha256": "^1.0.1",
"@types/indy-sdk": "^1.16.8",
"@types/indy-sdk": "^1.16.10",
"@types/node-fetch": "^2.5.10",
"@types/ws": "^7.4.4",
"abort-controller": "^3.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,11 +648,19 @@ export class CredentialService {

const credentialDefinition = await this.ledgerService.getCredentialDefinition(indyCredential.cred_def_id)

//Fetch Revocation Registry Definition if the issued credential has an associated revocation registry id
let revocationRegistryDefinition
if (indyCredential.rev_reg_id) {
const { revocRegDef } = await this.ledgerService.getRevocationRegistryDefinition(indyCredential.rev_reg_id)
revocationRegistryDefinition = revocRegDef
}

const credentialId = await this.indyHolderService.storeCredential({
credentialId: uuid(),
credentialRequestMetadata,
credential: indyCredential,
credentialDefinition,
revocationRegistryDefinition,
})
credentialRecord.credentialId = credentialId
credentialRecord.credentialMessage = issueCredentialMessage
Expand Down
85 changes: 69 additions & 16 deletions packages/core/src/modules/indy/services/IndyHolderService.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,78 @@
import type { Logger } from '../../../logger'
import type { RequestedCredentials } from '../../proofs'
import type * as Indy from 'indy-sdk'

import { Lifecycle, scoped } from 'tsyringe'

import { AgentConfig } from '../../../agent/AgentConfig'
import { IndySdkError } from '../../../error'
import { IndySdkError } from '../../../error/IndySdkError'
import { isIndyError } from '../../../utils/indyError'
import { IndyWallet } from '../../../wallet/IndyWallet'

import { IndyRevocationService } from './IndyRevocationService'

@scoped(Lifecycle.ContainerScoped)
export class IndyHolderService {
private indy: typeof Indy
private logger: Logger
private wallet: IndyWallet
private indyRevocationService: IndyRevocationService

public constructor(agentConfig: AgentConfig, wallet: IndyWallet) {
public constructor(agentConfig: AgentConfig, indyRevocationService: IndyRevocationService, wallet: IndyWallet) {
this.indy = agentConfig.agentDependencies.indy
this.wallet = wallet
this.indyRevocationService = indyRevocationService
this.logger = agentConfig.logger
}

/**
* Creates an Indy Proof in response to a proof request. Will create revocation state if the proof request requests proof of non-revocation
*
* @param proofRequest a Indy proof request
* @param requestedCredentials the requested credentials to use for the proof creation
* @param schemas schemas to use in proof creation
* @param credentialDefinitions credential definitions to use in proof creation
* @throws {Error} if there is an error during proof generation or revocation state generation
* @returns a promise of Indy Proof
*
* @todo support attribute non_revoked fields
*/
public async createProof({
proofRequest,
requestedCredentials,
schemas,
credentialDefinitions,
revocationStates = {},
}: CreateProofOptions) {
}: CreateProofOptions): Promise<Indy.IndyProof> {
try {
return await this.indy.proverCreateProof(
this.logger.debug('Creating Indy Proof')
const revocationStates: Indy.RevStates = await this.indyRevocationService.createRevocationState(
proofRequest,
requestedCredentials
)

const indyProof: Indy.IndyProof = await this.indy.proverCreateProof(
this.wallet.handle,
proofRequest,
requestedCredentials,
requestedCredentials.toJSON(),
this.wallet.masterSecretId,
schemas,
credentialDefinitions,
revocationStates
)

this.logger.trace('Created Indy Proof', {
indyProof,
})

return indyProof
} catch (error) {
throw new IndySdkError(error)
this.logger.error(`Error creating Indy Proof`, {
error,
proofRequest,
requestedCredentials,
})

throw isIndyError(error) ? new IndySdkError(error) : error
}
}

Expand All @@ -49,7 +86,7 @@ export class IndyHolderService {
credential,
credentialDefinition,
credentialId,
revocationRegistryDefinitions,
revocationRegistryDefinition,
}: StoreCredentialOptions): Promise<Indy.CredentialId> {
try {
return await this.indy.proverStoreCredential(
Expand All @@ -58,10 +95,14 @@ export class IndyHolderService {
credentialRequestMetadata,
credential,
credentialDefinition,
revocationRegistryDefinitions ?? null
revocationRegistryDefinition ?? null
)
} catch (error) {
throw new IndySdkError(error)
this.logger.error(`Error storing Indy Credential '${credentialId}'`, {
error,
})

throw isIndyError(error) ? new IndySdkError(error) : error
}
}

Expand All @@ -78,7 +119,11 @@ export class IndyHolderService {
try {
return await this.indy.proverGetCredential(this.wallet.handle, credentialId)
} catch (error) {
throw new IndySdkError(error)
this.logger.error(`Error getting Indy Credential '${credentialId}'`, {
error,
})

throw isIndyError(error) ? new IndySdkError(error) : error
}
}

Expand All @@ -101,7 +146,12 @@ export class IndyHolderService {
this.wallet.masterSecretId
)
} catch (error) {
throw new IndySdkError(error)
this.logger.error(`Error creating Indy Credential Request`, {
error,
credentialOffer,
})

throw isIndyError(error) ? new IndySdkError(error) : error
}
}

Expand Down Expand Up @@ -177,7 +227,11 @@ export class IndyHolderService {

return credentials
} catch (error) {
throw new IndySdkError(error)
this.logger.error(`Error Fetching Indy Credentials For Referent`, {
error,
})

throw isIndyError(error) ? new IndySdkError(error) : error
}
}
}
Expand All @@ -201,13 +255,12 @@ export interface StoreCredentialOptions {
credential: Indy.Cred
credentialDefinition: Indy.CredDef
credentialId?: Indy.CredentialId
revocationRegistryDefinitions?: Indy.RevRegsDefs
revocationRegistryDefinition?: Indy.RevocRegDef
}

export interface CreateProofOptions {
proofRequest: Indy.IndyProofRequest
requestedCredentials: Indy.IndyRequestedCredentials
requestedCredentials: RequestedCredentials
schemas: Indy.Schemas
credentialDefinitions: Indy.CredentialDefs
revocationStates?: Indy.RevStates
}
53 changes: 10 additions & 43 deletions packages/core/src/modules/indy/services/IndyIssuerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import type {
CredReq,
CredRevocId,
CredValues,
BlobReaderHandle,
} from 'indy-sdk'

import { Lifecycle, scoped } from 'tsyringe'
Expand All @@ -18,18 +17,21 @@ import { AgentConfig } from '../../../agent/AgentConfig'
import { AriesFrameworkError } from '../../../error/AriesFrameworkError'
import { IndySdkError } from '../../../error/IndySdkError'
import { isIndyError } from '../../../utils/indyError'
import { getDirFromFilePath } from '../../../utils/path'
import { IndyWallet } from '../../../wallet/IndyWallet'

import { IndyUtilitiesService } from './IndyUtilitiesService'

@scoped(Lifecycle.ContainerScoped)
export class IndyIssuerService {
private indy: typeof Indy
private wallet: IndyWallet
private indyUtilitiesService: IndyUtilitiesService
private fileSystem: FileSystem

public constructor(agentConfig: AgentConfig, wallet: IndyWallet) {
public constructor(agentConfig: AgentConfig, wallet: IndyWallet, indyUtilitiesService: IndyUtilitiesService) {
this.indy = agentConfig.agentDependencies.indy
this.wallet = wallet
this.indyUtilitiesService = indyUtilitiesService
this.fileSystem = agentConfig.fileSystem
}

Expand All @@ -44,7 +46,7 @@ export class IndyIssuerService {

return schema
} catch (error) {
throw new IndySdkError(error)
throw isIndyError(error) ? new IndySdkError(error) : error
}
}

Expand Down Expand Up @@ -74,7 +76,7 @@ export class IndyIssuerService {

return credentialDefinition
} catch (error) {
throw new IndySdkError(error)
throw isIndyError(error) ? new IndySdkError(error) : error
}
}

Expand All @@ -88,7 +90,7 @@ export class IndyIssuerService {
try {
return await this.indy.issuerCreateCredentialOffer(this.wallet.handle, credentialDefinitionId)
} catch (error) {
throw new IndySdkError(error)
throw isIndyError(error) ? new IndySdkError(error) : error
}
}

Expand All @@ -106,7 +108,7 @@ export class IndyIssuerService {
}: CreateCredentialOptions): Promise<[Cred, CredRevocId]> {
try {
// Indy SDK requires tailsReaderHandle. Use null if no tailsFilePath is present
const tailsReaderHandle = tailsFilePath ? await this.createTailsReader(tailsFilePath) : 0
const tailsReaderHandle = tailsFilePath ? await this.indyUtilitiesService.createTailsReader(tailsFilePath) : 0

if (revocationRegistryId || tailsFilePath) {
throw new AriesFrameworkError('Revocation not supported yet')
Expand All @@ -123,42 +125,7 @@ export class IndyIssuerService {

return [credential, credentialRevocationId]
} catch (error) {
if (isIndyError(error)) {
throw new IndySdkError(error)
}

throw error
}
}

/**
* Get a handler for the blob storage tails file reader.
*
* @param tailsFilePath The path of the tails file
* @returns The blob storage reader handle
*/
private async createTailsReader(tailsFilePath: string): Promise<BlobReaderHandle> {
try {
const tailsFileExists = await this.fileSystem.exists(tailsFilePath)

// Extract directory from path (should also work with windows paths)
const dirname = getDirFromFilePath(tailsFilePath)

if (!tailsFileExists) {
throw new AriesFrameworkError(`Tails file does not exist at path ${tailsFilePath}`)
}

const tailsReaderConfig = {
base_dir: dirname,
}

return await this.indy.openBlobStorageReader('default', tailsReaderConfig)
} catch (error) {
if (isIndyError(error)) {
throw new IndySdkError(error)
}

throw error
throw isIndyError(error) ? new IndySdkError(error) : error
}
}
}
Expand Down
Loading