diff --git a/src/crypto/public_key/elliptic/curves.js b/src/crypto/public_key/elliptic/curves.js index a4046bd9..2759661c 100644 --- a/src/crypto/public_key/elliptic/curves.js +++ b/src/crypto/public_key/elliptic/curves.js @@ -225,7 +225,7 @@ function getPreferredHashAlgo(oid) { } /** - * Validate ECDH and EcDSA parameters + * Validate ECDH and ECDSA parameters * Not suitable for EdDSA (different secret key format) * @param {module:enums.publicKey} algo - EC algorithm, to filter supported curves * @param {module:type/oid} oid - EC object identifier diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 099eeb95..40d2572a 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -117,10 +117,10 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe } /** - * Validate EcDSA parameters + * Validate ECDSA parameters * @param {module:type/oid} oid - Elliptic curve object identifier - * @param {Uint8Array} Q - EcDSA public point - * @param {Uint8Array} d - EcDSA secret scalar + * @param {Uint8Array} Q - ECDSA public point + * @param {Uint8Array} d - ECDSA secret scalar * @returns {Promise} Whether params are valid. * @async */ diff --git a/src/key/factory.js b/src/key/factory.js index d5670eeb..194be753 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -76,7 +76,7 @@ export async function generate(options, config) { * @param {Array} options.userIDs User IDs as strings or objects: 'Jo Doe ' or { name:'Jo Doe', email:'info@jo.com' } * @param {String} options.passphrase Passphrase used to encrypt the resulting private key * @param {Number} options.keyExpirationTime Number of seconds from the key creation time after which the key expires - * @param {Date} options.date Override the creation date of the key and the key signatures + * @param {Date} options.date Override the creation date of the key signatures * @param {Array} options.subkeys (optional) options for each subkey, default to main key options. e.g. [{sign: true, passphrase: '123'}] * @param {Object} config - Full configuration * diff --git a/src/key/helper.js b/src/key/helper.js index 505f875d..8e57e186 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -21,6 +21,7 @@ export async function generateSecretSubkey(options, config) { secretSubkeyPacket.packets = null; secretSubkeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm); await secretSubkeyPacket.generate(options.rsaBits, options.curve); + await secretSubkeyPacket.computeFingerprintAndKeyID(); return secretSubkeyPacket; } @@ -29,6 +30,7 @@ export async function generateSecretKey(options, config) { secretKeyPacket.packets = null; secretKeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm); await secretKeyPacket.generate(options.rsaBits, options.curve, options.config); + await secretKeyPacket.computeFingerprintAndKeyID(); return secretKeyPacket; } diff --git a/src/key/key.js b/src/key/key.js index 5f900bcd..dc7b08fc 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -82,6 +82,9 @@ class Key { } this.keyPacket = packetlist[i]; primaryKeyID = this.getKeyID(); + if (!primaryKeyID) { + throw new Error('Missing Key ID'); + } break; case enums.packet.userID: case enums.packet.userAttribute: @@ -186,25 +189,22 @@ class Key { /** * Returns an array containing all public or private subkeys matching keyID; - * If keyID is not present, returns all subkeys. - * @param {type/keyid} keyID - * @returns {Array} + * If no keyID is given, returns all subkeys. + * @param {type/keyID} [keyID] - key ID to look for + * @returns {Array} array of subkeys */ getSubkeys(keyID = null) { - const subKeys = []; - this.subKeys.forEach(subKey => { - if (!keyID || subKey.getKeyID().equals(keyID, true)) { - subKeys.push(subKey); - } - }); + const subKeys = this.subKeys.filter(subKey => ( + !keyID || subKey.getKeyID().equals(keyID, true) + )); return subKeys; } /** * Returns an array containing all public or private keys matching keyID. - * If keyID is not present, returns all keys starting with the primary key. - * @param {type/keyid} keyID - * @returns {Array} + * If no keyID is given, returns all keys, starting with the primary key. + * @param {type/keyid~KeyID} [keyID] - key ID to look for + * @returns {Array} array of keys */ getKeys(keyID = null) { const keys = []; @@ -250,31 +250,25 @@ class Key { /** * Returns key as public key (shallow copy) - * @param {Object} [config] - Full configuration, defaults to openpgp.config - * @returns {Key} New public Key. + * @returns {Key} New public Key */ toPublic() { const packetlist = new PacketList(); const keyPackets = this.toPacketList(); - let bytes; - let pubKeyPacket; - let pubSubkeyPacket; - for (let i = 0; i < keyPackets.length; i++) { - switch (keyPackets[i].constructor.tag) { - case enums.packet.secretKey: - bytes = keyPackets[i].writePublicKey(); - pubKeyPacket = new PublicKeyPacket(); - pubKeyPacket.read(bytes); + for (const keyPacket of keyPackets) { + switch (keyPacket.constructor.tag) { + case enums.packet.secretKey: { + const pubKeyPacket = PublicKeyPacket.fromSecretKeyPacket(keyPacket); packetlist.push(pubKeyPacket); break; - case enums.packet.secretSubkey: - bytes = keyPackets[i].writePublicKey(); - pubSubkeyPacket = new PublicSubkeyPacket(); - pubSubkeyPacket.read(bytes); + } + case enums.packet.secretSubkey: { + const pubSubkeyPacket = PublicSubkeyPacket.fromSecretSubkeyPacket(keyPacket); packetlist.push(pubSubkeyPacket); break; + } default: - packetlist.push(keyPackets[i]); + packetlist.push(keyPacket); } } return new Key(packetlist); @@ -827,7 +821,7 @@ class Key { const primaryKey = this.keyPacket; const { user } = await this.getPrimaryUser(date, userID, config); const results = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) : - [{ keyID: primaryKey.keyID, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }]; + [{ keyID: primaryKey.getKeyID(), valid: await user.verify(primaryKey, undefined, config).catch(() => false) }]; return results; } @@ -849,7 +843,7 @@ class Key { const primaryKey = this.keyPacket; await Promise.all(this.users.map(async function(user) { const signatures = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) : - [{ keyID: primaryKey.keyID, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }]; + [{ keyID: primaryKey.getKeyID(), valid: await user.verify(primaryKey, undefined, config).catch(() => false) }]; signatures.forEach(signature => { results.push({ userID: user.userID.userID, diff --git a/src/message.js b/src/message.js index 782a4835..345c7509 100644 --- a/src/message.js +++ b/src/message.js @@ -694,7 +694,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig /** * Create object containing signer's keyID and validity of signature - * @param {SignaturePacket} signature - Signature packets + * @param {SignaturePacket} signature - Signature packet * @param {Array} literalDataList - Array of literal data packets * @param {Array} keys - Array of keys to verify signatures * @param {Date} date - Verify the signature against the given date, diff --git a/src/openpgp.js b/src/openpgp.js index 30219f65..5233fcdd 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -83,6 +83,7 @@ export function generateKey({ userIDs = [], passphrase = "", type = "ecc", rsaBi * @param {Object|Array} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }` * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires + * @param {Date} [options.date] - Override the creation date of the key signatures * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config} * @returns {Promise} The generated key object in the form: * { key:Key, privateKeyArmored:String, publicKeyArmored:String, revocationCertificate:String } diff --git a/src/packet/public_key.js b/src/packet/public_key.js index 23b30945..b03d5d2b 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -17,8 +17,6 @@ /* eslint class-methods-use-this: ["error", { "exceptMethods": ["isDecrypted"] }] */ -import { Sha1 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha1/sha1'; -import { Sha256 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha256/sha256'; import KeyID from '../type/keyid'; import defaultConfig from '../config'; import crypto from '../crypto'; @@ -72,8 +70,8 @@ class PublicKeyPacket { */ this.expirationTimeV3 = 0; /** - * Fingerprint in lowercase hex - * @type {String} + * Fingerprint bytes + * @type {Uint8Array} */ this.fingerprint = null; /** @@ -84,12 +82,30 @@ class PublicKeyPacket { } /** - * Internal Parser for public keys as specified in {@link https://tools.ietf.org/html/rfc4880#section-5.5.2|RFC 4880 section 5.5.2 Public-Key Packet Formats} - * called by read_tag<num> - * @param {Uint8Array} bytes - Input array to read the packet from - * @returns {Object} This object with attributes set by the parser. + * Create a PublicKeyPacket from a SecretKeyPacket + * @param {SecretKeyPacket} secretKeyPacket - key packet to convert + * @returns {PublicKeyPacket} public key packet + * @static */ - read(bytes) { + static fromSecretKeyPacket(secretKeyPacket) { + const keyPacket = new PublicKeyPacket(); + const { version, created, algorithm, publicParams, keyID, fingerprint } = secretKeyPacket; + keyPacket.version = version; + keyPacket.created = created; + keyPacket.algorithm = algorithm; + keyPacket.publicParams = publicParams; + keyPacket.keyID = keyID; + keyPacket.fingerprint = fingerprint; + return keyPacket; + } + + /** + * Internal Parser for public keys as specified in {@link https://tools.ietf.org/html/rfc4880#section-5.5.2|RFC 4880 section 5.5.2 Public-Key Packet Formats} + * @param {Uint8Array} bytes - Input array to read the packet from + * @returns {Object} This object with attributes set by the parser + * @async + */ + async read(bytes) { let pos = 0; // A one-octet version number (3, 4 or 5). this.version = bytes[pos++]; @@ -117,6 +133,8 @@ class PublicKeyPacket { throw new Error('Error reading MPIs'); } + // we set the fingerprint and keyID already to make it possible to put together the key packets directly in the Key constructor + await this.computeFingerprintAndKeyID(); return pos; } throw new Error('Version ' + this.version + ' of the key packet is unsupported.'); @@ -146,7 +164,8 @@ class PublicKeyPacket { } /** - * Write packet in order to be hashed; either for a signature or a fingerprint. + * Write packet in order to be hashed; either for a signature or a fingerprint + * @param {Integer} version - target version of signature or key */ writeForHash(version) { const bytes = this.writePublicKey(); @@ -174,42 +193,56 @@ class PublicKeyPacket { } /** - * Calculates the key id of the key - * @returns {module:type/keyid~KeyID} A 8 byte key id. + * Return the key ID of the key + * @returns {module:type/keyid~KeyID} The 8-byte key ID */ getKeyID() { - if (this.keyID) { - return this.keyID; - } - this.keyID = new KeyID(); - if (this.version === 5) { - this.keyID.read(util.hexToUint8Array(this.getFingerprint()).subarray(0, 8)); - } else if (this.version === 4) { - this.keyID.read(util.hexToUint8Array(this.getFingerprint()).subarray(12, 20)); - } return this.keyID; } /** - * Calculates the fingerprint of the key - * @returns {Uint8Array} A Uint8Array containing the fingerprint. + * Computes and set the key ID and fingerprint of the key + * @async + */ + async computeFingerprintAndKeyID() { + await this.computeFingerprint(); + this.keyID = new KeyID(); + + if (this.version === 5) { + this.keyID.read(this.fingerprint.subarray(0, 8)); + } else if (this.version === 4) { + this.keyID.read(this.fingerprint.subarray(12, 20)); + } else { + throw new Error('Unsupported key version'); + } + } + + /** + * Computes and set the fingerprint of the key + */ + async computeFingerprint() { + const toHash = this.writeForHash(this.version); + + if (this.version === 5) { + this.fingerprint = await crypto.hash.sha256(toHash); + } else if (this.version === 4) { + this.fingerprint = await crypto.hash.sha1(toHash); + } else { + throw new Error('Unsupported key version'); + } + } + + /** + * Returns the fingerprint of the key, as an array of bytes + * @returns {Uint8Array} A Uint8Array containing the fingerprint */ getFingerprintBytes() { - if (this.fingerprint) { - return this.fingerprint; - } - const toHash = this.writeForHash(this.version); - if (this.version === 5) { - this.fingerprint = Sha256.bytes(toHash); - } else if (this.version === 4) { - this.fingerprint = Sha1.bytes(toHash); - } return this.fingerprint; } /** - * Calculates the fingerprint of the key - * @returns {String} A string containing the fingerprint in lowercase hex. + * Calculates and returns the fingerprint of the key, as a string + * @returns {String} A string containing the fingerprint in lowercase hex */ getFingerprint() { return util.uint8ArrayToHex(this.getFingerprintBytes()); diff --git a/src/packet/public_subkey.js b/src/packet/public_subkey.js index eb7514a7..731fc222 100644 --- a/src/packet/public_subkey.js +++ b/src/packet/public_subkey.js @@ -39,6 +39,24 @@ class PublicSubkeyPacket extends PublicKeyPacket { constructor(date, config) { super(date, config); } + + /** + * Create a PublicSubkeyPacket from a SecretSubkeyPacket + * @param {SecretSubkeyPacket} secretSubkeyPacket - subkey packet to convert + * @returns {SecretSubkeyPacket} public key packet + * @static + */ + static fromSecretSubkeyPacket(secretSubkeyPacket) { + const keyPacket = new PublicSubkeyPacket(); + const { version, created, algorithm, publicParams, keyID, fingerprint } = secretSubkeyPacket; + keyPacket.version = version; + keyPacket.created = created; + keyPacket.algorithm = algorithm; + keyPacket.publicParams = publicParams; + keyPacket.keyID = keyID; + keyPacket.fingerprint = fingerprint; + return keyPacket; + } } export default PublicSubkeyPacket; diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index 49ecf0b6..76584b76 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -80,10 +80,11 @@ class SecretKeyPacket extends PublicKeyPacket { * Internal parser for private keys as specified in * {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.5.3|RFC4880bis-04 section 5.5.3} * @param {String} bytes - Input string to read the packet from + * @async */ - read(bytes) { + async read(bytes) { // - A Public-Key or Public-Subkey packet, as described above. - let i = this.readPublicKey(bytes); + let i = await this.readPublicKey(bytes); // - One octet indicating string-to-key usage conventions. Zero // indicates that the secret-key data is not encrypted. 255 or 254 diff --git a/test/crypto/validate.js b/test/crypto/validate.js index a700b35d..31ef9569 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -74,9 +74,9 @@ vqBGKJzmO5q3cECw =X9kJ -----END PGP PRIVATE KEY BLOCK-----`; -function cloneKeyPacket(key) { +async function cloneKeyPacket(key) { const keyPacket = new openpgp.SecretKeyPacket(); - keyPacket.read(key.keyPacket.write()); + await keyPacket.read(key.keyPacket.write()); return keyPacket; } @@ -93,7 +93,7 @@ module.exports = () => { }); it('detect invalid edDSA Q', async function() { - const eddsaKeyPacket = cloneKeyPacket(eddsaKey); + const eddsaKeyPacket = await cloneKeyPacket(eddsaKey); const Q = eddsaKeyPacket.publicParams.Q; Q[0]++; await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); @@ -118,7 +118,7 @@ module.exports = () => { const { oid, Q } = eddsaKey.keyPacket.publicParams; const { seed } = eddsaKey.keyPacket.privateParams; - const ecdhKeyPacket = cloneKeyPacket(ecdhKey); + const ecdhKeyPacket = await cloneKeyPacket(ecdhKey); const ecdhOID = ecdhKeyPacket.publicParams.oid; ecdhKeyPacket.publicParams.oid = oid; @@ -130,11 +130,11 @@ module.exports = () => { await expect(ecdhKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); - it('EdDSA params are not valid for EcDSA', async function() { + it('EdDSA params are not valid for ECDSA', async function() { const { oid, Q } = eddsaKey.keyPacket.publicParams; const { seed } = eddsaKey.keyPacket.privateParams; - const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey); + const ecdsaKeyPacket = await cloneKeyPacket(ecdsaKey); const ecdsaOID = ecdsaKeyPacket.publicParams.oid; ecdsaKeyPacket.publicParams.oid = oid; await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); @@ -145,22 +145,22 @@ module.exports = () => { await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); - it('ECDH x25519 params are not valid for EcDSA', async function() { + it('ECDH x25519 params are not valid for ECDSA', async function() { const { oid, Q } = ecdhKey.keyPacket.publicParams; const { d } = ecdhKey.keyPacket.privateParams; - const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey); + const ecdsaKeyPacket = await cloneKeyPacket(ecdsaKey); 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() { + it('ECDSA params are not valid for EdDSA', async function() { const { oid, Q } = ecdsaKey.keyPacket.publicParams; const { d } = ecdsaKey.keyPacket.privateParams; - const eddsaKeyPacket = cloneKeyPacket(eddsaKey); + const eddsaKeyPacket = await cloneKeyPacket(eddsaKey); const eddsaOID = eddsaKeyPacket.publicParams.oid; eddsaKeyPacket.publicParams.oid = oid; await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); @@ -175,7 +175,7 @@ module.exports = () => { const { oid, Q } = ecdhKey.keyPacket.publicParams; const { d } = ecdhKey.keyPacket.privateParams; - const eddsaKeyPacket = cloneKeyPacket(eddsaKey); + const eddsaKeyPacket = await cloneKeyPacket(eddsaKey); const eddsaOID = eddsaKeyPacket.publicParams.oid; eddsaKeyPacket.publicParams.oid = oid; await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); @@ -202,7 +202,7 @@ module.exports = () => { } }); - it(`EcDSA ${curve} params should be valid`, async function() { + it(`ECDSA ${curve} params should be valid`, async function() { if (!ecdsaKey) { this.skip(); } @@ -213,7 +213,7 @@ module.exports = () => { if (!ecdsaKey) { this.skip(); } - const keyPacket = cloneKeyPacket(ecdsaKey); + const keyPacket = await cloneKeyPacket(ecdsaKey); const Q = keyPacket.publicParams.Q; Q[16]++; await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); @@ -228,7 +228,7 @@ module.exports = () => { }); it(`ECDH ${curve} - detect invalid Q`, async function() { - const keyPacket = cloneKeyPacket(ecdhKey); + const keyPacket = await cloneKeyPacket(ecdhKey); const Q = keyPacket.publicParams.Q; Q[16]++; await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); @@ -252,14 +252,14 @@ module.exports = () => { }); it('detect invalid RSA n', async function() { - const keyPacket = cloneKeyPacket(rsaKey); + const keyPacket = await cloneKeyPacket(rsaKey); 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 keyPacket = await cloneKeyPacket(rsaKey); const e = keyPacket.publicParams.e; e[0]++; await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); @@ -277,14 +277,14 @@ module.exports = () => { }); it('detect invalid DSA p', async function() { - const keyPacket = cloneKeyPacket(dsaKey); + const keyPacket = await cloneKeyPacket(dsaKey); 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 keyPacket = await cloneKeyPacket(dsaKey); const y = keyPacket.publicParams.y; y[0]++; @@ -292,7 +292,7 @@ module.exports = () => { }); it('detect invalid DSA g', async function() { - const keyPacket = cloneKeyPacket(dsaKey); + const keyPacket = await cloneKeyPacket(dsaKey); const g = keyPacket.publicParams.g; g[0]++; @@ -314,21 +314,21 @@ module.exports = () => { }); it('detect invalid p', async function() { - const keyPacket = cloneKeyPacket(egKey); + const keyPacket = await cloneKeyPacket(egKey); 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 keyPacket = await cloneKeyPacket(egKey); 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 keyPacket = await cloneKeyPacket(egKey); const g = keyPacket.publicParams.g; g[0]++; @@ -339,7 +339,7 @@ module.exports = () => { }); it('detect g with small order', async function() { - const keyPacket = cloneKeyPacket(egKey); + const keyPacket = await cloneKeyPacket(egKey); const p = keyPacket.publicParams.p; const g = keyPacket.publicParams.g; diff --git a/test/general/key.js b/test/general/key.js index 7cf5dee5..3fc84869 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3,7 +3,8 @@ const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); const util = require('../../src/util'); -const key = require('../../src/key'); +const { isAEADSupported, getPreferredAlgo } = require('../../src/key'); +const KeyID = require('../../src/type/keyid'); const chai = require('chai'); chai.use(require('chai-as-promised')); @@ -166,55 +167,54 @@ zoGJ6s48HcP591pN93uAitCcYcinY2ZslmdiCXw+zbeoX4spNrV4T4CYxBjNQdIa =8d2d -----END PGP PUBLIC KEY BLOCK-----`; -const twoKeys = - ['-----BEGIN PGP PUBLIC KEY BLOCK-----', - 'Version: GnuPG v2.0.19 (GNU/Linux)', - '', - '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', - 'PepQmgsu', - '=w6wd', - '-----END PGP PUBLIC KEY BLOCK-----'].join("\n"); +const twoKeys = `-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.19 (GNU/Linux) + +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 +PepQmgsu +=w6wd +-----END PGP PUBLIC KEY BLOCK-----`; const pub_revoked_subkeys = ['-----BEGIN PGP PUBLIC KEY BLOCK-----', @@ -2693,8 +2693,8 @@ function versionSpecificTests() { // ssb cv25519 2019-03-20 [E] // E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965 const key = await openpgp.readKey({ armoredKey: v5_sample_key }); - expect(key.primaryKey.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54'); - expect(key.subKeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965'); + expect(await key.primaryKey.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54'); + expect(await key.subKeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965'); await key.verifyPrimaryKey(); }); } @@ -2777,14 +2777,14 @@ module.exports = () => describe('Key', function() { expect(pubKeyV4).to.exist; expect(pubKeyV4.getKeyID().toHex()).to.equal('4a63613a4d6e4094'); - expect(pubKeyV4.getFingerprint()).to.equal('f470e50dcb1ad5f1e64e08644a63613a4d6e4094'); + expect(await pubKeyV4.getFingerprint()).to.equal('f470e50dcb1ad5f1e64e08644a63613a4d6e4094'); }); it('Create new key ID with fromID()', async function() { const [pubKeyV4] = await openpgp.readKeys({ armoredKeys: twoKeys }); const keyID = pubKeyV4.getKeyID(); - const newKeyID = keyID.constructor.fromID(keyID.toHex()); - expect(newKeyID.toHex()).to.equal(keyID.toHex()); + const newKeyID = KeyID.fromID(keyID.toHex()); + expect(newKeyID.equals(keyID)).to.be.true; }); it('Testing key method getSubkeys', async function() { @@ -2797,11 +2797,12 @@ module.exports = () => describe('Key', function() { openpgp.config ); - const subkeys = pubKey.getSubkeys(); + const subkeyPackets = [packetlist[8], packetlist[11]]; + const subkeys = await pubKey.getSubkeys(); expect(subkeys).to.exist; expect(subkeys).to.have.length(2); - expect(subkeys[0].getKeyID().equals(packetlist[8].getKeyID())).to.be.true; - expect(subkeys[1].getKeyID().equals(packetlist[11].getKeyID())).to.be.true; + expect(subkeys[0].getKeyID().equals(subkeyPackets[0].getKeyID())).to.be.true; + expect(subkeys[1].getKeyID().equals(subkeyPackets[1].getKeyID())).to.be.true; }); it('Verify status of revoked primary key', async function() { @@ -3133,12 +3134,13 @@ module.exports = () => describe('Key', function() { const dest = await openpgp.readKey({ armoredKey: pub_sig_test }); expect(source.subKeys[1]).to.exist; dest.subKeys.pop(); - return dest.update(source).then(() => { - expect(dest.subKeys[1]).to.exist; - expect( - dest.subKeys[1].getKeyID().toHex() - ).to.equal(source.subKeys[1].getKeyID().toHex()); - }); + await dest.update(source); + expect(dest.subKeys[1]).to.exist; + expect( + dest.subKeys[1].getKeyID().toHex() + ).to.equal( + source.subKeys[1].getKeyID().toHex() + ); }); it('update() - merge subkey - revocation signature', async function() { @@ -3300,7 +3302,7 @@ module.exports = () => describe('Key', function() { it("getPreferredAlgo('symmetric') - one key", async function() { const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const prefAlgo = await key.getPreferredAlgo('symmetric', [key1], undefined, undefined, { + const prefAlgo = await getPreferredAlgo('symmetric', [key1], undefined, undefined, { ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 }); expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256); @@ -3311,11 +3313,11 @@ module.exports = () => describe('Key', function() { const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); const primaryUser = await key2.getPrimaryUser(); primaryUser.selfCertification.preferredSymmetricAlgorithms = [6, aes192, cast5]; - const prefAlgo = await key.getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, { + const prefAlgo = await getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, { ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes192 }); expect(prefAlgo).to.equal(aes192); - const prefAlgo2 = await key.getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, { + const prefAlgo2 = await getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, { ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 }); expect(prefAlgo2).to.equal(aes128); @@ -3325,7 +3327,7 @@ module.exports = () => describe('Key', function() { const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); const primaryUser = await key2.getPrimaryUser(); primaryUser.selfCertification.preferredSymmetricAlgorithms = null; - const prefAlgo = await key.getPreferredAlgo('symmetric', [key1, key2]); + const prefAlgo = await getPreferredAlgo('symmetric', [key1, key2]); expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128); }); @@ -3334,11 +3336,11 @@ module.exports = () => describe('Key', function() { const primaryUser = await key1.getPrimaryUser(); primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag primaryUser.selfCertification.preferredAEADAlgorithms = [2,1]; - const prefAlgo = await key.getPreferredAlgo('aead', [key1], undefined, undefined, { + const prefAlgo = await getPreferredAlgo('aead', [key1], undefined, undefined, { ...openpgp.config, preferredAEADAlgorithm: openpgp.enums.aead.ocb }); expect(prefAlgo).to.equal(openpgp.enums.aead.ocb); - const supported = await key.isAEADSupported([key1]); + const supported = await isAEADSupported([key1]); expect(supported).to.be.true; }); @@ -3351,9 +3353,9 @@ module.exports = () => describe('Key', function() { primaryUser.selfCertification.preferredAEADAlgorithms = [2,1]; const primaryUser2 = await key2.getPrimaryUser(); primaryUser2.selfCertification.features = [7]; // Monkey-patch AEAD feature flag - const prefAlgo = await key.getPreferredAlgo('aead', [key1, key2]); + const prefAlgo = await getPreferredAlgo('aead', [key1, key2]); expect(prefAlgo).to.equal(openpgp.enums.aead.eax); - const supported = await key.isAEADSupported([key1, key2]); + const supported = await isAEADSupported([key1, key2]); expect(supported).to.be.true; }); @@ -3364,9 +3366,9 @@ module.exports = () => describe('Key', function() { const primaryUser = await key1.getPrimaryUser(); primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag primaryUser.selfCertification.preferredAEADAlgorithms = [2,1]; - const prefAlgo = await key.getPreferredAlgo('aead', [key1, key2]); + const prefAlgo = await getPreferredAlgo('aead', [key1, key2]); expect(prefAlgo).to.equal(openpgp.enums.aead.eax); - const supported = await key.isAEADSupported([key1, key2]); + const supported = await isAEADSupported([key1, key2]); expect(supported).to.be.false; }); @@ -3529,7 +3531,7 @@ VYGdb3eNlV8CfoEC key.users[0].revocationSignatures = []; return openpgp.encrypt({ publicKeys: [key], message: await openpgp.createMessage({ text: 'random data' }), date: new Date(1386842743000) }).then(() => { throw new Error('encryptSessionKey should not encrypt with revoked public key'); - }).catch(function(error) { + }).catch(error => { expect(error.message).to.equal('Error encrypting message: Could not find valid encryption key packet in key ' + key.getKeyID().toHex() + ': Subkey is revoked'); }); }); @@ -3550,8 +3552,7 @@ VYGdb3eNlV8CfoEC expect(updateKey).to.exist; expect(key.users).to.have.length(1); return key.update(updateKey).then(() => { - expect(key.getFingerprint()).to.equal( - updateKey.getFingerprint()); + expect(key.getFingerprint()).to.equal(updateKey.getFingerprint()); expect(key.users).to.have.length(2); expect(key.users[1].userID).to.be.null; }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 625b96be..5146c7fa 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -822,7 +822,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { return openpgp.decryptKey({ privateKey: privateKey, passphrase: passphrase - }).then(function(unlocked){ + }).then(unlocked => { expect(unlocked.getKeyID().toHex()).to.equal(privateKey.getKeyID().toHex()); expect(unlocked.subKeys[0].getKeyID().toHex()).to.equal(privateKey.subKeys[0].getKeyID().toHex()); expect(unlocked.isDecrypted()).to.be.true; @@ -830,7 +830,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { // original key should be unchanged expect(privateKey.isDecrypted()).to.be.false; expect(privateKey.keyPacket.privateParams).to.be.null; - originalKey.subKeys[0].getKeyID(); // fill in keyID expect(privateKey).to.deep.equal(originalKey); }); }); @@ -841,7 +840,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { return openpgp.decryptKey({ privateKey: privateKey, passphrase: ['rubbish', passphrase] - }).then(function(unlocked){ + }).then(unlocked => { expect(unlocked.getKeyID().toHex()).to.equal(privateKey.getKeyID().toHex()); expect(unlocked.subKeys[0].getKeyID().toHex()).to.equal(privateKey.subKeys[0].getKeyID().toHex()); expect(unlocked.isDecrypted()).to.be.true; @@ -849,7 +848,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { // original key should be unchanged expect(privateKey.isDecrypted()).to.be.false; expect(privateKey.keyPacket.privateParams).to.be.null; - originalKey.subKeys[0].getKeyID(); // fill in keyID expect(privateKey).to.deep.equal(originalKey); }); }); @@ -897,7 +895,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { return openpgp.encryptKey({ privateKey: key, passphrase: passphrase - }).then(function(locked){ + }).then(locked => { expect(locked.getKeyID().toHex()).to.equal(key.getKeyID().toHex()); expect(locked.subKeys[0].getKeyID().toHex()).to.equal(key.subKeys[0].getKeyID().toHex()); expect(locked.isDecrypted()).to.be.false; @@ -905,7 +903,6 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { // original key should be unchanged expect(key.isDecrypted()).to.be.true; expect(key.keyPacket.privateParams).to.not.be.null; - originalKey.subKeys[0].getKeyID(); // fill in keyID expect(key).to.deep.equal(originalKey); }); }); diff --git a/test/general/packet.js b/test/general/packet.js index 537dfa63..adef8676 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -927,12 +927,13 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ const rsa = openpgp.enums.publicKey.rsaEncryptSign; const key = new openpgp.SecretKeyPacket(); - return crypto.generateParams(rsa, 1024, 65537).then(function({ privateParams, publicParams }) { + return crypto.generateParams(rsa, 1024, 65537).then(async ({ privateParams, publicParams }) => { const testText = input.createSomeMessage(); key.publicParams = publicParams; key.privateParams = privateParams; key.algorithm = "rsaSign"; + await key.computeFingerprintAndKeyID(); const signed = new openpgp.PacketList(); const literal = new openpgp.LiteralDataPacket();