mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2026-03-11 11:15:00 +00:00
Store named key params in key objects (#1141)
- Store private and public params separately and by name in objects, instead of as an array - Do not keep params in MPI form, but convert them to Uint8Arrays when generating/parsing the key - Modify low-level crypto functions to always accept and return Uint8Arrays instead of BigIntegers - Move PKCS1 padding to lower level functions
This commit is contained in:
@@ -8,7 +8,7 @@ const expect = chai.expect;
|
||||
module.exports = () => describe('API functional testing', function() {
|
||||
const util = openpgp.util;
|
||||
const crypto = openpgp.crypto;
|
||||
const RSApubMPIstrs = [
|
||||
const RSAPublicKeyMaterial = util.concatUint8Array([
|
||||
new Uint8Array([0x08,0x00,0xac,0x15,0xb3,0xd6,0xd2,0x0f,0xf0,0x7a,0xdd,0x21,0xb7,
|
||||
0xbf,0x61,0xfa,0xca,0x93,0x86,0xc8,0x55,0x5a,0x4b,0xa6,0xa4,0x1a,
|
||||
0x60,0xa2,0x3a,0x37,0x06,0x08,0xd8,0x15,0x8e,0x85,0x45,0xaa,0xb7,
|
||||
@@ -30,8 +30,8 @@ module.exports = () => describe('API functional testing', function() {
|
||||
0xee,0xc9,0xa4,0xcd,0x15,0xdc,0x1b,0x8d,0x64,0xc1,0x36,0x17,0xc4,
|
||||
0x8d,0x5e,0x99,0x7a,0x5b,0x9f,0x39,0xd0,0x00,0x6e,0xf9]),
|
||||
new Uint8Array([0x00,0x11,0x01,0x00,0x01])
|
||||
];
|
||||
const RSAsecMPIstrs = [
|
||||
]);
|
||||
const RSAPrivateKeyMaterial = util.concatUint8Array([
|
||||
new Uint8Array([0x07,0xfe,0x23,0xff,0xce,0x45,0x6c,0x60,0x65,0x40,0x6e,0xae,0x35,
|
||||
0x10,0x56,0x60,0xee,0xab,0xfa,0x10,0x42,0xba,0xc7,0x04,0xaf,0x63,
|
||||
0xcd,0x3f,0x62,0xca,0x4b,0xfa,0xe1,0xa9,0x70,0xcd,0x34,0x8b,0xc8,
|
||||
@@ -82,9 +82,9 @@ module.exports = () => describe('API functional testing', function() {
|
||||
0x51,0xe0,0x22,0xf0,0xff,0xa7,0x42,0xd4,0xde,0x0b,0x47,0x8f,0x2b,
|
||||
0xf5,0x4d,0x04,0x32,0x91,0x89,0x4b,0x0e,0x05,0x8d,0x70,0xf9,0xbb,
|
||||
0xe7,0xd6,0x76,0xea,0x0e,0x1a,0x90,0x30,0xf5,0x98,0x01,0xc5,0x73])
|
||||
];
|
||||
]);
|
||||
|
||||
const DSApubMPIstrs = [
|
||||
const DSAPublicKeyMaterial = util.concatUint8Array([
|
||||
new Uint8Array([0x08,0x00,0xa8,0x85,0x5c,0x28,0x05,0x94,0x03,0xbe,0x07,0x6c,0x13,0x3e,0x65,
|
||||
0xfb,0xb5,0xe1,0x99,0x7c,0xfa,0x84,0xe3,0xac,0x47,0xa5,0xc4,0x46,0xd8,0x5f,
|
||||
0x44,0xe9,0xc1,0x6b,0x69,0xf7,0x10,0x76,0x49,0xa7,0x25,0x85,0xf4,0x1b,0xed,
|
||||
@@ -142,14 +142,14 @@ module.exports = () => describe('API functional testing', function() {
|
||||
0x67,0x8d,0x9d,0x14,0xb6,0x9d,0x32,0x82,0xd0,0xb5,0xc6,0x57,0xf0,0x91,0xd9,
|
||||
0xc3,0x26,0xae,0x9f,0xa9,0x67,0x49,0x96,0x5c,0x07,0x3e,0x47,0x5c,0xed,0x60,
|
||||
0x07,0xac,0x6a])
|
||||
];
|
||||
const DSAsecMPIstrs = [
|
||||
]);
|
||||
const DSAPrivateKeyMaterial = util.concatUint8Array([
|
||||
new Uint8Array([0x01,0x00,0x9b,0x58,0xa8,0xf4,0x04,0xb1,0xd5,0x14,0x09,0xe1,0xe1,0xa1,0x8a,
|
||||
0x0b,0xa3,0xc3,0xa3,0x66,0xaa,0x27,0x99,0x50,0x1c,0x4d,0xba,0x24,0xee,0xdf,
|
||||
0xdf,0xb8,0x8e,0x8e])
|
||||
];
|
||||
]);
|
||||
|
||||
const ElgamalpubMPIstrs = [
|
||||
const elGamalPublicKeyMaterial = util.concatUint8Array([
|
||||
new Uint8Array([0x08,0x00,0xea,0xcc,0xbe,0xe2,0xe4,0x5a,0x51,0x18,0x93,0xa1,0x12,0x2f,0x00,
|
||||
0x99,0x42,0xd8,0x5c,0x1c,0x2f,0xb6,0x3c,0xd9,0x94,0x61,0xb4,0x55,0x8d,0x4e,
|
||||
0x73,0xe6,0x69,0xbc,0x1d,0x33,0xe3,0x2d,0x91,0x23,0x69,0x95,0x98,0xd7,0x18,
|
||||
@@ -187,64 +187,37 @@ module.exports = () => describe('API functional testing', function() {
|
||||
0xda,0xba,0x19,0xf3,0xcb,0x10,0xa0,0x6b,0xd0,0x2d,0xbe,0x40,0x42,0x7b,0x9b,
|
||||
0x15,0xa4,0x2d,0xec,0xcf,0x09,0xd6,0xe3,0x92,0xc3,0x8d,0x65,0x6b,0x60,0x97,
|
||||
0xda,0x6b,0xca])
|
||||
];
|
||||
]);
|
||||
|
||||
const ElgamalsecMPIstrs = [
|
||||
const elGamalPrivateKeyMaterial = util.concatUint8Array([
|
||||
new Uint8Array([0x01,0x52,0x02,0x80,0x87,0xf6,0xe4,0x49,0xd7,0x2e,0x3e,0xfe,0x60,0xb9,0xa3,
|
||||
0x2a,0xf0,0x67,0x58,0xe9,0xf6,0x47,0x83,0xde,0x7e,0xfb,0xbb,0xbd,0xdf,0x48,
|
||||
0x12,0x1b,0x06,0x7d,0x13,0xbc,0x3b,0x49,0xf9,0x86,0xd4,0x53,0xed,0x2d,0x68])
|
||||
];
|
||||
]);
|
||||
|
||||
const RSApubMPIs = [];
|
||||
let i;
|
||||
for (i = 0; i < 2; i++) {
|
||||
RSApubMPIs[i] = new openpgp.MPI();
|
||||
RSApubMPIs[i].read(RSApubMPIstrs[i]);
|
||||
}
|
||||
const algoRSA = openpgp.enums.publicKey.rsaEncryptSign;
|
||||
const RSAPublicParams = crypto.parsePublicKeyParams(algoRSA, RSAPublicKeyMaterial).publicParams;
|
||||
const RSAPrivateParams = crypto.parsePrivateKeyParams(algoRSA, RSAPrivateKeyMaterial).privateParams;
|
||||
|
||||
const RSAsecMPIs = [];
|
||||
for (i = 0; i < 4; i++) {
|
||||
RSAsecMPIs[i] = new openpgp.MPI();
|
||||
RSAsecMPIs[i].read(RSAsecMPIstrs[i]);
|
||||
}
|
||||
const algoDSA = openpgp.enums.publicKey.dsa;
|
||||
const DSAPublicParams = crypto.parsePublicKeyParams(algoDSA, DSAPublicKeyMaterial).publicParams;
|
||||
const DSAPrivateParams = crypto.parsePrivateKeyParams(algoDSA, DSAPrivateKeyMaterial).privateParams;
|
||||
|
||||
const DSAsecMPIs = [];
|
||||
for (i = 0; i < 1; i++) {
|
||||
DSAsecMPIs[i] = new openpgp.MPI();
|
||||
DSAsecMPIs[i].read(DSAsecMPIstrs[i]);
|
||||
}
|
||||
|
||||
const DSApubMPIs = [];
|
||||
for (i = 0; i < 4; i++) {
|
||||
DSApubMPIs[i] = new openpgp.MPI();
|
||||
DSApubMPIs[i].read(DSApubMPIstrs[i]);
|
||||
}
|
||||
const ElgamalsecMPIs = [];
|
||||
for (i = 0; i < 1; i++) {
|
||||
ElgamalsecMPIs[i] = new openpgp.MPI();
|
||||
ElgamalsecMPIs[i].read(ElgamalsecMPIstrs[i]);
|
||||
}
|
||||
|
||||
const ElgamalpubMPIs = [];
|
||||
for (i = 0; i < 3; i++) {
|
||||
ElgamalpubMPIs[i] = new openpgp.MPI();
|
||||
ElgamalpubMPIs[i].read(ElgamalpubMPIstrs[i]);
|
||||
}
|
||||
const algoElGamal = openpgp.enums.publicKey.elgamal;
|
||||
const elGamalPublicParams = crypto.parsePublicKeyParams(algoElGamal, elGamalPublicKeyMaterial).publicParams;
|
||||
const elGamalPrivateParams = crypto.parsePrivateKeyParams(algoElGamal, elGamalPrivateKeyMaterial).privateParams;
|
||||
|
||||
const data = util.strToUint8Array("foobar");
|
||||
|
||||
describe('Sign and verify', function () {
|
||||
it('RSA', async function () {
|
||||
// FIXME
|
||||
//Originally we passed public and secret MPI separately, now they are joined. Is this what we want to do long term?
|
||||
// RSA
|
||||
return crypto.signature.sign(
|
||||
1, 2, RSApubMPIs.concat(RSAsecMPIs), data, await crypto.hash.digest(2, data)
|
||||
1, 2, RSAPublicParams, RSAPrivateParams, data, await crypto.hash.digest(2, data)
|
||||
).then(async RSAsignedData => {
|
||||
const RSAsignedDataMPI = new openpgp.MPI();
|
||||
RSAsignedDataMPI.read(RSAsignedData);
|
||||
return crypto.signature.verify(
|
||||
1, 2, [RSAsignedDataMPI], RSApubMPIs, data, await crypto.hash.digest(2, data)
|
||||
1, 2, [RSAsignedDataMPI], RSAPublicParams, data, await crypto.hash.digest(2, data)
|
||||
).then(success => {
|
||||
return expect(success).to.be.true;
|
||||
});
|
||||
@@ -252,9 +225,8 @@ module.exports = () => describe('API functional testing', function() {
|
||||
});
|
||||
|
||||
it('DSA', async function () {
|
||||
// DSA
|
||||
return crypto.signature.sign(
|
||||
17, 2, DSApubMPIs.concat(DSAsecMPIs), data, await crypto.hash.digest(2, data)
|
||||
17, 2, DSAPublicParams, DSAPrivateParams, data, await crypto.hash.digest(2, data)
|
||||
).then(async DSAsignedData => {
|
||||
DSAsignedData = util.uint8ArrayToStr(DSAsignedData);
|
||||
const DSAmsgMPIs = [];
|
||||
@@ -263,7 +235,7 @@ module.exports = () => describe('API functional testing', function() {
|
||||
DSAmsgMPIs[0].read(DSAsignedData.substring(0,34));
|
||||
DSAmsgMPIs[1].read(DSAsignedData.substring(34,68));
|
||||
return crypto.signature.verify(
|
||||
17, 2, DSAmsgMPIs, DSApubMPIs, data, await crypto.hash.digest(2, data)
|
||||
17, 2, DSAmsgMPIs, DSAPublicParams, data, await crypto.hash.digest(2, data)
|
||||
).then(success => {
|
||||
return expect(success).to.be.true;
|
||||
});
|
||||
@@ -356,9 +328,9 @@ module.exports = () => describe('API functional testing', function() {
|
||||
|
||||
it('Asymmetric using RSA with eme_pkcs1 padding', async function () {
|
||||
const symmKey = await crypto.generateSessionKey('aes256');
|
||||
return crypto.publicKeyEncrypt(1, RSApubMPIs, symmKey).then(RSAEncryptedData => {
|
||||
return crypto.publicKeyEncrypt(algoRSA, RSAPublicParams, symmKey).then(RSAEncryptedData => {
|
||||
return crypto.publicKeyDecrypt(
|
||||
1, RSApubMPIs.concat(RSAsecMPIs), RSAEncryptedData
|
||||
algoRSA, RSAPublicParams, RSAPrivateParams, RSAEncryptedData
|
||||
).then(data => {
|
||||
expect(data).to.deep.equal(symmKey);
|
||||
});
|
||||
@@ -367,9 +339,9 @@ module.exports = () => describe('API functional testing', function() {
|
||||
|
||||
it('Asymmetric using Elgamal with eme_pkcs1 padding', async function () {
|
||||
const symmKey = await crypto.generateSessionKey('aes256');
|
||||
return crypto.publicKeyEncrypt(16, ElgamalpubMPIs, symmKey).then(ElgamalEncryptedData => {
|
||||
return crypto.publicKeyEncrypt(algoElGamal, elGamalPublicParams, symmKey).then(ElgamalEncryptedData => {
|
||||
return crypto.publicKeyDecrypt(
|
||||
16, ElgamalpubMPIs.concat(ElgamalsecMPIs), ElgamalEncryptedData
|
||||
algoElGamal, elGamalPublicParams, elGamalPrivateParams, ElgamalEncryptedData
|
||||
).then(data => {
|
||||
expect(data).to.deep.equal(symmKey);
|
||||
});
|
||||
|
||||
@@ -22,16 +22,11 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
|
||||
|
||||
it('sign and verify using generated key params', async function() {
|
||||
const bits = openpgp.util.getWebCryptoAll() ? 2048 : 1024;
|
||||
const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const { publicParams, privateParams } = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const message = await openpgp.crypto.random.getRandomBytes(64);
|
||||
const hash_algo = openpgp.enums.write(openpgp.enums.hash, 'sha256');
|
||||
const hashed = await openpgp.crypto.hash.digest(hash_algo, message);
|
||||
const n = keyParams[0].toUint8Array();
|
||||
const e = keyParams[1].toUint8Array();
|
||||
const d = keyParams[2].toUint8Array();
|
||||
const p = keyParams[3].toUint8Array();
|
||||
const q = keyParams[4].toUint8Array();
|
||||
const u = keyParams[5].toUint8Array();
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const signature = await openpgp.crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed);
|
||||
expect(signature).to.exist;
|
||||
const verify = await openpgp.crypto.publicKey.rsa.verify(hash_algo, message, signature, n, e, hashed);
|
||||
@@ -40,13 +35,8 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
|
||||
|
||||
it('encrypt and decrypt using generated key params', async function() {
|
||||
const bits = openpgp.util.getWebCryptoAll() ? 2048 : 1024;
|
||||
const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const n = keyParams[0].toUint8Array();
|
||||
const e = keyParams[1].toUint8Array();
|
||||
const d = keyParams[2].toUint8Array();
|
||||
const p = keyParams[3].toUint8Array();
|
||||
const q = keyParams[4].toUint8Array();
|
||||
const u = keyParams[5].toUint8Array();
|
||||
const { publicParams, privateParams } = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const message = await openpgp.crypto.generateSessionKey('aes256');
|
||||
const encrypted = await openpgp.crypto.publicKey.rsa.encrypt(message, n, e);
|
||||
const result = new openpgp.MPI(encrypted);
|
||||
@@ -59,13 +49,8 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
|
||||
this.skip();
|
||||
}
|
||||
const bits = 1024;
|
||||
const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const n = keyParams[0].toUint8Array();
|
||||
const e = keyParams[1].toUint8Array();
|
||||
const d = keyParams[2].toUint8Array();
|
||||
const p = keyParams[3].toUint8Array();
|
||||
const q = keyParams[4].toUint8Array();
|
||||
const u = keyParams[5].toUint8Array();
|
||||
const { publicParams, privateParams } = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const message = await openpgp.crypto.generateSessionKey('aes256');
|
||||
const encryptedBn = await openpgp.crypto.publicKey.rsa.bnEncrypt(message, n, e);
|
||||
const decrypted1 = await openpgp.crypto.publicKey.rsa.nodeDecrypt(encryptedBn, n, e, d, p, q, u);
|
||||
@@ -80,13 +65,8 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
|
||||
this.skip();
|
||||
}
|
||||
const bits = openpgp.util.getWebCrypto() ? 2048 : 1024;
|
||||
const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const n = keyParams[0].toUint8Array();
|
||||
const e = keyParams[1].toUint8Array();
|
||||
const d = keyParams[2].toUint8Array();
|
||||
const p = keyParams[3].toUint8Array();
|
||||
const q = keyParams[4].toUint8Array();
|
||||
const u = keyParams[5].toUint8Array();
|
||||
const { publicParams, privateParams } = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const message = await openpgp.crypto.random.getRandomBytes(64);
|
||||
const hashName = 'sha256';
|
||||
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName);
|
||||
@@ -107,13 +87,8 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
|
||||
this.skip();
|
||||
}
|
||||
const bits = openpgp.util.getWebCrypto() ? 2048 : 1024;
|
||||
const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const n = keyParams[0].toUint8Array();
|
||||
const e = keyParams[1].toUint8Array();
|
||||
const d = keyParams[2].toUint8Array();
|
||||
const p = keyParams[3].toUint8Array();
|
||||
const q = keyParams[4].toUint8Array();
|
||||
const u = keyParams[5].toUint8Array();
|
||||
const { publicParams, privateParams } = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const message = await openpgp.crypto.random.getRandomBytes(64);
|
||||
const hashName = 'sha256';
|
||||
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName);
|
||||
@@ -137,13 +112,8 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
|
||||
this.skip();
|
||||
}
|
||||
const bits = 1024;
|
||||
const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const n = keyParams[0].toUint8Array();
|
||||
const e = keyParams[1].toUint8Array();
|
||||
const d = keyParams[2].toUint8Array();
|
||||
const p = keyParams[3].toUint8Array();
|
||||
const q = keyParams[4].toUint8Array();
|
||||
const u = keyParams[5].toUint8Array();
|
||||
const { publicParams, privateParams } = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const message = await openpgp.crypto.random.getRandomBytes(64);
|
||||
const hashName = 'sha256';
|
||||
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName);
|
||||
@@ -158,13 +128,8 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
|
||||
this.skip();
|
||||
}
|
||||
const bits = openpgp.util.getWebCrypto() ? 2048 : 1024;
|
||||
const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const n = keyParams[0].toUint8Array();
|
||||
const e = keyParams[1].toUint8Array();
|
||||
const d = keyParams[2].toUint8Array();
|
||||
const p = keyParams[3].toUint8Array();
|
||||
const q = keyParams[4].toUint8Array();
|
||||
const u = keyParams[5].toUint8Array();
|
||||
const { publicParams, privateParams } = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
|
||||
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
|
||||
const message = await openpgp.crypto.random.getRandomBytes(64);
|
||||
const hashName = 'sha256';
|
||||
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName);
|
||||
|
||||
@@ -93,12 +93,12 @@ module.exports = () => {
|
||||
|
||||
it('detect invalid edDSA Q', async function() {
|
||||
const eddsaKeyPacket = cloneKeyPacket(eddsaKey);
|
||||
const Q = eddsaKeyPacket.params[1];
|
||||
Q.data[0]++;
|
||||
const Q = eddsaKeyPacket.publicParams.Q;
|
||||
Q[0]++;
|
||||
await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
const infQ = new Uint8Array(Q.data.length);
|
||||
eddsaKeyPacket.params[1] = new openpgp.MPI(infQ);
|
||||
const infQ = new Uint8Array(Q.length);
|
||||
eddsaKeyPacket.publicParams.Q = infQ;
|
||||
await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
});
|
||||
@@ -114,86 +114,78 @@ module.exports = () => {
|
||||
});
|
||||
|
||||
it('EdDSA params are not valid for ECDH', async function() {
|
||||
const oid = eddsaKey.keyPacket.params[0];
|
||||
const Q = eddsaKey.keyPacket.params[1];
|
||||
const seed = eddsaKey.keyPacket.params[2];
|
||||
const { oid, Q } = eddsaKey.keyPacket.publicParams;
|
||||
const { seed } = eddsaKey.keyPacket.privateParams;
|
||||
|
||||
const ecdhKeyPacket = cloneKeyPacket(ecdhKey);
|
||||
const ecdhOID = ecdhKeyPacket.params[0];
|
||||
const ecdhOID = ecdhKeyPacket.publicParams.oid;
|
||||
|
||||
ecdhKeyPacket.params[0] = oid;
|
||||
ecdhKeyPacket.publicParams.oid = oid;
|
||||
await expect(ecdhKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
ecdhKeyPacket.params[0] = ecdhOID;
|
||||
ecdhKeyPacket.params[1] = Q;
|
||||
ecdhKeyPacket.params[3] = seed;
|
||||
ecdhKeyPacket.publicParams.oid = ecdhOID;
|
||||
ecdhKeyPacket.publicParams.Q = Q;
|
||||
ecdhKeyPacket.privateParams.d = seed;
|
||||
await expect(ecdhKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('EdDSA params are not valid for EcDSA', async function() {
|
||||
const oid = eddsaKey.keyPacket.params[0];
|
||||
const Q = eddsaKey.keyPacket.params[1];
|
||||
const seed = eddsaKey.keyPacket.params[2];
|
||||
const { oid, Q } = eddsaKey.keyPacket.publicParams;
|
||||
const { seed } = eddsaKey.keyPacket.privateParams;
|
||||
|
||||
const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey);
|
||||
const ecdsaOID = ecdsaKeyPacket.params[0];
|
||||
ecdsaKeyPacket.params[0] = oid;
|
||||
const ecdsaOID = ecdsaKeyPacket.publicParams.oid;
|
||||
ecdsaKeyPacket.publicParams.oid = oid;
|
||||
await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
ecdsaKeyPacket.params[0] = ecdsaOID;
|
||||
ecdsaKeyPacket.params[1] = Q;
|
||||
ecdsaKeyPacket.params[2] = seed;
|
||||
ecdsaKeyPacket.publicParams.oid = ecdsaOID;
|
||||
ecdsaKeyPacket.publicParams.Q = Q;
|
||||
ecdsaKeyPacket.privateParams.d = seed;
|
||||
await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('ECDH x25519 params are not valid for EcDSA', async function() {
|
||||
const ecdh25519KeyPacket = ecdhKey.keyPacket;
|
||||
const oid = ecdh25519KeyPacket.params[0];
|
||||
const Q = ecdh25519KeyPacket.params[1];
|
||||
const d = ecdh25519KeyPacket.params[3];
|
||||
const { oid, Q } = ecdhKey.keyPacket.publicParams;
|
||||
const { d } = ecdhKey.keyPacket.privateParams;
|
||||
|
||||
const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey);
|
||||
ecdsaKeyPacket.params[0] = oid;
|
||||
ecdsaKeyPacket.params[1] = Q;
|
||||
ecdsaKeyPacket.params[2] = d;
|
||||
ecdsaKeyPacket.publicParams.oid = oid;
|
||||
ecdsaKeyPacket.publicParams.Q = Q;
|
||||
ecdsaKeyPacket.privateParams.d = d;
|
||||
await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('EcDSA params are not valid for EdDSA', async function() {
|
||||
const oid = ecdsaKey.keyPacket.params[0];
|
||||
const Q = ecdsaKey.keyPacket.params[1];
|
||||
const d = ecdsaKey.keyPacket.params[2];
|
||||
const { oid, Q } = ecdsaKey.keyPacket.publicParams;
|
||||
const { d } = ecdsaKey.keyPacket.privateParams;
|
||||
|
||||
const eddsaKeyPacket = cloneKeyPacket(eddsaKey);
|
||||
const eddsaOID = eddsaKeyPacket.params[0];
|
||||
eddsaKeyPacket.params[0] = oid;
|
||||
const eddsaOID = eddsaKeyPacket.publicParams.oid;
|
||||
eddsaKeyPacket.publicParams.oid = oid;
|
||||
await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
eddsaKeyPacket.params[0] = eddsaOID;
|
||||
eddsaKeyPacket.params[1] = Q;
|
||||
eddsaKeyPacket.params[2] = d;
|
||||
eddsaKeyPacket.publicParams.oid = eddsaOID;
|
||||
eddsaKeyPacket.publicParams.Q = Q;
|
||||
eddsaKeyPacket.privateParams.seed = d;
|
||||
await expect(eddsaKeyPacket.validate()).to.be.rejected;
|
||||
});
|
||||
|
||||
it('ECDH x25519 params are not valid for EdDSA', async function() {
|
||||
const ecdh25519KeyPacket = ecdhKey.keyPacket;
|
||||
const oid = ecdh25519KeyPacket.params[0];
|
||||
const Q = ecdh25519KeyPacket.params[1];
|
||||
const d = ecdh25519KeyPacket.params[3];
|
||||
const { oid, Q } = ecdhKey.keyPacket.publicParams;
|
||||
const { d } = ecdhKey.keyPacket.privateParams;
|
||||
|
||||
const eddsaKeyPacket = cloneKeyPacket(eddsaKey);
|
||||
const eddsaOID = eddsaKeyPacket.params[0];
|
||||
eddsaKeyPacket.params[0] = oid;
|
||||
const eddsaOID = eddsaKeyPacket.publicParams.oid;
|
||||
eddsaKeyPacket.publicParams.oid = oid;
|
||||
await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
eddsaKeyPacket.params[0] = eddsaOID;
|
||||
eddsaKeyPacket.params[1] = Q;
|
||||
eddsaKeyPacket.params[2] = d;
|
||||
eddsaKeyPacket.publicParams.oid = eddsaOID;
|
||||
eddsaKeyPacket.publicParams.Q = Q;
|
||||
eddsaKeyPacket.privateParams.seed = d;
|
||||
await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
const curves = ['curve25519', 'p256', 'p384', 'p521', 'secp256k1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'];
|
||||
curves.forEach(curve => {
|
||||
describe(`ECC ${curve} parameter validation`, () => {
|
||||
@@ -216,12 +208,12 @@ module.exports = () => {
|
||||
|
||||
it('detect invalid EcDSA Q', async function() {
|
||||
const keyPacket = cloneKeyPacket(ecdsaKey);
|
||||
const Q = keyPacket.params[1];
|
||||
Q.data[0]++;
|
||||
const Q = keyPacket.publicParams.Q;
|
||||
Q[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
const infQ = new Uint8Array(Q.data.length);
|
||||
keyPacket.params[1] = new openpgp.MPI(infQ);
|
||||
const infQ = new Uint8Array(Q.length);
|
||||
keyPacket.publicParams.Q = infQ;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
}
|
||||
@@ -232,12 +224,12 @@ module.exports = () => {
|
||||
|
||||
it('detect invalid ECDH Q', async function() {
|
||||
const keyPacket = cloneKeyPacket(ecdhKey);
|
||||
const Q = keyPacket.params[1];
|
||||
Q.data[16]++;
|
||||
const Q = keyPacket.publicParams.Q;
|
||||
Q[16]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
const infQ = new Uint8Array(Q.data.length);
|
||||
keyPacket.params[1] = new openpgp.MPI(infQ);
|
||||
const infQ = new Uint8Array(Q.length);
|
||||
keyPacket.publicParams.Q = infQ;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
});
|
||||
@@ -255,15 +247,15 @@ module.exports = () => {
|
||||
|
||||
it('detect invalid RSA n', async function() {
|
||||
const keyPacket = cloneKeyPacket(rsaKey);
|
||||
const n = keyPacket.params[0];
|
||||
n.data[0]++;
|
||||
const n = keyPacket.publicParams.n;
|
||||
n[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('detect invalid RSA e', async function() {
|
||||
const keyPacket = cloneKeyPacket(rsaKey);
|
||||
const e = keyPacket.params[1];
|
||||
e.data[0]++;
|
||||
const e = keyPacket.publicParams.e;
|
||||
e[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
});
|
||||
@@ -280,28 +272,27 @@ module.exports = () => {
|
||||
|
||||
it('detect invalid DSA p', async function() {
|
||||
const keyPacket = cloneKeyPacket(dsaKey);
|
||||
const p = keyPacket.params[0];
|
||||
p.data[0]++;
|
||||
const p = keyPacket.publicParams.p;
|
||||
p[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('detect invalid DSA y', async function() {
|
||||
const keyPacket = cloneKeyPacket(dsaKey);
|
||||
const y = keyPacket.params[3];
|
||||
const y = keyPacket.publicParams.y;
|
||||
|
||||
y.data[0]++;
|
||||
y[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('detect invalid DSA g', async function() {
|
||||
const keyPacket = cloneKeyPacket(dsaKey);
|
||||
const g = keyPacket.params[2];
|
||||
const g = keyPacket.publicParams.g;
|
||||
|
||||
g.data[0]++;
|
||||
g[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
const gOne = new openpgp.MPI(new Uint8Array([1]));
|
||||
keyPacket.params[2] = gOne;
|
||||
keyPacket.publicParams.g = new Uint8Array([1]);
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
});
|
||||
@@ -318,40 +309,39 @@ module.exports = () => {
|
||||
|
||||
it('detect invalid p', async function() {
|
||||
const keyPacket = cloneKeyPacket(egKey);
|
||||
const p = keyPacket.params[0];
|
||||
p.data[0]++;
|
||||
const p = keyPacket.publicParams.p;
|
||||
p[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('detect invalid y', async function() {
|
||||
const keyPacket = cloneKeyPacket(egKey);
|
||||
const y = keyPacket.params[2];
|
||||
y.data[0]++;
|
||||
const y = keyPacket.publicParams.y;
|
||||
y[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('detect invalid g', async function() {
|
||||
const keyPacket = cloneKeyPacket(egKey);
|
||||
const g = keyPacket.params[1];
|
||||
const g = keyPacket.publicParams.g;
|
||||
|
||||
g.data[0]++;
|
||||
g[0]++;
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
|
||||
const gOne = new openpgp.MPI(new Uint8Array([1]));
|
||||
keyPacket.params[1] = gOne;
|
||||
keyPacket.publicParams.g = new Uint8Array([1]);
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
|
||||
it('detect g with small order', async function() {
|
||||
const keyPacket = cloneKeyPacket(egKey);
|
||||
const p = keyPacket.params[0].toUint8Array();
|
||||
const g = keyPacket.params[1].toUint8Array();
|
||||
const p = keyPacket.publicParams.p;
|
||||
const g = keyPacket.publicParams.g;
|
||||
|
||||
const pBN = new BN(p);
|
||||
const gModP = new BN(g).toRed(new BN.red(pBN));
|
||||
// g**(p-1)/2 has order 2
|
||||
const gOrd2 = gModP.redPow(pBN.subn(1).shrn(1));
|
||||
keyPacket.params[1] = new openpgp.MPI(gOrd2.toArrayLike(Uint8Array, 'be'));
|
||||
keyPacket.publicParams.g = gOrd2.toArrayLike(Uint8Array, 'be');
|
||||
await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user