Don't use asmcrypto's streaming API when not necessary
Optimization for Firefox
This commit is contained in:
parent
e1a8b17753
commit
eb72d4dd63
|
@ -43,10 +43,14 @@ function hashjs_hash(hash) {
|
|||
|
||||
function asmcrypto_hash(hash) {
|
||||
return function(data) {
|
||||
if (util.isStream(data)) {
|
||||
const hashInstance = new hash();
|
||||
return stream.transform(data, value => {
|
||||
hashInstance.process(value);
|
||||
}, () => hashInstance.finish().result);
|
||||
} else {
|
||||
return hash.bytes(data);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ Message.prototype.getSigningKeyIds = function() {
|
|||
* @returns {Promise<Message>} new message with decrypted content
|
||||
* @async
|
||||
*/
|
||||
Message.prototype.decrypt = async function(privateKeys, passwords, sessionKeys) {
|
||||
Message.prototype.decrypt = async function(privateKeys, passwords, sessionKeys, asStream) {
|
||||
const keyObjs = sessionKeys || await this.decryptSessionKeys(privateKeys, passwords);
|
||||
|
||||
const symEncryptedPacketlist = this.packets.filterByTag(
|
||||
|
@ -120,7 +120,7 @@ Message.prototype.decrypt = async function(privateKeys, passwords, sessionKeys)
|
|||
}
|
||||
|
||||
try {
|
||||
await symEncryptedPacket.decrypt(keyObjs[i].algorithm, keyObjs[i].data);
|
||||
await symEncryptedPacket.decrypt(keyObjs[i].algorithm, keyObjs[i].data, asStream);
|
||||
break;
|
||||
} catch (e) {
|
||||
util.print_debug_error(e);
|
||||
|
@ -260,7 +260,7 @@ Message.prototype.getText = function() {
|
|||
* @returns {Promise<Message>} new message with encrypted content
|
||||
* @async
|
||||
*/
|
||||
Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard=false, date=new Date(), userId={}) {
|
||||
Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard=false, date=new Date(), userId={}, asStream) {
|
||||
let symAlgo;
|
||||
let aeadAlgo;
|
||||
let symEncryptedPacket;
|
||||
|
@ -300,7 +300,7 @@ Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard
|
|||
}
|
||||
symEncryptedPacket.packets = this.packets;
|
||||
|
||||
await symEncryptedPacket.encrypt(symAlgo, sessionKey);
|
||||
await symEncryptedPacket.encrypt(symAlgo, sessionKey, asStream);
|
||||
|
||||
msg.packets.push(symEncryptedPacket);
|
||||
symEncryptedPacket.packets = new packet.List(); // remove packets after encryption
|
||||
|
@ -536,7 +536,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
|
|||
* @returns {Promise<Array<({keyid: module:type/keyid, valid: Boolean})>>} list of signer's keyid and validity of signature
|
||||
* @async
|
||||
*/
|
||||
Message.prototype.verify = async function(keys, date=new Date()) {
|
||||
Message.prototype.verify = async function(keys, date=new Date(), asStream) {
|
||||
const msg = this.unwrapCompressed();
|
||||
const literalDataList = msg.packets.filterByTag(enums.packet.literal);
|
||||
if (literalDataList.length !== 1) {
|
||||
|
@ -548,7 +548,7 @@ Message.prototype.verify = async function(keys, date=new Date()) {
|
|||
onePassSig.signatureData = stream.fromAsync(() => new Promise(resolve => {
|
||||
onePassSig.signatureDataResolve = resolve;
|
||||
}));
|
||||
onePassSig.hashed = onePassSig.hash(literalDataList[0]);
|
||||
onePassSig.hashed = onePassSig.hash(literalDataList[0], undefined, asStream);
|
||||
});
|
||||
return stream.transform(msg.packets.stream, signature => {
|
||||
const onePassSig = onePassSigList.pop();
|
||||
|
|
|
@ -323,7 +323,7 @@ export function encrypt({ data, dataType, publicKeys, privateKeys, passwords, se
|
|||
}
|
||||
}
|
||||
message = message.compress(compression);
|
||||
return message.encrypt(publicKeys, passwords, sessionKey, wildcard, date, toUserId);
|
||||
return message.encrypt(publicKeys, passwords, sessionKey, wildcard, date, toUserId, asStream);
|
||||
|
||||
}).then(async encrypted => {
|
||||
if (armor) {
|
||||
|
@ -364,13 +364,13 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe
|
|||
return asyncProxy.delegate('decrypt', { message, privateKeys, passwords, sessionKeys, publicKeys, format, asStream, signature, date });
|
||||
}
|
||||
|
||||
return message.decrypt(privateKeys, passwords, sessionKeys).then(async function(decrypted) {
|
||||
return message.decrypt(privateKeys, passwords, sessionKeys, asStream).then(async function(decrypted) {
|
||||
if (!publicKeys) {
|
||||
publicKeys = [];
|
||||
}
|
||||
|
||||
const result = {};
|
||||
result.signatures = signature ? await decrypted.verifyDetached(signature, publicKeys, date) : await decrypted.verify(publicKeys, date);
|
||||
result.signatures = signature ? await decrypted.verifyDetached(signature, publicKeys, date) : await decrypted.verify(publicKeys, date, asStream);
|
||||
result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
|
||||
result.data = await convertStream(result.data, asStream);
|
||||
result.signatures = await convertStreamArray(result.signatures, asStream);
|
||||
|
@ -462,7 +462,7 @@ export function verify({ message, publicKeys, asStream, signature=null, date=new
|
|||
|
||||
return Promise.resolve().then(async function() {
|
||||
const result = {};
|
||||
result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys, date);
|
||||
result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys, date, asStream);
|
||||
result.data = message instanceof CleartextMessage ? message.getText() : message.getLiteralData();
|
||||
result.data = await convertStream(result.data, asStream);
|
||||
result.signatures = await convertStreamArray(result.signatures, asStream);
|
||||
|
|
|
@ -658,9 +658,13 @@ Signature.prototype.toHash = function(data) {
|
|||
}
|
||||
};
|
||||
|
||||
Signature.prototype.hash = function(data, toHash) {
|
||||
Signature.prototype.hash = function(data, toHash, asStream=true) {
|
||||
const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
|
||||
return crypto.hash.digest(hashAlgorithm, toHash || this.toHash(data));
|
||||
if (!toHash) toHash = this.toHash(data);
|
||||
if (!asStream && util.isStream(toHash)) {
|
||||
return stream.fromAsync(async () => this.hash(data, await stream.readToEnd(toHash)));
|
||||
}
|
||||
return crypto.hash.digest(hashAlgorithm, toHash);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* @requires util
|
||||
*/
|
||||
|
||||
import { AES_CFB_Decrypt, AES_CFB_Encrypt } from 'asmcrypto.js/src/aes/cfb/exports';
|
||||
import { AES_CFB, AES_CFB_Decrypt, AES_CFB_Encrypt } from 'asmcrypto.js/src/aes/cfb/exports';
|
||||
|
||||
import config from '../config';
|
||||
import crypto from '../crypto';
|
||||
|
@ -90,8 +90,9 @@ SymEncryptedIntegrityProtected.prototype.write = function () {
|
|||
* @returns {Promise<Boolean>}
|
||||
* @async
|
||||
*/
|
||||
SymEncryptedIntegrityProtected.prototype.encrypt = async function (sessionKeyAlgorithm, key) {
|
||||
const bytes = this.packets.write();
|
||||
SymEncryptedIntegrityProtected.prototype.encrypt = async function (sessionKeyAlgorithm, key, asStream) {
|
||||
let bytes = this.packets.write();
|
||||
if (!asStream) bytes = await stream.readToEnd(bytes);
|
||||
const prefixrandom = await crypto.getPrefixRandom(sessionKeyAlgorithm);
|
||||
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
|
||||
const prefix = util.concat([prefixrandom, repeat]);
|
||||
|
@ -118,12 +119,13 @@ SymEncryptedIntegrityProtected.prototype.encrypt = async function (sessionKeyAlg
|
|||
* @returns {Promise<Boolean>}
|
||||
* @async
|
||||
*/
|
||||
SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlgorithm, key) {
|
||||
SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlgorithm, key, asStream) {
|
||||
if (!asStream) this.encrypted = await stream.readToEnd(this.encrypted);
|
||||
const encrypted = stream.clone(this.encrypted);
|
||||
const encryptedClone = stream.passiveClone(encrypted);
|
||||
let decrypted;
|
||||
if (sessionKeyAlgorithm.substr(0, 3) === 'aes') { // AES optimizations. Native code for node, asmCrypto for browser.
|
||||
decrypted = aesDecrypt(sessionKeyAlgorithm, encrypted, key);
|
||||
decrypted = aesDecrypt(sessionKeyAlgorithm, encrypted, key, asStream);
|
||||
} else {
|
||||
decrypted = crypto.cfb.decrypt(sessionKeyAlgorithm, key, await stream.readToEnd(encrypted), false);
|
||||
}
|
||||
|
@ -176,8 +178,12 @@ function aesDecrypt(algo, ct, key) {
|
|||
if (nodeCrypto) { // Node crypto library.
|
||||
pt = nodeDecrypt(algo, ct, key);
|
||||
} else { // asm.js fallback
|
||||
if (util.isStream(ct)) {
|
||||
const cfb = new AES_CFB_Decrypt(key);
|
||||
pt = stream.transform(ct, value => cfb.process(value).result, () => cfb.finish().result);
|
||||
} else {
|
||||
pt = AES_CFB.decrypt(ct, key);
|
||||
}
|
||||
}
|
||||
return stream.slice(pt, crypto.cipher[algo].blockSize + 2); // Remove random prefix
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user