@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
JavaScript
;
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));
}