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

fix: P256 key parity corrections #1137

Merged
merged 5 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
114 changes: 114 additions & 0 deletions __tests__/data.migration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// noinspection ES6PreferShortImport

import { KeyManagementSystem, SecretBox } from '../packages/kms-local/src'
import { Entities, KeyStore, migrations, PrivateKeyStore } from '../packages/data-store/src'
import { PrivateKeyStoreJson } from '../packages/data-store-json/src'

import { DataSource } from 'typeorm'
import * as fs from 'fs'

import { jest } from '@jest/globals'
import { fileURLToPath } from 'url'
import { dirname } from 'path'

// @ts-ignore TS1343
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

jest.setTimeout(60000)

const dbEncryptionKey = '29739248cad1bd1a0fc4d9b75cd4d2990de535baf5caadfdf8d8f86664aa830c'

describe('data handling tests', () => {
describe('can recompute p256 keys from old database', () => {
const fixture = __dirname + '/fixtures/local-database-before-p256key-migration.sqlite'
const databaseFile = fixture + '.tmp'
// intentionally using DataSource instead of Promise<DataSource> to test compatibility
let dbConnection: DataSource

beforeAll(async () => {
await fs.promises.copyFile(fixture, databaseFile)
dbConnection = new DataSource({
name: 'test',
type: 'sqlite',
database: databaseFile,
synchronize: false,
migrations: migrations,
migrationsRun: true,
logging: false,
entities: Entities,
})
})

afterAll(async () => {
try {
await dbConnection?.destroy()
} catch (e: any) {
// nop
}
try {
await fs.promises.unlink(databaseFile)
} catch (e: any) {
// nop
}
})

it('should recompute p256 keys', async () => {
const kmsLocal = new KeyManagementSystem(
new PrivateKeyStore(dbConnection, new SecretBox(dbEncryptionKey)),
)
const managedKeyStore = new KeyStore(dbConnection)
// list known private keys. kms-local will compute the correct public keys
const allPrivKeys = await kmsLocal.listKeys()
const keyIds: string[] = []
for (const privKey of allPrivKeys) {
if (privKey.type === 'Secp256r1') {
const managedKey = await managedKeyStore.getKey({ kid: privKey.kid })
if (managedKey.publicKeyHex.length === 64) {
keyIds.push(privKey.kid)
managedKey.publicKeyHex = privKey.publicKeyHex
}
await managedKeyStore.importKey(managedKey)
}
}
for (const kid of keyIds) {
const managedKey = await managedKeyStore.getKey({ kid })
expect(managedKey.publicKeyHex.length).toEqual(66)
expect(managedKey.publicKeyHex).toMatch(/^(02|03).*/)
}
})
})
describe('kms-local maintains public key values for listKeys', () => {
it('when using data-store-json', async () => {
const memoryJsonStore = {
notifyUpdate: () => Promise.resolve(),
}
const kmsLocal = new KeyManagementSystem(
new PrivateKeyStoreJson(memoryJsonStore, new SecretBox(dbEncryptionKey)),
)
const key = await kmsLocal.createKey({ type: 'Secp256r1' })
const allPrivKeys = await kmsLocal.listKeys()
const foundKey = allPrivKeys.find((k) => k.kid === key.kid)
expect(foundKey?.publicKeyHex).toEqual(key.publicKeyHex)
})

it('when using data-store', async () => {
const dbConnection = new DataSource({
type: 'sqlite',
database: ':memory:',
entities: Entities,
synchronize: false,
migrations: migrations,
migrationsRun: true,
logging: false,
})
const kmsLocal = new KeyManagementSystem(
new PrivateKeyStore(dbConnection, new SecretBox(dbEncryptionKey)),
)
const key = await kmsLocal.createKey({ type: 'Secp256r1' })
const allPrivKeys = await kmsLocal.listKeys()
const foundKey = allPrivKeys.find((k) => k.kid === key.kid)
expect(foundKey?.publicKeyHex).toEqual(key.publicKeyHex)
})
})
})
Binary file not shown.
11 changes: 6 additions & 5 deletions __tests__/initial.migration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,19 @@ import { KeyManager } from '../packages/key-manager/src'
import { DIDManager } from '../packages/did-manager/src'
import { FakeDidProvider, FakeDidResolver } from '../packages/test-utils/src'

