Merge pull request #564 from FlowCrypt/master
process blocks that miss a checksum | #563
This commit is contained in:
commit
dd1ae4d325
|
@ -40,6 +40,7 @@ export default {
|
||||||
aead_protect: false, // use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption
|
aead_protect: false, // use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption
|
||||||
integrity_protect: true, // use integrity protection for symmetric encryption
|
integrity_protect: true, // use integrity protection for symmetric encryption
|
||||||
ignore_mdc_error: false, // fail on decrypt if message is not integrity protected
|
ignore_mdc_error: false, // fail on decrypt if message is not integrity protected
|
||||||
|
checksum_required: false, // do not throw error when armor is missing a checksum
|
||||||
rsa_blinding: true,
|
rsa_blinding: true,
|
||||||
use_native: true, // use native node.js crypto and Web Crypto apis (if available)
|
use_native: true, // use native node.js crypto and Web Crypto apis (if available)
|
||||||
zero_copy: false, // use transferable objects between the Web Worker and main thread
|
zero_copy: false, // use transferable objects between the Web Worker and main thread
|
||||||
|
|
|
@ -191,8 +191,7 @@ function createcrc24(input) {
|
||||||
/**
|
/**
|
||||||
* Splits a message into two parts, the headers and the body. This is an internal function
|
* Splits a message into two parts, the headers and the body. This is an internal function
|
||||||
* @param {String} text OpenPGP armored message part
|
* @param {String} text OpenPGP armored message part
|
||||||
* @returns {(Boolean|Object)} Either false in case of an error
|
* @returns {Object} An object with attribute "headers" containing the headers
|
||||||
* or an object with attribute "headers" containing the headers and
|
|
||||||
* and an attribute "body" containing the body.
|
* and an attribute "body" containing the body.
|
||||||
*/
|
*/
|
||||||
function splitHeaders(text) {
|
function splitHeaders(text) {
|
||||||
|
@ -234,19 +233,19 @@ function verifyHeaders(headers) {
|
||||||
/**
|
/**
|
||||||
* Splits a message into two parts, the body and the checksum. This is an internal function
|
* Splits a message into two parts, the body and the checksum. This is an internal function
|
||||||
* @param {String} text OpenPGP armored message part
|
* @param {String} text OpenPGP armored message part
|
||||||
* @returns {(Boolean|Object)} Either false in case of an error
|
* @returns {Object} An object with attribute "body" containing the body
|
||||||
* or an object with attribute "body" containing the body
|
|
||||||
* and an attribute "checksum" containing the checksum.
|
* and an attribute "checksum" containing the checksum.
|
||||||
*/
|
*/
|
||||||
function splitChecksum(text) {
|
function splitChecksum(text) {
|
||||||
|
text = text.trim();
|
||||||
var body = text;
|
var body = text;
|
||||||
var checksum = "";
|
var checksum = "";
|
||||||
|
|
||||||
var lastEquals = text.lastIndexOf("=");
|
var lastEquals = text.lastIndexOf("=");
|
||||||
|
|
||||||
if (lastEquals >= 0) {
|
if (lastEquals >= 0 && lastEquals !== text.length - 1) { // '=' as the last char means no checksum
|
||||||
body = text.slice(0, lastEquals);
|
body = text.slice(0, lastEquals);
|
||||||
checksum = text.slice(lastEquals + 1);
|
checksum = text.slice(lastEquals + 1).substr(0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { body: body, checksum: checksum };
|
return { body: body, checksum: checksum };
|
||||||
|
@ -268,6 +267,7 @@ function dearmor(text) {
|
||||||
|
|
||||||
var type = getType(text);
|
var type = getType(text);
|
||||||
|
|
||||||
|
text = text.trim() + "\n";
|
||||||
var splittext = text.split(reSplit);
|
var splittext = text.split(reSplit);
|
||||||
|
|
||||||
// IE has a bug in split with a re. If the pattern matches the beginning of the
|
// IE has a bug in split with a re. If the pattern matches the beginning of the
|
||||||
|
@ -309,12 +309,9 @@ function dearmor(text) {
|
||||||
checksum = sig_sum.checksum;
|
checksum = sig_sum.checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
checksum = checksum.substr(0, 4);
|
if (!verifyCheckSum(result.data, checksum) && (checksum || config.checksum_required)) {
|
||||||
|
// will NOT throw error if checksum is empty AND checksum is not required (GPG compatibility)
|
||||||
if (!verifyCheckSum(result.data, checksum)) {
|
throw new Error("Ascii armor integrity check on message failed: '" + checksum + "' should be '" +
|
||||||
throw new Error("Ascii armor integrity check on message failed: '" +
|
|
||||||
checksum +
|
|
||||||
"' should be '" +
|
|
||||||
getCheckSum(result.data) + "'");
|
getCheckSum(result.data) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ describe("ASCII armor", function() {
|
||||||
expect(msg).to.throw(Error, /Unknown ASCII armor type/);
|
expect(msg).to.throw(Error, /Unknown ASCII armor type/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Armor checksum validation', function () {
|
it('Armor checksum validation - mismatch', function () {
|
||||||
var privKey =
|
var privKey =
|
||||||
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
|
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
|
||||||
'Version: OpenPGP.js v0.3.0',
|
'Version: OpenPGP.js v0.3.0',
|
||||||
|
@ -152,9 +152,140 @@ describe("ASCII armor", function() {
|
||||||
'=wJN@',
|
'=wJN@',
|
||||||
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
|
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
|
||||||
|
|
||||||
var result = openpgp.key.readArmored(privKey);
|
// try with default config
|
||||||
expect(result.err).to.exist;
|
var result_1 = openpgp.key.readArmored(privKey);
|
||||||
expect(result.err[0].message).to.match(/Ascii armor integrity check on message failed/);
|
expect(result_1.err).to.exist;
|
||||||
|
expect(result_1.err[0].message).to.match(/Ascii armor integrity check on message failed/);
|
||||||
|
|
||||||
|
// try opposite config
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
|
var result_2 = openpgp.key.readArmored(privKey);
|
||||||
|
expect(result_2.err).to.exist;
|
||||||
|
expect(result_2.err[0].message).to.match(/Ascii armor integrity check on message failed/);
|
||||||
|
|
||||||
|
// back to default
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Armor checksum validation - valid', function () {
|
||||||
|
var privKey =
|
||||||
|
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
|
||||||
|
'Version: OpenPGP.js v0.3.0',
|
||||||
|
'Comment: http://openpgpjs.org',
|
||||||
|
'',
|
||||||
|
'xbYEUubX7gEBANDWhzoP+Tr/IyRSv++vl5jBesQIPTYGQBdzF4YDnGEBABEB',
|
||||||
|
'AAH+CQMIfzdw4/PKNl5gVXdtfDFdSIN8yJT2rbeg3+SsWexXZNNdRaONWaiB',
|
||||||
|
'Z5cG9Q6+BoXKsEshIdcYOgwsAgRxlPpRA34Vvmg2QBk7PhdrkbK7aqENsJ1w',
|
||||||
|
'dIlLD6p9GmLE20yVff58/fMiUtPRgsD83SpKTAX6EM1ulpkuQQNjmrVc5qc8',
|
||||||
|
'7AMdF80JdW5kZWZpbmVkwj8EEAEIABMFAlLm1+4JEBD8MASZrpALAhsDAAAs',
|
||||||
|
'QgD8CUrwv7Hrp/INR0/UvAvzS52VztREQwQWTJMrgTNHBGjHtgRS5tfuAQEA',
|
||||||
|
'nys9SaSgR+l6iZc/M8hGIUmbuahE2/+mtw+/l0RO+WcAEQEAAf4JAwjr39Yi',
|
||||||
|
'FzjxImDN1IoYVsonA9M+BtIIJHafuQUHjyEr1paJJK5xS6KlyGgpMTXTD6y/',
|
||||||
|
'qxS3ZSPPzHGRrs2CmkVEiPmurn9Ed05tb0y9OnJkWtuh3z9VVq9d8zHzuENa',
|
||||||
|
'bUfli+P/v+dRaZ+1rSOxUFbFYbFB5XK/A9b/OPFrv+mb4KrtLxugwj8EGAEI',
|
||||||
|
'ABMFAlLm1+4JEBD8MASZrpALAhsMAAC3IgD8DnLGbMnpLtrX72RCkPW1ffLq',
|
||||||
|
'71vlXMJNXvoCeuejiRw=',
|
||||||
|
'=wJNM',
|
||||||
|
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
|
||||||
|
|
||||||
|
// try with default config
|
||||||
|
var result_1 = openpgp.key.readArmored(privKey);
|
||||||
|
expect(result_1.err).to.not.exist;
|
||||||
|
|
||||||
|
// try opposite config
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
|
var result_2 = openpgp.key.readArmored(privKey);
|
||||||
|
expect(result_2.err).to.not.exist;
|
||||||
|
|
||||||
|
// back to default
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Armor checksum validation - missing', function () {
|
||||||
|
var privKeyNoCheckSum =
|
||||||
|
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
|
||||||
|
'Version: OpenPGP.js v0.3.0',
|
||||||
|
'Comment: http://openpgpjs.org',
|
||||||
|
'',
|
||||||
|
'xbYEUubX7gEBANDWhzoP+Tr/IyRSv++vl5jBesQIPTYGQBdzF4YDnGEBABEB',
|
||||||
|
'AAH+CQMIfzdw4/PKNl5gVXdtfDFdSIN8yJT2rbeg3+SsWexXZNNdRaONWaiB',
|
||||||
|
'Z5cG9Q6+BoXKsEshIdcYOgwsAgRxlPpRA34Vvmg2QBk7PhdrkbK7aqENsJ1w',
|
||||||
|
'dIlLD6p9GmLE20yVff58/fMiUtPRgsD83SpKTAX6EM1ulpkuQQNjmrVc5qc8',
|
||||||
|
'7AMdF80JdW5kZWZpbmVkwj8EEAEIABMFAlLm1+4JEBD8MASZrpALAhsDAAAs',
|
||||||
|
'QgD8CUrwv7Hrp/INR0/UvAvzS52VztREQwQWTJMrgTNHBGjHtgRS5tfuAQEA',
|
||||||
|
'nys9SaSgR+l6iZc/M8hGIUmbuahE2/+mtw+/l0RO+WcAEQEAAf4JAwjr39Yi',
|
||||||
|
'FzjxImDN1IoYVsonA9M+BtIIJHafuQUHjyEr1paJJK5xS6KlyGgpMTXTD6y/',
|
||||||
|
'qxS3ZSPPzHGRrs2CmkVEiPmurn9Ed05tb0y9OnJkWtuh3z9VVq9d8zHzuENa',
|
||||||
|
'bUfli+P/v+dRaZ+1rSOxUFbFYbFB5XK/A9b/OPFrv+mb4KrtLxugwj8EGAEI',
|
||||||
|
'ABMFAlLm1+4JEBD8MASZrpALAhsMAAC3IgD8DnLGbMnpLtrX72RCkPW1ffLq',
|
||||||
|
'71vlXMJNXvoCeuejiRw=',
|
||||||
|
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
|
||||||
|
|
||||||
|
// try with default config
|
||||||
|
var result_1 = openpgp.key.readArmored(privKeyNoCheckSum);
|
||||||
|
if(openpgp.config.checksum_required) {
|
||||||
|
expect(result_1.err).to.exist;
|
||||||
|
expect(result_1.err[0].message).to.match(/Ascii armor integrity check on message failed/);
|
||||||
|
} else {
|
||||||
|
expect(result_1.err).to.not.exist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try opposite config
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
|
var result_2 = openpgp.key.readArmored(privKeyNoCheckSum);
|
||||||
|
if(openpgp.config.checksum_required) {
|
||||||
|
expect(result_2.err).to.exist;
|
||||||
|
expect(result_2.err[0].message).to.match(/Ascii armor integrity check on message failed/);
|
||||||
|
} else {
|
||||||
|
expect(result_2.err).to.not.exist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// back to default
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Armor checksum validation - missing - trailing newline', function () {
|
||||||
|
var privKeyNoCheckSumWithTrailingNewline =
|
||||||
|
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
|
||||||
|
'Version: OpenPGP.js v0.3.0',
|
||||||
|
'Comment: http://openpgpjs.org',
|
||||||
|
'',
|
||||||
|
'xbYEUubX7gEBANDWhzoP+Tr/IyRSv++vl5jBesQIPTYGQBdzF4YDnGEBABEB',
|
||||||
|
'AAH+CQMIfzdw4/PKNl5gVXdtfDFdSIN8yJT2rbeg3+SsWexXZNNdRaONWaiB',
|
||||||
|
'Z5cG9Q6+BoXKsEshIdcYOgwsAgRxlPpRA34Vvmg2QBk7PhdrkbK7aqENsJ1w',
|
||||||
|
'dIlLD6p9GmLE20yVff58/fMiUtPRgsD83SpKTAX6EM1ulpkuQQNjmrVc5qc8',
|
||||||
|
'7AMdF80JdW5kZWZpbmVkwj8EEAEIABMFAlLm1+4JEBD8MASZrpALAhsDAAAs',
|
||||||
|
'QgD8CUrwv7Hrp/INR0/UvAvzS52VztREQwQWTJMrgTNHBGjHtgRS5tfuAQEA',
|
||||||
|
'nys9SaSgR+l6iZc/M8hGIUmbuahE2/+mtw+/l0RO+WcAEQEAAf4JAwjr39Yi',
|
||||||
|
'FzjxImDN1IoYVsonA9M+BtIIJHafuQUHjyEr1paJJK5xS6KlyGgpMTXTD6y/',
|
||||||
|
'qxS3ZSPPzHGRrs2CmkVEiPmurn9Ed05tb0y9OnJkWtuh3z9VVq9d8zHzuENa',
|
||||||
|
'bUfli+P/v+dRaZ+1rSOxUFbFYbFB5XK/A9b/OPFrv+mb4KrtLxugwj8EGAEI',
|
||||||
|
'ABMFAlLm1+4JEBD8MASZrpALAhsMAAC3IgD8DnLGbMnpLtrX72RCkPW1ffLq',
|
||||||
|
'71vlXMJNXvoCeuejiRw=',
|
||||||
|
'-----END PGP PRIVATE KEY BLOCK-----',
|
||||||
|
''].join('\n');
|
||||||
|
|
||||||
|
// try with default config
|
||||||
|
var result_1 = openpgp.key.readArmored(privKeyNoCheckSumWithTrailingNewline);
|
||||||
|
if(openpgp.config.checksum_required) {
|
||||||
|
expect(result_1.err).to.exist;
|
||||||
|
expect(result_1.err[0].message).to.match(/Ascii armor integrity check on message failed/);
|
||||||
|
} else {
|
||||||
|
expect(result_1.err).to.not.exist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try opposite config
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
|
var result_2 = openpgp.key.readArmored(privKeyNoCheckSumWithTrailingNewline);
|
||||||
|
if(openpgp.config.checksum_required) {
|
||||||
|
expect(result_2.err).to.exist;
|
||||||
|
expect(result_2.err[0].message).to.match(/Ascii armor integrity check on message failed/);
|
||||||
|
} else {
|
||||||
|
expect(result_2.err).to.not.exist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// back to default
|
||||||
|
openpgp.config.checksum_required = !openpgp.config.checksum_required;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Accept header with trailing whitespace', function () {
|
it('Accept header with trailing whitespace', function () {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user