Skip to content
Snippets Groups Projects

Resolve "[Document Sealing] Add document proto buffers"

Merged Zdravko Iliev requested to merge 28-document-sealing-add-document-proto-buffers into master
Compare and
13 files
+ 3320
344
Compare changes
  • Side-by-side
  • Inline
Files
13
@@ -5,10 +5,9 @@ import Utils, {
base64ToArrayBuffer,
arrayBufferToBase64,
} from "../src/utils/common";
import { MessageData } from "../src";
import { MessageData, DocumentData, IpfsContentData } from "../src";
const emailData: MessageData = {
statusId: "123",
sender: {
name: "Arty",
email: "arty@mail.ru",
@@ -42,118 +41,230 @@ const emailData: MessageData = {
senderPublicKeyUuid: "<uuid>",
};
const documentData: DocumentData = {
author: "Craig McCracken",
documentTitle: "The_Powerpuff_Girls",
creationDate: new Date().toDateString(),
lastModDate: new Date().toDateString(),
documentPages: 2,
};
/**
* Algorithm spec
* https://code.vereign.com/internal/product/-/issues/70#note_56356
*/
describe("QrCodeDataService", () => {
it("performs the whole QR code data breakage/assembling routine", async () => {
/**
* Encode
*/
const encodedEmailData = QrCodeDataService.encodeEmailData(emailData);
const compressedEmailData = Utils.compressData(encodedEmailData);
const {
data,
iv: sessionIv,
key: sessionKey,
} = await CryptoService.encryptAESGCM(
arrayBufferToBase64(compressedEmailData)
);
// 32 is a head bytes size. It's the minimum, and the bigger is better.
// Increase it as long as you can maintain good appearance of the QR code
const { head, tail } = QrCodeDataService.breakQrCodeData(data, 32);
const encodedSessionKey = QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(sessionKey),
data: arrayBufferToBase64(sessionIv),
});
describe("Email", () => {
it("performs the whole QR code data breakage/assembling routine", async () => {
/**
* Encode
*/
const encodedEmailData = QrCodeDataService.encodeEmailData(emailData);
const compressedEmailData = Utils.compressData(encodedEmailData);
const {
data,
iv: sessionIv,
key: sessionKey,
} = await CryptoService.encryptAESGCM(
arrayBufferToBase64(compressedEmailData)
);
// 32 is a head bytes size. It's the minimum, and the bigger is better.
// Increase it as long as you can maintain good appearance of the QR code
const { head, tail } = QrCodeDataService.breakQrCodeData(data, 32);
const encodedSessionKey = QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(sessionKey),
data: arrayBufferToBase64(sessionIv),
});
// In client apps, RSA encryption happens using HSM service.
const { privateKeyPEM, publicKeyPEM } =
await CryptoService.generateRSAKeys();
const encryptedSessionKey = await CryptoService.encryptRSA(
publicKeyPEM,
base64ToArrayBuffer(encodedSessionKey)
);
const {
data: doubleEncryptedSessionKey,
iv: storageIv,
key: storageKey,
} = await CryptoService.encryptAESGCM(
arrayBufferToBase64(encryptedSessionKey)
);
// Put base64 of this into QR code data as `?q=` param
const encodedStorageKeyAndHead = QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(storageKey),
data: arrayBufferToBase64(head),
});
const encodedDoubleEncryptedSessionKey =
QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(doubleEncryptedSessionKey),
data: arrayBufferToBase64(storageIv),
});
// In client apps, RSA encryption happens using HSM service.
const {
privateKeyPEM,
publicKeyPEM,
} = await CryptoService.generateRSAKeys();
const encryptedSessionKey = await CryptoService.encryptRSA(
publicKeyPEM,
base64ToArrayBuffer(encodedSessionKey)
);
const {
data: doubleEncryptedSessionKey,
iv: storageIv,
key: storageKey,
} = await CryptoService.encryptAESGCM(
arrayBufferToBase64(encryptedSessionKey)
);
// Put base64 of this into QR code data as `?q=` param
const encodedStorageKeyAndHead = QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(storageKey),
data: arrayBufferToBase64(head),
// Send this to putQRCodeData api
const backblazeData = {
sessionKey: encodedDoubleEncryptedSessionKey,
tail: arrayBufferToBase64(tail),
};
/**
* Decode
*/
// Retrieve base64 of this from QR code URL
const decodedStorageKeyAndHead = QrCodeDataService.decodeKeyDataPair(
encodedStorageKeyAndHead
);
// decode this from backblaze data
const { key: doubleEncryptedSessionKeyDecoded, data: storageIvDecoded } =
QrCodeDataService.decodeKeyDataPair(backblazeData.sessionKey);
const doubleDecryptedSessionKey = await CryptoService.decryptAESGCM(
base64ToArrayBuffer(doubleEncryptedSessionKeyDecoded),
base64ToArrayBuffer(decodedStorageKeyAndHead.key),
base64ToArrayBuffer(storageIvDecoded)
);
// In client apps, RSA decryption happens using HSM service.
const decryptedSessionKey = await CryptoService.decryptRSA(
privateKeyPEM,
base64ToArrayBuffer(doubleDecryptedSessionKey)
);
const decodedSessionKey =
QrCodeDataService.decodeKeyDataPair(decryptedSessionKey);
const assembledData = QrCodeDataService.assembleQrCodeData(
base64ToArrayBuffer(decodedStorageKeyAndHead.data),
base64ToArrayBuffer(backblazeData.tail)
);
const decryptedEmailData = await CryptoService.decryptAESGCM(
assembledData,
base64ToArrayBuffer(decodedSessionKey.key),
base64ToArrayBuffer(decodedSessionKey.data)
);
const decompressedEmailData = Utils.decompressData(decryptedEmailData);
const decodedEmailData = QrCodeDataService.decodeEmailData(
decompressedEmailData
);
expect(decodedEmailData).toEqual(emailData);
});
});
const encodedDoubleEncryptedSessionKey = QrCodeDataService.encodeKeyDataPair(
{
key: arrayBufferToBase64(doubleEncryptedSessionKey),
data: arrayBufferToBase64(storageIv),
}
);
// Send this to putQRCodeData api
const backblazeData = {
sessionKey: encodedDoubleEncryptedSessionKey,
tail: arrayBufferToBase64(tail),
};
/**
* Decode
*/
// Retrieve base64 of this from QR code URL
const decodedStorageKeyAndHead = QrCodeDataService.decodeKeyDataPair(
encodedStorageKeyAndHead
);
// decode this from backblaze data
const {
key: doubleEncryptedSessionKeyDecoded,
data: storageIvDecoded,
} = QrCodeDataService.decodeKeyDataPair(backblazeData.sessionKey);
const doubleDecryptedSessionKey = await CryptoService.decryptAESGCM(
base64ToArrayBuffer(doubleEncryptedSessionKeyDecoded),
base64ToArrayBuffer(decodedStorageKeyAndHead.key),
base64ToArrayBuffer(storageIvDecoded)
);
// In client apps, RSA decryption happens using HSM service.
const decryptedSessionKey = await CryptoService.decryptRSA(
privateKeyPEM,
base64ToArrayBuffer(doubleDecryptedSessionKey)
);
const decodedSessionKey = QrCodeDataService.decodeKeyDataPair(
decryptedSessionKey
);
const assembledData = QrCodeDataService.assembleQrCodeData(
base64ToArrayBuffer(decodedStorageKeyAndHead.data),
base64ToArrayBuffer(backblazeData.tail)
);
const decryptedEmailData = await CryptoService.decryptAESGCM(
assembledData,
base64ToArrayBuffer(decodedSessionKey.key),
base64ToArrayBuffer(decodedSessionKey.data)
);
const decompressedEmailData = Utils.decompressData(decryptedEmailData);
const decodedEmailData = QrCodeDataService.decodeEmailData(
decompressedEmailData
);
expect(decodedEmailData).toEqual(emailData);
describe("Documents", () => {
it("performs the whole QR code data breakage/assembling routine ", async () => {
/**
* Encode
*/
const encodedDocumentData =
QrCodeDataService.encodeDocumentData(documentData);
const compressedDocumentData = Utils.compressData(encodedDocumentData);
const {
data,
iv: sessionIv,
key: sessionKey,
} = await CryptoService.encryptAESGCM(
arrayBufferToBase64(compressedDocumentData)
);
const { head, tail } = QrCodeDataService.breakQrCodeData(data, 32);
const encodedSessionKey = QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(sessionKey),
data: arrayBufferToBase64(sessionIv),
});
// In client apps, RSA encryption happens using HSM service.
const { privateKeyPEM, publicKeyPEM } =
await CryptoService.generateRSAKeys();
const encryptedSessionKey = await CryptoService.encryptRSA(
publicKeyPEM,
base64ToArrayBuffer(encodedSessionKey)
);
const {
data: doubleEncryptedSessionKey,
iv: storageIv,
key: storageKey,
} = await CryptoService.encryptAESGCM(
arrayBufferToBase64(encryptedSessionKey)
);
// Put base64 of this into QR code data as `?q=` param
const encodedStorageKeyAndHead = QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(storageKey),
data: arrayBufferToBase64(head),
});
const encodedDoubleEncryptedSessionKey =
QrCodeDataService.encodeKeyDataPair({
key: arrayBufferToBase64(doubleEncryptedSessionKey),
data: arrayBufferToBase64(storageIv),
});
// Send this to putQRCodeData api
const backblazeData = {
sessionKey: encodedDoubleEncryptedSessionKey,
tail: arrayBufferToBase64(tail),
};
/**
* Decode Document
*/
// Retrieve base64 of this from QR code URL
const decodedStorageKeyAndHead = QrCodeDataService.decodeKeyDataPair(
encodedStorageKeyAndHead
);
// decode this from backblaze data
const { key: doubleEncryptedSessionKeyDecoded, data: storageIvDecoded } =
QrCodeDataService.decodeKeyDataPair(backblazeData.sessionKey);
const doubleDecryptedSessionKey = await CryptoService.decryptAESGCM(
base64ToArrayBuffer(doubleEncryptedSessionKeyDecoded),
base64ToArrayBuffer(decodedStorageKeyAndHead.key),
base64ToArrayBuffer(storageIvDecoded)
);
// In client apps, RSA decryption happens using HSM service.
const decryptedSessionKey = await CryptoService.decryptRSA(
privateKeyPEM,
base64ToArrayBuffer(doubleDecryptedSessionKey)
);
const decodedSessionKey =
QrCodeDataService.decodeKeyDataPair(decryptedSessionKey);
const assembledData = QrCodeDataService.assembleQrCodeData(
base64ToArrayBuffer(decodedStorageKeyAndHead.data),
base64ToArrayBuffer(backblazeData.tail)
);
const decryptedDocumentData = await CryptoService.decryptAESGCM(
assembledData,
base64ToArrayBuffer(decodedSessionKey.key),
base64ToArrayBuffer(decodedSessionKey.data)
);
const decompressedDocumentData = Utils.decompressData(
decryptedDocumentData
);
const decodedDocumentData = QrCodeDataService.decodeDocumentData(
decompressedDocumentData
);
expect(decodedDocumentData).toEqual(documentData);
});
});
});
Loading