Merge pull request #763 from twiss/decrypt-performance-fix
Decryption performance fix
This commit is contained in:
commit
e616f8a242
|
@ -192,6 +192,26 @@ function verifyHeaders(headers) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a message into two parts, the body and the checksum. This is an internal function
|
||||
* @param {String} text OpenPGP armored message part
|
||||
* @returns {Object} An object with attribute "body" containing the body
|
||||
* and an attribute "checksum" containing the checksum.
|
||||
*/
|
||||
function splitChecksum(text) {
|
||||
let body = text;
|
||||
let checksum = "";
|
||||
|
||||
const lastEquals = text.lastIndexOf("=");
|
||||
|
||||
if (lastEquals >= 0 && lastEquals !== text.length - 1) { // '=' as the last char means no checksum
|
||||
body = text.slice(0, lastEquals);
|
||||
checksum = text.slice(lastEquals + 1).substr(0, 4);
|
||||
}
|
||||
|
||||
return { body: body, checksum: checksum };
|
||||
}
|
||||
|
||||
/**
|
||||
* DeArmor an OpenPGP armored message; verify the checksum and return
|
||||
* the encoded bytes
|
||||
|
@ -204,7 +224,7 @@ function verifyHeaders(headers) {
|
|||
function dearmor(input) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const reSplit = /^-----[^-]+-----$/;
|
||||
const reSplit = /^-----[^-]+-----$/m;
|
||||
const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/;
|
||||
|
||||
let type;
|
||||
|
@ -213,21 +233,17 @@ function dearmor(input) {
|
|||
let headersDone;
|
||||
let text = [];
|
||||
let textDone;
|
||||
let resolved = false;
|
||||
let checksum;
|
||||
let data = base64.decode(stream.transformPair(input, async (readable, writable) => {
|
||||
const reader = stream.getReader(readable);
|
||||
const writer = stream.getWriter(writable);
|
||||
while (true) {
|
||||
if (resolved) await writer.ready;
|
||||
try {
|
||||
const lineUntrimmed = await reader.readLine();
|
||||
if (lineUntrimmed === undefined) {
|
||||
try {
|
||||
while (true) {
|
||||
let line = await reader.readLine();
|
||||
if (line === undefined) {
|
||||
throw new Error('Misformed armored text');
|
||||
}
|
||||
// remove trailing whitespace at end of lines
|
||||
// remove leading whitespace for compat with older versions of OpenPGP.js
|
||||
const line = lineUntrimmed.trim();
|
||||
line = line.replace(/[\t\r\n ]+$/, '');
|
||||
if (!type) {
|
||||
if (reSplit.test(line)) {
|
||||
type = getType(line);
|
||||
|
@ -243,13 +259,13 @@ function dearmor(input) {
|
|||
headersDone = true;
|
||||
if (textDone || type !== 2) {
|
||||
resolve({ text, data, headers, type });
|
||||
resolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!textDone && type === 2) {
|
||||
if (!reSplit.test(line)) {
|
||||
// Reverse dash-escaping for msg
|
||||
text.push(util.removeTrailingSpaces(lineUntrimmed.replace(/^- /, '').replace(/[\r\n]+$/, '')));
|
||||
text.push(line.replace(/^- /, ''));
|
||||
} else {
|
||||
text = text.join('\r\n');
|
||||
textDone = true;
|
||||
|
@ -257,26 +273,40 @@ function dearmor(input) {
|
|||
lastHeaders = [];
|
||||
headersDone = false;
|
||||
}
|
||||
} else {
|
||||
if (!reSplit.test(line)) {
|
||||
if (line[0] !== '=') {
|
||||
await writer.write(line);
|
||||
} else {
|
||||
checksum = line.substr(1);
|
||||
}
|
||||
} else {
|
||||
await writer.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
if (resolved) {
|
||||
await writer.abort(e);
|
||||
} else {
|
||||
reject(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
return;
|
||||
}
|
||||
const writer = stream.getWriter(writable);
|
||||
try {
|
||||
while (true) {
|
||||
await writer.ready;
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
throw new Error('Misformed armored text');
|
||||
}
|
||||
const line = value + '';
|
||||
if (line.indexOf('=') === -1 && line.indexOf('-') === -1) {
|
||||
await writer.write(line);
|
||||
} else {
|
||||
let remainder = line + await reader.readToEnd();
|
||||
remainder = remainder.replace(/[\t\r ]+$/mg, '');
|
||||
const parts = remainder.split(reSplit);
|
||||
if (parts.length === 1) {
|
||||
throw new Error('Misformed armored text');
|
||||
}
|
||||
const split = splitChecksum(parts[0].slice(0, -1));
|
||||
checksum = split.checksum;
|
||||
await writer.write(split.body);
|
||||
break;
|
||||
}
|
||||
}
|
||||
await writer.ready;
|
||||
await writer.close();
|
||||
} catch(e) {
|
||||
await writer.abort(e);
|
||||
}
|
||||
}));
|
||||
data = stream.transformPair(data, async (readable, writable) => {
|
||||
|
|
|
@ -106,19 +106,20 @@ function r2s(t, u) {
|
|||
let a = 0;
|
||||
|
||||
return stream.transform(t, value => {
|
||||
const r = [];
|
||||
const tl = value.length;
|
||||
const r = new Uint8Array(Math.ceil(0.75 * tl));
|
||||
let index = 0;
|
||||
for (let n = 0; n < tl; n++) {
|
||||
c = b64.indexOf(value.charAt(n));
|
||||
if (c >= 0) {
|
||||
if (s) {
|
||||
r.push(a | ((c >> (6 - s)) & 255));
|
||||
r[index++] = a | ((c >> (6 - s)) & 255);
|
||||
}
|
||||
s = (s + 2) & 7;
|
||||
a = (c << s) & 255;
|
||||
}
|
||||
}
|
||||
return new Uint8Array(r);
|
||||
return r.subarray(0, index);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -142,8 +142,10 @@ function pako_zlib(constructor, options = {}) {
|
|||
return function(data) {
|
||||
const obj = new constructor(options);
|
||||
return stream.transform(data, value => {
|
||||
obj.push(value, pako.Z_SYNC_FLUSH);
|
||||
return obj.result;
|
||||
if (value.length) {
|
||||
obj.push(value, pako.Z_SYNC_FLUSH);
|
||||
return obj.result;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -256,14 +256,13 @@ export default {
|
|||
packet = await reader.readBytes(packet_length);
|
||||
await callback({ tag, packet });
|
||||
}
|
||||
const { done, value } = await reader.read();
|
||||
if (!done) reader.unshift(value);
|
||||
const nextPacket = await reader.peekBytes(2);
|
||||
if (writer) {
|
||||
await writer.ready;
|
||||
await writer.close();
|
||||
}
|
||||
if (streaming) await callbackReturned;
|
||||
return done || !value || !value.length;
|
||||
return !nextPacket || !nextPacket.length;
|
||||
} catch(e) {
|
||||
if (writer) {
|
||||
await writer.abort(e);
|
||||
|
|
|
@ -304,7 +304,7 @@ describe("ASCII armor", function() {
|
|||
|
||||
it('Accept header with trailing whitespace', async function () {
|
||||
const privKey =
|
||||
['-----BEGIN PGP PRIVATE KEY BLOCK-----\t \r',
|
||||
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
|
||||
'Version: OpenPGP.js v0.3.0',
|
||||
'Comment: https://openpgpjs.org',
|
||||
'',
|
||||
|
@ -321,7 +321,8 @@ describe("ASCII armor", function() {
|
|||
'ABMFAlLm1+4JEBD8MASZrpALAhsMAAC3IgD8DnLGbMnpLtrX72RCkPW1ffLq',
|
||||
'71vlXMJNXvoCeuejiRw=',
|
||||
'=wJNM',
|
||||
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
|
||||
'-----END PGP PRIVATE KEY BLOCK-----',
|
||||
''].join('\t \r\n');
|
||||
|
||||
const result = await openpgp.key.readArmored(privKey);
|
||||
expect(result.err).to.not.exist;
|
||||
|
|
|
@ -841,19 +841,19 @@ const wrong_key =
|
|||
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
||||
|
||||
const expiredKey =
|
||||
`-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
`-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
xcA4BAAAAAEBAgCgONc0J8rfO6cJw5YTP38x1ze2tAYIO7EcmRCNYwMkXngb
|
||||
0Qdzg34Q5RW0rNiR56VB6KElPUhePRPVklLFiIvHABEBAAEAAf9qabYMzsz/
|
||||
/LeRVZSsTgTljmJTdzd2ambUbpi+vt8MXJsbaWh71vjoLMWSXajaKSPDjVU5
|
||||
waFNt9kLqwGGGLqpAQD5ZdMH2XzTq6GU9Ka69iZs6Pbnzwdz59Vc3i8hXlUj
|
||||
zQEApHargCTsrtvSrm+hK/pN51/BHAy9lxCAw9f2etx+AeMA/RGrijkFZtYt
|
||||
jeWdv/usXL3mgHvEcJv63N5zcEvDX5X4W1bND3Rlc3QxIDxhQGIuY29tPsJ7
|
||||
BBABCAAvBQIAAAABBQMAAAU5BgsJBwgDAgkQzcF99nGrkAkEFQgKAgMWAgEC
|
||||
GQECGwMCHgEAABAlAfwPehmLZs+gOhOTTaSslqQ50bl/REjmv42Nyr1ZBlQS
|
||||
DECl1Qu4QyeXin29uEXWiekMpNlZVsEuc8icCw6ABhIZ
|
||||
=/7PI
|
||||
-----END PGP PRIVATE KEY BLOCK-----`;
|
||||
xcA4BAAAAAEBAgCgONc0J8rfO6cJw5YTP38x1ze2tAYIO7EcmRCNYwMkXngb
|
||||
0Qdzg34Q5RW0rNiR56VB6KElPUhePRPVklLFiIvHABEBAAEAAf9qabYMzsz/
|
||||
/LeRVZSsTgTljmJTdzd2ambUbpi+vt8MXJsbaWh71vjoLMWSXajaKSPDjVU5
|
||||
waFNt9kLqwGGGLqpAQD5ZdMH2XzTq6GU9Ka69iZs6Pbnzwdz59Vc3i8hXlUj
|
||||
zQEApHargCTsrtvSrm+hK/pN51/BHAy9lxCAw9f2etx+AeMA/RGrijkFZtYt
|
||||
jeWdv/usXL3mgHvEcJv63N5zcEvDX5X4W1bND3Rlc3QxIDxhQGIuY29tPsJ7
|
||||
BBABCAAvBQIAAAABBQMAAAU5BgsJBwgDAgkQzcF99nGrkAkEFQgKAgMWAgEC
|
||||
GQECGwMCHgEAABAlAfwPehmLZs+gOhOTTaSslqQ50bl/REjmv42Nyr1ZBlQS
|
||||
DECl1Qu4QyeXin29uEXWiekMpNlZVsEuc8icCw6ABhIZ
|
||||
=/7PI
|
||||
-----END PGP PRIVATE KEY BLOCK-----`;
|
||||
|
||||
const multipleBindingSignatures =
|
||||
`-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
|
Loading…
Reference in New Issue
Block a user