From 30bd6102d5d4278bbbb47074ef51c3b344a3288c Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Thu, 1 Mar 2018 11:35:16 -0800 Subject: [PATCH] OID's stored as Uint8Array --- src/crypto/public_key/elliptic/curves.js | 2 +- src/crypto/public_key/elliptic/key.js | 14 +++--- src/enums.js | 20 ++++---- src/type/oid.js | 18 ++++---- test/crypto/elliptic.js | 58 +++++++++++++----------- test/general/ecc_nist.js | 12 ++--- test/general/oid.js | 9 ++-- test/general/x25519.js | 2 +- 8 files changed, 71 insertions(+), 64 deletions(-) diff --git a/src/crypto/public_key/elliptic/curves.js b/src/crypto/public_key/elliptic/curves.js index 3bf361c7..cd1dd8ed 100644 --- a/src/crypto/public_key/elliptic/curves.js +++ b/src/crypto/public_key/elliptic/curves.js @@ -194,7 +194,7 @@ async function generate(curve) { curve = new Curve(curve); const keyPair = await curve.genKeyPair(); return { - oid: new OID(curve.oid.slice(2)), + oid: curve.oid, Q: new BN(keyPair.getPublic()), d: new BN(keyPair.getPrivate()), hash: curve.hash, diff --git a/src/crypto/public_key/elliptic/key.js b/src/crypto/public_key/elliptic/key.js index d3fbe92e..0d33787f 100644 --- a/src/crypto/public_key/elliptic/key.js +++ b/src/crypto/public_key/elliptic/key.js @@ -29,7 +29,7 @@ */ import BN from 'bn.js'; -import { curves, webCurves, nodeCurves } from './curves'; +import { webCurves, nodeCurves } from './curves'; import hash from '../../hash'; import util from '../../../util'; import enums from '../../../enums'; @@ -132,9 +132,10 @@ async function webSign(curve, hash_algo, message, keyPair) { key, message )); + return { - r: signature.slice(0, len), - s: signature.slice(len, len << 1) + r: new BN(signature.slice(0, len)), + s: new BN(signature.slice(len, len << 1)) }; } @@ -159,9 +160,10 @@ async function webVerify(curve, hash_algo, { r, s }, message, publicKey) { ["verify"] ); - r = [].concat(Array(len - r.length).fill(0), r); - s = [].concat(Array(len - s.length).fill(0), s); - const signature = new Uint8Array([].concat(r, s)).buffer; + const signature = util.concatUint8Array([ + new Uint8Array(len - r.length), r, + new Uint8Array(len - s.length), s + ]).buffer; return webCrypto.verify( { diff --git a/src/enums.js b/src/enums.js index 74799d4f..e69f5def 100644 --- a/src/enums.js +++ b/src/enums.js @@ -15,37 +15,37 @@ export default { "secp256r1": "p256", "prime256v1": "p256", "1.2.840.10045.3.1.7": "p256", - "2a8648ce3d030107": "p256", - "2A8648CE3D030107": "p256", + "2a8648ce3d030107": "p256", + "2A8648CE3D030107": "p256", /** NIST P-384 Curve */ "p384": "p384", "P-384": "p384", "secp384r1": "p384", "1.3.132.0.34": "p384", - "2b81040022": "p384", - "2B81040022": "p384", + "2b81040022": "p384", + "2B81040022": "p384", /** NIST P-521 Curve */ "p521": "p521", "P-521": "p521", "secp521r1": "p521", "1.3.132.0.35": "p521", - "2b81040023": "p521", - "2B81040023": "p521", + "2b81040023": "p521", + "2B81040023": "p521", /** SECP256k1 Curve */ "secp256k1": "secp256k1", "1.3.132.0.10": "secp256k1", - "2b8104000a": "secp256k1", - "2B8104000A": "secp256k1", + "2b8104000a": "secp256k1", + "2B8104000A": "secp256k1", /** Ed25519 Curve */ "ed25519": "ed25519", "Ed25519": "ed25519", "1.3.6.1.4.1.11591.15.1": "ed25519", - "2b06010401da470f01": "ed25519", - "2B06010401DA470F01": "ed25519", + "2b06010401da470f01": "ed25519", + "2B06010401DA470F01": "ed25519", /** Curve25519 */ "cv25519": "curve25519", diff --git a/src/type/oid.js b/src/type/oid.js index 94df3ddd..b7fdb4f4 100644 --- a/src/type/oid.js +++ b/src/type/oid.js @@ -40,15 +40,16 @@ import enums from '../enums'; /** * @constructor */ -function OID(oid) { +export default function OID(oid) { if (oid instanceof OID) { this.oid = oid.oid; } else if (util.isArray(oid) || util.isUint8Array(oid)) { + oid = new Uint8Array(oid); if (oid[0] === 0x06) { // DER encoded oid byte array - oid = oid.slice(2); + oid = oid.subarray(2); } - this.oid = util.Uint8Array_to_str(oid); + this.oid = oid; } else { this.oid = ''; } @@ -63,7 +64,7 @@ OID.prototype.read = function (input) { if (input.length >= 1) { const length = input[0]; if (input.length >= 1+length) { - this.oid = util.Uint8Array_to_str(input.subarray(1, 1+length)); + this.oid = input.subarray(1, 1+length); return 1+this.oid.length; } } @@ -75,7 +76,7 @@ OID.prototype.read = function (input) { * @return {Uint8Array} Array with the serialized value the OID */ OID.prototype.write = function () { - return util.str_to_Uint8Array(String.fromCharCode(this.oid.length)+this.oid); + return util.concatUint8Array([new Uint8Array([this.oid.length]), this.oid]); }; /** @@ -83,7 +84,7 @@ OID.prototype.write = function () { * @return {string} String with the hex value of the OID */ OID.prototype.toHex = function() { - return util.str_to_hex(this.oid); + return util.Uint8Array_to_hex(this.oid); }; /** @@ -100,8 +101,5 @@ OID.prototype.getName = function() { }; OID.fromClone = function (clone) { - const oid = new OID(clone.oid); - return oid; + return new OID(clone.oid); }; - -export default OID; diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index 5a018489..afee0f55 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -15,8 +15,9 @@ describe('Elliptic Curve Cryptography', function () { 0x1F, 0x89, 0xCC, 0xFF, 0x0A, 0x26, 0x05, 0xA2, 0x3C, 0x2A, 0x35, 0x25, 0x26, 0x11, 0xD7, 0xEA, 0xA1, 0xED, 0x29, 0x95, 0xB5, 0xE1, 0x5F, 0x1D -]), - pub: new Uint8Array([0x04, + ]), + pub: new Uint8Array([ + 0x04, 0x80, 0x2C, 0x40, 0x76, 0x31, 0x20, 0xB6, 0x9B, 0x48, 0x3B, 0x05, 0xEB, 0x6C, 0x1E, 0x3F, 0x49, 0x84, 0xF7, 0xD2, 0xAD, 0x16, 0xA1, 0x6F, 0x62, @@ -34,8 +35,9 @@ describe('Elliptic Curve Cryptography', function () { 0xA7, 0xC1, 0xA3, 0x4B, 0xC0, 0xBD, 0xFE, 0x3E, 0xF1, 0xBE, 0x76, 0xCB, 0xE8, 0xAB, 0x3B, 0xBD, 0xB6, 0x84, 0xC7, 0x8B, 0x91, 0x2F, 0x76, 0x8B -]), - pub: new Uint8Array([0x04, + ]), + pub: new Uint8Array([ + 0x04, 0x44, 0x83, 0xA0, 0x3E, 0x5B, 0x0A, 0x0D, 0x9B, 0xA0, 0x06, 0xDF, 0x38, 0xC7, 0x64, 0xCD, 0x62, 0x7D, 0x5E, 0x3D, 0x3B, 0x50, 0xF5, 0x06, 0xC7, @@ -60,8 +62,9 @@ describe('Elliptic Curve Cryptography', function () { 0x33, 0xAD, 0xC0, 0x0B, 0x56, 0xB1, 0x06, 0x8C, 0x57, 0x48, 0xA3, 0x73, 0xDB, 0xE0, 0x19, 0x50, 0x2E, 0x79 -]), - pub: new Uint8Array([0x04, + ]), + pub: new Uint8Array([ + 0x04, 0x01, 0x0D, 0xD5, 0xCA, 0xD8, 0xB0, 0xEF, 0x9F, 0x2B, 0x7E, 0x58, 0x99, 0xDE, 0x05, 0xF6, 0xF6, 0x64, 0x6B, 0xCD, 0x59, 0x2E, 0x39, 0xB8, 0x82, @@ -86,8 +89,9 @@ describe('Elliptic Curve Cryptography', function () { 0x7B, 0x8F, 0xDE, 0x5D, 0x91, 0x4D, 0xDC, 0xA0, 0xAD, 0x05, 0xAB, 0x8F, 0x87, 0x9B, 0x57, 0x48, 0xAE, 0x8A, 0xE0, 0xF9, 0x39, 0xBD, 0x24, 0x00 -]), - pub: new Uint8Array([0x04, + ]), + pub: new Uint8Array([ + 0x04, 0xA8, 0x02, 0x35, 0x2C, 0xB7, 0x24, 0x95, 0x51, 0x0A, 0x65, 0x26, 0x7D, 0xDF, 0xEA, 0x64, 0xB3, 0xA8, 0xE1, 0x4F, 0xDD, 0x12, 0x84, 0x7E, 0x59, @@ -104,8 +108,9 @@ describe('Elliptic Curve Cryptography', function () { 0x4D, 0xDF, 0x96, 0xA4, 0xED, 0x8E, 0x5B, 0xF9, 0xBD, 0xD3, 0xFE, 0xAE, 0x3F, 0xB2, 0xCF, 0xEE, 0xA7, 0xDB, 0xD0, 0x58, 0xA7, 0x47, 0xF8, 0x7C -]), - pub: new Uint8Array([0x04, + ]), + pub: new Uint8Array([ + 0x04, 0xD3, 0x36, 0x11, 0xF9, 0xF9, 0xAB, 0x39, 0x23, 0x15, 0xB9, 0x71, 0x7B, 0x2A, 0x0B, 0xA6, 0x6D, 0x39, 0x6D, 0x64, 0x87, 0x22, 0x9A, 0xA3, 0x0A, @@ -117,20 +122,20 @@ describe('Elliptic Curve Cryptography', function () { message: new Uint8Array([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -]), + ]), signature: { r: new Uint8Array([ 0xF1, 0x78, 0x1C, 0xA5, 0x13, 0x21, 0x0C, 0xBA, 0x6F, 0x18, 0x5D, 0xB3, 0x01, 0xE2, 0x17, 0x1B, 0x67, 0x65, 0x7F, 0xC6, 0x1F, 0x50, 0x12, 0xFB, 0x2F, 0xD3, 0xA4, 0x29, 0xE3, 0xC2, 0x44, 0x9F -]), + ]), s: new Uint8Array([ 0x7F, 0x08, 0x69, 0x6D, 0xBB, 0x1B, 0x9B, 0xF2, 0x62, 0x1C, 0xCA, 0x80, 0xC6, 0x15, 0xB2, 0xAE, 0x60, 0x50, 0xD1, 0xA7, 0x1B, 0x32, 0xF3, 0xB1, 0x01, 0x0B, 0xDF, 0xC6, 0xAB, 0xF0, 0xEB, 0x01 -]) + ]) } }; describe('Basic Operations', function () { @@ -215,11 +220,7 @@ describe('Elliptic Curve Cryptography', function () { } const ecdsa = elliptic_curves.ecdsa; return ecdsa.verify( - oid, - hash, - {r: new BN(r), s: new BN(s)}, - message, - new Uint8Array(pub) + oid, hash, { r: new Uint8Array(r), s: new Uint8Array(s) }, message, new Uint8Array(pub) ); }; const secp256k1_dummy_value = new Uint8Array([ @@ -227,8 +228,9 @@ describe('Elliptic Curve Cryptography', function () { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -]); - const secp256k1_dummy_point = new Uint8Array([0x04, + ]); + const secp256k1_dummy_point = new Uint8Array([ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -237,7 +239,8 @@ describe('Elliptic Curve Cryptography', function () { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); - const secp256k1_invalid_point = new Uint8Array([0x04, + const secp256k1_invalid_point = new Uint8Array([ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -271,7 +274,7 @@ describe('Elliptic Curve Cryptography', function () { const p384_message = new Uint8Array([ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF -]); + ]); const p384_r = new Uint8Array([ 0x9D, 0x07, 0xCA, 0xA5, 0x9F, 0xBE, 0xB8, 0x76, 0xA9, 0xB9, 0x66, 0x0F, 0xA0, 0x64, 0x70, 0x5D, @@ -279,7 +282,7 @@ describe('Elliptic Curve Cryptography', function () { 0x8B, 0x37, 0x83, 0xE7, 0xBC, 0x1C, 0x4C, 0x86, 0xCB, 0x3C, 0xD5, 0x9B, 0x68, 0xF0, 0x65, 0xEB, 0x3A, 0xB6, 0xD6, 0xA6, 0xCF, 0x85, 0x3D, 0xA9 -]); + ]); const p384_s = new Uint8Array([ 0x32, 0x85, 0x78, 0xCC, 0xEA, 0xC5, 0x22, 0x83, 0x10, 0x73, 0x1C, 0xCF, 0x10, 0x8A, 0x52, 0x11, @@ -287,7 +290,7 @@ describe('Elliptic Curve Cryptography', function () { 0x11, 0x11, 0xBC, 0x0F, 0x6D, 0x98, 0xE2, 0x16, 0x68, 0x58, 0x23, 0x1D, 0x11, 0xEF, 0x3D, 0x21, 0x30, 0x75, 0x24, 0x39, 0x48, 0x89, 0x03, 0xDC -]); + ]); it('Valid signature', function (done) { expect(verify_signature('p384', 8, p384_r, p384_s, p384_message, key_data.p384.pub)) .to.eventually.be.true.notify(done); @@ -331,8 +334,9 @@ describe('Elliptic Curve Cryptography', function () { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -]); - const secp256k1_point = new Uint8Array([0x04, + ]); + const secp256k1_point = new Uint8Array([ + 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -344,7 +348,7 @@ describe('Elliptic Curve Cryptography', function () { const secp256k1_data = new Uint8Array([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -]); + ]); it('Invalid curve oid', function (done) { expect(decrypt_message( diff --git a/test/general/ecc_nist.js b/test/general/ecc_nist.js index 38350161..df5339b9 100644 --- a/test/general/ecc_nist.js +++ b/test/general/ecc_nist.js @@ -29,7 +29,7 @@ describe('Elliptic Curve Cryptography', function () { 'HLr5fhoGnRots3JSC0j20UQQOKVOXaW3', '=VpL9', '-----END PGP PUBLIC KEY BLOCK-----' -].join('\n'), + ].join('\n'), priv: [ '-----BEGIN PGP PRIVATE KEY BLOCK-----', 'Version: OpenPGP.js 1.3+secp256k1', @@ -51,7 +51,7 @@ describe('Elliptic Curve Cryptography', function () { '9tFEEDilTl2ltw==', '=C3TW', '-----END PGP PRIVATE KEY BLOCK-----' -].join('\n'), + ].join('\n'), message: 'Shall I hear more, or shall I speak at this?' }, juliet: { @@ -74,7 +74,7 @@ describe('Elliptic Curve Cryptography', function () { '+0kjoUNu6PRIll/jMgTVAXn0Mov6HqJ95A==', '=ISmy', '-----END PGP PUBLIC KEY BLOCK-----' -].join('\n'), + ].join('\n'), priv: [ '-----BEGIN PGP PRIVATE KEY BLOCK-----', 'Version: OpenPGP.js 1.3+secp256k1', @@ -96,7 +96,7 @@ describe('Elliptic Curve Cryptography', function () { '1QF59DKL+h6ifeQ=', '=QvXN', '-----END PGP PRIVATE KEY BLOCK-----' -].join('\n'), + ].join('\n'), message: 'O Romeo, Romeo! Wherefore art thou Romeo?', message_signed: [ '-----BEGIN PGP SIGNED MESSAGE-----', @@ -111,7 +111,7 @@ describe('Elliptic Curve Cryptography', function () { '6yc7nzn1FBYFzMz8aFIA/3FlcIvR+eLvRTVmfiEatB6IU6JviBnzxR1gA/SOdyS2', '=GCiR', '-----END PGP SIGNATURE-----' -].join('\n'), + ].join('\n'), message_encrypted: [ '-----BEGIN PGP MESSAGE-----', 'Version: GnuPG v2', @@ -127,7 +127,7 @@ describe('Elliptic Curve Cryptography', function () { 'DP/V1yLuBUZuRg==', '=GEAB', '-----END PGP MESSAGE-----' -].join('\n') + ].join('\n') } }; function load_pub_key(name) { diff --git a/test/general/oid.js b/test/general/oid.js index 47b4ec73..69611140 100644 --- a/test/general/oid.js +++ b/test/general/oid.js @@ -4,6 +4,7 @@ const expect = require('chai').expect; describe('Oid tests', function() { const OID = openpgp.OID; + const util = openpgp.util; const p256_oid = new Uint8Array([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]); const p384_oid = new Uint8Array([0x2B, 0x81, 0x04, 0x00, 0x22]); const p521_oid = new Uint8Array([0x2B, 0x81, 0x04, 0x00, 0x23]); @@ -14,7 +15,7 @@ describe('Oid tests', function() { expect(oid).to.exist; expect(oid.oid).to.exist; expect(oid.oid).to.have.length(data.length); - expect(oid.oid).to.equal(openpgp.util.Uint8Array_to_str(data)); + expect(oid.toHex()).to.equal(util.Uint8Array_to_hex(data)); }); }); it('Reading and writing', function() { @@ -25,12 +26,14 @@ describe('Oid tests', function() { expect(oid.read(data)).to.equal(data.length); expect(oid.oid).to.exist; expect(oid.oid).to.have.length(data.length-1); - expect(oid.oid).to.equal(openpgp.util.Uint8Array_to_str(data.subarray(1))); + expect(oid.toHex()).to.equal(util.Uint8Array_to_hex(data.subarray(1))); const result = oid.write(); expect(result).to.exist; expect(result).to.have.length(data.length); expect(result[0]).to.equal(data.length-1); - expect(openpgp.util.Uint8Array_to_str(result.subarray(1))).to.equal(openpgp.util.Uint8Array_to_str(data.subarray(1))); + expect( + util.Uint8Array_to_hex(result.subarray(1)) + ).to.equal(util.Uint8Array_to_hex(data.subarray(1))); }); }); }); diff --git a/test/general/x25519.js b/test/general/x25519.js index c8fdc78b..cd21bca1 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -338,9 +338,9 @@ describe('X25519 Cryptography', function () { describe('Ed25519 Test Vectors from RFC8032', function () { // https://tools.ietf.org/html/rfc8032#section-7.1 const signature = openpgp.crypto.signature; - const curve = new elliptic.Curve('ed25519'); const util = openpgp.util; function testVector(vector) { + const curve = new elliptic.Curve('ed25519'); const S = curve.keyFromSecret(vector.SECRET_KEY); const P = curve.keyFromPublic('40'+vector.PUBLIC_KEY); expect(S.getPublic()).to.deep.equal(P.getPublic());