Skip to content

Commit

Permalink
Merge pull request #127 from blu3beri/fix/argon2i-support
Browse files Browse the repository at this point in the history
  • Loading branch information
berendsliedrecht authored Apr 3, 2023
2 parents 91e3e45 + 8108823 commit 9f088c8
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ function handleReturnPointer<Return>(returnValue: Buffer): Return {
export class NodeJSAriesAskar implements AriesAskar {
private promisify = async (method: (nativeCallbackPtr: Buffer, id: number) => void): Promise<void> => {
return new Promise((resolve, reject) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const cb: NativeCallback = (id, _) => {
deallocateCallbackBuffer(id)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ariesAskar, Migration } from '@hyperledger/aries-askar-shared'
import { Migration } from '@hyperledger/aries-askar-shared'
import fs from 'fs'
import path from 'path'

Expand Down
40 changes: 34 additions & 6 deletions wrappers/javascript/aries-askar-nodejs/tests/store.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Store, StoreKeyMethod, Key, KeyAlgs, AriesAskarError } from '@hyperledger/aries-askar-shared'
import { Store, StoreKeyMethod, Key, KeyAlgs, AriesAskarError, KdfMethod } from '@hyperledger/aries-askar-shared'
import { promises } from 'fs'

import { firstEntry, getRawKey, secondEntry, setupWallet, testStoreUri } from './utils'
Expand All @@ -18,6 +18,34 @@ describe('Store and Session', () => {
await store.close(true)
})

test('argon2i mod', async () => {
const argon2iModStore = await Store.provision({
recreate: true,
passKey: 'abc',
uri: testStoreUri,
keyMethod: new StoreKeyMethod(KdfMethod.Argon2IMod),
})

const session = await argon2iModStore.openSession()
await expect(session.fetch({ name: 'unknownKey', category: 'unknownCategory' })).resolves.toBeNull()

await argon2iModStore.close()
})

test('argon2i int', async () => {
const argon2iIntStore = await Store.provision({
recreate: true,
passKey: 'abc',
uri: testStoreUri,
keyMethod: new StoreKeyMethod(KdfMethod.Argon2IInt),
})

const session = await argon2iIntStore.openSession()
await expect(session.fetch({ name: 'unknownKey', category: 'unknownCategory' })).resolves.toBeNull()

await argon2iIntStore.close()
})

test('Rekey', async () => {
const initialKey = Store.generateRawKey()

Expand All @@ -33,28 +61,28 @@ describe('Store and Session', () => {
recreate: true,
profile: 'rekey',
uri: `sqlite://${storagePath}/rekey.db`,
keyMethod: StoreKeyMethod.Raw,
keyMethod: new StoreKeyMethod(KdfMethod.Raw),
passKey: initialKey,
})

const newKey = Store.generateRawKey()
await newStore.rekey({ keyMethod: StoreKeyMethod.Raw, passKey: newKey })
await newStore.rekey({ keyMethod: new StoreKeyMethod(KdfMethod.Raw), passKey: newKey })

await newStore.close()

await expect(
Store.open({
profile: 'rekey',
uri: `sqlite://${storagePath}/rekey.db`,
keyMethod: StoreKeyMethod.Raw,
keyMethod: new StoreKeyMethod(KdfMethod.Raw),
passKey: initialKey,
})
).rejects.toThrowError(AriesAskarError)

newStore = await Store.open({
profile: 'rekey',
uri: `sqlite://${storagePath}/rekey.db`,
keyMethod: StoreKeyMethod.Raw,
keyMethod: new StoreKeyMethod(KdfMethod.Raw),
passKey: newKey,
})

Expand Down Expand Up @@ -215,7 +243,7 @@ describe('Store and Session', () => {
if (!store.uri.includes(':memory:')) {
// Test accessing profile after re-opening
const key = getRawKey()
const store2 = await Store.open({ uri: testStoreUri, keyMethod: StoreKeyMethod.Raw, passKey: key })
const store2 = await Store.open({ uri: testStoreUri, keyMethod: new StoreKeyMethod(KdfMethod.Raw), passKey: key })
const session3 = await store2.openSession()
//Should not find previously stored record
await expect(session3.count(firstEntry)).resolves.toStrictEqual(0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '@hyperledger/aries-askar-nodejs'
import { Store, StoreKeyMethod } from '@hyperledger/aries-askar-shared'
import { Store, StoreKeyMethod, KdfMethod } from '@hyperledger/aries-askar-shared'

export const getRawKey = () => Store.generateRawKey(Buffer.from('00000000000000000000000000000My1'))
export const testStoreUri = process.env.URI || 'sqlite://:memory:'
Expand All @@ -10,7 +10,7 @@ export const setupWallet = async () => {
return await Store.provision({
recreate: true,
uri: testStoreUri,
keyMethod: StoreKeyMethod.Raw,
keyMethod: new StoreKeyMethod(KdfMethod.Raw),
passKey: key,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { CallbackWithResponse, ReturnObject } from '../utils'

type LocalKeyHandle = string

// TODO: convert all any types
// TODO: convert all unknown types
export interface NativeBindings {
version(options: Record<string, never>): string
getCurrentError(options: Record<string, never>): string
Expand Down Expand Up @@ -37,117 +37,117 @@ export interface NativeBindings {

keyAeadGetParams(options: { localKeyHandle: string }): ReturnObject<{ nonceLength: number; tagLength: number }>

keyAeadRandomNonce(options: any): ReturnObject<ArrayBuffer>
keyAeadRandomNonce(options: unknown): ReturnObject<ArrayBuffer>

keyConvert(options: any): ReturnObject<LocalKeyHandle>
keyConvert(options: unknown): ReturnObject<LocalKeyHandle>

keyCryptoBox(options: any): ReturnObject<ArrayBuffer>
keyCryptoBox(options: unknown): ReturnObject<ArrayBuffer>

keyCryptoBoxOpen(options: any): ReturnObject<ArrayBuffer>
keyCryptoBoxOpen(options: unknown): ReturnObject<ArrayBuffer>

keyCryptoBoxRandomNonce(options: Record<string, never>): ReturnObject<ArrayBuffer>

keyCryptoBoxSeal(options: any): ReturnObject<ArrayBuffer>
keyCryptoBoxSeal(options: unknown): ReturnObject<ArrayBuffer>

keyCryptoBoxSealOpen(options: any): ReturnObject<ArrayBuffer>
keyCryptoBoxSealOpen(options: unknown): ReturnObject<ArrayBuffer>

keyDeriveEcdh1pu(options: any): ReturnObject<LocalKeyHandle>
keyDeriveEcdh1pu(options: unknown): ReturnObject<LocalKeyHandle>

keyDeriveEcdhEs(options: any): ReturnObject<LocalKeyHandle>
keyDeriveEcdhEs(options: unknown): ReturnObject<LocalKeyHandle>

keyEntryListCount(options: any): ReturnObject<number>
keyEntryListCount(options: unknown): ReturnObject<number>

keyEntryListFree(options: any): ReturnObject<never>
keyEntryListFree(options: unknown): ReturnObject<never>

keyEntryListGetAlgorithm(options: any): ReturnObject<string>
keyEntryListGetAlgorithm(options: unknown): ReturnObject<string>

keyEntryListGetMetadata(options: any): ReturnObject<string>
keyEntryListGetMetadata(options: unknown): ReturnObject<string>

keyEntryListGetName(options: any): ReturnObject<string>
keyEntryListGetName(options: unknown): ReturnObject<string>

keyEntryListGetTags(options: any): ReturnObject<string>
keyEntryListGetTags(options: unknown): ReturnObject<string>

keyEntryListLoadLocal(options: any): ReturnObject<LocalKeyHandle>
keyEntryListLoadLocal(options: unknown): ReturnObject<LocalKeyHandle>

keyFree(options: any): ReturnObject<never>
keyFree(options: unknown): ReturnObject<never>

keyFromJwk(options: any): ReturnObject<LocalKeyHandle>
keyFromJwk(options: unknown): ReturnObject<LocalKeyHandle>

keyFromKeyExchange(options: any): ReturnObject<LocalKeyHandle>
keyFromKeyExchange(options: unknown): ReturnObject<LocalKeyHandle>

keyFromPublicBytes(options: any): ReturnObject<LocalKeyHandle>
keyFromPublicBytes(options: unknown): ReturnObject<LocalKeyHandle>

keyFromSecretBytes(options: any): ReturnObject<LocalKeyHandle>
keyFromSecretBytes(options: unknown): ReturnObject<LocalKeyHandle>

keyFromSeed(options: any): ReturnObject<LocalKeyHandle>
keyFromSeed(options: unknown): ReturnObject<LocalKeyHandle>

keyGenerate(options: any): ReturnObject<LocalKeyHandle>
keyGenerate(options: unknown): ReturnObject<LocalKeyHandle>

keyGetAlgorithm(options: any): ReturnObject<string>
keyGetAlgorithm(options: unknown): ReturnObject<string>

keyGetEphemeral(options: any): ReturnObject<number>
keyGetEphemeral(options: unknown): ReturnObject<number>

keyGetJwkPublic(options: any): ReturnObject<string>
keyGetJwkPublic(options: unknown): ReturnObject<string>

keyGetJwkSecret(options: any): ReturnObject<ArrayBuffer>
keyGetJwkSecret(options: unknown): ReturnObject<ArrayBuffer>

keyGetJwkThumbprint(options: any): ReturnObject<string>
keyGetJwkThumbprint(options: unknown): ReturnObject<string>

keyGetPublicBytes(options: any): ReturnObject<ArrayBuffer>
keyGetPublicBytes(options: unknown): ReturnObject<ArrayBuffer>

keyGetSecretBytes(options: any): ReturnObject<ArrayBuffer>
keyGetSecretBytes(options: unknown): ReturnObject<ArrayBuffer>

keySignMessage(options: any): ReturnObject<ArrayBuffer>
keySignMessage(options: unknown): ReturnObject<ArrayBuffer>

keyUnwrapKey(options: any): ReturnObject<LocalKeyHandle>
keyUnwrapKey(options: unknown): ReturnObject<LocalKeyHandle>

keyVerifySignature(options: any): ReturnObject<number>
keyVerifySignature(options: unknown): ReturnObject<number>

keyWrapKey(options: any): ReturnObject<{ buffer: ArrayBuffer; tagPos: number; noncePos: number }>
keyWrapKey(options: unknown): ReturnObject<{ buffer: ArrayBuffer; tagPos: number; noncePos: number }>

scanFree(options: any): ReturnObject<never>
scanFree(options: unknown): ReturnObject<never>

scanNext(options: any): ReturnObject<never>
scanNext(options: unknown): ReturnObject<never>

scanStart(options: any): ReturnObject<number>
scanStart(options: unknown): ReturnObject<number>

sessionClose(options: any): ReturnObject<never>
sessionClose(options: unknown): ReturnObject<never>

sessionCount(options: any): ReturnObject<never>
sessionCount(options: unknown): ReturnObject<never>

sessionFetch(options: any): ReturnObject<never>
sessionFetch(options: unknown): ReturnObject<never>

sessionFetchAll(options: any): ReturnObject<never>
sessionFetchAll(options: unknown): ReturnObject<never>

sessionFetchAllKeys(options: any): ReturnObject<never>
sessionFetchAllKeys(options: unknown): ReturnObject<never>

sessionFetchKey(options: any): ReturnObject<never>
sessionFetchKey(options: unknown): ReturnObject<never>

sessionInsertKey(options: any): ReturnObject<never>
sessionInsertKey(options: unknown): ReturnObject<never>

sessionRemoveAll(options: any): ReturnObject<never>
sessionRemoveAll(options: unknown): ReturnObject<never>

sessionRemoveKey(options: any): ReturnObject<never>
sessionRemoveKey(options: unknown): ReturnObject<never>

sessionStart(options: any): ReturnObject<never>
sessionStart(options: unknown): ReturnObject<never>

sessionUpdate(options: any): ReturnObject<never>
sessionUpdate(options: unknown): ReturnObject<never>

sessionUpdateKey(options: any): ReturnObject<never>
sessionUpdateKey(options: unknown): ReturnObject<never>

setCustomLogger(options: any): ReturnObject<never>
setCustomLogger(options: unknown): ReturnObject<never>

setDefaultLogger(options: any): ReturnObject<never>
setDefaultLogger(options: unknown): ReturnObject<never>

setMaxLogLevel(options: any): ReturnObject<never>
setMaxLogLevel(options: unknown): ReturnObject<never>

storeClose(options: any): ReturnObject<never>
storeClose(options: unknown): ReturnObject<never>

storeCreateProfile(options: any): ReturnObject<never>
storeCreateProfile(options: unknown): ReturnObject<never>

storeGenerateRawKey(options: { seed?: ArrayBuffer }): ReturnObject<string>

storeGetProfileName(options: any): ReturnObject<never>
storeGetProfileName(options: unknown): ReturnObject<never>

storeOpen(options: {
specUri: string
Expand All @@ -157,13 +157,13 @@ export interface NativeBindings {
cb: CallbackWithResponse<number>
}): ReturnObject<never>

storeProvision(options: any): ReturnObject<never>
storeProvision(options: unknown): ReturnObject<never>

storeRekey(options: any): ReturnObject<never>
storeRekey(options: unknown): ReturnObject<never>

storeRemove(options: any): ReturnObject<never>
storeRemove(options: unknown): ReturnObject<never>

storeRemoveProfile(options: any): ReturnObject<never>
storeRemoveProfile(options: unknown): ReturnObject<never>

migrateIndySdk(options: any): ReturnObject<never>
migrateIndySdk(options: unknown): ReturnObject<never>
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export type StoreProvisionOptions = {
profile?: string
recreate: boolean
}
export type StoreRekeyOptions = { storeHandle: StoreHandle; keyMethod: string; passKey: string }
export type StoreRekeyOptions = { storeHandle: StoreHandle; keyMethod?: string; passKey: string }
export type StoreRemoveOptions = { specUri: string }
export type StoreRemoveProfileOptions = { storeHandle: StoreHandle; profile: string }

Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion wrappers/javascript/aries-askar-shared/src/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ export * from './KeyAlgs'
export * from './KeyMethod'
export * from './SigAlgs'
export * from './LogLevel'
export * from './StoreKeyMethod'
16 changes: 11 additions & 5 deletions wrappers/javascript/aries-askar-shared/src/store/Store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { StoreHandle } from '../crypto'
import type { StoreKeyMethod } from '../enums/StoreKeyMethod'
import type { StoreKeyMethod } from './StoreKeyMethod'

import { ariesAskar } from '../ariesAskar'

Expand Down Expand Up @@ -36,8 +36,8 @@ export class Store {
return await ariesAskar.storeRemoveProfile({ profile: name, storeHandle: this.handle })
}

public async rekey({ keyMethod, passKey }: { keyMethod: StoreKeyMethod; passKey: string }) {
return await ariesAskar.storeRekey({ keyMethod, passKey, storeHandle: this.handle })
public async rekey({ keyMethod, passKey }: { keyMethod?: StoreKeyMethod; passKey: string }) {
return await ariesAskar.storeRekey({ keyMethod: keyMethod?.toUri(), passKey, storeHandle: this.handle })
}

public static async provision({
Expand All @@ -53,7 +53,13 @@ export class Store {
profile?: string
recreate: boolean
}) {
const handle = await ariesAskar.storeProvision({ specUri: uri, keyMethod, profile, passKey, recreate })
const handle = await ariesAskar.storeProvision({
specUri: uri,
keyMethod: keyMethod?.toUri(),
profile,
passKey,
recreate,
})
return new Store({ handle, uri })
}

Expand All @@ -68,7 +74,7 @@ export class Store {
passKey?: string
profile?: string
}) {
const handle = await ariesAskar.storeOpen({ profile, passKey, keyMethod, specUri: uri })
const handle = await ariesAskar.storeOpen({ profile, passKey, keyMethod: keyMethod?.toUri(), specUri: uri })
return new Store({ uri, handle })
}

Expand Down
18 changes: 18 additions & 0 deletions wrappers/javascript/aries-askar-shared/src/store/StoreKeyMethod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export enum KdfMethod {
Raw = 'raw',
None = 'none',
Argon2IMod = 'kdf:argon2i:mod',
Argon2IInt = 'kdf:argon2i:int',
}

export class StoreKeyMethod {
private method: KdfMethod

public constructor(method: KdfMethod) {
this.method = method
}

public toUri() {
return this.method.toString()
}
}
1 change: 1 addition & 0 deletions wrappers/javascript/aries-askar-shared/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './Scan'
export * from './Store'
export * from './OpenSession'
export * from './Session'
export * from './StoreKeyMethod'

0 comments on commit 9f088c8

Please sign in to comment.