iocane
Version:
Textual encryption library
107 lines (106 loc) • 4.34 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.unpackEncryptedData = exports.prepareHeader = exports.prepareFooter = exports.packEncryptedData = exports.itemsToBuffer = void 0;
var signature_1 = require("../shared/signature");
var symbols_1 = require("../symbols");
function itemsToBuffer(items) {
return Buffer.concat(items.reduce(function (buffers, item) {
var data;
if (typeof item === "string" || typeof item === "number") {
data = Buffer.from("".concat(item), "utf8");
}
else if (item instanceof Buffer) {
data = item;
}
else {
throw new Error("Failed packing data: Invalid component type: ".concat(typeof item));
}
buffers.push(sizeToBuffer(data.length));
buffers.push(data);
return buffers;
}, []));
}
exports.itemsToBuffer = itemsToBuffer;
function packEncryptedData(encryptedComponents) {
var border = Buffer.from((0, signature_1.getBinaryContentBorder)());
var components = [prepareHeader(encryptedComponents)];
if (encryptedComponents.content) {
components.push(itemsToBuffer([border]), encryptedComponents.content, border);
}
components.push(prepareFooter(encryptedComponents));
return Buffer.concat(components);
}
exports.packEncryptedData = packEncryptedData;
function prepareFooter(encryptedComponents) {
var auth = encryptedComponents.auth;
var componentsSuffix = JSON.stringify({
auth: auth
});
return itemsToBuffer([componentsSuffix]);
}
exports.prepareFooter = prepareFooter;
function prepareHeader(encryptedComponents) {
var signature = Buffer.from((0, signature_1.getBinarySignature)());
var iv = encryptedComponents.iv, salt = encryptedComponents.salt, rounds = encryptedComponents.rounds, method = encryptedComponents.method;
var componentsPrefix = JSON.stringify({
iv: iv,
salt: salt,
rounds: rounds,
method: method
});
return Buffer.concat([signature, itemsToBuffer([componentsPrefix])]);
}
exports.prepareHeader = prepareHeader;
function sizeToBuffer(size) {
var buffer = Buffer.alloc(symbols_1.SIZE_ENCODING_BYTES);
buffer.writeUInt32BE(size, 0);
return buffer;
}
function unpackEncryptedData(encryptedContent) {
var offset = 0;
var expectedSignature = Buffer.from((0, signature_1.getBinarySignature)());
var sigLen = expectedSignature.length;
var signature = encryptedContent.slice(0, sigLen);
if (!signature.equals(expectedSignature)) {
throw new Error("Failed unpacking data: Signature mismatch");
}
offset = sigLen;
// Read header
var headerSize = encryptedContent.readUInt32BE(offset);
offset += symbols_1.SIZE_ENCODING_BYTES;
var headerData = encryptedContent.slice(offset, offset + headerSize);
offset += headerSize;
// Read content border
var contentBorderSize = encryptedContent.readUInt32BE(offset);
offset += symbols_1.SIZE_ENCODING_BYTES;
var contentBorder = encryptedContent.slice(offset, offset + contentBorderSize);
offset += contentBorderSize;
var contentBorderRef = Buffer.from((0, signature_1.getBinaryContentBorder)());
if (!contentBorderRef.equals(contentBorder)) {
throw new Error("Decoding error: Encrypted content length is corrupt");
}
// Locate end of content
var endBorderOffset = encryptedContent.indexOf(contentBorder, offset);
if (endBorderOffset === -1) {
throw new Error("Decoding error: Encrypted content corrupt or incomplete");
}
var contentBuff = encryptedContent.slice(offset, endBorderOffset);
offset = endBorderOffset + contentBorderSize;
// Read footer
var footerSize = encryptedContent.readUInt32BE(offset);
offset += symbols_1.SIZE_ENCODING_BYTES;
var footerData = encryptedContent.slice(offset, offset + footerSize);
offset += footerSize;
// Decode
var _a = JSON.parse(headerData.toString("utf8")), iv = _a.iv, salt = _a.salt, rounds = _a.rounds, method = _a.method;
var auth = JSON.parse(footerData.toString("utf8")).auth;
return {
content: contentBuff,
iv: iv,
salt: salt,
auth: auth,
rounds: rounds,
method: method
};
}
exports.unpackEncryptedData = unpackEncryptedData;
;