chore: add mechanism for legacy uuid aad
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
|||||||
} from './../../../../Types/EncryptedParameters'
|
} from './../../../../Types/EncryptedParameters'
|
||||||
import { DecryptedParameters } from '../../../../Types/DecryptedParameters'
|
import { DecryptedParameters } from '../../../../Types/DecryptedParameters'
|
||||||
import { DeriveHashingKeyUseCase } from '../Hash/DeriveHashingKey'
|
import { DeriveHashingKeyUseCase } from '../Hash/DeriveHashingKey'
|
||||||
|
import { V004Components } from '../../V004AlgorithmTypes'
|
||||||
|
|
||||||
export class GenerateDecryptedParametersUseCase {
|
export class GenerateDecryptedParametersUseCase {
|
||||||
private base64DataUsecase = new CreateConsistentBase64JsonPayloadUseCase(this.crypto)
|
private base64DataUsecase = new CreateConsistentBase64JsonPayloadUseCase(this.crypto)
|
||||||
@@ -39,7 +40,7 @@ export class GenerateDecryptedParametersUseCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentResult = this.decryptContent(encrypted, contentKeyResult.contentKey)
|
const contentResult = this.decryptContent(encrypted, contentKeyResult.decrypted)
|
||||||
if (!contentResult) {
|
if (!contentResult) {
|
||||||
return {
|
return {
|
||||||
uuid: encrypted.uuid,
|
uuid: encrypted.uuid,
|
||||||
@@ -54,17 +55,17 @@ export class GenerateDecryptedParametersUseCase {
|
|||||||
hashingKey,
|
hashingKey,
|
||||||
{
|
{
|
||||||
additionalData: contentKeyResult.components.additionalData,
|
additionalData: contentKeyResult.components.additionalData,
|
||||||
plaintext: contentKeyResult.contentKey,
|
plaintext: contentKeyResult.decrypted,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
additionalData: contentResult.components.additionalData,
|
additionalData: contentResult.components.additionalData,
|
||||||
plaintext: contentResult.content,
|
plaintext: contentResult.decrypted,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
uuid: encrypted.uuid,
|
uuid: encrypted.uuid,
|
||||||
content: JSON.parse(contentResult.content),
|
content: JSON.parse(contentResult.decrypted),
|
||||||
signatureData: signatureVerificationResult,
|
signatureData: signatureVerificationResult,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,34 +73,7 @@ export class GenerateDecryptedParametersUseCase {
|
|||||||
private decryptContent(encrypted: EncryptedOutputParameters, contentKey: string) {
|
private decryptContent(encrypted: EncryptedOutputParameters, contentKey: string) {
|
||||||
const contentComponents = deconstructEncryptedPayloadString(encrypted.content)
|
const contentComponents = deconstructEncryptedPayloadString(encrypted.content)
|
||||||
|
|
||||||
const contentAuthenticatedData = this.stringToAuthenticatedDataUseCase.execute(
|
return this.decrypt(encrypted, contentComponents, contentKey)
|
||||||
contentComponents.authenticatedData,
|
|
||||||
{
|
|
||||||
u: encrypted.uuid,
|
|
||||||
v: encrypted.version,
|
|
||||||
ksi: encrypted.key_system_identifier,
|
|
||||||
svu: encrypted.shared_vault_uuid,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
const authenticatedDataString = this.base64DataUsecase.execute(contentAuthenticatedData)
|
|
||||||
|
|
||||||
const content = this.crypto.xchacha20Decrypt(
|
|
||||||
contentComponents.ciphertext,
|
|
||||||
contentComponents.nonce,
|
|
||||||
contentKey,
|
|
||||||
authenticatedDataString,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!content) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
content,
|
|
||||||
components: contentComponents,
|
|
||||||
authenticatedDataString,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private decryptContentKey(
|
private decryptContentKey(
|
||||||
@@ -108,32 +82,37 @@ export class GenerateDecryptedParametersUseCase {
|
|||||||
) {
|
) {
|
||||||
const contentKeyComponents = deconstructEncryptedPayloadString(encrypted.enc_item_key)
|
const contentKeyComponents = deconstructEncryptedPayloadString(encrypted.enc_item_key)
|
||||||
|
|
||||||
const contentKeyAuthenticatedData = this.stringToAuthenticatedDataUseCase.execute(
|
return this.decrypt(encrypted, contentKeyComponents, key.itemsKey)
|
||||||
contentKeyComponents.authenticatedData,
|
}
|
||||||
{
|
|
||||||
u: encrypted.uuid,
|
|
||||||
v: encrypted.version,
|
|
||||||
ksi: encrypted.key_system_identifier,
|
|
||||||
svu: encrypted.shared_vault_uuid,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
const authenticatedDataString = this.base64DataUsecase.execute(contentKeyAuthenticatedData)
|
private decrypt(encrypted: EncryptedOutputParameters, components: V004Components, key: string) {
|
||||||
|
const rawAuthenticatedData = this.stringToAuthenticatedDataUseCase.executeRaw(components.authenticatedData)
|
||||||
|
|
||||||
const contentKey = this.crypto.xchacha20Decrypt(
|
const doesRawContainLegacyUppercaseUuid = /[A-Z]/.test(rawAuthenticatedData.u)
|
||||||
contentKeyComponents.ciphertext,
|
|
||||||
contentKeyComponents.nonce,
|
const authenticatedData = this.stringToAuthenticatedDataUseCase.execute(components.authenticatedData, {
|
||||||
key.itemsKey,
|
u: doesRawContainLegacyUppercaseUuid ? encrypted.uuid.toUpperCase() : encrypted.uuid,
|
||||||
|
v: encrypted.version,
|
||||||
|
ksi: encrypted.key_system_identifier,
|
||||||
|
svu: encrypted.shared_vault_uuid,
|
||||||
|
})
|
||||||
|
|
||||||
|
const authenticatedDataString = this.base64DataUsecase.execute(authenticatedData)
|
||||||
|
|
||||||
|
const decrypted = this.crypto.xchacha20Decrypt(
|
||||||
|
components.ciphertext,
|
||||||
|
components.nonce,
|
||||||
|
key,
|
||||||
authenticatedDataString,
|
authenticatedDataString,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!contentKey) {
|
if (!decrypted) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
contentKey,
|
decrypted,
|
||||||
components: contentKeyComponents,
|
components: components,
|
||||||
authenticatedDataString,
|
authenticatedDataString,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,4 +16,9 @@ export class StringToAuthenticatedDataUseCase {
|
|||||||
...override,
|
...override,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
executeRaw(rawAuthenticatedData: string): RootKeyEncryptedAuthenticatedData | ItemAuthenticatedData {
|
||||||
|
const base = JSON.parse(this.crypto.base64Decode(rawAuthenticatedData))
|
||||||
|
return base
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Result, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
|||||||
import { GetHost } from './GetHost'
|
import { GetHost } from './GetHost'
|
||||||
|
|
||||||
export class IsApplicationUsingThirdPartyHost implements SyncUseCaseInterface<boolean> {
|
export class IsApplicationUsingThirdPartyHost implements SyncUseCaseInterface<boolean> {
|
||||||
private readonly APPLICATION_DEFAULT_HOSTS = ['api.standardnotes.com', 'sync.standardnotes.org']
|
private readonly APPLICATION_DEFAULT_HOSTS = ['api.standardnotes.com', 'sync.standardnotes.org', 'localhost:3123']
|
||||||
|
|
||||||
private readonly FILES_DEFAULT_HOSTS = ['files.standardnotes.com']
|
private readonly FILES_DEFAULT_HOSTS = ['files.standardnotes.com']
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export const VaultTests = {
|
export const VaultTests = {
|
||||||
enabled: true,
|
enabled: false,
|
||||||
exclusive: false,
|
exclusive: false,
|
||||||
files: [
|
files: [
|
||||||
'vaults/vaults.test.js',
|
'vaults/vaults.test.js',
|
||||||
|
|||||||
Reference in New Issue
Block a user