UNPKG

@sebastianp265/safe-server-side-storage-client

Version:

Library for Confidential Server-Side Message Storage Using the Labyrinth Protocol

73 lines (72 loc) 6.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CorruptedMessageRecoverySecrets = exports.VirtualDeviceEncryptedRecoverySecrets = void 0; exports.encryptVirtualDeviceRecoverySecrets = encryptVirtualDeviceRecoverySecrets; exports.decryptVirtualDeviceRecoverySecrets = decryptVirtualDeviceRecoverySecrets; const VirtualDeviceKeyBundle_1 = require("../key-bundles/VirtualDeviceKeyBundle"); const authenticated_symmetric_encryption_1 = require("../../crypto/authenticated-symmetric-encryption"); const utils_1 = require("../../crypto/utils"); const keys_1 = require("../../crypto/keys"); const BytesSerializer_1 = require("../../BytesSerializer"); class VirtualDeviceEncryptedRecoverySecrets { encryptedEpochSequenceId; encryptedEpochRootKey; encryptedDeviceKeyPriv; encryptedEpochStorageKeyPriv; constructor(encryptedEpochSequenceId, encryptedEpochRootKey, encryptedEpochStorageKeyPriv, encryptedDeviceKeyPriv) { this.encryptedEpochSequenceId = encryptedEpochSequenceId; this.encryptedEpochRootKey = encryptedEpochRootKey; this.encryptedEpochStorageKeyPriv = encryptedEpochStorageKeyPriv; this.encryptedDeviceKeyPriv = encryptedDeviceKeyPriv; } static deserialize(virtualDeviceEncryptedRecoverSecretsSerialized) { const { encryptedEpochSequenceId, encryptedEpochRootKey, encryptedEpochStorageKeyPriv, encryptedDeviceKeyPriv, } = virtualDeviceEncryptedRecoverSecretsSerialized; return new VirtualDeviceEncryptedRecoverySecrets(BytesSerializer_1.bytesSerializerProvider.bytesSerializer.deserialize(encryptedEpochSequenceId), BytesSerializer_1.bytesSerializerProvider.bytesSerializer.deserialize(encryptedEpochRootKey), BytesSerializer_1.bytesSerializerProvider.bytesSerializer.deserialize(encryptedEpochStorageKeyPriv), BytesSerializer_1.bytesSerializerProvider.bytesSerializer.deserialize(encryptedDeviceKeyPriv)); } serialize() { return { encryptedEpochSequenceId: BytesSerializer_1.bytesSerializerProvider.bytesSerializer.serialize(this.encryptedEpochSequenceId), encryptedEpochRootKey: BytesSerializer_1.bytesSerializerProvider.bytesSerializer.serialize(this.encryptedEpochRootKey), encryptedEpochStorageKeyPriv: BytesSerializer_1.bytesSerializerProvider.bytesSerializer.serialize(this.encryptedEpochStorageKeyPriv), encryptedDeviceKeyPriv: BytesSerializer_1.bytesSerializerProvider.bytesSerializer.serialize(this.encryptedDeviceKeyPriv), }; } } exports.VirtualDeviceEncryptedRecoverySecrets = VirtualDeviceEncryptedRecoverySecrets; function encryptVirtualDeviceRecoverySecrets(virtualDeviceDecryptionKey, epochWithoutId, virtualDevicePrivateKeyBundle) { const encryptedEpochSequenceId = (0, authenticated_symmetric_encryption_1.encryptWithRandomNonce)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:epoch_anon_id"), (0, utils_1.asciiStringToBytes)(epochWithoutId.sequenceId)); const encryptedEpochRootKey = (0, authenticated_symmetric_encryption_1.encryptWithRandomNonce)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:epoch_root_key"), epochWithoutId.rootKey); const encryptedDeviceKeyPriv = (0, authenticated_symmetric_encryption_1.encryptWithRandomNonce)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:virtual_device_private_key"), (0, utils_1.asciiStringToBytes)(virtualDevicePrivateKeyBundle.deviceKeyPriv.serialize())); const encryptedEpochStorageKeyPriv = (0, authenticated_symmetric_encryption_1.encryptWithRandomNonce)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:epoch_storage_key_priv"), (0, utils_1.asciiStringToBytes)(virtualDevicePrivateKeyBundle.epochStorageKeyPriv.serialize())); return new VirtualDeviceEncryptedRecoverySecrets(encryptedEpochSequenceId, encryptedEpochRootKey, encryptedEpochStorageKeyPriv, encryptedDeviceKeyPriv); } class CorruptedMessageRecoverySecrets extends Error { constructor() { super("Your message history recovery secrets has been corrupted"); Object.setPrototypeOf(this, CorruptedMessageRecoverySecrets.prototype); } } exports.CorruptedMessageRecoverySecrets = CorruptedMessageRecoverySecrets; function decryptVirtualDeviceRecoverySecrets(virtualDeviceDecryptionKey, virtualDeviceEncryptedRecoverySecrets, expectedVirtualDevicePublicKeyBundle) { const epochSequenceId = (0, utils_1.bytesToAsciiString)((0, authenticated_symmetric_encryption_1.decrypt)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:epoch_anon_id"), virtualDeviceEncryptedRecoverySecrets.encryptedEpochSequenceId)); const epochRootKey = (0, authenticated_symmetric_encryption_1.decrypt)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:epoch_root_key"), virtualDeviceEncryptedRecoverySecrets.encryptedEpochRootKey); const deviceKeyPriv = keys_1.PrivateKey.deserialize((0, utils_1.bytesToAsciiString)((0, authenticated_symmetric_encryption_1.decrypt)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:virtual_device_private_key"), virtualDeviceEncryptedRecoverySecrets.encryptedDeviceKeyPriv))); const epochStorageKeyPriv = keys_1.PrivateKey.deserialize((0, utils_1.bytesToAsciiString)((0, authenticated_symmetric_encryption_1.decrypt)(virtualDeviceDecryptionKey, (0, utils_1.asciiStringToBytes)("virtual_device:epoch_storage_key_priv"), virtualDeviceEncryptedRecoverySecrets.encryptedEpochStorageKeyPriv))); const virtualDevicePrivateKeyBundle = new VirtualDeviceKeyBundle_1.VirtualDevicePrivateKeyBundle(deviceKeyPriv, epochStorageKeyPriv); const virtualDeviceKeyBundle = new VirtualDeviceKeyBundle_1.VirtualDeviceKeyBundle(virtualDevicePrivateKeyBundle, virtualDevicePrivateKeyBundle.getPublicKeyBundle()); if (!isVirtualDevicePublicKeyBundleValid(expectedVirtualDevicePublicKeyBundle, virtualDeviceKeyBundle.pub)) { throw new CorruptedMessageRecoverySecrets(); } return { virtualDeviceKeyBundle, epochWithoutId: { rootKey: epochRootKey, sequenceId: epochSequenceId, }, }; } function isVirtualDevicePublicKeyBundleValid(expected, actual) { return (expected.deviceKeyPub.equals(actual.deviceKeyPub) && (0, utils_1.bytes_equal)(expected.epochStorageKeySig, actual.epochStorageKeySig) && expected.epochStorageKeyPub.equals(actual.epochStorageKeyPub)); }