import { DataSourceOptions, DataSource } from 'typeorm'
import { DataSource, DataSourceOptions } from 'typeorm'
import { Resolver } from 'did-resolver'
import { getResolver as ethrDidResolver } from 'ethr-did-resolver'
import { getResolver as webDidResolver } from 'web-did-resolver'
import * as fs from 'fs'

import { jest } from '@jest/globals'
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import { fileURLToPath } from 'url'
import { dirname } from 'path'

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// @ts-ignore TS1343
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

jest.setTimeout(60000)

Expand Down
2 changes: 1 addition & 1 deletion __tests__/localAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ let databaseFile: string

const setup = async (options?: IAgentOptions): Promise<boolean> => {
databaseFile =
options?.context?.databaseFile || `./tmp/local-database-${Math.random().toPrecision(5)}.sqlite`
options?.context?.databaseFile || ':memory:'
dbConnection = new DataSource({
name: options?.context?.['dbName'] || 'test',
type: 'sqlite',
Expand Down
15 changes: 5 additions & 10 deletions __tests__/localMemoryStoreAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ import {
ICredentialIssuerLD,
LdDefaultContexts,
VeramoEcdsaSecp256k1RecoverySignature2020,
VeramoEd25519Signature2018, VeramoEd25519Signature2020, VeramoJsonWebSignature2020,
VeramoEd25519Signature2018,
VeramoEd25519Signature2020,
VeramoJsonWebSignature2020,
} from '../packages/credential-ld/src'
import { EthrDIDProvider } from '../packages/did-provider-ethr/src'
import { WebDIDProvider } from '../packages/did-provider-web/src'
Expand Down Expand Up @@ -73,7 +75,6 @@ import credentialInterop from './shared/credentialInterop.js'

jest.setTimeout(60000)

const databaseFile = `./tmp/local-database2-${Math.random().toPrecision(5)}.sqlite`
const infuraProjectId = '3586660d179141e3801c3895de1c2eba'

let agent: TAgent<
Expand All @@ -96,7 +97,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
dbConnection = new DataSource({
name: 'test',
type: 'sqlite',
database: databaseFile,
database: ':memory:',
synchronize: false,
migrations: migrations,
migrationsRun: true,
Expand Down Expand Up @@ -207,16 +208,10 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {

const tearDown = async (): Promise<boolean> => {
try {
await (await dbConnection).dropDatabase()
await (await dbConnection).close()
await dbConnection?.destroy()
} catch (e) {
// nop
}
try {
fs.unlinkSync(databaseFile)
} catch (e) {
//nop
}
return true
}

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/__tests__/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('cli version', () => {
})

// this seems to fail because of an incompatibility between jest and the `multiformats@11` transitive dependency
it.skip('should load the agent', async () => {
it('should load the agent', async () => {
const { agent } = await createObjects(await getConfig('./packages/cli/default/default.yml'), {
agent: '/agent',
})
Expand Down
22 changes: 15 additions & 7 deletions packages/data-store-json/src/identifier/private-key-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export class PrivateKeyStoreJson extends AbstractPrivateKeyStore {
private readonly notifyUpdate: DiffCallback

/**
* @param jsonStore - This serves as the JSON object storing data in memory as well as providing an update notification
* callback to persist this data. The JSON object does not have to be shared with other users of
* @param jsonStore - This serves as the JSON object storing data in memory as well as providing an update
* notification callback to persist this data. The JSON object does not have to be shared with other users of
* {@link VeramoJsonStore}, but it can be.
* @param secretBox - If this is used, then key material is encrypted, even in memory.
*/
Expand Down Expand Up @@ -66,10 +66,12 @@ export class PrivateKeyStoreJson extends AbstractPrivateKeyStore {
async importKey(args: ImportablePrivateKey): Promise<ManagedPrivateKey> {
debug('Saving private key data', args.alias)
const alias = args.alias || uuid4()
const key: ManagedPrivateKey = deserialize(serialize({
...args,
alias,
}))
const key: ManagedPrivateKey = deserialize(
serialize({
...args,
alias,
}),
)
if (this.secretBox && key.privateKeyHex) {
const copy = key.privateKeyHex
key.privateKeyHex = await this.secretBox.encrypt(copy)
Expand All @@ -89,6 +91,12 @@ export class PrivateKeyStoreJson extends AbstractPrivateKeyStore {
}

async listKeys(): Promise<Array<ManagedPrivateKey>> {
return deserialize(serialize(Object.values(this.cacheTree.privateKeys)))
const keys = Object.values(this.cacheTree.privateKeys)
if (this.secretBox) {
for (const key of keys) {
key.privateKeyHex = await this.secretBox.decrypt(key.privateKeyHex)
}
}
return deserialize(serialize(keys))
}
}
7 changes: 6 additions & 1 deletion packages/data-store/src/identifier/private-key-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ export class PrivateKeyStore extends AbstractPrivateKeyStore {
}

async listKeys(): Promise<Array<ManagedPrivateKey>> {
const keys = await (await getConnectedDb(this.dbConnection)).getRepository(PrivateKey).find()
let keys = await (await getConnectedDb(this.dbConnection)).getRepository(PrivateKey).find()
if (this.secretBox) {
for (const key of keys) {
key.privateKeyHex = await this.secretBox?.decrypt(key.privateKeyHex) as string
}
}
return keys
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ const DIDCommEventSniffer: IEventListener = {
onEvent: jest.fn(() => Promise.resolve()),
}

const databaseFile = `./tmp/local-database2-${Math.random().toPrecision(5)}.sqlite`

describe('coordinate-mediation-message-handler', () => {
let recipient: IIdentifier
let mediator: IIdentifier
Expand All @@ -56,7 +54,7 @@ describe('coordinate-mediation-message-handler', () => {
dbConnection = new DataSource({
name: 'test',
type: 'sqlite',
database: databaseFile,
database: ':memory:',
synchronize: false,
migrations: migrations,
migrationsRun: true,
Expand Down Expand Up @@ -171,8 +169,14 @@ describe('coordinate-mediation-message-handler', () => {
afterAll(async () => {
try {
await new Promise((resolve, reject) => didCommEndpointServer?.close(resolve))
} catch (e) {
//nop
} catch (e: any) {
// nop
}

try {
await dbConnection?.destroy()
} catch (e: any) {
// nop
}
})

Expand Down
9 changes: 6 additions & 3 deletions packages/did-comm/src/__tests__/message-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ const DIDCommEventSniffer: IEventListener = {
onEvent: jest.fn(() => Promise.resolve()),
}

const databaseFile = `./tmp/local-database2-${Math.random().toPrecision(5)}.sqlite`

describe('did-comm-message-handler', () => {
let sender: IIdentifier
let recipient: IIdentifier
Expand All @@ -50,7 +48,7 @@ describe('did-comm-message-handler', () => {
dbConnection = new DataSource({
name: 'test',
type: 'sqlite',
database: databaseFile,
database: ':memory:',
synchronize: false,
migrations: migrations,
migrationsRun: true,
Expand Down Expand Up @@ -166,6 +164,11 @@ describe('did-comm-message-handler', () => {
} catch (e) {
//nop
}
try {
await dbConnection?.destroy()
} catch (e: any) {
// nop
}
})

const expectMessageReceived = (id: string, packing: string) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ const DIDCommEventSniffer: IEventListener = {
onEvent: jest.fn(() => Promise.resolve()),
}

const databaseFile = `./tmp/local-database2-${Math.random().toPrecision(5)}.sqlite`

describe('messagepickup-message-handler', () => {
describe('PickupMediatorMessageHandler', () => {
let recipient: IIdentifier
Expand All @@ -73,7 +71,7 @@ describe('messagepickup-message-handler', () => {
dbConnection = new DataSource({
name: 'test',
type: 'sqlite',
database: databaseFile,
database: ':memory:',
synchronize: false,
migrations: migrations,
migrationsRun: true,
Expand Down Expand Up @@ -236,8 +234,13 @@ describe('messagepickup-message-handler', () => {
afterAll(async () => {
try {
await new Promise((resolve, reject) => didCommEndpointServer?.close(resolve))
} catch (e) {
//nop
} catch (e: any) {
// nop
}
try {
await dbConnection?.destroy()
} catch (e: any) {
// nop
}
})

Expand Down Expand Up @@ -788,7 +791,7 @@ describe('messagepickup-message-handler', () => {
dbConnection = new DataSource({
name: 'test',
type: 'sqlite',
database: databaseFile,
database: ':memory:',
synchronize: false,
migrations: migrations,
migrationsRun: true,
Expand Down Expand Up @@ -951,8 +954,13 @@ describe('messagepickup-message-handler', () => {
afterAll(async () => {
try {
await new Promise((resolve, reject) => didCommEndpointServer?.close(resolve))
} catch (e) {
//nop
} catch (e: any) {
// nop
}
try {
await dbConnection?.destroy()
} catch (e: any) {
// nop
}
})

Expand Down
Loading