Skip to content

Commit

Permalink
fix(askar): anoncrypt messages unpacking (#1332)
Browse files Browse the repository at this point in the history
Signed-off-by: Ariel Gentile <gentilester@gmail.com>
  • Loading branch information
genaris authored Feb 21, 2023
1 parent fb7ee50 commit 1c6aeae
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 126 deletions.
68 changes: 67 additions & 1 deletion packages/anoncreds/tests/legacyAnonCredsSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@ import {
} from '@aries-framework/core'
import { randomUUID } from 'crypto'

import { AnonCredsRsModule } from '../../anoncreds-rs/src'
import { AskarModule } from '../../askar/src'
import { uuid } from '../../core/src/utils/uuid'
import { setupSubjectTransports, setupEventReplaySubjects } from '../../core/tests'
import {
getAgentOptions,
makeConnection,
genesisTransactions,
taaVersion,
taaAcceptanceMechanism,
waitForCredentialRecordSubject,
waitForProofExchangeRecordSubject,
} from '../../core/tests/helpers'
Expand All @@ -43,6 +49,7 @@ import {
IndySdkSovDidResolver,
} from '../../indy-sdk/src'
import { getIndySdkModuleConfig } from '../../indy-sdk/tests/setupIndySdkModule'
import { IndyVdrAnonCredsRegistry, IndyVdrSovDidResolver, IndyVdrModule } from '../../indy-vdr/src'
import {
V1CredentialProtocol,
V1ProofProtocol,
Expand All @@ -52,7 +59,9 @@ import {
} from '../src'

// Helper type to get the type of the agents (with the custom modules) for the credential tests
export type AnonCredsTestsAgent = Agent<ReturnType<typeof getLegacyAnonCredsModules>>
export type AnonCredsTestsAgent =
| Agent<ReturnType<typeof getLegacyAnonCredsModules>>
| Agent<ReturnType<typeof getAskarAnonCredsIndyModules>>

export const getLegacyAnonCredsModules = ({
autoAcceptCredentials,
Expand Down Expand Up @@ -97,6 +106,63 @@ export const getLegacyAnonCredsModules = ({
return modules
}

export const getAskarAnonCredsIndyModules = ({
autoAcceptCredentials,
autoAcceptProofs,
}: { autoAcceptCredentials?: AutoAcceptCredential; autoAcceptProofs?: AutoAcceptProof } = {}) => {
const legacyIndyCredentialFormatService = new LegacyIndyCredentialFormatService()
const legacyIndyProofFormatService = new LegacyIndyProofFormatService()

const indyNetworkConfig = {
id: `localhost-${uuid()}`,
isProduction: false,
genesisTransactions,
indyNamespace: 'pool:localtest',
transactionAuthorAgreement: { version: taaVersion, acceptanceMechanism: taaAcceptanceMechanism },
}

const modules = {
credentials: new CredentialsModule({
autoAcceptCredentials,
credentialProtocols: [
new V1CredentialProtocol({
indyCredentialFormat: legacyIndyCredentialFormatService,
}),
new V2CredentialProtocol({
credentialFormats: [legacyIndyCredentialFormatService],
}),
],
}),
proofs: new ProofsModule({
autoAcceptProofs,
proofProtocols: [
new V1ProofProtocol({
indyProofFormat: legacyIndyProofFormatService,
}),
new V2ProofProtocol({
proofFormats: [legacyIndyProofFormatService],
}),
],
}),
anoncreds: new AnonCredsModule({
registries: [new IndyVdrAnonCredsRegistry()],
}),
anoncredsRs: new AnonCredsRsModule(),
indyVdr: new IndyVdrModule({
networks: [indyNetworkConfig],
}),
dids: new DidsModule({
resolvers: [new IndyVdrSovDidResolver()], // TODO: Support Registrar for tests
}),
askar: new AskarModule(),
cache: new CacheModule({
cache: new InMemoryLruCache({ limit: 100 }),
}),
} as const

return modules
}

export async function presentLegacyAnonCredsProof({
verifierAgent,
verifierReplay,
Expand Down
8 changes: 4 additions & 4 deletions packages/askar/src/wallet/AskarWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,7 @@ export class AskarWallet implements Wallet {
const protectedJson = JsonEncoder.fromBase64(messagePackage.protected)

const alg = protectedJson.alg
const isAuthcrypt = alg === 'Authcrypt'

if (!isAuthcrypt && alg != 'Anoncrypt') {
if (!['Anoncrypt', 'Authcrypt'].includes(alg)) {
throw new WalletError(`Unsupported pack algorithm: ${alg}`)
}

Expand Down Expand Up @@ -645,6 +643,8 @@ export class AskarWallet implements Wallet {
message: recipient.encrypted_key,
nonce: recipient.iv,
})
} else {
payloadKey = CryptoBox.sealOpen({ ciphertext: recipient.encrypted_key, recipientKey: recip_x })
}
break
}
Expand All @@ -653,7 +653,7 @@ export class AskarWallet implements Wallet {
throw new WalletError('No corresponding recipient key found')
}

if (!senderKey && isAuthcrypt) {
if (!senderKey && alg === 'Authcrypt') {
throw new WalletError('Sender public key not provided for Authcrypt')
}

Expand Down
199 changes: 78 additions & 121 deletions tests/e2e-askar-indy-sdk-wallet-subject.test.ts
Original file line number Diff line number Diff line change
@@ -1,141 +1,98 @@
import type { SubjectMessage } from './transport/SubjectInboundTransport'
import type { AnonCredsTestsAgent } from '../packages/anoncreds/tests/legacyAnonCredsSetup'

import indySdk from 'indy-sdk'
import { Subject } from 'rxjs'

import { getAgentOptions, makeConnection, waitForBasicMessage } from '../packages/core/tests/helpers'
import {
getAskarAnonCredsIndyModules,
getLegacyAnonCredsModules,
} from '../packages/anoncreds/tests/legacyAnonCredsSetup'
import { getAgentOptions } from '../packages/core/tests/helpers'

import { AskarModule } from '@aries-framework/askar'
import { Agent, DependencyManager, InjectionSymbols } from '@aries-framework/core'
import { IndySdkModule, IndySdkStorageService, IndySdkWallet } from '@aries-framework/indy-sdk'
import { Agent, AutoAcceptCredential, MediatorPickupStrategy } from '@aries-framework/core'

import { e2eTest } from './e2e-test'
import { SubjectInboundTransport } from './transport/SubjectInboundTransport'
import { SubjectOutboundTransport } from './transport/SubjectOutboundTransport'

// FIXME: Re-include in tests when Askar NodeJS wrapper performance is improved
describe.skip('E2E Askar-Indy SDK Wallet Subject tests', () => {
let recipientAgent: Agent
let senderAgent: Agent

afterEach(async () => {
if (recipientAgent) {
await recipientAgent.shutdown()
await recipientAgent.wallet.delete()
}

if (senderAgent) {
await senderAgent.shutdown()
await senderAgent.wallet.delete()
}
const recipientAgentOptions = getAgentOptions(
'E2E Askar Subject Recipient',
{
mediatorPickupStrategy: MediatorPickupStrategy.PickUpV1,
},
getAskarAnonCredsIndyModules({
autoAcceptCredentials: AutoAcceptCredential.ContentApproved,
})

test('Wallet Subject flow - Indy Sender / Askar Receiver ', async () => {
// Sender is an Agent using Indy SDK Wallet
const senderDependencyManager = new DependencyManager()
senderDependencyManager.registerContextScoped(InjectionSymbols.Wallet, IndySdkWallet)
senderDependencyManager.registerSingleton(InjectionSymbols.StorageService, IndySdkStorageService)
senderAgent = new Agent(
getAgentOptions(
'E2E Wallet Subject Sender Indy',
{ endpoints: ['rxjs:sender'] },
{ indySdk: new IndySdkModule({ indySdk }) }
),
senderDependencyManager
)

// Recipient is an Agent using Askar Wallet
recipientAgent = new Agent(
getAgentOptions(
'E2E Wallet Subject Recipient Askar',
{ endpoints: ['rxjs:recipient'] },
{ askar: new AskarModule() }
)
)

await e2eWalletTest(senderAgent, recipientAgent)
)
const mediatorAgentOptions = getAgentOptions(
'E2E Askar Subject Mediator',
{
endpoints: ['rxjs:mediator'],
autoAcceptMediationRequests: true,
},
getAskarAnonCredsIndyModules({
autoAcceptCredentials: AutoAcceptCredential.ContentApproved,
})

test('Wallet Subject flow - Askar Sender / Askar Recipient ', async () => {
// Sender is an Agent using Askar Wallet
senderAgent = new Agent(
getAgentOptions('E2E Wallet Subject Sender Askar', { endpoints: ['rxjs:sender'] }, { askar: new AskarModule() })
)

// Recipient is an Agent using Askar Wallet
recipientAgent = new Agent(
getAgentOptions(
'E2E Wallet Subject Recipient Askar',
{ endpoints: ['rxjs:recipient'] },
{ askar: new AskarModule() }
)
)

await e2eWalletTest(senderAgent, recipientAgent)
)
const senderAgentOptions = getAgentOptions(
'E2E Indy SDK Subject Sender',
{
endpoints: ['rxjs:sender'],
mediatorPollingInterval: 1000,
mediatorPickupStrategy: MediatorPickupStrategy.PickUpV1,
},
getLegacyAnonCredsModules({
autoAcceptCredentials: AutoAcceptCredential.ContentApproved,
})
)

test('Wallet Subject flow - Indy Sender / Indy Recipient ', async () => {
// Sender is an Agent using Indy SDK Wallet
const senderDependencyManager = new DependencyManager()
senderDependencyManager.registerContextScoped(InjectionSymbols.Wallet, IndySdkWallet)
senderDependencyManager.registerSingleton(InjectionSymbols.StorageService, IndySdkStorageService)
senderAgent = new Agent(
getAgentOptions(
'E2E Wallet Subject Sender Indy',
{ endpoints: ['rxjs:sender'] },
{ indySdk: new IndySdkModule({ indySdk }) }
),
senderDependencyManager
)
describe.skip('E2E Askar-AnonCredsRS-IndyVDR Subject tests', () => {
let recipientAgent: AnonCredsTestsAgent
let mediatorAgent: AnonCredsTestsAgent
let senderAgent: AnonCredsTestsAgent

// Recipient is an Agent using Indy Wallet
const recipientDependencyManager = new DependencyManager()
recipientDependencyManager.registerContextScoped(InjectionSymbols.Wallet, IndySdkWallet)
recipientDependencyManager.registerSingleton(InjectionSymbols.StorageService, IndySdkStorageService)
recipientAgent = new Agent(
getAgentOptions(
'E2E Wallet Subject Recipient Indy',
{ endpoints: ['rxjs:recipient'] },
{ indySdk: new IndySdkModule({ indySdk }) }
),
recipientDependencyManager
)

await e2eWalletTest(senderAgent, recipientAgent)
beforeEach(async () => {
recipientAgent = new Agent(recipientAgentOptions)
mediatorAgent = new Agent(mediatorAgentOptions)
senderAgent = new Agent(senderAgentOptions)
})
})

export async function e2eWalletTest(senderAgent: Agent, recipientAgent: Agent) {
const recipientMessages = new Subject<SubjectMessage>()
const senderMessages = new Subject<SubjectMessage>()

const subjectMap = {
'rxjs:recipient': recipientMessages,
'rxjs:sender': senderMessages,
}

// Recipient Setup
recipientAgent.registerOutboundTransport(new SubjectOutboundTransport(subjectMap))
recipientAgent.registerInboundTransport(new SubjectInboundTransport(recipientMessages))
await recipientAgent.initialize()

// Sender Setup
senderAgent.registerOutboundTransport(new SubjectOutboundTransport(subjectMap))
senderAgent.registerInboundTransport(new SubjectInboundTransport(senderMessages))
await senderAgent.initialize()
afterEach(async () => {
await recipientAgent.shutdown()
await recipientAgent.wallet.delete()
await mediatorAgent.shutdown()
await mediatorAgent.wallet.delete()
await senderAgent.shutdown()
await senderAgent.wallet.delete()
})

// Make connection between sender and recipient
const [recipientSenderConnection, senderRecipientConnection] = await makeConnection(recipientAgent, senderAgent)
expect(recipientSenderConnection).toBeConnectedWith(senderRecipientConnection)
test('Full Subject flow (connect, request mediation, issue, verify)', async () => {
const mediatorMessages = new Subject<SubjectMessage>()
const senderMessages = new Subject<SubjectMessage>()

// Sender sends a basic message and Recipient waits for it
await senderAgent.basicMessages.sendMessage(senderRecipientConnection.id, 'Hello')
await waitForBasicMessage(recipientAgent, {
content: 'Hello',
})
const subjectMap = {
'rxjs:mediator': mediatorMessages,
'rxjs:sender': senderMessages,
}

// Recipient sends a basic message and Sender waits for it
await recipientAgent.basicMessages.sendMessage(recipientSenderConnection.id, 'How are you?')
await waitForBasicMessage(senderAgent, {
content: 'How are you?',
// Recipient Setup
recipientAgent.registerOutboundTransport(new SubjectOutboundTransport(subjectMap))
await recipientAgent.initialize()

// Mediator Setup
mediatorAgent.registerOutboundTransport(new SubjectOutboundTransport(subjectMap))
mediatorAgent.registerInboundTransport(new SubjectInboundTransport(mediatorMessages))
await mediatorAgent.initialize()

// Sender Setup
senderAgent.registerOutboundTransport(new SubjectOutboundTransport(subjectMap))
senderAgent.registerInboundTransport(new SubjectInboundTransport(senderMessages))
await senderAgent.initialize()

await e2eTest({
mediatorAgent,
senderAgent,
recipientAgent,
})
})
}
})

0 comments on commit 1c6aeae

Please sign in to comment.