Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

UVF support #274

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

Draft
wants to merge 107 commits into
base: develop
Choose a base branch
Loading
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
2d080ea
add `"alg": "A256KW"` support for JWEs
overheadhunter Mar 2, 2024
d109cff
uvf metadata (WiP).
chenkins Feb 28, 2024
55633f1
remove dead code from `backend.ts` for now
overheadhunter Apr 13, 2024
fe7ff3d
disentangle v8 and uvf based vaults
overheadhunter Apr 13, 2024
be8803c
move vault format 8 code to separate file
overheadhunter Apr 13, 2024
b51cc59
move UVF code to separate file
overheadhunter Apr 13, 2024
a9f12d4
adjust UVF payload to latest spec
overheadhunter Apr 13, 2024
cdf5571
Merge branch 'develop' into feature/uvf
overheadhunter Apr 20, 2024
3f77d16
new JWE API supporting compact and JSON format
overheadhunter Apr 25, 2024
3646379
use correct `AlgorithmID` for Concat KDF
overheadhunter Apr 26, 2024
f1c14fd
added tests
overheadhunter Apr 26, 2024
e0a7ab1
Merge branch 'develop' into feature/uvf
overheadhunter Apr 28, 2024
aa1690f
type cleanup
overheadhunter Apr 28, 2024
e6e028a
include recovery key in UVF metadata
overheadhunter Apr 28, 2024
a85cf3c
create UVF-based vault
overheadhunter Apr 28, 2024
32f2743
store uvf metadata and recovery key in vault table
overheadhunter May 2, 2024
a63ef34
adjusted to DTO model
overheadhunter May 2, 2024
6ce1569
Merge branch 'develop' into feature/uvf
overheadhunter May 2, 2024
01c8a06
grant permission to UVF vault
overheadhunter May 2, 2024
36eb79c
fix autocompletion mistake
overheadhunter May 2, 2024
3cf9c8e
use common interfaces for VF8 and UVF
overheadhunter May 2, 2024
69f0360
fix linter errors
overheadhunter May 2, 2024
7bddc62
experimental implementation of `serializePrivateKey()`
overheadhunter May 2, 2024
ba05d8b
make config.ts usable during tests
overheadhunter May 2, 2024
3d1db01
deduplicate "encrypt for user"
overheadhunter May 3, 2024
6b46862
store recovery key among vault key in access token
overheadhunter May 3, 2024
cb4e53a
reordered fields
overheadhunter May 3, 2024
b294f55
store recovery key as PKCS8 instead of words
overheadhunter May 9, 2024
a3fc184
adjusted parameter order
overheadhunter May 9, 2024
aeafffe
fix mocha test explorer: `document is not defined`
overheadhunter May 9, 2024
17c7099
fix method signature
overheadhunter May 9, 2024
f3f3e02
relax linter
overheadhunter May 9, 2024
aa49371
add tests
overheadhunter May 9, 2024
eda2621
add tests
overheadhunter May 9, 2024
815199f
reduce public API surface
overheadhunter May 9, 2024
037157f
add tests
overheadhunter May 9, 2024
2a40d01
speed up tests by reducing KDF iteration count
overheadhunter May 9, 2024
5118876
Merge branch 'develop' into feature/uvf
overheadhunter May 9, 2024
e4f9865
renamed files
overheadhunter May 10, 2024
e27d20a
clean up tests
overheadhunter May 10, 2024
657598a
fix uneffective test
overheadhunter May 10, 2024
88a95eb
clean up test
overheadhunter May 10, 2024
c229fdd
remove outdated TODOs
overheadhunter May 10, 2024
b46f55e
restore recovery key from human-readable form
overheadhunter May 10, 2024
b0790aa
store JWK Set in backend
overheadhunter May 10, 2024
98cd173
expose `jwks.json` and `vault.uvf` endpoints
overheadhunter May 10, 2024
00641e4
switch to MemberDto
overheadhunter May 16, 2024
4f3e969
cleanup
overheadhunter May 16, 2024
8320786
include role-depending data in access token
overheadhunter May 16, 2024
458e98a
Merge branch 'develop' into feature/uvf
overheadhunter May 16, 2024
8cb9af6
add `UniversalVaultFormat.recover(...)`
overheadhunter May 16, 2024
aad13fa
Merge branch 'develop' into feature/uvf
overheadhunter May 17, 2024
686713b
Merge branch 'develop' into feature/uvf
overheadhunter May 17, 2024
994d7b3
Merge branch 'develop' into feature/uvf
overheadhunter May 17, 2024
155d640
remove unnecessary guard
overheadhunter May 17, 2024
9b4f5ba
fix weird error message in unit tests
overheadhunter May 21, 2024
388426f
pass in URL during vault template generation
overheadhunter May 21, 2024
52b97b5
improve test
overheadhunter May 21, 2024
7224b46
add root directory to vault template
overheadhunter May 21, 2024
81e9ab4
split up `computeDirId` and `computeDirIdHash`
overheadhunter May 21, 2024
9c3ab12
add `dir.uvf` file to vault template
overheadhunter May 21, 2024
ec4415d
refine test
overheadhunter May 22, 2024
2947b80
show also uvf recovery key in vault details
infeo May 22, 2024
2d03e39
fix linter hints
infeo May 22, 2024
bf85c2a
(unfinished) rework recover Vault dialog
infeo May 27, 2024
8d86446
Do not erase uploaded file on failed upload
infeo May 28, 2024
57cfd0a
improve error handling
infeo May 28, 2024
b1f9fc4
define event listeners as functions
infeo May 28, 2024
a667e0d
remove unused Error class
infeo May 28, 2024
871b6de
set vault type during recovery
infeo May 28, 2024
3368768
minor adjustments
infeo May 28, 2024
b43a946
add additional verification to vaultformat 8 module
infeo May 29, 2024
ea77daf
Add negative test for vaultFormat8 verfiy and recover
infeo May 30, 2024
c2fe768
reduce diff
infeo May 30, 2024
b2cb75d
add doc string
infeo Jun 3, 2024
64d8ff6
add tests for simple jwt parsing
infeo Jun 3, 2024
eaaad24
improve error handling
infeo Jun 3, 2024
597b2cc
add error translations
infeo Jun 3, 2024
b7a0687
more wording/translations
infeo Jun 5, 2024
afd370f
fix display bug
infeo Jun 5, 2024
0de22c9
Merge branch 'develop' into feature/uvf
overheadhunter Jun 6, 2024
917fedc
use new JWE parser in `userdata.ts`
overheadhunter Jun 6, 2024
847ecc4
dedup
overheadhunter Jun 6, 2024
26369a5
adjust DTO to carry both EC keys
overheadhunter Jun 6, 2024
e77ca7a
Merge branch 'develop' into feature/uvf
overheadhunter Jul 12, 2024
3e30a00
Merge branch 'develop' into feature/uvf
overheadhunter Nov 3, 2024
fd0add4
fixed test
overheadhunter Nov 3, 2024
68eb5d9
fixed linter warnings
overheadhunter Nov 3, 2024
ebd5f7d
Merge branch 'develop' into feature/uvf
overheadhunter Jan 17, 2025
4268484
make tests run from IDE again
overheadhunter Jan 17, 2025
3ca8f78
linter error
overheadhunter Jan 17, 2025
a0ce488
spec is final now
overheadhunter Jan 17, 2025
da7fe40
encode keys with base64url; values with base64
overheadhunter Jan 17, 2025
3cc7d27
use corrected test vectors confirmed in java
overheadhunter Jan 17, 2025
f684a58
fix incorrect hkdf output size
overheadhunter Jan 17, 2025
12106cc
Merge branch 'develop' into feature/uvf
overheadhunter Jan 31, 2025
c1d6c29
reordered flyway migrations
overheadhunter Jan 31, 2025
5a38a4d
Merge branch 'develop' into feature/uvf
overheadhunter Feb 7, 2025
fd6db88
reordered migrations
overheadhunter Feb 7, 2025
1f0b7c6
Merge branch 'develop' into feature/uvf
overheadhunter Feb 24, 2025
cd68e29
Merge branch 'develop' into feature/uvf
overheadhunter Mar 22, 2025
3a65446
Merge branch 'develop' into feature/uvf
overheadhunter Apr 24, 2025
b5a94a9
use base64url in `vault.uvf`
overheadhunter Apr 24, 2025
7e285ea
fix base64url encoding and tests
overheadhunter Apr 24, 2025
6efd702
fix test broken during merge cd68e29
overheadhunter Apr 24, 2025
ce36aa1
run linter
overheadhunter Apr 24, 2025
928b613
Merge branch 'develop' into feature/uvf
overheadhunter May 2, 2025
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
Prev Previous commit
Next Next commit
move vault format 8 code to separate file
  • Loading branch information
