Skip to content

Commit

Permalink
Merge branch 'refactor/remove-indy' into refactor/remove-master-secre…
Browse files Browse the repository at this point in the history
…t-id
  • Loading branch information
TimoGlastra committed Feb 20, 2023
2 parents e7b00f5 + 133fdca commit db6801a
Show file tree
Hide file tree
Showing 53 changed files with 413 additions and 260 deletions.
2 changes: 1 addition & 1 deletion demo/src/Alice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class Alice extends BaseAgent {
public connectionRecordFaberId?: string

public constructor(port: number, name: string) {
super({ port, name, useSharedComponents: false })
super({ port, name, useLegacyIndySdk: true })
this.connected = false
}

Expand Down
25 changes: 12 additions & 13 deletions demo/src/BaseAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs'
import { AskarModule } from '@aries-framework/askar'
import {
TypedArrayEncoder,
KeyType,
DidsModule,
V2ProofProtocol,
Expand Down Expand Up @@ -45,24 +46,24 @@ const indyNetworkConfig = {
connectOnStartup: true,
} satisfies IndySdkPoolConfig | IndyVdrPoolConfig

type DemoAgent = Agent<ReturnType<typeof getIndySdkModules> | ReturnType<typeof getSharedComponentModules>>
type DemoAgent = Agent<ReturnType<typeof getLegacyIndySdkModules> | ReturnType<typeof getAskarAnonCredsIndyModules>>

export class BaseAgent {
public port: number
public name: string
public config: InitConfig
public agent: DemoAgent
public anonCredsIssuerId: string
public usesSharedComponents: boolean
public useLegacyIndySdk: boolean

public constructor({
port,
name,
useSharedComponents,
useLegacyIndySdk = false,
}: {
port: number
name: string
useSharedComponents: boolean
useLegacyIndySdk?: boolean
}) {
this.name = name
this.port = port
Expand All @@ -82,12 +83,12 @@ export class BaseAgent {

// TODO: do not hardcode this
this.anonCredsIssuerId = '2jEvRuKmfBJTRa7QowDpNN'
this.usesSharedComponents = useSharedComponents
this.useLegacyIndySdk = useLegacyIndySdk

this.agent = new Agent({
config,
dependencies: agentDependencies,
modules: useSharedComponents ? getSharedComponentModules() : getIndySdkModules(),
modules: useLegacyIndySdk ? getLegacyIndySdkModules() : getAskarAnonCredsIndyModules(),
})
this.agent.registerInboundTransport(new HttpInboundTransport({ port }))
this.agent.registerOutboundTransport(new HttpOutboundTransport())
Expand All @@ -100,14 +101,12 @@ export class BaseAgent {
// We need to make sure the key to submit transactions is created. We should update this to use the dids module, and allow
// to add an existing did based on a seed/secretKey, and not register it on the the ledger. However for Indy SDK we currently
// use the deprecated publicDidSeed property (which will register the did in the wallet), and for Askar we manually create the key
// in the wallet. Additional issue is that when creating a key in askar using the seed, it will give different results than indy-sdk
// but if we create the key in askar from the seed, but use it as the secret key, it will work.
// For IndySDK we can't call createKey as it won't allow to sign the transactions in that case, as it needs to be a did
if (this.usesSharedComponents) {
// in the wallet.
if (!this.useLegacyIndySdk) {
try {
await this.agent.context.wallet.createKey({
keyType: KeyType.Ed25519,
seed: 'afjdemoverysercure00000000000000',
privateKey: TypedArrayEncoder.fromString('afjdemoverysercure00000000000000'),
})
} catch (error) {
// We assume the key already exists, and that's why askar failed
Expand All @@ -118,7 +117,7 @@ export class BaseAgent {
}
}

function getSharedComponentModules() {
function getAskarAnonCredsIndyModules() {
const legacyIndyCredentialFormatService = new LegacyIndyCredentialFormatService()
const legacyIndyProofFormatService = new LegacyIndyProofFormatService()

Expand Down Expand Up @@ -159,7 +158,7 @@ function getSharedComponentModules() {
} as const
}

function getIndySdkModules() {
function getLegacyIndySdkModules() {
const legacyIndyCredentialFormatService = new LegacyIndyCredentialFormatService()
const legacyIndyProofFormatService = new LegacyIndyProofFormatService()

Expand Down
2 changes: 1 addition & 1 deletion demo/src/Faber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class Faber extends BaseAgent {
public ui: BottomBar

public constructor(port: number, name: string) {
super({ port, name, useSharedComponents: true })
super({ port, name })
this.ui = new ui.BottomBar()
}

Expand Down
6 changes: 3 additions & 3 deletions packages/anoncreds/src/utils/tails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import type { AgentContext, FileSystem } from '@aries-framework/core'

import { TypedArrayEncoder, InjectionSymbols } from '@aries-framework/core'

const getTailsFilePath = (basePath: string, tailsHash: string) => `${basePath}/afj/anoncreds/tails/${tailsHash}`
const getTailsFilePath = (cachePath: string, tailsHash: string) => `${cachePath}/anoncreds/tails/${tailsHash}`

export function tailsFileExists(agentContext: AgentContext, tailsHash: string): Promise<boolean> {
const fileSystem = agentContext.dependencyManager.resolve<FileSystem>(InjectionSymbols.FileSystem)
const tailsFilePath = getTailsFilePath(fileSystem.basePath, tailsHash)
const tailsFilePath = getTailsFilePath(fileSystem.cachePath, tailsHash)

return fileSystem.exists(tailsFilePath)
}
Expand All @@ -27,7 +27,7 @@ export async function downloadTailsFile(

// hash is used as file identifier
const tailsExists = await tailsFileExists(agentContext, tailsHashBase58)
const tailsFilePath = getTailsFilePath(fileSystem.basePath, tailsHashBase58)
const tailsFilePath = getTailsFilePath(fileSystem.cachePath, tailsHashBase58)
agentContext.config.logger.debug(
`Tails file for ${tailsLocation} ${tailsExists ? 'is stored' : 'is not stored'} at ${tailsFilePath}`
)
Expand Down
13 changes: 11 additions & 2 deletions packages/askar/src/utils/askarWalletConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ export const keyDerivationMethodToStoreKeyMethod = (keyDerivationMethod?: KeyDer
return correspondenceTable[keyDerivationMethod] as StoreKeyMethod
}

export const uriFromWalletConfig = (walletConfig: WalletConfig, basePath: string): { uri: string; path?: string } => {
/**
* Creates a proper askar wallet URI value based on walletConfig
* @param walletConfig WalletConfig object
* @param afjDataPath framework data path (used in case walletConfig.storage.path is undefined)
* @returns string containing the askar wallet URI
*/
export const uriFromWalletConfig = (
walletConfig: WalletConfig,
afjDataPath: string
): { uri: string; path?: string } => {
let uri = ''
let path

Expand All @@ -31,7 +40,7 @@ export const uriFromWalletConfig = (walletConfig: WalletConfig, basePath: string
if (walletConfig.storage.inMemory) {
uri = 'sqlite://:memory:'
} else {
path = `${(walletConfig.storage.path as string) ?? basePath + '/wallet'}/${walletConfig.id}/sqlite.db`
path = (walletConfig.storage.path as string) ?? `${afjDataPath}/wallet/${walletConfig.id}/sqlite.db`
uri = `sqlite://${path}`
}
} else if (walletConfig.storage.type === 'postgres') {
Expand Down
24 changes: 16 additions & 8 deletions packages/askar/src/wallet/AskarWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export class AskarWallet implements Wallet {
}

try {
const { uri } = uriFromWalletConfig(this.walletConfig, this.fileSystem.basePath)
const { uri } = uriFromWalletConfig(this.walletConfig, this.fileSystem.dataPath)
await Store.remove(uri)
} catch (error) {
const errorMessage = `Error deleting wallet '${this.walletConfig.id}': ${error.message}`
Expand Down Expand Up @@ -332,21 +332,30 @@ export class AskarWallet implements Wallet {
* Create a key with an optional seed and keyType.
* The keypair is also automatically stored in the wallet afterwards
*
* @param seed string The seed for creating a key
* @param privateKey Buffer Optional privateKey for creating a key
* @param seed string Optional seed for creating a key
* @param keyType KeyType the type of key that should be created
*
* @returns a Key instance with a publicKeyBase58
*
* @throws {WalletError} When an unsupported keytype is requested
* @throws {WalletError} When the key could not be created
*/
public async createKey({ seed, keyType }: WalletCreateKeyOptions): Promise<Key> {
public async createKey({ seed, privateKey, keyType }: WalletCreateKeyOptions): Promise<Key> {
try {
if (seed && privateKey) {
throw new AriesFrameworkError('Only one of seed and privateKey can be set')
}

if (keyTypeSupportedByAskar(keyType)) {
const algorithm = keyAlgFromString(keyType)

// Create key from seed
const key = seed ? AskarKey.fromSeed({ seed: Buffer.from(seed), algorithm }) : AskarKey.generate(algorithm)
// Create key
const key = privateKey
? AskarKey.fromSecretBytes({ secretKey: privateKey, algorithm })
: seed
? AskarKey.fromSeed({ seed, algorithm })
: AskarKey.generate(algorithm)

// Store key
await this.session.insertKey({ key, name: TypedArrayEncoder.toBase58(key.publicBytes) })
Expand All @@ -356,7 +365,7 @@ export class AskarWallet implements Wallet {
if (this.signingKeyProviderRegistry.hasProviderForKeyType(keyType)) {
const signingKeyProvider = this.signingKeyProviderRegistry.getProviderForKeyType(keyType)

const keyPair = await signingKeyProvider.createKeyPair({ seed })
const keyPair = await signingKeyProvider.createKeyPair({ seed, privateKey })
await this.storeKeyPair(keyPair)
return Key.fromPublicKeyBase58(keyPair.publicKeyBase58, keyType)
}
Expand Down Expand Up @@ -384,7 +393,6 @@ export class AskarWallet implements Wallet {
if (!TypedArrayEncoder.isTypedArray(data)) {
throw new WalletError(`Currently not supporting signing of multiple messages`)
}

const keyEntry = await this.session.fetchKey({ name: key.publicKeyBase58 })

if (!keyEntry) {
Expand Down Expand Up @@ -675,7 +683,7 @@ export class AskarWallet implements Wallet {
}

private async getAskarWalletConfig(walletConfig: WalletConfig) {
const { uri, path } = uriFromWalletConfig(walletConfig, this.fileSystem.basePath)
const { uri, path } = uriFromWalletConfig(walletConfig, this.fileSystem.dataPath)

// Make sure path exists before creating the wallet
if (path) {
Expand Down
47 changes: 36 additions & 11 deletions packages/askar/src/wallet/__tests__/AskarWallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const walletConfig: WalletConfig = {
describe('AskarWallet basic operations', () => {
let askarWallet: AskarWallet

const seed = 'sample-seed'
const seed = TypedArrayEncoder.fromString('sample-seed')
const privateKey = TypedArrayEncoder.fromString('2103de41b4ae37e8e28586d84a342b67')
const message = TypedArrayEncoder.fromString('sample-message')

beforeEach(async () => {
Expand All @@ -58,12 +59,36 @@ describe('AskarWallet basic operations', () => {
expect(nonce).toMatch(/[0-9]+/)
})

test('Create ed25519 keypair', async () => {
await expect(
askarWallet.createKey({ seed: '2103de41b4ae37e8e28586d84a342b67', keyType: KeyType.Ed25519 })
).resolves.toMatchObject({
test('Create ed25519 keypair from seed', async () => {
const key = await askarWallet.createKey({
seed,
keyType: KeyType.Ed25519,
})

expect(key).toMatchObject({
keyType: KeyType.Ed25519,
})
})

test('Create ed25519 keypair from private key', async () => {
const key = await askarWallet.createKey({
privateKey,
keyType: KeyType.Ed25519,
})

expect(key).toMatchObject({
keyType: KeyType.Ed25519,
})
})

test('Attempt to create ed25519 keypair from both seed and private key', async () => {
await expect(
askarWallet.createKey({
privateKey,
seed,
keyType: KeyType.Ed25519,
})
).rejects.toThrowError()
})

test('Create x25519 keypair', async () => {
Expand Down Expand Up @@ -101,15 +126,15 @@ describe.skip('Currently, all KeyTypes are supported by Askar natively', () => {
describe('AskarWallet with custom signing provider', () => {
let askarWallet: AskarWallet

const seed = 'sample-seed'
const seed = TypedArrayEncoder.fromString('sample-seed')
const message = TypedArrayEncoder.fromString('sample-message')

class DummySigningProvider implements SigningProvider {
public keyType: KeyType = KeyType.Bls12381g1g2

public async createKeyPair(options: CreateKeyPairOptions): Promise<KeyPair> {
return {
publicKeyBase58: encodeToBase58(Buffer.from(options.seed || 'publicKeyBase58')),
publicKeyBase58: encodeToBase58(Buffer.from(options.seed || TypedArrayEncoder.fromString('publicKeyBase58'))),
privateKeyBase58: 'privateKeyBase58',
keyType: KeyType.Bls12381g1g2,
}
Expand Down Expand Up @@ -167,11 +192,11 @@ describe.skip('Currently, all KeyTypes are supported by Askar natively', () => {
})

test('Attempt to create the same custom keypair twice', async () => {
await askarWallet.createKey({ seed: 'keybase58', keyType: KeyType.Bls12381g1g2 })
await askarWallet.createKey({ seed: TypedArrayEncoder.fromString('keybase58'), keyType: KeyType.Bls12381g1g2 })

await expect(askarWallet.createKey({ seed: 'keybase58', keyType: KeyType.Bls12381g1g2 })).rejects.toThrow(
WalletError
)
await expect(
askarWallet.createKey({ seed: TypedArrayEncoder.fromString('keybase58'), keyType: KeyType.Bls12381g1g2 })
).rejects.toThrow(WalletError)
})
})
})
Expand Down
9 changes: 5 additions & 4 deletions packages/bbs-signatures/src/Bls12381g2SigningProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ export class Bls12381g2SigningProvider implements SigningProvider {
*
* @throws {SigningProviderError} When a key could not be created
*/
public async createKeyPair({ seed }: CreateKeyPairOptions): Promise<KeyPair> {
// Generate bytes from the seed as required by the bbs-signatures libraries
const seedBytes = seed ? TypedArrayEncoder.fromString(seed) : undefined
public async createKeyPair({ seed, privateKey }: CreateKeyPairOptions): Promise<KeyPair> {
if (privateKey) {
throw new SigningProviderError('Cannot create keypair from private key')
}

const blsKeyPair = await generateBls12381G2KeyPair(seedBytes)
const blsKeyPair = await generateBls12381G2KeyPair(seed)

return {
keyType: KeyType.Bls12381g2,
Expand Down
9 changes: 7 additions & 2 deletions packages/bbs-signatures/tests/bbs-signatures.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
W3cPresentation,
W3cVerifiablePresentation,
Ed25519Signature2018,
TypedArrayEncoder,
} from '@aries-framework/core'

import { SignatureSuiteRegistry } from '../../core/src/modules/vc/SignatureSuiteRegistry'
Expand Down Expand Up @@ -63,7 +64,8 @@ describeSkipNode17And18('BBS W3cCredentialService', () => {
let wallet: Wallet
let agentContext: AgentContext
let w3cCredentialService: W3cCredentialService
const seed = 'testseed000000000000000000000001'
const seed = TypedArrayEncoder.fromString('testseed000000000000000000000001')
const privateKey = TypedArrayEncoder.fromString('testseed000000000000000000000001')

beforeAll(async () => {
wallet = new IndySdkWallet(indySdk, agentConfig.logger, signingProviderRegistry)
Expand Down Expand Up @@ -219,7 +221,10 @@ describeSkipNode17And18('BBS W3cCredentialService', () => {

describe('signPresentation', () => {
it('should sign the presentation successfully', async () => {
const signingKey = await wallet.createKey({ seed, keyType: KeyType.Ed25519 })
const signingKey = await wallet.createKey({
privateKey,
keyType: KeyType.Ed25519,
})
const signingDidKey = new DidKey(signingKey)
const verificationMethod = `${signingDidKey.did}#${signingDidKey.key.fingerprint}`
const presentation = JsonTransformer.fromJSON(BbsBlsSignature2020Fixtures.TEST_VP_DOCUMENT, W3cPresentation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const walletConfig: WalletConfig = {

describeSkipNode17And18('BBS Signing Provider', () => {
let wallet: Wallet
const seed = 'sample-seed'
const seed = TypedArrayEncoder.fromString('sample-seed')
const message = TypedArrayEncoder.fromString('sample-message')

beforeEach(async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { V2IssueCredentialMessage } from '../../core/src/modules/credentials/protocol/v2/messages/V2IssueCredentialMessage'
import type { EventReplaySubject, JsonLdTestsAgent } from '../../core/tests'

import { TypedArrayEncoder } from '../../core/src'
import { KeyType } from '../../core/src/crypto'
import { CredentialState } from '../../core/src/modules/credentials/models'
import { CredentialExchangeRecord } from '../../core/src/modules/credentials/repository/CredentialExchangeRecord'
Expand Down Expand Up @@ -64,10 +65,13 @@ describeSkipNode17And18('credentials, BBS+ signature', () => {
holderName: 'Alice Agent Credentials LD BBS+',
}))

await faberAgent.context.wallet.createKey({ keyType: KeyType.Ed25519, seed: 'testseed000000000000000000000001' })
await faberAgent.context.wallet.createKey({
keyType: KeyType.Ed25519,
privateKey: TypedArrayEncoder.fromString('testseed000000000000000000000001'),
})
await faberAgent.context.wallet.createKey({
keyType: KeyType.Bls12381g2,
seed: 'testseed000000000000000000000001',
seed: TypedArrayEncoder.fromString('testseed000000000000000000000001'),
})
})

Expand Down
Loading

0 comments on commit db6801a

Please sign in to comment.