From 310d8dd9b9fb9edb12fe94d8c218c8d3818a660d Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 20 Apr 2018 19:38:46 +0200 Subject: [PATCH] Fix V5 key fingerprint in ECDH parameters --- src/crypto/public_key/elliptic/ecdh.js | 4 +--- src/packet/public_key.js | 19 +++++++++++++------ .../public_key_encrypted_session_key.js | 4 ++-- test/crypto/elliptic.js | 8 ++++---- test/general/packet.js | 4 ++-- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 8cdc3509..ef256b36 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -46,7 +46,7 @@ function buildEcdhParam(public_algo, oid, cipher_algo, hash_algo, fingerprint) { new Uint8Array([public_algo]), kdf_params.write(), util.str_to_Uint8Array("Anonymous Sender "), - fingerprint + fingerprint.subarray(0, 20) ]); } @@ -73,7 +73,6 @@ function kdf(hash_algo, X, length, param) { * @async */ async function encrypt(oid, cipher_algo, hash_algo, m, Q, fingerprint) { - fingerprint = util.hex_to_Uint8Array(fingerprint); const curve = new Curve(oid); const param = buildEcdhParam(enums.publicKey.ecdh, oid, cipher_algo, hash_algo, fingerprint); cipher_algo = enums.read(enums.symmetric, cipher_algo); @@ -102,7 +101,6 @@ async function encrypt(oid, cipher_algo, hash_algo, m, Q, fingerprint) { * @async */ async function decrypt(oid, cipher_algo, hash_algo, V, C, d, fingerprint) { - fingerprint = util.hex_to_Uint8Array(fingerprint); const curve = new Curve(oid); const param = buildEcdhParam(enums.publicKey.ecdh, oid, cipher_algo, hash_algo, fingerprint); cipher_algo = enums.read(enums.symmetric, cipher_algo); diff --git a/src/packet/public_key.js b/src/packet/public_key.js index 491d3ddd..939689c7 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -202,9 +202,9 @@ PublicKey.prototype.getKeyId = function () { /** * Calculates the fingerprint of the key - * @returns {String} A string containing the fingerprint in lowercase hex + * @returns {Uint8Array} A Uint8Array containing the fingerprint */ -PublicKey.prototype.getFingerprint = function () { +PublicKey.prototype.getFingerprintBytes = function () { if (this.fingerprint) { return this.fingerprint; } @@ -212,10 +212,10 @@ PublicKey.prototype.getFingerprint = function () { if (this.version === 5) { const bytes = this.writePublicKey(); toHash = util.concatUint8Array([new Uint8Array([0x9A]), util.writeNumber(bytes.length, 4), bytes]); - this.fingerprint = util.Uint8Array_to_str(crypto.hash.sha256(toHash)); + this.fingerprint = crypto.hash.sha256(toHash); } else if (this.version === 4) { toHash = this.writeOld(); - this.fingerprint = util.Uint8Array_to_str(crypto.hash.sha1(toHash)); + this.fingerprint = crypto.hash.sha1(toHash); } else if (this.version === 3) { const algo = enums.write(enums.publicKey, this.algorithm); const paramCount = crypto.getPubKeyParamTypes(algo).length; @@ -223,12 +223,19 @@ PublicKey.prototype.getFingerprint = function () { for (let i = 0; i < paramCount; i++) { toHash += this.params[i].toString(); } - this.fingerprint = util.Uint8Array_to_str(crypto.hash.md5(util.str_to_Uint8Array(toHash))); + this.fingerprint = crypto.hash.md5(util.str_to_Uint8Array(toHash)); } - this.fingerprint = util.str_to_hex(this.fingerprint); return this.fingerprint; }; +/** + * Calculates the fingerprint of the key + * @returns {String} A string containing the fingerprint in lowercase hex + */ +PublicKey.prototype.getFingerprint = function () { + return util.Uint8Array_to_hex(this.getFingerprintBytes()); +}; + /** * Returns algorithm information * @returns {Promise} An object of the form {algorithm: String, bits:int, curve:String} diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index f926d0ca..f70c166c 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -122,7 +122,7 @@ PublicKeyEncryptedSessionKey.prototype.encrypt = async function (key) { } this.encrypted = await crypto.publicKeyEncrypt( - algo, key.params, toEncrypt, key.fingerprint); + algo, key.params, toEncrypt, key.getFingerprintBytes()); return true; }; @@ -138,7 +138,7 @@ PublicKeyEncryptedSessionKey.prototype.encrypt = async function (key) { PublicKeyEncryptedSessionKey.prototype.decrypt = async function (key) { const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm); const result = await crypto.publicKeyDecrypt( - algo, key.params, this.encrypted, key.fingerprint); + algo, key.params, this.encrypted, key.getFingerprintBytes()); let checksum; let decoded; diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index e1156a63..ed41edc8 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -317,7 +317,7 @@ describe('Elliptic Curve Cryptography', function () { new Uint8Array(ephemeral), data, new Uint8Array(priv), - fingerprint + new Uint8Array(fingerprint) ); }); }; @@ -344,17 +344,17 @@ describe('Elliptic Curve Cryptography', function () { it('Invalid curve oid', function (done) { expect(decrypt_message( - '', 2, 7, [], [], [], '' + '', 2, 7, [], [], [], [] )).to.be.rejectedWith(Error, /Not valid curve/).notify(done); }); it('Invalid ephemeral key', function (done) { expect(decrypt_message( - 'secp256k1', 2, 7, [], [], [], '' + 'secp256k1', 2, 7, [], [], [], [] )).to.be.rejectedWith(Error, /Unknown point format/).notify(done); }); it('Invalid key data integrity', function (done) { expect(decrypt_message( - 'secp256k1', 2, 7, secp256k1_value, secp256k1_point, secp256k1_data, '' + 'secp256k1', 2, 7, secp256k1_value, secp256k1_point, secp256k1_data, [] )).to.be.rejectedWith(Error, /Key Data Integrity failed/).notify(done); }); }); diff --git a/test/general/packet.js b/test/general/packet.js index 32ba3b25..25e1e43e 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -269,13 +269,13 @@ describe("Packet", function() { enc.publicKeyAlgorithm = 'rsa_encrypt'; enc.sessionKeyAlgorithm = 'aes256'; enc.publicKeyId.bytes = '12345678'; - return enc.encrypt({ params: mpi }).then(() => { + return enc.encrypt({ params: mpi, getFingerprintBytes() {} }).then(() => { msg.push(enc); msg2.read(msg.write()); - return msg2[0].decrypt({ params: mpi }).then(() => { + return msg2[0].decrypt({ params: mpi, getFingerprintBytes() {} }).then(() => { expect(stringify(msg2[0].sessionKey)).to.equal(stringify(enc.sessionKey)); expect(msg2[0].sessionKeyAlgorithm).to.equal(enc.sessionKeyAlgorithm);