Add config parameter to top-level functions (#1241)

Refactor functions to take the configuration as a parameter.

This allows setting a config option for a single function call, whereas
setting `openpgp.config` could lead to concurrency-related issues when
multiple async function calls are made at the same time.

`openpgp.config` is used as default for unset config values in top-level
functions.
`openpgp.config` is used as default config object in low-level functions
(i.e., when calling a low-level function, it may be required to pass
`{ ...openpgp.config, modifiedConfig: modifiedValue }`).

Also,

- remove `config.rsaBlinding`: blinding is now always applied to RSA decryption
- remove `config.debug`: debugging mode can be enabled by setting
  `process.env.NODE_ENV = 'development'`
- remove `config.useNative`: native crypto is always used when available
This commit is contained in:
larabr
2021-02-26 20:04:54 +01:00
committed by GitHub
parent 15ee659c9c
commit 7f37a8aaca
51 changed files with 1361 additions and 1038 deletions

View File

@@ -242,33 +242,11 @@ module.exports = () => describe('API functional testing', function() {
await Promise.all(symmAlgos.map(async function(algo) {
const symmKey = await crypto.generateSessionKey(algo);
const IV = new Uint8Array(crypto.cipher[algo].blockSize);
const symmencData = await crypto.cfb.encrypt(algo, symmKey, util.strToUint8Array(plaintext), IV);
const symmencData = await crypto.cfb.encrypt(algo, symmKey, util.strToUint8Array(plaintext), IV, openpgp.config);
const text = util.uint8ArrayToStr(await crypto.cfb.decrypt(algo, symmKey, symmencData, new Uint8Array(crypto.cipher[algo].blockSize)));
expect(text).to.equal(plaintext);
}));
}
function testAESGCM(plaintext, nativeDecrypt) {
symmAlgos.forEach(function(algo) {
if (algo.substr(0,3) === 'aes') {
it(algo, async function() {
const key = await crypto.generateSessionKey(algo);
const iv = await crypto.random.getRandomBytes(crypto.gcm.ivLength);
let modeInstance = await crypto.gcm(algo, key);
const ciphertext = await modeInstance.encrypt(util.strToUint8Array(plaintext), iv);
openpgp.config.useNative = nativeDecrypt;
modeInstance = await crypto.gcm(algo, key);
const decrypted = await modeInstance.decrypt(util.strToUint8Array(util.uint8ArrayToStr(ciphertext)), iv);
const decryptedStr = util.uint8ArrayToStr(decrypted);
expect(decryptedStr).to.equal(plaintext);
});
}
});
}
it("Symmetric with OpenPGP CFB", async function () {
await testCFB("hello");
await testCFB("1234567");
@@ -276,45 +254,6 @@ module.exports = () => describe('API functional testing', function() {
await testCFB("12345678901234567890123456789012345678901234567890");
});
describe('Symmetric AES-GCM (native)', function() {
let useNativeVal;
beforeEach(function() {
useNativeVal = openpgp.config.useNative;
openpgp.config.useNative = true;
});
afterEach(function() {
openpgp.config.useNative = useNativeVal;
});
testAESGCM("12345678901234567890123456789012345678901234567890", true);
});
describe('Symmetric AES-GCM (asm.js fallback)', function() {
let useNativeVal;
beforeEach(function() {
useNativeVal = openpgp.config.useNative;
openpgp.config.useNative = false;
});
afterEach(function() {
openpgp.config.useNative = useNativeVal;
});
testAESGCM("12345678901234567890123456789012345678901234567890", false);
});
describe('Symmetric AES-GCM (native encrypt, asm.js decrypt)', function() {
let useNativeVal;
beforeEach(function() {
useNativeVal = openpgp.config.useNative;
openpgp.config.useNative = true;
});
afterEach(function() {
openpgp.config.useNative = useNativeVal;
});
testAESGCM("12345678901234567890123456789012345678901234567890", false);
});
it('Asymmetric using RSA with eme_pkcs1 padding', async function () {
const symmKey = await crypto.generateSessionKey('aes256');
return crypto.publicKeyEncrypt(algoRSA, RSAPublicParams, symmKey).then(RSAEncryptedData => {

View File

@@ -2,10 +2,10 @@
// Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js
const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
const EAX = require('../../src/crypto/eax');
const util = require('../../src/util');
const sandbox = require('sinon/lib/sinon/sandbox');
const chai = require('chai');
chai.use(require('chai-as-promised'));
@@ -125,30 +125,45 @@ function testAESEAX() {
});
}
module.exports = () => {
module.exports = () => describe('Symmetric AES-EAX', function() {
let sinonSandbox;
let getWebCryptoStub;
let getNodeCryptoStub;
const disableNative = () => {
enableNative();
// stubbed functions return undefined
getWebCryptoStub = sinonSandbox.stub(util, "getWebCrypto");
getNodeCryptoStub = sinonSandbox.stub(util, "getNodeCrypto");
};
const enableNative = () => {
getWebCryptoStub && getWebCryptoStub.restore();
getNodeCryptoStub && getNodeCryptoStub.restore();
};
describe('Symmetric AES-EAX (native)', function() {
let useNativeVal;
beforeEach(function() {
useNativeVal = openpgp.config.useNative;
openpgp.config.useNative = true;
beforeEach(function () {
sinonSandbox = sandbox.create();
enableNative();
});
afterEach(function() {
openpgp.config.useNative = useNativeVal;
afterEach(function () {
sinonSandbox.restore();
});
testAESEAX();
});
describe('Symmetric AES-EAX (asm.js fallback)', function() {
let useNativeVal;
beforeEach(function() {
useNativeVal = openpgp.config.useNative;
openpgp.config.useNative = false;
beforeEach(function () {
sinonSandbox = sandbox.create();
disableNative();
});
afterEach(function() {
openpgp.config.useNative = useNativeVal;
afterEach(function () {
sinonSandbox.restore();
});
testAESEAX();
});
};
});

View File

@@ -4,6 +4,7 @@ const KDFParams = require('../../src/type/kdf_params');
const elliptic_curves = require('../../src/crypto/public_key/elliptic');
const util = require('../../src/util');
const sandbox = require('sinon/lib/sinon/sandbox');
const chai = require('chai');
const elliptic_data = require('./elliptic_data');
@@ -133,133 +134,111 @@ module.exports = () => describe('ECDH key exchange @lightweight', function () {
]);
describe('ECDHE key generation', function () {
const ecdh = elliptic_curves.ecdh;
it('Invalid curve', async function () {
if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) {
this.skip();
}
const { key: publicKey } = await openpgp.generateKey({ curve: "secp256k1", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = Q1;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
await expect(
openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') })
const curve = new elliptic_curves.Curve('secp256k1');
const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test');
expect(
ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1)
).to.be.rejectedWith(Error, /Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|Unknown point format/);
});
it('Invalid public part of ephemeral key and private key', async function () {
const { key: publicKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = Q1;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = Q2;
privateKey.subKeys[0].keyPacket.privateParams.d = d2;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
it('Different keys', async function () {
const curve = new elliptic_curves.Curve('curve25519');
const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test');
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1);
await expect(
openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).to.be.rejectedWith('Error decrypting message: Key Data Integrity failed');
ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint1)
).to.be.rejectedWith(/Key Data Integrity failed/);
});
it('Invalid fingerprint', async function () {
const { key: publicKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = Q1;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = Q2;
privateKey.subKeys[0].keyPacket.privateParams.d = d2;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint2;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
const curve = new elliptic_curves.Curve('curve25519');
const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test');
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q2, fingerprint1);
await expect(
openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).to.be.rejectedWith('Error decrypting message: Session key decryption failed');
});
it('Different keys', async function () {
const { key: publicKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = Q2;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = Q1;
privateKey.subKeys[0].keyPacket.privateParams.d = d1;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
await expect(
openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).to.be.rejectedWith('Error decrypting message: Key Data Integrity failed');
ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint2)
).to.be.rejectedWith(/Key Data Integrity failed/);
});
it('Successful exchange curve25519', async function () {
const { key: publicKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = Q1;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: "curve25519", userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = Q1;
privateKey.subKeys[0].keyPacket.privateParams.d = d1;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
expect((
await openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).data).to.equal('test');
});
it('Successful exchange NIST P256', async function () {
const { key: publicKey } = await openpgp.generateKey({ curve: "p256", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = key_data.p256.pub;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: "p256", userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = key_data.p256.pub;
privateKey.subKeys[0].keyPacket.privateParams.d = key_data.p256.priv;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
expect((
await openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).data).to.equal('test');
});
it('Successful exchange NIST P384', async function () {
const { key: publicKey } = await openpgp.generateKey({ curve: "p384", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = key_data.p384.pub;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: "p384", userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = key_data.p384.pub;
privateKey.subKeys[0].keyPacket.privateParams.d = key_data.p384.priv;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
expect((
await openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).data).to.equal('test');
});
it('Successful exchange NIST P521', async function () {
const { key: publicKey } = await openpgp.generateKey({ curve: "p521", userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = key_data.p521.pub;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: "p521", userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = key_data.p521.pub;
privateKey.subKeys[0].keyPacket.privateParams.d = key_data.p521.priv;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
expect((
await openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).data).to.equal('test');
const curve = new elliptic_curves.Curve('curve25519');
const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test');
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1);
expect(await ecdh.decrypt(oid, kdfParams, V, C, Q1, d1, fingerprint1)).to.deep.equal(data);
});
it('Comparing decrypting with useNative = true and false', async function () {
const names = ["p256", "p384", "p521"];
return Promise.all(names.map(async function (name) {
const { key: publicKey } = await openpgp.generateKey({ curve: name, userIds: [{ name: 'Test' }] });
publicKey.subKeys[0].keyPacket.publicParams.Q = key_data[name].pub;
publicKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const { key: privateKey } = await openpgp.generateKey({ curve: name, userIds: [{ name: 'Test' }] });
privateKey.subKeys[0].keyPacket.publicParams.Q = key_data[name].pub;
privateKey.subKeys[0].keyPacket.privateParams.d = key_data[name].priv;
privateKey.subKeys[0].keyPacket.fingerprint = fingerprint1;
const armoredMessage = await openpgp.encrypt({ publicKeys: [publicKey], message: openpgp.Message.fromText('test') });
expect((
await openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).data).to.equal('test');
const useNative = openpgp.config.useNative;
openpgp.config.useNative = !useNative;
try {
expect((
await openpgp.decrypt({ privateKeys: [privateKey], message: await openpgp.readMessage({ armoredMessage }) })
).data).to.equal('test');
} finally {
openpgp.config.useNative = useNative;
}
}));
['p256', 'p384', 'p521'].forEach(curveName => {
it(`NIST ${curveName} - Successful exchange`, async function () {
const curve = new elliptic_curves.Curve(curveName);
const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test');
const Q = key_data[curveName].pub;
const d = key_data[curveName].priv;
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1);
expect(await ecdh.decrypt(oid, kdfParams, V, C, Q, d, fingerprint1)).to.deep.equal(data);
});
});
describe('Comparing decrypting with and without native crypto', () => {
let sinonSandbox;
let getWebCryptoStub;
let getNodeCryptoStub;
beforeEach(function () {
sinonSandbox = sandbox.create();
});
afterEach(function () {
sinonSandbox.restore();
});
const disableNative = () => {
enableNative();
// stubbed functions return undefined
getWebCryptoStub = sinonSandbox.stub(util, "getWebCrypto");
getNodeCryptoStub = sinonSandbox.stub(util, "getNodeCrypto");
};
const enableNative = () => {
getWebCryptoStub && getWebCryptoStub.restore();
getNodeCryptoStub && getNodeCryptoStub.restore();
};
['p256', 'p384', 'p521'].forEach(curveName => {
it(`NIST ${curveName}`, async function () {
const nodeCrypto = util.getNodeCrypto();
const webCrypto = util.getWebCrypto();
if (!nodeCrypto && !webCrypto) {
this.skip();
}
const curve = new elliptic_curves.Curve(curveName);
const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test');
const Q = key_data[curveName].pub;
const d = key_data[curveName].priv;
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1);
const nativeDecryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'deriveBits') : sinonSandbox.spy(nodeCrypto, 'createECDH');
expect(await ecdh.decrypt(oid, kdfParams, V, C, Q, d, fingerprint1)).to.deep.equal(data);
disableNative();
expect(await ecdh.decrypt(oid, kdfParams, V, C, Q, d, fingerprint1)).to.deep.equal(data);
if (curveName !== 'p521') { // safari does not implement p521 in webcrypto
expect(nativeDecryptSpy.calledOnce).to.be.true;
}
});
});
});
});
});

View File

@@ -4,6 +4,7 @@ const hashMod = require('../../src/crypto/hash');
const config = require('../../src/config');
const util = require('../../src/util');
const sandbox = require('sinon/lib/sinon/sandbox');
const chai = require('chai');
const elliptic_data = require('./elliptic_data');
@@ -99,6 +100,29 @@ module.exports = () => describe('Elliptic Curve Cryptography @lightweight', func
});
});
describe('ECDSA signature', function () {
let sinonSandbox;
let getWebCryptoStub;
let getNodeCryptoStub;
beforeEach(function () {
sinonSandbox = sandbox.create();
});
afterEach(function () {
sinonSandbox.restore();
});
const disableNative = () => {
enableNative();
// stubbed functions return undefined
getWebCryptoStub = sinonSandbox.stub(util, "getWebCrypto");
getNodeCryptoStub = sinonSandbox.stub(util, "getNodeCrypto");
};
const enableNative = () => {
getWebCryptoStub && getWebCryptoStub.restore();
getNodeCryptoStub && getNodeCryptoStub.restore();
};
const verify_signature = async function (oid, hash, r, s, message, pub) {
if (util.isString(message)) {
message = util.strToUint8Array(message);
@@ -151,7 +175,7 @@ module.exports = () => describe('Elliptic Curve Cryptography @lightweight', func
});
it('Invalid public key', async function () {
if (!config.useIndutnyElliptic && !util.getNodeCrypto()) {
this.skip();
this.skip(); // webcrypto does not implement secp256k1
}
if (util.getNodeCrypto()) {
await expect(verify_signature(
@@ -162,20 +186,13 @@ module.exports = () => describe('Elliptic Curve Cryptography @lightweight', func
)).to.eventually.be.false;
}
if (config.useIndutnyElliptic) {
const useNative = config.useNative;
config.useNative = false;
try {
await Promise.all([
expect(verify_signature(
'secp256k1', 8, [], [], [], []
)).to.be.rejectedWith(Error, /Unknown point format/),
expect(verify_signature(
'secp256k1', 8, [], [], [], secp256k1_invalid_point_format
)).to.be.rejectedWith(Error, /Unknown point format/)
]);
} finally {
config.useNative = useNative;
}
disableNative();
await expect(verify_signature(
'secp256k1', 8, [], [], [], []
)).to.be.rejectedWith(Error, /Unknown point format/);
await expect(verify_signature(
'secp256k1', 8, [], [], [], secp256k1_invalid_point_format
)).to.be.rejectedWith(Error, /Unknown point format/);
}
});
it('Invalid point', async function () {
@@ -188,15 +205,10 @@ module.exports = () => describe('Elliptic Curve Cryptography @lightweight', func
)).to.eventually.be.false;
}
if (config.useIndutnyElliptic) {
const useNative = config.useNative;
config.useNative = false;
try {
await expect(verify_signature(
'secp256k1', 8, [], [], [], secp256k1_invalid_point
)).to.be.rejectedWith(Error, /Invalid elliptic public key/);
} finally {
config.useNative = useNative;
}
disableNative();
await expect(verify_signature(
'secp256k1', 8, [], [], [], secp256k1_invalid_point
)).to.be.rejectedWith(Error, /Invalid elliptic public key/);
}
});
it('Invalid signature', function (done) {

86
test/crypto/gcm.js Normal file
View File

@@ -0,0 +1,86 @@
const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
const crypto = require('../../src/crypto');
const util = require('../../src/util');
const sandbox = require('sinon/lib/sinon/sandbox');
const chai = require('chai');
chai.use(require('chai-as-promised'));
const expect = chai.expect;
module.exports = () => describe('Symmetric AES-GCM (experimental)', function() {
let sinonSandbox;
let getWebCryptoStub;
let getNodeCryptoStub;
beforeEach(function () {
sinonSandbox = sandbox.create();
enableNative();
});
afterEach(function () {
sinonSandbox.restore();
});
const disableNative = () => {
enableNative();
// stubbed functions return undefined
getWebCryptoStub = sinonSandbox.stub(util, "getWebCrypto");
getNodeCryptoStub = sinonSandbox.stub(util, "getNodeCrypto");
};
const enableNative = () => {
getWebCryptoStub && getWebCryptoStub.restore();
getNodeCryptoStub && getNodeCryptoStub.restore();
};
function testAESGCM(plaintext, nativeEncrypt, nativeDecrypt) {
const aesAlgos = Object.keys(openpgp.enums.symmetric).filter(
algo => algo.substr(0,3) === 'aes'
);
aesAlgos.forEach(function(algo) {
it(algo, async function() {
const nodeCrypto = util.getNodeCrypto();
const webCrypto = util.getWebCrypto();
if (!nodeCrypto && !webCrypto) {
this.skip(); // eslint-disable-line no-invalid-this
}
const key = await crypto.generateSessionKey(algo);
const iv = await crypto.random.getRandomBytes(crypto.gcm.ivLength);
const nativeEncryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'encrypt') : sinonSandbox.spy(nodeCrypto, 'createCipheriv');
const nativeDecryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'decrypt') : sinonSandbox.spy(nodeCrypto, 'createDecipheriv');
nativeEncrypt || disableNative();
let modeInstance = await crypto.gcm(algo, key);
const ciphertext = await modeInstance.encrypt(util.strToUint8Array(plaintext), iv);
enableNative();
nativeDecrypt || disableNative();
modeInstance = await crypto.gcm(algo, key);
const decrypted = await modeInstance.decrypt(util.strToUint8Array(util.uint8ArrayToStr(ciphertext)), iv);
enableNative();
const decryptedStr = util.uint8ArrayToStr(decrypted);
expect(decryptedStr).to.equal(plaintext);
if (algo !== 'aes192') { // not implemented by webcrypto
// sanity check: native crypto was indeed on/off
expect(nativeEncryptSpy.called).to.equal(nativeEncrypt);
expect(nativeDecryptSpy.called).to.equal(nativeDecrypt);
}
});
});
}
describe('Symmetric AES-GCM (native)', function() {
testAESGCM("12345678901234567890123456789012345678901234567890", true, true);
});
describe('Symmetric AES-GCM (asm.js fallback)', function() {
testAESGCM("12345678901234567890123456789012345678901234567890", false, false);
});
describe('Symmetric AES-GCM (native encrypt, asm.js decrypt)', function() {
testAESGCM("12345678901234567890123456789012345678901234567890", true, false);
});
});

View File

@@ -7,6 +7,7 @@ module.exports = () => describe('Crypto', function () {
require('./ecdh.js')();
require('./pkcs5.js')();
require('./aes_kw.js')();
require('./gcm.js')();
require('./eax.js')();
require('./ocb.js')();
require('./rsa.js')();

View File

@@ -3,6 +3,7 @@ const crypto = require('../../src/crypto');
const random = require('../../src/crypto/random');
const util = require('../../src/util');
const sandbox = require('sinon/lib/sinon/sandbox');
const chai = require('chai');
chai.use(require('chai-as-promised'));
@@ -13,6 +14,30 @@ const expect = chai.expect;
/* eslint-disable no-invalid-this */
const native = util.getWebCrypto() || util.getNodeCrypto();
module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptography with native crypto', function () {
let sinonSandbox;
let getWebCryptoStub;
let getNodeCryptoStub;
beforeEach(function () {
sinonSandbox = sandbox.create();
enableNative();
});
afterEach(function () {
sinonSandbox.restore();
});
const disableNative = () => {
enableNative();
// stubbed functions return undefined
getWebCryptoStub = sinonSandbox.stub(util, "getWebCrypto");
getNodeCryptoStub = sinonSandbox.stub(util, "getNodeCrypto");
};
const enableNative = () => {
getWebCryptoStub && getWebCryptoStub.restore();
getNodeCryptoStub && getNodeCryptoStub.restore();
};
it('generate rsa key', async function() {
const bits = 1024;
const keyObject = await crypto.publicKey.rsa.generate(bits, 65537);
@@ -49,29 +74,24 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
it('decrypt nodeCrypto by bnCrypto and vice versa', async function() {
if (!util.getNodeCrypto()) {
this.skip();
this.skip(); // webcrypto does not implement RSA PKCS#1 v.15 decryption
}
const bits = 1024;
const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
const message = await crypto.generateSessionKey('aes256');
const useNative = openpgp.config.useNative;
try {
openpgp.config.useNative = false;
const encryptedBn = await crypto.publicKey.rsa.encrypt(message, n, e);
openpgp.config.useNative = true;
const decrypted1 = await crypto.publicKey.rsa.decrypt(encryptedBn, n, e, d, p, q, u);
expect(decrypted1).to.deep.equal(message);
const encryptedNode = await crypto.publicKey.rsa.encrypt(message, n, e);
openpgp.config.useNative = false;
const decrypted2 = await crypto.publicKey.rsa.decrypt(encryptedNode, n, e, d, p, q, u);
expect(decrypted2).to.deep.equal(message);
} finally {
openpgp.config.useNative = useNative;
}
disableNative();
const encryptedBn = await crypto.publicKey.rsa.encrypt(message, n, e);
enableNative();
const decrypted1 = await crypto.publicKey.rsa.decrypt(encryptedBn, n, e, d, p, q, u);
expect(decrypted1).to.deep.equal(message);
const encryptedNode = await crypto.publicKey.rsa.encrypt(message, n, e);
disableNative();
const decrypted2 = await crypto.publicKey.rsa.decrypt(encryptedNode, n, e, d, p, q, u);
expect(decrypted2).to.deep.equal(message);
});
it('compare native crypto and bn math sign', async function() {
it('compare native crypto and bnSign', async function() {
const bits = 1024;
const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
@@ -79,25 +99,14 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
const hashName = 'sha256';
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName);
const hashed = await crypto.hash.digest(hash_algo, message);
const useNative = openpgp.config.useNative;
try {
openpgp.config.useNative = true;
let signatureWeb;
try {
signatureWeb = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed);
} catch (error) {
util.printDebugError('web crypto error');
this.skip();
}
openpgp.config.useNative = false;
const signatureBN = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed);
expect(util.uint8ArrayToHex(signatureWeb)).to.be.equal(util.uint8ArrayToHex(signatureBN));
} finally {
openpgp.config.useNative = useNative;
}
enableNative();
const signatureNative = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed);
disableNative();
const signatureBN = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed);
expect(util.uint8ArrayToHex(signatureNative)).to.be.equal(util.uint8ArrayToHex(signatureBN));
});
it('compare native crypto and bn math verify', async function() {
it('compare native crypto and bnVerify', async function() {
const bits = 1024;
const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
@@ -105,24 +114,12 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
const hashName = 'sha256';
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName);
const hashed = await crypto.hash.digest(hash_algo, message);
let verifyWeb;
let signature;
const useNative = openpgp.config.useNative;
try {
openpgp.config.useNative = true;
try {
signature = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed);
verifyWeb = await crypto.publicKey.rsa.verify(hash_algo, message, signature, n, e);
} catch (error) {
util.printDebugError('web crypto error');
this.skip();
}
openpgp.config.useNative = false;
const verifyBN = await crypto.publicKey.rsa.verify(hash_algo, message, signature, n, e, hashed);
expect(verifyWeb).to.be.true;
expect(verifyBN).to.be.true;
} finally {
openpgp.config.useNative = useNative;
}
enableNative();
const signatureNative = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed);
const verifyNative = await crypto.publicKey.rsa.verify(hash_algo, message, signatureNative, n, e);
disableNative();
const verifyBN = await crypto.publicKey.rsa.verify(hash_algo, message, signatureNative, n, e, hashed);
expect(verifyNative).to.be.true;
expect(verifyBN).to.be.true;
});
});

View File

@@ -244,13 +244,13 @@ EJ4QcD/oQ6x1M/8X/iKQCtxZP8RnlrbH7ExkNON5s5g=
});
it('Decrypt and verify message with leading zero in hash signed with old elliptic algorithm', async function () {
//this test would not work with nodeCrypto, since message is signed with leading zero stripped from the hash
const useNative = openpgp.config.useNative;
openpgp.config.useNative = false;
if (util.getNodeCrypto()) {
this.skip(); // eslint-disable-line no-invalid-this
}
const juliet = await load_priv_key('juliet');
const romeo = await load_pub_key('romeo');
const msg = await openpgp.readMessage({ armoredMessage: data.romeo.message_encrypted_with_leading_zero_in_hash_signed_by_elliptic_with_old_implementation });
const result = await openpgp.decrypt({ privateKeys: juliet, publicKeys: [romeo], message: msg });
openpgp.config.useNative = useNative;
expect(result).to.exist;
expect(result.data).to.equal(data.romeo.message_with_leading_zero_in_hash_old_elliptic_implementation);
expect(result.signatures).to.have.length(1);

242
test/general/config.js Normal file
View File

@@ -0,0 +1,242 @@
const { expect } = require('chai');
const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
module.exports = () => describe('Custom configuration', function() {
it('openpgp.generateKey', async function() {
const v5KeysVal = openpgp.config.v5Keys;
const preferHashAlgorithmVal = openpgp.config.preferHashAlgorithm;
const showCommentVal = openpgp.config.showComment;
openpgp.config.v5Keys = false;
openpgp.config.preferHashAlgorithm = openpgp.enums.hash.sha256;
openpgp.config.showComment = false;
try {
const opt = {
userIds: { name: 'Test User', email: 'text@example.com' }
};
const { key, privateKeyArmored } = await openpgp.generateKey(opt);
expect(key.keyPacket.version).to.equal(4);
expect(privateKeyArmored.indexOf(openpgp.config.commentString) > 0).to.be.false;
expect(key.users[0].selfCertifications[0].preferredHashAlgorithms[0]).to.equal(openpgp.config.preferHashAlgorithm);
const config = {
v5Keys: true,
showComment: true,
preferHashAlgorithm: openpgp.enums.hash.sha512
};
const opt2 = {
userIds: { name: 'Test User', email: 'text@example.com' },
config
};
const { key: key2, privateKeyArmored: privateKeyArmored2 } = await openpgp.generateKey(opt2);
expect(key2.keyPacket.version).to.equal(5);
expect(privateKeyArmored2.indexOf(openpgp.config.commentString) > 0).to.be.true;
expect(key2.users[0].selfCertifications[0].preferredHashAlgorithms[0]).to.equal(config.preferHashAlgorithm);
} finally {
openpgp.config.v5Keys = v5KeysVal;
openpgp.config.preferHashAlgorithm = preferHashAlgorithmVal;
openpgp.config.showComment = showCommentVal;
}
});
it('openpgp.reformatKey', async function() {
const compressionVal = openpgp.config.compression;
const preferHashAlgorithmVal = openpgp.config.preferHashAlgorithm;
const showCommentVal = openpgp.config.showComment;
openpgp.config.compression = openpgp.enums.compression.bzip2;
openpgp.config.preferHashAlgorithm = openpgp.enums.hash.sha256;
openpgp.config.showComment = false;
try {
const userIds = { name: 'Test User', email: 'text2@example.com' };
const { key: origKey } = await openpgp.generateKey({ userIds });
const opt = { privateKey: origKey, userIds };
const { key: refKey, privateKeyArmored: refKeyArmored } = await openpgp.reformatKey(opt);
const prefs = refKey.users[0].selfCertifications[0];
expect(prefs.preferredCompressionAlgorithms[0]).to.equal(openpgp.config.compression);
expect(prefs.preferredHashAlgorithms[0]).to.equal(openpgp.config.preferHashAlgorithm);
expect(refKeyArmored.indexOf(openpgp.config.commentString) > 0).to.be.false;
const config = {
showComment: true,
compression: openpgp.enums.compression.zip,
preferHashAlgorithm: openpgp.enums.hash.sha512
};
const opt2 = { privateKey: origKey, userIds, config };
const { key: refKey2, privateKeyArmored: refKeyArmored2 } = await openpgp.reformatKey(opt2);
const prefs2 = refKey2.users[0].selfCertifications[0];
expect(prefs2.preferredCompressionAlgorithms[0]).to.equal(config.compression);
expect(prefs2.preferredHashAlgorithms[0]).to.equal(config.preferHashAlgorithm);
expect(refKeyArmored2.indexOf(openpgp.config.commentString) > 0).to.be.true;
} finally {
openpgp.config.compression = compressionVal;
openpgp.config.preferHashAlgorithm = preferHashAlgorithmVal;
openpgp.config.showComment = showCommentVal;
}
});
it('openpgp.revokeKey', async function() {
const showCommentVal = openpgp.config.showComment;
openpgp.config.showComment = false;
try {
const userIds = { name: 'Test User', email: 'text2@example.com' };
const { key, revocationCertificate } = await openpgp.generateKey({ userIds });
const opt = { key };
const { privateKeyArmored: revKeyArmored } = await openpgp.revokeKey(opt);
expect(revKeyArmored.indexOf(openpgp.config.commentString) > 0).to.be.false;
const opt2 = { key, config: { showComment: true } };
const { privateKeyArmored: revKeyArmored2 } = await openpgp.revokeKey(opt2);
expect(revKeyArmored2.indexOf(openpgp.config.commentString) > 0).to.be.true;
const opt3 = {
key,
revocationCertificate,
config: { rejectHashAlgorithms: new Set([openpgp.enums.hash.sha256, openpgp.enums.hash.sha512]) }
};
await expect(openpgp.revokeKey(opt3)).to.be.rejectedWith(/Insecure hash algorithm/);
} finally {
openpgp.config.showComment = showCommentVal;
}
});
it('openpgp.decryptKey', async function() {
const userIds = { name: 'Test User', email: 'text2@example.com' };
const passphrase = '12345678';
const { key } = await openpgp.generateKey({ userIds, passphrase });
key.keyPacket.makeDummy();
const opt = {
privateKey: await openpgp.readKey({ armoredKey: key.armor() }),
passphrase,
config: { rejectHashAlgorithms: new Set([openpgp.enums.hash.sha256, openpgp.enums.hash.sha512]) }
};
await expect(openpgp.decryptKey(opt)).to.be.rejectedWith(/Insecure hash algorithm/);
});
it('openpgp.encryptKey', async function() {
const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte;
openpgp.config.s2kIterationCountByte = 224;
try {
const passphrase = '12345678';
const userIds = { name: 'Test User', email: 'text2@example.com' };
const { key: privateKey } = await openpgp.generateKey({ userIds });
const encKey = await openpgp.encryptKey({ privateKey, userIds, passphrase });
expect(encKey.keyPacket.s2k.c).to.equal(openpgp.config.s2kIterationCountByte);
const config = { s2kIterationCountByte: 123 };
const encKey2 = await openpgp.encryptKey({ privateKey, userIds, passphrase, config });
expect(encKey2.keyPacket.s2k.c).to.equal(config.s2kIterationCountByte);
} finally {
openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal;
}
});
it('openpgp.encrypt', async function() {
const aeadProtectVal = openpgp.config.aeadProtect;
const compressionVal = openpgp.config.compression;
openpgp.config.aeadProtect = false;
openpgp.config.compression = openpgp.enums.compression.uncompressed;
try {
const passwords = ['12345678'];
const message = openpgp.Message.fromText("test");
const armored = await openpgp.encrypt({ message, passwords });
const encrypted = await openpgp.readMessage({ armoredMessage: armored });
const { packets: [skesk, encData] } = encrypted;
expect(skesk.version).to.equal(4); // cfb
expect(encData.tag).to.equal(openpgp.enums.packet.symEncryptedIntegrityProtectedData);
const { packets: [literal] } = await encrypted.decrypt(null, passwords, null, encrypted.fromStream, openpgp.config);
expect(literal.tag).to.equal(openpgp.enums.packet.literalData);
const config = {
aeadProtect: true,
compression: openpgp.enums.compression.zip,
deflateLevel: 1
};
const armored2 = await openpgp.encrypt({ message, passwords, config });
const encrypted2 = await openpgp.readMessage({ armoredMessage: armored2 });
const { packets: [skesk2, encData2] } = encrypted2;
expect(skesk2.version).to.equal(5);
expect(encData2.tag).to.equal(openpgp.enums.packet.AEADEncryptedData);
const { packets: [compressed] } = await encrypted2.decrypt(null, passwords, null, encrypted2.fromStream, openpgp.config);
expect(compressed.tag).to.equal(openpgp.enums.packet.compressedData);
expect(compressed.algorithm).to.equal("zip");
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
openpgp.config.compression = compressionVal;
}
});
it('openpgp.sign', async function() {
const userIds = { name: 'Test User', email: 'text2@example.com' };
const { privateKeyArmored } = await openpgp.generateKey({ userIds });
const key = await openpgp.readKey({ armoredKey: privateKeyArmored });
const message = openpgp.Message.fromText("test");
const opt = {
message,
privateKeys: key,
config: { rejectHashAlgorithms: new Set([openpgp.enums.hash.sha256, openpgp.enums.hash.sha512]) }
};
await expect(openpgp.sign(opt)).to.be.rejectedWith(/Insecure hash algorithm/);
opt.detached = true;
await expect(openpgp.sign(opt)).to.be.rejectedWith(/Insecure hash algorithm/);
const clearText = openpgp.CleartextMessage.fromText("test");
const opt2 = {
message: clearText,
privateKeys: key,
config: { rejectHashAlgorithms: new Set([openpgp.enums.hash.sha256, openpgp.enums.hash.sha512]) }
};
await expect(openpgp.sign(opt2)).to.be.rejectedWith(/Insecure hash algorithm/);
});
it('openpgp.verify', async function() {
const userIds = { name: 'Test User', email: 'text2@example.com' };
const { privateKeyArmored } = await openpgp.generateKey({ userIds });
const key = await openpgp.readKey({ armoredKey: privateKeyArmored });
const config = { rejectMessageHashAlgorithms: new Set([openpgp.enums.hash.sha256, openpgp.enums.hash.sha512]) };
const message = openpgp.Message.fromText("test");
const signed = await openpgp.sign({ message, privateKeys: key });
const opt = {
message: await openpgp.readMessage({ armoredMessage: signed }),
publicKeys: key,
config
};
const { signatures: [sig] } = await openpgp.verify(opt);
await expect(sig.error).to.match(/Insecure message hash algorithm/);
const armoredSignature = await openpgp.sign({ message, privateKeys: key, detached: true });
const opt2 = {
message,
signature: await openpgp.readSignature({ armoredSignature }),
publicKeys: key,
config
};
const { signatures: [sig2] } = await openpgp.verify(opt2);
await expect(sig2.error).to.match(/Insecure message hash algorithm/);
const cleartext = openpgp.CleartextMessage.fromText("test");
const signedCleartext = await openpgp.sign({ message: cleartext, privateKeys: key });
const opt3 = {
message: await openpgp.readCleartextMessage({ cleartextMessage: signedCleartext }),
publicKeys: key,
config
};
const { signatures: [sig3] } = await openpgp.verify(opt3);
await expect(sig3.error).to.match(/Insecure message hash algorithm/);
});
});

View File

@@ -7,6 +7,7 @@ module.exports = () => describe('General', function () {
require('./signature.js')();
require('./key.js')();
require('./openpgp.js')();
require('./config.js')();
require('./hkp.js')();
require('./wkd.js')();
require('./oid.js')();

View File

@@ -2162,16 +2162,17 @@ function versionSpecificTests() {
}
});
it('Generated key is not unlocked by default', function() {
it('Generated key is not unlocked by default', async function() {
const opt = { userIds: { name: 'test', email: 'a@b.com' }, passphrase: '123' };
let key;
return openpgp.generateKey(opt).then(function(newKey) {
key = newKey.key;
return openpgp.Message.fromText('hello').encrypt([key]);
}).then(function(msg) {
return msg.decrypt([key]);
}).catch(function(err) {
expect(err.message).to.equal('Private key is not decrypted.');
const { key } = await openpgp.generateKey(opt);
return openpgp.encrypt({
message: openpgp.Message.fromText('hello'),
publicKeys: key
}).then(async armoredMessage => openpgp.decrypt({
message: await openpgp.readMessage({ armoredMessage }),
privateKeys: key
})).catch(function(err) {
expect(err.message).to.match(/Private key is not decrypted./);
});
});
@@ -2725,7 +2726,7 @@ module.exports = () => describe('Key', function() {
`.replace(/\s+/g, ''));
const packetlist = new openpgp.PacketList();
await packetlist.read(packetBytes, { PublicKeyPacket: openpgp.PublicKeyPacket });
await packetlist.read(packetBytes, { PublicKeyPacket: openpgp.PublicKeyPacket }, undefined, openpgp.config);
const key = packetlist[0];
expect(key).to.exist;
});
@@ -2755,7 +2756,7 @@ module.exports = () => describe('Key', function() {
const packetlist = new openpgp.PacketList();
await packetlist.read((await openpgp.unarmor(pub_sig_test)).data, openpgp);
await packetlist.read((await openpgp.unarmor(pub_sig_test)).data, openpgp, undefined, openpgp.config);
const subkeys = pubKey.getSubkeys();
expect(subkeys).to.exist;
@@ -2826,23 +2827,18 @@ module.exports = () => describe('Key', function() {
});
it('should not decrypt using a sign-only RSA key, unless explicitly configured', async function () {
const allowSigningKeyDecryption = openpgp.config.allowInsecureDecryptionWithSigningKeys;
const key = await openpgp.readKey({ armoredKey: rsaSignOnly });
try {
openpgp.config.allowInsecureDecryptionWithSigningKeys = false;
await expect(openpgp.decrypt({
message: await openpgp.readMessage({ armoredMessage: encryptedRsaSignOnly }),
privateKeys: key
})).to.be.rejectedWith(/Session key decryption failed/);
openpgp.config.allowInsecureDecryptionWithSigningKeys = true;
await expect(openpgp.decrypt({
message: await openpgp.readMessage({ armoredMessage: encryptedRsaSignOnly }),
privateKeys: key
})).to.be.fulfilled;
} finally {
openpgp.config.allowInsecureDecryptionWithSigningKeys = allowSigningKeyDecryption;
}
await expect(openpgp.decrypt({
message: await openpgp.readMessage({ armoredMessage: encryptedRsaSignOnly }),
privateKeys: key
})).to.be.rejectedWith(/Session key decryption failed/);
await expect(openpgp.decrypt({
message: await openpgp.readMessage({ armoredMessage: encryptedRsaSignOnly }),
privateKeys: key,
config: { allowInsecureDecryptionWithSigningKeys: true }
})).to.be.fulfilled;
});
it('Method getExpirationTime V4 Key', async function() {
@@ -3233,7 +3229,7 @@ module.exports = () => describe('Key', function() {
const input = await openpgp.unarmor(revocation_certificate_arm4);
const packetlist = new openpgp.PacketList();
await packetlist.read(input.data, { SignaturePacket: openpgp.SignaturePacket });
await packetlist.read(input.data, { SignaturePacket: openpgp.SignaturePacket }, undefined, openpgp.config);
const armored = openpgp.armor(openpgp.enums.armor.publicKey, packetlist.write());
expect(revocationCertificate.replace(/^Comment: .*$\n/mg, '')).to.equal(armored.replace(/^Comment: .*$\n/mg, ''));

View File

@@ -685,7 +685,7 @@ function withCompression(tests) {
tests(
function(options) {
options.compression = compression;
options.config = { compression };
return options;
},
function() {
@@ -798,31 +798,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
});
describe('generateKey - integration tests', function() {
let useNativeVal;
beforeEach(function() {
useNativeVal = openpgp.config.useNative;
});
afterEach(function() {
openpgp.config.useNative = useNativeVal;
});
it('should work in JS', function() {
openpgp.config.useNative = false;
const opt = {
userIds: [{ name: 'Test User', email: 'text@example.com' }]
};
return openpgp.generateKey(opt).then(function(newKey) {
expect(newKey.key.getUserIds()[0]).to.equal('Test User <text@example.com>');
expect(newKey.publicKeyArmored).to.match(/^-----BEGIN PGP PUBLIC/);
expect(newKey.privateKeyArmored).to.match(/^-----BEGIN PGP PRIVATE/);
});
});
it('should work in with native crypto', function() {
openpgp.config.useNative = true;
it('should work', function() {
const opt = {
userIds: [{ name: 'Test User', email: 'text@example.com' }]
};
@@ -845,7 +821,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
let privateKey;
let publicKey;
let publicKeyNoAEAD;
let useNativeVal;
let aeadProtectVal;
let aeadModeVal;
let aeadChunkSizeByteVal;
@@ -864,7 +839,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
publicKey_1337 = privateKey_1337.toPublic();
privateKeyMismatchingParams = await openpgp.readKey({ armoredKey: mismatchingKeyParams });
useNativeVal = openpgp.config.useNative;
aeadProtectVal = openpgp.config.aeadProtect;
aeadModeVal = openpgp.config.aeadMode;
aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte;
@@ -872,7 +846,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
});
afterEach(function() {
openpgp.config.useNative = useNativeVal;
openpgp.config.aeadProtect = aeadProtectVal;
openpgp.config.aeadMode = aeadModeVal;
openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal;
@@ -2389,7 +2362,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encryptOpt).then(async function (encrypted) {
const message = await openpgp.readMessage({ binaryMessage: encrypted });
return message.decrypt([privateKey_2038_2045]);
return message.decrypt([privateKey_2038_2045], undefined, undefined, undefined, openpgp.config);
}).then(async function (packets) {
const literals = packets.packets.filterByTag(openpgp.enums.packet.literalData);
expect(literals.length).to.equal(1);
@@ -2410,7 +2383,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encryptOpt).then(async function (encrypted) {
const message = await openpgp.readMessage({ binaryMessage: encrypted });
return message.decrypt([privateKey_2000_2008]);
return message.decrypt([privateKey_2000_2008], undefined, undefined, undefined, openpgp.config);
}).then(async function (packets) {
const literals = packets.packets.filterByTag(openpgp.enums.packet.literalData);
expect(literals.length).to.equal(1);
@@ -2431,12 +2404,12 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encryptOpt).then(async function (encrypted) {
const message = await openpgp.readMessage({ binaryMessage: encrypted });
return message.decrypt([privateKey_2000_2008]);
return message.decrypt([privateKey_2000_2008], undefined, undefined, undefined, openpgp.config);
}).then(async function (message) {
const literals = message.packets.filterByTag(openpgp.enums.packet.literalData);
expect(literals.length).to.equal(1);
expect(+literals[0].date).to.equal(+past);
const signatures = await message.verify([publicKey_2000_2008], past);
const signatures = await message.verify([publicKey_2000_2008], past, undefined, openpgp.config);
expect(await openpgp.stream.readToEnd(message.getText())).to.equal(plaintext);
expect(+(await signatures[0].signature).packets[0].created).to.equal(+past);
expect(await signatures[0].verified).to.be.true;
@@ -2459,13 +2432,13 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encryptOpt).then(async function (encrypted) {
const message = await openpgp.readMessage({ binaryMessage: encrypted });
return message.decrypt([privateKey_2038_2045]);
return message.decrypt([privateKey_2038_2045], undefined, undefined, undefined, openpgp.config);
}).then(async function (message) {
const literals = message.packets.filterByTag(openpgp.enums.packet.literalData);
expect(literals.length).to.equal(1);
expect(literals[0].format).to.equal('binary');
expect(+literals[0].date).to.equal(+future);
const signatures = await message.verify([publicKey_2038_2045], future);
const signatures = await message.verify([publicKey_2038_2045], future, undefined, openpgp.config);
expect(await openpgp.stream.readToEnd(message.getLiteralData())).to.deep.equal(data);
expect(+(await signatures[0].signature).packets[0].created).to.equal(+future);
expect(await signatures[0].verified).to.be.true;
@@ -2488,13 +2461,13 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encryptOpt).then(async function (encrypted) {
const message = await openpgp.readMessage({ binaryMessage: encrypted });
return message.decrypt([privateKey_2038_2045]);
return message.decrypt([privateKey_2038_2045], undefined, undefined, undefined, openpgp.config);
}).then(async function (message) {
const literals = message.packets.filterByTag(openpgp.enums.packet.literalData);
expect(literals.length).to.equal(1);
expect(literals[0].format).to.equal('mime');
expect(+literals[0].date).to.equal(+future);
const signatures = await message.verify([publicKey_2038_2045], future);
const signatures = await message.verify([publicKey_2038_2045], future, undefined, openpgp.config);
expect(await openpgp.stream.readToEnd(message.getLiteralData())).to.deep.equal(data);
expect(+(await signatures[0].signature).packets[0].created).to.equal(+future);
expect(await signatures[0].verified).to.be.true;

View File

@@ -65,49 +65,65 @@ module.exports = () => describe("Packet", function() {
'=KXkj\n' +
'-----END PGP PRIVATE KEY BLOCK-----';
it('Symmetrically encrypted packet', async function() {
it('Symmetrically encrypted packet without integrity protection - allow decryption', async function() {
const aeadProtectVal = openpgp.config.aeadProtect;
const ignoreMdcErrorVal = openpgp.config.ignoreMdcError;
openpgp.config.aeadProtect = false;
openpgp.config.ignoreMdcError = true;
const message = new openpgp.PacketList();
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
literal.setText(testText);
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
message.push(enc);
enc.packets.push(literal);
try {
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
message.push(enc);
enc.packets.push(literal);
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
const algo = 'aes256';
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
const algo = 'aes256';
await enc.encrypt(algo, key);
await enc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.Message();
await msg2.packets.read(message.write(), { SymmetricallyEncryptedDataPacket: openpgp.SymmetricallyEncryptedDataPacket });
msg2.packets[0].ignoreMdcError = true;
const dec = await msg2.decrypt(null, null, [{ algorithm: algo, data: key }]);
const msg2 = new openpgp.PacketList();
await msg2.read(message.write(), { SymmetricallyEncryptedDataPacket: openpgp.SymmetricallyEncryptedDataPacket });
await msg2[0].decrypt(algo, key, undefined, openpgp.config);
expect(await stringify(dec.packets[0].data)).to.equal(stringify(literal.data));
expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data));
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
openpgp.config.ignoreMdcError = ignoreMdcErrorVal;
}
});
it('Symmetrically encrypted packet - MDC error for modern cipher', async function() {
const message = new openpgp.PacketList();
const testText = input.createSomeMessage();
it('Symmetrically encrypted packet without integrity protection - disallow decryption by default', async function() {
const aeadProtectVal = openpgp.config.aeadProtect;
openpgp.config.aeadProtect = false;
const literal = new openpgp.LiteralDataPacket();
literal.setText(testText);
try {
const message = new openpgp.PacketList();
const testText = input.createSomeMessage();
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
message.push(enc);
await enc.packets.push(literal);
const literal = new openpgp.LiteralDataPacket();
literal.setText(testText);
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
const algo = 'aes256';
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
message.push(enc);
await enc.packets.push(literal);
await enc.encrypt(algo, key);
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
const algo = 'aes256';
const msg2 = new openpgp.PacketList();
await msg2.read(message.write(), { SymmetricallyEncryptedDataPacket: openpgp.SymmetricallyEncryptedDataPacket });
await expect(msg2[0].decrypt(algo, key)).to.eventually.be.rejectedWith('Decryption failed due to missing MDC.');
await enc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList();
await msg2.read(message.write(), { SymmetricallyEncryptedDataPacket: openpgp.SymmetricallyEncryptedDataPacket });
await expect(msg2[0].decrypt(algo, key, undefined, openpgp.config)).to.eventually.be.rejectedWith('Decryption failed due to missing MDC.');
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
}
});
it('Sym. encrypted integrity protected packet', async function() {
@@ -122,61 +138,40 @@ module.exports = () => describe("Packet", function() {
msg.push(enc);
literal.setText(testText);
enc.packets.push(literal);
await enc.encrypt(algo, key);
await enc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList();
await msg2.read(msg.write(), openpgp);
await msg2[0].decrypt(algo, key);
await msg2[0].decrypt(algo, key, undefined, openpgp.config);
expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data));
});
it('Sym. encrypted AEAD protected packet', function() {
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
const algo = 'aes256';
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
const enc = new openpgp.AEADEncryptedDataPacket();
const msg = new openpgp.PacketList();
msg.push(enc);
literal.setText(testText);
enc.packets.push(literal);
const msg2 = new openpgp.PacketList();
return enc.encrypt(algo, key).then(async function() {
await msg2.read(msg.write(), openpgp);
return msg2[0].decrypt(algo, key);
}).then(async function() {
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
});
});
it('Sym. encrypted AEAD protected packet (AEAD)', async function() {
const aeadProtectVal = openpgp.config.aeadProtect;
openpgp.config.aeadProtect = true;
const testText = input.createSomeMessage();
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
const algo = 'aes256';
const literal = new openpgp.LiteralDataPacket();
const enc = new openpgp.AEADEncryptedDataPacket();
const msg = new openpgp.PacketList();
msg.push(enc);
literal.setText(testText);
enc.packets.push(literal);
const msg2 = new openpgp.PacketList();
openpgp.config.aeadProtect = false;
try {
await enc.encrypt(algo, key);
await msg2.read(msg.write(), openpgp);
await msg2[0].decrypt(algo, key);
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
const algo = 'aes256';
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
const enc = new openpgp.AEADEncryptedDataPacket();
const msg = new openpgp.PacketList();
msg.push(enc);
literal.setText(testText);
enc.packets.push(literal);
const msg2 = new openpgp.PacketList();
return enc.encrypt(algo, key, undefined, openpgp.config).then(async function() {
await msg2.read(msg.write(), openpgp);
return msg2[0].decrypt(algo, key);
}).then(async function() {
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
});
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
}
@@ -208,10 +203,6 @@ module.exports = () => describe("Packet", function() {
const encryptStub = cryptStub(webCrypto, 'encrypt');
const decryptStub = cryptStub(webCrypto, 'decrypt');
const aeadProtectVal = openpgp.config.aeadProtect;
const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte;
openpgp.config.aeadProtect = true;
openpgp.config.aeadChunkSizeByte = 0;
const testText = input.createSomeMessage();
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
@@ -229,15 +220,13 @@ module.exports = () => describe("Packet", function() {
const msg2 = new openpgp.PacketList();
try {
await enc.encrypt(algo, key);
await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 0 });
await msg2.read(msg.write(), openpgp);
await msg2[0].decrypt(algo, key);
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
expect(encryptStub.callCount > 1).to.be.true;
expect(decryptStub.callCount > 1).to.be.true;
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal;
encryptStub.restore();
decryptStub.restore();
}
@@ -257,11 +246,6 @@ module.exports = () => describe("Packet", function() {
ab 01 3d e1 25 95 86 90 6e ab 24 76
`.replace(/\s+/g, ''));
const aeadProtectVal = openpgp.config.aeadProtect;
const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte;
openpgp.config.aeadProtect = true;
openpgp.config.aeadChunkSizeByte = 14;
const iv = util.hexToUint8Array('b7 32 37 9f 73 c4 92 8d e2 5f ac fe 65 17 ec 10'.replace(/\s+/g, ''));
const key = util.hexToUint8Array('86 f1 ef b8 69 52 32 9f 24 ac d3 bf d0 e5 34 6d'.replace(/\s+/g, ''));
const algo = 'aes128';
@@ -281,15 +265,13 @@ module.exports = () => describe("Packet", function() {
randomBytesStub.returns(iv);
try {
await enc.encrypt(algo, key);
await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 14 });
const data = msg.write();
expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes);
await msg2.read(data, openpgp);
await msg2[0].decrypt(algo, key);
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal;
randomBytesStub.restore();
}
});
@@ -323,7 +305,7 @@ module.exports = () => describe("Packet", function() {
it('Public key encrypted symmetric key packet', function() {
const rsa = openpgp.enums.publicKey.rsaEncryptSign;
const keySize = util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
const keySize = 1024;
return crypto.generateParams(rsa, keySize, 65537).then(function({ publicParams, privateParams }) {
const enc = new openpgp.PublicKeyEncryptedSessionKeyPacket();
@@ -453,36 +435,43 @@ module.exports = () => describe("Packet", function() {
});
});
it('Sym. encrypted session key reading/writing', async function() {
const passphrase = 'hello';
const algo = 'aes256';
const testText = input.createSomeMessage();
it('Sym. encrypted session key reading/writing (CFB)', async function() {
const aeadProtectVal = openpgp.config.aeadProtect;
openpgp.config.aeadProtect = false;
const literal = new openpgp.LiteralDataPacket();
const key_enc = new openpgp.SymEncryptedSessionKeyPacket();
const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket();
const msg = new openpgp.PacketList();
try {
const passphrase = 'hello';
const algo = 'aes256';
const testText = input.createSomeMessage();
msg.push(key_enc);
msg.push(enc);
const literal = new openpgp.LiteralDataPacket();
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
const seip = new openpgp.SymEncryptedIntegrityProtectedDataPacket();
const msg = new openpgp.PacketList();
key_enc.sessionKeyAlgorithm = algo;
await key_enc.encrypt(passphrase);
msg.push(skesk);
msg.push(seip);
const key = key_enc.sessionKey;
skesk.sessionKeyAlgorithm = algo;
await skesk.encrypt(passphrase, openpgp.config);
literal.setText(testText);
enc.packets.push(literal);
await enc.encrypt(algo, key);
const key = skesk.sessionKey;
const msg2 = new openpgp.PacketList();
await msg2.read(msg.write(), openpgp);
literal.setText(testText);
seip.packets.push(literal);
await seip.encrypt(algo, key, undefined, openpgp.config);
await msg2[0].decrypt(passphrase);
const key2 = msg2[0].sessionKey;
await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2);
const msg2 = new openpgp.PacketList();
await msg2.read(msg.write(), openpgp);
expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data));
await msg2[0].decrypt(passphrase);
const key2 = msg2[0].sessionKey;
await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2);
expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data));
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
}
});
it('Sym. encrypted session key reading/writing (AEAD)', async function() {
@@ -495,21 +484,21 @@ module.exports = () => describe("Packet", function() {
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
const key_enc = new openpgp.SymEncryptedSessionKeyPacket();
const enc = new openpgp.AEADEncryptedDataPacket();
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
const aeadEnc = new openpgp.AEADEncryptedDataPacket();
const msg = new openpgp.PacketList();
msg.push(key_enc);
msg.push(enc);
msg.push(skesk);
msg.push(aeadEnc);
key_enc.sessionKeyAlgorithm = algo;
await key_enc.encrypt(passphrase);
skesk.sessionKeyAlgorithm = algo;
await skesk.encrypt(passphrase, openpgp.config);
const key = key_enc.sessionKey;
const key = skesk.sessionKey;
literal.setText(testText);
enc.packets.push(literal);
await enc.encrypt(algo, key);
aeadEnc.packets.push(literal);
await aeadEnc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList();
await msg2.read(msg.write(), openpgp);
@@ -566,22 +555,22 @@ module.exports = () => describe("Packet", function() {
const algo = 'aes128';
const literal = new openpgp.LiteralDataPacket(0);
const key_enc = new openpgp.SymEncryptedSessionKeyPacket();
const enc = new openpgp.AEADEncryptedDataPacket();
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
const encData = new openpgp.AEADEncryptedDataPacket();
const msg = new openpgp.PacketList();
msg.push(key_enc);
msg.push(enc);
msg.push(skesk);
msg.push(encData);
key_enc.sessionKeyAlgorithm = algo;
await key_enc.encrypt(passphrase);
skesk.sessionKeyAlgorithm = algo;
await skesk.encrypt(passphrase, openpgp.config);
const key = key_enc.sessionKey;
const key = skesk.sessionKey;
literal.setBytes(util.strToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
literal.filename = '';
enc.packets.push(literal);
await enc.encrypt(algo, key);
encData.packets.push(literal);
await encData.encrypt(algo, key, undefined, openpgp.config);
const data = msg.write();
expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes);
@@ -653,14 +642,14 @@ module.exports = () => describe("Packet", function() {
msg.push(enc);
key_enc.sessionKeyAlgorithm = algo;
await key_enc.encrypt(passphrase);
await key_enc.encrypt(passphrase, openpgp.config);
const key = key_enc.sessionKey;
literal.setBytes(util.strToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
literal.filename = '';
enc.packets.push(literal);
await enc.encrypt(algo, key);
await enc.encrypt(algo, key, undefined, openpgp.config);
const data = msg.write();
expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes);
@@ -712,18 +701,18 @@ module.exports = () => describe("Packet", function() {
});
it('Secret key reading with signature verification.', async function() {
const key = new openpgp.PacketList();
await key.read((await openpgp.unarmor(armored_key)).data, openpgp);
const packets = new openpgp.PacketList();
await packets.read((await openpgp.unarmor(armored_key)).data, openpgp);
const [keyPacket, userIdPacket, keySigPacket, subkeyPacket, subkeySigPacket] = packets;
expect(keySigPacket.verified).to.be.null;
expect(subkeySigPacket.verified).to.be.null;
expect(key[2].verified).to.be.null;
expect(key[4].verified).to.be.null;
await key[2].verify(
key[0], openpgp.enums.signature.certGeneric, { userId: key[1], key: key[0] }
).then(async () => expect(key[2].verified).to.be.true);
await key[4].verify(
key[0], openpgp.enums.signature.keyBinding, { key: key[0], bind: key[3] }
).then(async () => expect(key[4].verified).to.be.true);
await keySigPacket.verify(
keyPacket, openpgp.enums.signature.certGeneric, { userId: userIdPacket, key: keyPacket }
).then(async () => expect(keySigPacket.verified).to.be.true);
await subkeySigPacket.verify(
keyPacket, openpgp.enums.signature.keyBinding, { key: keyPacket, bind: subkeyPacket }
).then(async () => expect(subkeySigPacket.verified).to.be.true);
});
it('Reading a signed, encrypted message.', async function() {
@@ -743,22 +732,27 @@ module.exports = () => describe("Packet", function() {
'=htrB\n' +
'-----END PGP MESSAGE-----';
const key = new openpgp.PacketList();
await key.read((await openpgp.unarmor(armored_key)).data, openpgp);
await key[3].decrypt('test');
const packets = new openpgp.PacketList();
await packets.read((await openpgp.unarmor(armored_key)).data, openpgp);
const keyPacket = packets[0];
const subkeyPacket = packets[3];
await subkeyPacket.decrypt('test');
const msg = new openpgp.PacketList();
await msg.read((await openpgp.unarmor(armored_msg)).data, openpgp);
const [pkesk, encData] = msg;
return msg[0].decrypt(key[3]).then(async () => {
await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
return pkesk.decrypt(subkeyPacket).then(async () => {
await encData.decrypt(pkesk.sessionKeyAlgorithm, pkesk.sessionKey);
const payload = msg[1].packets[0].packets;
const payload = encData.packets[0].packets;
payload.concat(await openpgp.stream.readToEnd(payload.stream, arr => arr));
const literal = payload[1];
const signature = payload[2];
await Promise.all([
payload[2].verify(key[0], openpgp.enums.signature.binary, payload[1]),
openpgp.stream.pipe(payload[1].getBytes(),new openpgp.stream.WritableStream())
signature.verify(keyPacket, openpgp.enums.signature.binary, literal),
openpgp.stream.pipe(literal.getBytes(), new openpgp.stream.WritableStream())
]);
});
});
@@ -842,20 +836,20 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
it('Writing and encryption of a secret key packet (AEAD)', async function() {
const rsa = openpgp.enums.publicKey.rsaEncryptSign;
const keySize = util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
const { privateParams, publicParams } = await crypto.generateParams(rsa, keySize, 65537);
const { privateParams, publicParams } = await crypto.generateParams(rsa, 1024, 65537);
const secretKeyPacket = new openpgp.SecretKeyPacket();
const secretKeyPacket = new openpgp.SecretKeyPacket(undefined, { ...openpgp.config, v5Keys: true });
secretKeyPacket.privateParams = privateParams;
secretKeyPacket.publicParams = publicParams;
secretKeyPacket.algorithm = "rsaSign";
secretKeyPacket.isEncrypted = false;
await secretKeyPacket.encrypt('hello');
await secretKeyPacket.encrypt('hello', openpgp.config);
expect(secretKeyPacket.s2k_usage).to.equal(253);
const raw = new openpgp.PacketList();
raw.push(secretKeyPacket);
const packetList = new openpgp.PacketList();
await packetList.read(raw.write(), openpgp);
await packetList.read(raw.write(), openpgp, undefined, openpgp.config);
const secretKeyPacket2 = packetList[0];
await secretKeyPacket2.decrypt('hello');
@@ -864,39 +858,29 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
});
it('Writing and encryption of a secret key packet (CFB)', async function() {
const aeadProtectVal = openpgp.config.aeadProtect;
openpgp.config.aeadProtect = false;
const rsa = openpgp.enums.publicKey.rsaEncryptSign;
const keySize = util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
const { privateParams, publicParams } = await crypto.generateParams(rsa, 1024, 65537);
const secretKeyPacket = new openpgp.SecretKeyPacket(undefined, { ...openpgp.config, v5Keys: false });
secretKeyPacket.privateParams = privateParams;
secretKeyPacket.publicParams = publicParams;
secretKeyPacket.algorithm = "rsaSign";
secretKeyPacket.isEncrypted = false;
await secretKeyPacket.encrypt('hello', openpgp.config);
expect(secretKeyPacket.s2k_usage).to.equal(254);
try {
const { privateParams, publicParams } = await crypto.generateParams(rsa, keySize, 65537);
const secretKeyPacket = new openpgp.SecretKeyPacket();
secretKeyPacket.privateParams = privateParams;
secretKeyPacket.publicParams = publicParams;
secretKeyPacket.algorithm = "rsaSign";
secretKeyPacket.isEncrypted = false;
await secretKeyPacket.encrypt('hello');
const raw = new openpgp.PacketList();
raw.push(secretKeyPacket);
const packetList = new openpgp.PacketList();
await packetList.read(raw.write(), openpgp);
const secretKeyPacket2 = packetList[0];
await secretKeyPacket2.decrypt('hello');
} finally {
openpgp.config.aeadProtect = aeadProtectVal;
}
const raw = new openpgp.PacketList();
raw.push(secretKeyPacket);
const packetList = new openpgp.PacketList();
await packetList.read(raw.write(), openpgp, undefined, openpgp.config);
const secretKeyPacket2 = packetList[0];
await secretKeyPacket2.decrypt('hello');
});
it('Writing and verification of a signature packet', function() {
const rsa = openpgp.enums.publicKey.rsaEncryptSign;
const key = new openpgp.SecretKeyPacket();
const rsa = openpgp.enums.publicKey.rsaEncryptSign;
const keySize = util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
return crypto.generateParams(rsa, keySize, 65537).then(function({ privateParams, publicParams }) {
return crypto.generateParams(rsa, 1024, 65537).then(function({ privateParams, publicParams }) {
const testText = input.createSomeMessage();
key.publicParams = publicParams;

View File

@@ -919,8 +919,8 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
it('Checks for critical bit in non-human-readable notations', async function() {
try {
openpgp.config.tolerant = false;
await openpgp.readSignature({
config: { tolerant: false },
armoredSignature: `-----BEGIN PGP SIGNATURE-----
wsEfBAABCABJBYJfKDH0K5QAAAAAAB0ABXVua25vd25AdGVzdHMuc2VxdW9pYS1w
@@ -940,8 +940,6 @@ bwM=
throw new Error('openpgp.readSignature should throw but it did not.');
} catch (e) {
expect(e.message).to.equal('Unknown critical notation: unknown@tests.sequoia-pgp.org');
} finally {
openpgp.config.tolerant = true;
}
});
@@ -1625,8 +1623,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const privKey2 = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey2.decrypt('hello world');
const opt = { rsaBits: 512, userIds: { name:'test', email:'a@b.com' }, passphrase: null };
if (util.getWebCryptoAll()) { opt.rsaBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
const opt = { rsaBits: 2048, userIds: { name:'test', email:'a@b.com' }, passphrase: null };
const { key: generatedKey } = await openpgp.generateKey(opt);
const detachedSig = await msg.signDetached([generatedKey, privKey2]);
const result = await msg.verifyDetached(detachedSig, [generatedKey.toPublic(), pubKey2]);
@@ -1638,9 +1635,8 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const opt = { userIds: { name:'test', email:'a@b.com' }, passphrase: null };
return openpgp.generateKey(opt).then(function(gen) {
const key = gen.key;
let message = openpgp.Message.fromText('hello world');
message = message.sign([key]);
expect(message).to.exist;
const message = openpgp.Message.fromText('hello world');
return message.sign([key]);
});
});

View File

@@ -7,7 +7,7 @@ module.exports = function(config) {
basePath: '..',
// hostname for local
hostname: 'localhost',
hostname: '127.0.0.1',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
@@ -79,7 +79,8 @@ module.exports = function(config) {
accessKey: process.env.BROWSERSTACK_KEY,
build: process.env.GITHUB_SHA,
name: process.env.GITHUB_WORKFLOW,
project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}`
project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}`,
timeout: 450
},
// define browsers

View File

@@ -1,7 +1,6 @@
const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
const { readKey, Key, readCleartextMessage, CleartextMessage, enums, PacketList, SignaturePacket } = openpgp;
const key = require('../../src/key');
const chai = require('chai');
chai.use(require('chai-as-promised'));
@@ -9,23 +8,23 @@ chai.use(require('chai-as-promised'));
const expect = chai.expect;
async function generateTestData() {
const victimPrivKey = await key.generate({
const victimPrivKey = (await openpgp.generateKey({
userIds: [{ name: 'Victim', email: 'victim@example.com' }],
type: 'rsa',
rsaBits: 1024,
rsaBits: 2048,
subkeys: [{
sign: true
}]
});
})).key;
victimPrivKey.revocationSignatures = [];
const attackerPrivKey = await key.generate({
const attackerPrivKey = (await openpgp.generateKey({
userIds: [{ name: 'Attacker', email: 'attacker@example.com' }],
type: 'rsa',
rsaBits: 1024,
rsaBits: 2048,
subkeys: [],
sign: false
});
})).key;
attackerPrivKey.revocationSignatures = [];
const signed = await openpgp.sign({
message: await CleartextMessage.fromText('I am batman'),

View File

@@ -6,16 +6,18 @@
* - if it fails to run, edit this file to match the actual library API, then edit the definitions file (openpgp.d.ts) accordingly.
*/
import { generateKey, readKey, readKeys, Key, readMessage, Message, CleartextMessage, encrypt, decrypt, sign, verify } from '../..';
import { generateKey, readKey, readKeys, Key, readMessage, Message, CleartextMessage, encrypt, decrypt, sign, verify, config } from '../..';
import { expect } from 'chai';
(async () => {
// Generate keys
const { publicKeyArmored, key } = await generateKey({ userIds: [{ email: "user@corp.co" }] });
const { publicKeyArmored, key } = await generateKey({ userIds: [{ email: "user@corp.co" }], config: { v5Keys: true } });
expect(key).to.be.instanceOf(Key);
const privateKeys = [key];
const publicKeys = [key.toPublic()];
expect(key.toPublic().armor(config)).to.equal(publicKeyArmored);
// Parse keys
expect(await readKey({ armoredKey: publicKeyArmored })).to.be.instanceOf(Key);