diff --git a/src/crypto/pkcs1.js b/src/crypto/pkcs1.js index f1c194e6..54ac6171 100644 --- a/src/crypto/pkcs1.js +++ b/src/crypto/pkcs1.js @@ -95,8 +95,7 @@ export default { * @return {String} message, an octet string */ decode: function(EM) { - // FIXME - // leading zeros truncated by jsbn + // leading zeros truncated by bn.js if (EM.charCodeAt(0) !== 0) { EM = String.fromCharCode(0) + EM; } diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 3b935960..6427b359 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -129,6 +129,8 @@ export default { /** * Generate a new random private key B bits long with public exponent E + * @param {Integer} B RSA bit length + * @param {String} E RSA public exponent in hex */ generate: async function(B, E) { let key; diff --git a/src/type/mpi.js b/src/type/mpi.js index b3d98d1d..03c6f517 100644 --- a/src/type/mpi.js +++ b/src/type/mpi.js @@ -42,7 +42,7 @@ import util from '../util'; */ export default function MPI(data) { /** An implementation dependent integer */ - if (data instanceof BN) { + if (BN.isBN(data)) { this.fromBN(data); } else if (util.isUint8Array(data)) { this.fromUint8Array(data); @@ -54,35 +54,27 @@ export default function MPI(data) { } /** - * Parsing function for a mpi ({@link https://tools.ietf.org/html/rfc4880#section3.2|RFC 4880 3.2}). - * @param {Uint8Array} input Payload of mpi data - * @param {String} endian Endianness of the payload; 'be' for big-endian or 'le' for little-endian - * @return {Integer} Length of data read + * Parsing function for a MPI ({@link https://tools.ietf.org/html/rfc4880#section-3.2|RFC 4880 3.2}). + * @param {Uint8Array} input Payload of MPI data + * @param {String} endian Endianness of the data; 'be' for big-endian or 'le' for little-endian + * @return {Integer} Length of data read */ MPI.prototype.read = function (bytes, endian='be') { if (util.isString(bytes)) { bytes = util.str2Uint8Array(bytes); + } else { + bytes = util.copyUint8Array(bytes); } const bits = (bytes[0] << 8) | bytes[1]; - - // Additional rules: - // - // The size of an MPI is ((MPI.length + 7) / 8) + 2 octets. - // - // The length field of an MPI describes the length starting from its - // most significant non-zero bit. Thus, the MPI [00 02 01] is not - // formed correctly. It should be [00 01 01]. - - // TODO: Verification of this size method! This size calculation as - // specified above is not applicable in JavaScript const bytelen = Math.ceil(bits / 8); - let payload = bytes.subarray(2, 2 + bytelen); + const payload = bytes.subarray(2, 2 + bytelen); + if (endian === 'le') { - payload = Uint8Array.from(payload).reverse(); + payload.reverse(); } - const raw = util.Uint8Array2str(payload); - this.fromBytes(raw); + + this.fromUint8Array(payload); return 2 + bytelen; }; @@ -118,9 +110,6 @@ MPI.prototype.fromString = function (str) { this.data = new BN(util.str2Uint8Array(str)); }; -// TODO remove this -MPI.prototype.fromBytes = MPI.prototype.fromString; - MPI.prototype.toBN = function () { return this.data.clone(); }; diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js index 7d3bca0f..56dc2a6c 100644 --- a/test/crypto/crypto.js +++ b/test/crypto/crypto.js @@ -378,10 +378,10 @@ describe('API functional testing', function() { it('Asymmetric using RSA with eme_pkcs1 padding', function () { const symmKey = util.Uint8Array2str(crypto.generateSessionKey('aes256')); - const RSAUnencryptedData = new openpgp.MPI(); - RSAUnencryptedData.fromBytes(crypto.pkcs1.eme.encode(symmKey, RSApubMPIs[0].byteLength())); + const RSAUnencryptedData = crypto.pkcs1.eme.encode(symmKey, RSApubMPIs[0].byteLength()) + const RSAUnencryptedMPI = new openpgp.MPI(RSAUnencryptedData); return crypto.publicKeyEncrypt( - 1, RSApubMPIs, RSAUnencryptedData + 1, RSApubMPIs, RSAUnencryptedMPI ).then(RSAEncryptedData => { return crypto.publicKeyDecrypt( @@ -398,11 +398,11 @@ describe('API functional testing', function() { it('Asymmetric using Elgamal with eme_pkcs1 padding', function () { const symmKey = util.Uint8Array2str(crypto.generateSessionKey('aes256')); - const ElgamalUnencryptedData = new openpgp.MPI(); - ElgamalUnencryptedData.fromBytes(crypto.pkcs1.eme.encode(symmKey, ElgamalpubMPIs[0].byteLength())); + const ElgamalUnencryptedData = crypto.pkcs1.eme.encode(symmKey, ElgamalpubMPIs[0].byteLength()); + const ElgamalUnencryptedMPI = new openpgp.MPI(ElgamalUnencryptedData); return crypto.publicKeyEncrypt( - 16, ElgamalpubMPIs, ElgamalUnencryptedData + 16, ElgamalpubMPIs, ElgamalUnencryptedMPI ).then(ElgamalEncryptedData => { return crypto.publicKeyDecrypt( diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index 29adc473..b5bf328d 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -5,13 +5,6 @@ chai.use(require('chai-as-promised')); const expect = chai.expect; -const bin2bi = function (bytes) { - const mpi = new openpgp.MPI(); - bytes = openpgp.util.bin2str(bytes); - mpi.fromBytes(bytes); - return mpi.toUint8Array(); // FIXME -}; - describe('Elliptic Curve Cryptography', function () { const elliptic_curves = openpgp.crypto.publicKey.elliptic; const key_data = { @@ -219,9 +212,9 @@ describe('Elliptic Curve Cryptography', function () { return ecdsa.verify( oid, hash, - {r: bin2bi(r), s: bin2bi(s)}, + {r: new Uint8Array(r), s: new Uint8Array(s)}, message, - bin2bi(pub) + new Uint8Array(pub) ); }; const secp256k1_dummy_value = new Uint8Array([ @@ -297,8 +290,8 @@ describe('Elliptic Curve Cryptography', function () { it('Sign and verify message', function () { const curve = elliptic_curves.get('p521'); return curve.genKeyPair().then(keyPair => { - const keyPublic = bin2bi(keyPair.getPublic()); - const keyPrivate = bin2bi(keyPair.getPrivate()); + const keyPublic = new Uint8Array(keyPair.getPublic()); + const keyPrivate = new Uint8Array(keyPair.getPrivate()); const oid = curve.oid; const message = p384_message; return elliptic_curves.ecdsa.sign(oid, 10, message, keyPrivate).then(signature => { @@ -321,9 +314,9 @@ describe('Elliptic Curve Cryptography', function () { curve.oid, cipher, hash, - bin2bi(ephemeral), + new Uint8Array(ephemeral), data, - bin2bi(priv), + new Uint8Array(priv), fingerprint ); }); diff --git a/test/general/packet.js b/test/general/packet.js index c614a633..8e924fff 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -204,7 +204,7 @@ describe("Packet", function() { }); }); - it('Secret key packet (reading, unencrypted)', function(done) { + it('Secret key packet (reading, unencrypted)', function() { const armored_key = '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + @@ -239,17 +239,14 @@ describe("Packet", function() { enc.sessionKeyAlgorithm = 'aes256'; enc.publicKeyId.bytes = '12345678'; - enc.encrypt(key).then(() => { - - enc.decrypt(key).then(() => { - + return enc.encrypt(key).then(() => { + return enc.decrypt(key).then(() => { expect(stringify(enc.sessionKey)).to.equal(stringify(secret)); - done(); }); }); }); - it('Public key encrypted packet (reading, GPG)', function(done) { + it('Public key encrypted packet (reading, GPG)', function() { const armored_key = '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + @@ -304,17 +301,16 @@ describe("Packet", function() { const msg = new openpgp.packet.List(); msg.read(openpgp.armor.decode(armored_msg).data); - msg[0].decrypt(key).then(() => { - msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); + return msg[0].decrypt(key).then(() => { + return msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); const text = stringify(msg[1].packets[0].packets[0].data); expect(text).to.equal('Hello world!'); - done(); }); }); - it('Sym encrypted session key reading/writing', function(done) { + it('Sym. encrypted session key reading/writing', function(done) { const passphrase = 'hello'; const algo = 'aes256'; @@ -346,7 +342,7 @@ describe("Packet", function() { done(); }); - it('Secret key encryption/decryption test', function(done) { + it('Secret key encryption/decryption test', function() { const armored_msg = '-----BEGIN PGP MESSAGE-----\n' + 'Version: GnuPG v2.0.19 (GNU/Linux)\n' + @@ -367,13 +363,12 @@ describe("Packet", function() { const msg = new openpgp.packet.List(); msg.read(openpgp.armor.decode(armored_msg).data); - msg[0].decrypt(key).then(() => { - msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); + return msg[0].decrypt(key).then(() => { + return msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); const text = stringify(msg[1].packets[0].packets[0].data); expect(text).to.equal('Hello world!'); - done(); }); });