Skip to content

Commit

Permalink
split up computeDirId and computeDirIdHash
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed May 21, 2024
1 parent 7224b46 commit 81e9ab4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
13 changes: 10 additions & 3 deletions frontend/src/common/universalVaultFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,18 +413,25 @@ export class UniversalVaultFormat implements AccessTokenProducing, VaultTemplate
return this.metadata.encrypt(apiURL, vault, this.memberKey, this.recoveryKey);
}

public async computeRootDirIdHash(): Promise<string> {
public async computeRootDirId(): Promise<Uint8Array> {
const textencoder = new TextEncoder();
const initialSeed = await crypto.subtle.importKey('raw', this.metadata.initialSeed, { name: 'HKDF' }, false, ['deriveBits', 'deriveKey']);
const initialSeed = await crypto.subtle.importKey('raw', this.metadata.initialSeed, { name: 'HKDF' }, false, ['deriveBits']);
const rootDirId = await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-512', salt: this.metadata.kdfSalt, info: textencoder.encode('rootDirId') }, initialSeed, 256);
return new Uint8Array(rootDirId);
}

public async computeRootDirIdHash(rootDirId: Uint8Array): Promise<string> {
const textencoder = new TextEncoder();
const initialSeed = await crypto.subtle.importKey('raw', this.metadata.initialSeed, { name: 'HKDF' }, false, ['deriveKey']);
const hmacKey = await crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-512', salt: this.metadata.kdfSalt, info: textencoder.encode('hmac') }, initialSeed, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
const rootDirHash = await crypto.subtle.sign("HMAC", hmacKey, rootDirId);
return base32.stringify(new Uint8Array(rootDirHash).slice(0, 20));
}

/** @inheritdoc */
public async exportTemplate(apiURL: string, vault: VaultDto): Promise<Blob> {
const rootDirHash = await this.computeRootDirIdHash();
const rootDirId = await this.computeRootDirId();
const rootDirHash = await this.computeRootDirIdHash(rootDirId);
const zip = new JSZip();
zip.file('vault.uvf', this.createMetadataFile(apiURL, vault));
zip.folder('d')?.folder(rootDirHash.substring(0, 2))?.folder(rootDirHash.substring(2)); // TODO verify after merging https://github.com/encryption-alliance/unified-vault-format/pull/24
Expand Down
12 changes: 10 additions & 2 deletions frontend/test/common/universalVaultFormat.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,16 @@ describe('UVF', () => {
expect(jwk.kid).to.not.be.empty;
});

it('computeRootDirIdHash() creates a hash', async () => {
const hash = await uvf.computeRootDirIdHash();
it('computeRootDirId() deterministically creates a dir ID', async () => {
const dirId = await uvf.computeRootDirId();
expect(dirId).to.have.a.lengthOf(32);
expect(base64.stringify(dirId)).to.eq('24UBEDeGu5taq7U4GqyA0MXUXb9HTYS6p3t9vvHGJAc=');
});

it('computeRootDirIdHash() creates a truncated hmac', async () => {
const rootDirId = base64.parse('24UBEDeGu5taq7U4GqyA0MXUXb9HTYS6p3t9vvHGJAc=');
const hash = await uvf.computeRootDirIdHash(rootDirId);
expect(hash).to.have.a.lengthOf(32);
expect(hash).to.eq('6DYU3E5BTPAZ4DWEQPQK3AIHX2DXSPHG');
});
});
Expand Down

0 comments on commit 81e9ab4

Please sign in to comment.