Skip to content

Commit

Permalink
update DID Document signature on registry commit
Browse files Browse the repository at this point in the history
  • Loading branch information
VolkerSchiewe authored and Exulansis committed Aug 11, 2019
1 parent 9a380ea commit 1584f1b
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 64 deletions.
8 changes: 5 additions & 3 deletions tests/data/didDocument.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const mockPublicKeyHex =

/* JSON form to ensure toJSON and fromJSON work as intended */

export const didDocumentJSON_v0 = {
export const didDocumentJSONv0 = {
authentication: [
{
publicKey: mockKeyId,
Expand Down Expand Up @@ -38,7 +38,8 @@ export const didDocumentJSON_v0 = {
type: 'EcdsaKoblitzSignature2016',
creator: mockKeyId,
nonce: '1842fb5f567dd532',
signatureValue: '',
signatureValue:
'3e4bca6a08643c4a67c02abd109accd19f2f9ad1c93cd9f39d3f23edc122de7a72d1de44420b456c20b1875ed254417efdf8dd16fb8ded818d830dac475ec55a',
created: '1970-01-01T00:00:00.000Z',
},
'@context': defaultContextIdentity,
Expand Down Expand Up @@ -78,7 +79,8 @@ export const didDocumentJSON = {
type: 'EcdsaKoblitzSignature2016',
creator: mockKeyId,
nonce: '1842fb5f567dd532',
signatureValue: '',
signatureValue:
'3e4bca6a08643c4a67c02abd109accd19f2f9ad1c93cd9f39d3f23edc122de7a72d1de44420b456c20b1875ed254417efdf8dd16fb8ded818d830dac475ec55a',
created: '1970-01-01T00:00:00.000Z',
},
'@context': defaultContextIdentity,
Expand Down
37 changes: 31 additions & 6 deletions tests/identity/didDocument.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as chai from 'chai'
import * as sinon from 'sinon'
import * as crypto from 'crypto'
import { testPublicIdentityKey } from '../data/keys.data'
import { testPublicIdentityKey, testSeed } from '../data/keys.data'
import {
didDocumentJSON_v0,
didDocumentJSONv0,
didDocumentJSON,
mockDid,
mockKeyId,
Expand All @@ -18,10 +18,18 @@ import {
ServiceEndpointsSection,
PublicKeySection,
} from '../../ts/identity/didDocument/sections'
import { SoftwareKeyProvider } from '../../ts/vaultedKeyProvider/softwareProvider'
import { KeyTypes } from '../../ts/vaultedKeyProvider/types'

const expect = chai.expect

describe('DidDocument', () => {
const sandbox = sinon.createSandbox()
const vault = SoftwareKeyProvider.fromSeed(testSeed, 'password')
const derivationArgs = {
derivationPath: KeyTypes.jolocomIdentityKey,
encryptionPass: 'password',
}

let referenceDidDocument
let clock
Expand All @@ -41,6 +49,7 @@ describe('DidDocument', () => {
referenceDidDocument.addServiceEndpoint(
ServiceEndpointsSection.fromJSON(mockPubProfServiceEndpointJSON),
)
await referenceDidDocument.sign(vault, derivationArgs, mockKeyId)
})

after(() => {
Expand Down Expand Up @@ -73,14 +82,15 @@ describe('DidDocument', () => {
})

it('Should correctly implement fromJSON for version 0', () => {
const didDocFromJSON_v0 = DidDocument.fromJSON(didDocumentJSON_v0)
didDocFromJSON_v0.addAuthKey(mockPublicKey2 as PublicKeySection)
expect(referenceDidDocument).to.deep.eq(didDocFromJSON_v0)
const didDocumentv0 = DidDocument.fromJSON(didDocumentJSONv0)

didDocumentv0.addAuthKey(mockPublicKey2 as PublicKeySection)
expect(didDocumentv0).to.deep.eq(referenceDidDocument)
})

it('Should correctly implement fromJSON', () => {
const didDocFromJSON = DidDocument.fromJSON(didDocumentJSON)
expect(referenceDidDocument).to.deep.eq(didDocFromJSON)
expect(didDocFromJSON).to.deep.eq(referenceDidDocument)
})

it('Should correctly implement toJSON', () => {
Expand All @@ -93,6 +103,21 @@ describe('DidDocument', () => {
expect(normalized).to.deep.eq(normalizedDidDocument)
})

it('should correctly sign the DID document', async () => {
await referenceDidDocument.sign(
vault,
{
derivationPath: KeyTypes.jolocomIdentityKey,
encryptionPass: 'password',
},
mockKeyId,
)

expect(referenceDidDocument.signature).to.eq(
'3e4bca6a08643c4a67c02abd109accd19f2f9ad1c93cd9f39d3f23edc122de7a72d1de44420b456c20b1875ed254417efdf8dd16fb8ded818d830dac475ec55a',
)
})

it('implements getters', () => {
/* Makes later comparisons simpler */
const {
Expand Down
68 changes: 38 additions & 30 deletions tests/jolocomRegistry/commit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,22 @@ import {
didDocumentJSON,
mockDid,
mockIpfsHash,
mockKeyId,
} from '../data/didDocument.data'
import { KeyTypes } from '../../ts/vaultedKeyProvider/types'
import { encryptionPass } from './jolocomRegistry.data'
import { mockPubProfServiceEndpointJSON } from '../data/didDocumentSections.data'
import { publicProfileCredJSON } from '../data/identity.data'
import { SignedCredential } from '../../ts/credentials/signedCredential/signedCredential'
import { jolocomContractsAdapter } from '../../ts/contracts/contractsAdapter'
import { jolocomContractsGateway } from '../../ts/contracts/contractsGateway'
import * as crypto from 'crypto'

chai.use(sinonChai)
const expect = chai.expect

describe('Jolocom registry - commit', () => {
let sandbox = sinon.createSandbox()
let mock = sinon.createSandbox()
let clock
const vault = SoftwareKeyProvider.fromSeed(testSeed, encryptionPass)

Expand All @@ -34,14 +36,25 @@ describe('Jolocom registry - commit', () => {
encryptionPass,
}

const didDocumentWithPP = DidDocument.fromJSON(didDocumentJSON)
const didDocument = DidDocument.fromJSON(didDocumentJSON)

before(() => {
didDocument.service = undefined

before(async () => {
clock = sinon.useFakeTimers()
mock
.stub(crypto, 'randomBytes')
.returns(Buffer.from('1842fb5f567dd532', 'hex'))
await didDocument.sign(vault, keyMetadata, mockKeyId)
})

afterEach(() => {
sandbox.restore()
})

after(() => {
mock.restore()
clock.restore()
})

Expand Down Expand Up @@ -82,22 +95,18 @@ describe('Jolocom registry - commit', () => {
])

sandbox.assert.calledWith(testRegistry.ipfsConnector.storeJSON, {
data: didDocumentJSON,
data: didDocument.toJSON(),
pin: true,
})
})

it('should commit with local public profile, and no remote', async () => {
const testRegistry: any = createJolocomRegistry()

const extendedDidDocumentJSON = {
...didDocumentJSON,
service: [mockPubProfServiceEndpointJSON],
}
const publicProfile = SignedCredential.fromJSON(publicProfileCredJSON)

const localIdentity = Identity.fromDidDocument({
didDocument,
didDocument: didDocumentWithPP,
publicProfile,
})
const remoteIdentity = Identity.fromDidDocument({ didDocument })
Expand Down Expand Up @@ -125,14 +134,21 @@ describe('Jolocom registry - commit', () => {

sandbox.assert.calledWith(testRegistry.resolve, mockDid)
sandbox.assert.calledTwice(testRegistry.ipfsConnector.storeJSON)
sandbox.assert.calledWith(testRegistry.ipfsConnector.storeJSON, {
data: extendedDidDocumentJSON,
pin: true,
})
sandbox.assert.calledWith(testRegistry.ipfsConnector.storeJSON, {
data: publicProfileCredJSON,
pin: true,
})

expect(testRegistry.ipfsConnector.storeJSON.getCall(0).args).to.deep.eq([
{
data: publicProfileCredJSON,
pin: true,
},
])

expect(testRegistry.ipfsConnector.storeJSON.getCall(1).args).to.deep.eq([
{
data: didDocumentJSON,
pin: true,
},
])

sandbox.assert.calledWith(testRegistry.ethereumConnector.updateDIDRecord, {
did: mockDid,
ethereumKey: testPrivateEthereumKey,
Expand All @@ -143,19 +159,14 @@ describe('Jolocom registry - commit', () => {
it('should commit with updated public profile', async () => {
const testRegistry: any = createJolocomRegistry()

const extendedDidDocumentJSON = {
...didDocumentJSON,
service: [mockPubProfServiceEndpointJSON],
}
const extendedDidDocument = DidDocument.fromJSON(extendedDidDocumentJSON)
const publicProfile = SignedCredential.fromJSON(publicProfileCredJSON)

const localIdentity = Identity.fromDidDocument({
didDocument: extendedDidDocument,
didDocument: didDocumentWithPP,
publicProfile,
})
const remoteIdentity = Identity.fromDidDocument({
didDocument: extendedDidDocument,
didDocument: didDocumentWithPP,
publicProfile,
})

Expand Down Expand Up @@ -183,7 +194,7 @@ describe('Jolocom registry - commit', () => {
sandbox.assert.calledWith(testRegistry.resolve, mockDid)
sandbox.assert.calledTwice(testRegistry.ipfsConnector.storeJSON)
sandbox.assert.calledWith(testRegistry.ipfsConnector.storeJSON, {
data: extendedDidDocumentJSON,
data: didDocumentJSON,
pin: true,
})
sandbox.assert.calledWith(testRegistry.ipfsConnector.storeJSON, {
Expand All @@ -200,16 +211,13 @@ describe('Jolocom registry - commit', () => {
it('should commit with removed public profile', async () => {
const testRegistry: any = createJolocomRegistry()

didDocumentJSON.service = []

const extendedDidDocument = DidDocument.fromJSON(didDocumentJSON)
const publicProfile = SignedCredential.fromJSON(publicProfileCredJSON)

const localIdentity = Identity.fromDidDocument({
didDocument: extendedDidDocument,
didDocument: didDocument,
})
const remoteIdentity = Identity.fromDidDocument({
didDocument: extendedDidDocument,
didDocument: didDocumentWithPP,
publicProfile,
})

Expand Down Expand Up @@ -237,7 +245,7 @@ describe('Jolocom registry - commit', () => {
sandbox.assert.calledWith(testRegistry.resolve, mockDid)
sandbox.assert.calledOnce(testRegistry.ipfsConnector.storeJSON)
sandbox.assert.calledWith(testRegistry.ipfsConnector.storeJSON, {
data: didDocumentJSON,
data: didDocument.toJSON(),
pin: true,
})
sandbox.assert.calledWith(testRegistry.ethereumConnector.updateDIDRecord, {
Expand Down
2 changes: 0 additions & 2 deletions tests/jolocomRegistry/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ describe('Jolocom Registry - create', () => {

before(async () => {
sandbox.stub(mockVault, 'getPublicKey').returns(testPublicIdentityKey)
sandbox.stub(mockVault, 'signDigestable').returns(msgSignature)
sandbox.stub(mockVault, 'getPrivateKey').returns(testPrivateIdentityKey)

sandbox.stub(JolocomRegistry.prototype, 'commit').resolves()
Expand All @@ -43,7 +42,6 @@ describe('Jolocom Registry - create', () => {
const jolocomRegistry = createJolocomRegistry()

const expectedDidDoc = Object.assign({}, didDocumentJSON)
expectedDidDoc.proof.signatureValue = msgSignature.toString('hex')

identityWallet = await jolocomRegistry.create(mockVault, encryptionPass)

Expand Down
4 changes: 3 additions & 1 deletion tests/jolocomRegistry/resolve.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ describe('Jolocom Registry - resolve', () => {

before(() => {
registry.ethereumConnector.resolveDID = sinon.stub().returns(mockIpfsHash)
registry.ipfsConnector.catJSON = sinon.stub().returns(didDocumentJSON)
registry.ipfsConnector.catJSON = sinon
.stub()
.returns({ ...didDocumentJSON, service: [] })
})

afterEach(() => {
Expand Down
33 changes: 21 additions & 12 deletions ts/identity/didDocument/didDocument.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
plainToClass,
classToPlain,
Type,
ClassTransformOptions,
Exclude,
Expose,
plainToClass,
Transform,
ClassTransformOptions,
Type,
} from 'class-transformer'
import { IDidDocumentAttrs } from './types'
import { canonize } from 'jsonld'
Expand All @@ -18,12 +18,16 @@ import {
import { ISigner } from '../../registries/types'
import { ContextEntry } from 'cred-types-jolocom-core'
import { defaultContextIdentity } from '../../utils/contexts'
import { sha256, publicKeyToDID } from '../../utils/crypto'
import { publicKeyToDID, sha256 } from '../../utils/crypto'
import {
ILinkedDataSignature,
IDigestable,
ILinkedDataSignature,
} from '../../linkedDataSignature/types'
import { SoftwareKeyProvider } from '../../vaultedKeyProvider/softwareProvider'
import {
IKeyDerivationArgs,
IVaultedKeyProvider,
} from '../../vaultedKeyProvider/types'

/**
* Class modelling a Did Document
Expand Down Expand Up @@ -330,25 +334,30 @@ export class DidDocument implements IDigestable {
PublicKeySection.fromEcdsa(publicKey, keyId, did),
)
didDocument.addAuthKeyId(didDocument.publicKey[0].id)
await didDocument.prepareSignature(keyId)

return didDocument
}

/**
* Sets all fields on the instance necessary to compute the signature
* @param keyId - Public key identifier, as defined in the {@link https://w3c-ccg.github.io/did-spec/#public-keys | specification}.
* @example `didDocument.prepareSignature('did:jolo:...#keys-1')`
* @example `didDocument.sign(vault, { derivationPath: KeyTypes.jolocomIdentityKey, encryptionPass: 'password', }, keyId)`
*/

private prepareSignature(keyId: string) {
const inOneYear = new Date()
inOneYear.setFullYear(new Date().getFullYear() + 1)

public async sign(
vaultedKeyProvider: IVaultedKeyProvider,
derivationArgs: IKeyDerivationArgs,
keyId: string,
): Promise<void> {
this._proof = new EcdsaLinkedDataSignature()
this._proof.creator = keyId
this._proof.signature = ''
this._proof.nonce = SoftwareKeyProvider.getRandom(8).toString('hex')

const didDocumentSignature = await vaultedKeyProvider.signDigestable(
derivationArgs,
this,
)
this._proof.signature = didDocumentSignature.toString('hex')
}

/**
Expand Down
2 changes: 1 addition & 1 deletion ts/identity/didDocument/sections/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface IServiceEndpointSectionAttrs {
description: string
}

export interface IAuthenticationSectionAttrs_v0 {
export interface IAuthenticationSectionAttrsv0 {
publicKey: string
type: string
}
Expand Down
4 changes: 2 additions & 2 deletions ts/identity/didDocument/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
IAuthenticationSectionAttrs_v0,
IAuthenticationSectionAttrsv0,
IAuthenticationSectionAttrs,
IPublicKeySectionAttrs,
IServiceEndpointSectionAttrs,
Expand All @@ -12,7 +12,7 @@ export interface IDidDocumentAttrs {
specVersion?: number
id: string
authentication?:
| IAuthenticationSectionAttrs_v0[]
| IAuthenticationSectionAttrsv0[]
| IAuthenticationSectionAttrs[]
publicKey?: IPublicKeySectionAttrs[]
service?: IServiceEndpointSectionAttrs[]
Expand Down
Loading

0 comments on commit 1584f1b

Please sign in to comment.