overheadhunter committed Apr 13, 2024
commit be8803c6a1d6a52deafe7528104e3690f797c0c2
304 changes: 33 additions & 271 deletions 304 frontend/src/common/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as miscreant from 'miscreant';
import { base16, base32, base64, base64url } from 'rfc4648';
import { base16, base32, base64 } from 'rfc4648';
import { JWEBuilder, JWEParser } from './jwe';
import { CRC32, DB, wordEncoder } from './util';
import { DB } from './util';

import { VaultMetadataJWEAutomaticAccessGrantDto } from './backend';

Expand All @@ -14,249 +14,11 @@ export class UnwrapKeyError extends Error {
}
}

export interface VaultConfigPayload {
jti: string
format: number
cipherCombo: string
shorteningThreshold: number
}

export interface VaultConfigHeaderHub {
clientId: string
authEndpoint: string
tokenEndpoint: string
authSuccessUrl: string
authErrorUrl: string
apiBaseUrl: string
// deprecated:
devicesResourceUrl: string
}

interface UserKeysJWEPayload {
key: string
}

interface VaultKeysWEPayload {
key: string
}

const GCM_NONCE_LEN = 12;

export class VaultKeys {
// in this browser application, this 512 bit key is used
// as a hmac key to sign the vault config.
// however when used by cryptomator, it gets split into
// a 256 bit encryption key and a 256 bit mac key
private static readonly MASTERKEY_KEY_DESIGNATION: HmacImportParams | HmacKeyGenParams = {
name: 'HMAC',
hash: 'SHA-256',
length: 512
};

readonly masterKey: CryptoKey;

protected constructor(masterKey: CryptoKey) {
this.masterKey = masterKey;
}

/**
* Creates a new masterkey
* @returns A new masterkey
*/
public static async create(): Promise<VaultKeys> {
const key = crypto.subtle.generateKey(
VaultKeys.MASTERKEY_KEY_DESIGNATION,
true,
['sign']
);
return new VaultKeys(await key);
}


/**
* Decrypts the vault's masterkey (vault8 and uvf) using the user's private key
* @param jwe JWE containing the vault key
* @param userPrivateKey The user's private key
* @returns The masterkey
*/
public static async decryptWithUserKey(jwe: string, userPrivateKey: CryptoKey): Promise<VaultKeys> {
let rawKey = new Uint8Array();
try {
const payload: VaultKeysWEPayload = await JWEParser.parse(jwe).decryptEcdhEs(userPrivateKey);
rawKey = base64.parse(payload.key);
const masterKey = crypto.subtle.importKey('raw', rawKey, VaultKeys.MASTERKEY_KEY_DESIGNATION, true, ['sign']);
return new VaultKeys(await masterKey);
} finally {
rawKey.fill(0x00);
}
}

/**
* Unwraps keys protected by the legacy "Vault Admin Password".
* @param vaultAdminPassword Vault Admin Password
* @param wrappedMasterkey The wrapped masterkey
* @param wrappedOwnerPrivateKey The wrapped owner private key
* @param ownerPublicKey The owner public key
* @param salt PBKDF2 Salt
* @param iterations PBKDF2 Iterations
* @returns The unwrapped key material.
* @throws WrongPasswordError, if the wrong password is used
* @deprecated Only used during "claim vault ownership" workflow for legacy vaults
*/
public static async decryptWithAdminPassword(vaultAdminPassword: string, wrappedMasterkey: string, wrappedOwnerPrivateKey: string, ownerPublicKey: string, salt: string, iterations: number): Promise<[VaultKeys, CryptoKeyPair]> {
// pbkdf2:
const encodedPw = new TextEncoder().encode(vaultAdminPassword);
const pwKey = crypto.subtle.importKey('raw', encodedPw, 'PBKDF2', false, ['deriveKey']);
const kek = crypto.subtle.deriveKey(
{
name: 'PBKDF2',
hash: 'SHA-256',
salt: base64.parse(salt, { loose: true }),
iterations: iterations
},
await pwKey,
{ name: 'AES-GCM', length: 256 },
false,
['unwrapKey']
);
// unwrapping
const decodedMasterKey = base64.parse(wrappedMasterkey, { loose: true });
const decodedPrivateKey = base64.parse(wrappedOwnerPrivateKey, { loose: true });
const decodedPublicKey = base64.parse(ownerPublicKey, { loose: true });
try {
const masterkey = crypto.subtle.unwrapKey(
'raw',
decodedMasterKey.slice(GCM_NONCE_LEN),
await kek,
{ name: 'AES-GCM', iv: decodedMasterKey.slice(0, GCM_NONCE_LEN) },
VaultKeys.MASTERKEY_KEY_DESIGNATION,
true,
['sign']
);
const privKey = crypto.subtle.unwrapKey(
'pkcs8',
decodedPrivateKey.slice(GCM_NONCE_LEN),
await kek,
{ name: 'AES-GCM', iv: decodedPrivateKey.slice(0, GCM_NONCE_LEN) },
{ name: 'ECDSA', namedCurve: 'P-384' },
false,
['sign']
);
const pubKey = crypto.subtle.importKey(
'spki',
decodedPublicKey,
{ name: 'ECDSA', namedCurve: 'P-384' },
true,
['verify']
);
return [new VaultKeys(await masterkey), { privateKey: await privKey, publicKey: await pubKey }];
} catch (error) {
throw new UnwrapKeyError(error);
}
}

/**
* Restore the master key from a given recovery key, create a new admin signature key pair.
* @param recoveryKey The recovery key
* @returns The recovered master key
* @throws Error, if passing a malformed recovery key
*/
public static async recover(recoveryKey: string): Promise<VaultKeys> {
// decode and check recovery key:
const decoded = wordEncoder.decode(recoveryKey);
if (decoded.length !== 66) {
throw new Error('Invalid recovery key length.');
}
const decodedKey = decoded.subarray(0, 64);
const crc32 = CRC32.compute(decodedKey);
if (decoded[64] !== (crc32 & 0xFF)
|| decoded[65] !== (crc32 >> 8 & 0xFF)) {
throw new Error('Invalid recovery key checksum.');
}

// construct new VaultKeys from recovered key
const key = crypto.subtle.importKey(
'raw',
decodedKey,
VaultKeys.MASTERKEY_KEY_DESIGNATION,
true,
['sign']
);
return new VaultKeys(await key);
}

public async createVaultConfig(kid: string, hubConfig: VaultConfigHeaderHub, payload: VaultConfigPayload): Promise<string> {
const header = JSON.stringify({
kid: kid,
typ: 'jwt',
alg: 'HS256',
hub: hubConfig
});
const payloadJson = JSON.stringify(payload);
const encoder = new TextEncoder();
const unsignedToken = base64url.stringify(encoder.encode(header), { pad: false }) + '.' + base64url.stringify(encoder.encode(payloadJson), { pad: false });
const encodedUnsignedToken = new TextEncoder().encode(unsignedToken);
const signature = await crypto.subtle.sign(
'HMAC',
this.masterKey,
encodedUnsignedToken
);
return unsignedToken + '.' + base64url.stringify(new Uint8Array(signature), { pad: false });
}

public async hashDirectoryId(cleartextDirectoryId: string): Promise<string> {
const dirHash = new TextEncoder().encode(cleartextDirectoryId);
const rawkey = new Uint8Array(await crypto.subtle.exportKey('raw', this.masterKey));
try {
// miscreant lib requires mac key first and then the enc key
const encKey = rawkey.subarray(0, rawkey.length / 2 | 0);
const macKey = rawkey.subarray(rawkey.length / 2 | 0);
const shiftedRawKey = new Uint8Array([...macKey, ...encKey]);
const key = await miscreant.SIV.importKey(shiftedRawKey, 'AES-SIV');
const ciphertext = await key.seal(dirHash, []);
// hash is only used as deterministic scheme for the root dir
const hash = await crypto.subtle.digest('SHA-1', ciphertext);
return base32.stringify(new Uint8Array(hash));
} finally {
rawkey.fill(0x00);
}
}

/**
* Encrypts this masterkey using the given public key
* @param userPublicKey The recipient's public key (DER-encoded)
* @returns a JWE containing this Masterkey
*/
public async encryptForUser(userPublicKey: Uint8Array): Promise<string> {
const publicKey = await crypto.subtle.importKey('spki', userPublicKey, UserKeys.KEY_DESIGNATION, false, []);
const rawkey = new Uint8Array(await crypto.subtle.exportKey('raw', this.masterKey));
try {
const payload: VaultKeysWEPayload = {
key: base64.stringify(rawkey),
};
return JWEBuilder.ecdhEs(publicKey).encrypt(payload);
} finally {
rawkey.fill(0x00);
}
}

/**
* Encode masterkey for offline backup purposes, allowing re-importing the key for recovery purposes
*/
public async createRecoveryKey(): Promise<string> {
const rawkey = new Uint8Array(await crypto.subtle.exportKey('raw', this.masterKey));

// add 16 bit checksum:
const crc32 = CRC32.compute(rawkey);
const checksum = new Uint8Array(2);
checksum[0] = crc32 & 0xff; // append the least significant byte of the crc
checksum[1] = crc32 >> 8 & 0xff; // followed by the second-least significant byte
const combined = new Uint8Array([...rawkey, ...checksum]);

// encode using human-readable words:
return wordEncoder.encodePadded(combined);
}
}
export const GCM_NONCE_LEN = 12;

export class UserKeys {
public static readonly KEY_USAGES: KeyUsage[] = ['deriveBits'];
Expand Down Expand Up @@ -467,11 +229,11 @@ export class VaultMetadata {
};

readonly automaticAccessGrant: VaultMetadataJWEAutomaticAccessGrantDto;
readonly keys: Record<string,CryptoKey>;
readonly keys: Record<string, CryptoKey>;
readonly latestFileKey: string;
readonly nameKey: string;

protected constructor(automaticAccessGrant: VaultMetadataJWEAutomaticAccessGrantDto, keys: Record<string,CryptoKey>, latestFileKey: string, nameKey: string) {
protected constructor(automaticAccessGrant: VaultMetadataJWEAutomaticAccessGrantDto, keys: Record<string, CryptoKey>, latestFileKey: string, nameKey: string) {
this.automaticAccessGrant = automaticAccessGrant;
this.keys = keys;
this.latestFileKey = latestFileKey;
Expand All @@ -495,9 +257,9 @@ export class VaultMetadata {
// TODO https://github.com/encryption-alliance/unified-vault-format/pull/19 is this correct?
['sign']
);
const fileKeyId = Array(4).fill(null).map(()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62)).join("")
const nameKeyId = Array(4).fill(null).map(()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62)).join("")
const keys: Record<string,CryptoKey> = {};
const fileKeyId = Array(4).fill(null).map(() => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random() * 62)).join("")
const nameKeyId = Array(4).fill(null).map(() => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random() * 62)).join("")
const keys: Record<string, CryptoKey> = {};
keys[fileKeyId] = await fileKey;
keys[nameKeyId] = await nameKey;
return new VaultMetadata(automaticAccessGrant, keys, fileKeyId, nameKeyId);
Expand All @@ -510,21 +272,21 @@ export class VaultMetadata {
* @returns vault metadata
*/
public static async decryptWithMasterKey(jwe: string, masterKey: CryptoKey): Promise<VaultMetadata> {
const payload = await JWEParser.parse(jwe).decryptA256kw(masterKey);
const keys: Record<string,string> = payload['keys'];
const keysImported: Record<string,CryptoKey> = payload['keys'];
for (const k in keys) {
// TODO https://github.com/encryption-alliance/unified-vault-format/pull/19 is this correct?
keysImported[k] = await crypto.subtle.importKey('raw', base64.parse(keys[k]), VaultMetadata.RAWKEY_KEY_DESIGNATION, true, ['sign']);
}
const latestFileKey = payload['latestFileKey']
const nameKey = payload['nameKey']
return new VaultMetadata(
payload['org.cryptomator.automaticAccessGrant'],
keysImported,
latestFileKey,
nameKey
);
const payload = await JWEParser.parse(jwe).decryptA256kw(masterKey);
const keys: Record<string, string> = payload['keys'];
const keysImported: Record<string, CryptoKey> = payload['keys'];
for (const k in keys) {
// TODO https://github.com/encryption-alliance/unified-vault-format/pull/19 is this correct?
keysImported[k] = await crypto.subtle.importKey('raw', base64.parse(keys[k]), VaultMetadata.RAWKEY_KEY_DESIGNATION, true, ['sign']);
}
const latestFileKey = payload['latestFileKey']
const nameKey = payload['nameKey']
return new VaultMetadata(
payload['org.cryptomator.automaticAccessGrant'],
keysImported,
latestFileKey,
nameKey
);
}

/**
Expand All @@ -533,19 +295,19 @@ export class VaultMetadata {
* @returns a JWE containing this Masterkey
*/
public async encryptWithMasterKey(masterKey: CryptoKey): Promise<string> {
const keysExported: Record<string,string> = {};
const keysExported: Record<string, string> = {};
for (const k in this.keys) {
keysExported[k] = base64.stringify(new Uint8Array(await crypto.subtle.exportKey('raw', this.keys[k])));
}
const payload = {
fileFormat: "AES-256-GCM-32k",
nameFormat: "AES-256-SIV",
keys: keysExported,
latestFileKey: this.latestFileKey,
nameKey: this.nameKey,
// TODO https://github.com/encryption-alliance/unified-vault-format/pull/21 finalize kdf
kdf: "1STEP-HMAC-SHA512",
'org.cryptomator.automaticAccessGrant': this.automaticAccessGrant
fileFormat: "AES-256-GCM-32k",
nameFormat: "AES-256-SIV",
keys: keysExported,
latestFileKey: this.latestFileKey,
nameKey: this.nameKey,
// TODO https://github.com/encryption-alliance/unified-vault-format/pull/21 finalize kdf
kdf: "1STEP-HMAC-SHA512",
'org.cryptomator.automaticAccessGrant': this.automaticAccessGrant
}
return JWEBuilder.a256kw(masterKey).encrypt(payload);
}
Expand All @@ -554,7 +316,7 @@ export class VaultMetadata {
const dirHash = new TextEncoder().encode(cleartextDirectoryId);
// TODO https://github.com/encryption-alliance/unified-vault-format/pull/19 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MUST NEVER BE RELEASED LIKE THIS
// TODO https://github.com/encryption-alliance/unified-vault-format/pull/19 use rawFileKey,rawNameKey for rootDirHash for now - should depend on nameKey only!!
const rawkey = new Uint8Array([...new Uint8Array(await crypto.subtle.exportKey('raw', this.keys[this.latestFileKey])),...new Uint8Array(await crypto.subtle.exportKey('raw', this.keys[this.nameKey]))]);
const rawkey = new Uint8Array([...new Uint8Array(await crypto.subtle.exportKey('raw', this.keys[this.latestFileKey])), ...new Uint8Array(await crypto.subtle.exportKey('raw', this.keys[this.nameKey]))]);
try {
// miscreant lib requires mac key first and then the enc key
const encKey = rawkey.subarray(0, rawkey.length / 2 | 0);
Expand Down
2 changes: 1 addition & 1 deletion 2 frontend/src/common/vaultconfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import JSZip from 'jszip';
import config, { absBackendBaseURL, absFrontendBaseURL } from '../common/config';
import { VaultConfigHeaderHub, VaultConfigPayload, VaultKeys } from '../common/crypto';
import { VaultConfigHeaderHub, VaultConfigPayload, VaultKeys } from '../common/vaultv8';

export class VaultConfig {
readonly vaultConfigToken: string;
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.