Comparing version 0.9.2 to 0.9.3
@@ -0,1 +1,25 @@ | ||
<a name="0.9.3"></a> | ||
## [0.9.3](https://github.com/cisco/node-jose/compare/0.9.2...v0.9.3) (2017-02-20) | ||
### Update | ||
* maintain dependencies via Greenkeeper ([2fde860746b009b6522fd9a990b4a62c34d034e4](https://github.com/cisco/node-jose/commit/2fde860746b009b6522fd9a990b4a62c34d034e4)) | ||
* update jsbn to version 1.1.0 ([8a83b10c860e3c36aa581e890f5eeea7db23ec35](https://github.com/cisco/node-jose/commit/8a83b10c860e3c36aa581e890f5eeea7db23ec35)) | ||
### Fix | ||
* Validate EC public key is on configured curve ([f92cffb4a0398b4b1158be98423369233282e0af](https://github.com/cisco/node-jose/commit/f92cffb4a0398b4b1158be98423369233282e0af)) | ||
### Doc | ||
* note webpack support ([b011c001958c2e346b522e87cdb107f01e584da9](https://github.com/cisco/node-jose/commit/b011c001958c2e346b522e87cdb107f01e584da9)) | ||
### Build | ||
* additional tests on ECDH failures ([af19f289811e75522bb8de662e76b1aef15a95fa](https://github.com/cisco/node-jose/commit/af19f289811e75522bb8de662e76b1aef15a95fa)) | ||
* update gulp-mocha to latest version 🚀 ([1e44875e9c1cad370cc44808bddf5fab99226eb0](https://github.com/cisco/node-jose/commit/1e44875e9c1cad370cc44808bddf5fab99226eb0)) | ||
* Update webpack to the latest version 🚀 ([bb513056143ad2ecf7b44862d3d7ac00e80852eb](https://github.com/cisco/node-jose/commit/bb513056143ad2ecf7b44862d3d7ac00e80852eb)) | ||
# Release Notes | ||
@@ -2,0 +26,0 @@ |
@@ -43,2 +43,19 @@ /*! | ||
var validatePublic = function(pk, form) { | ||
var pubKey = pk && ecUtil.convertToForge(pk, true); | ||
if (!pubKey || !pubKey.isValid()) { | ||
return Promise.reject(new Error("invalid EC public key")); | ||
} | ||
switch (form) { | ||
case "jwk": | ||
pubKey = ecUtil.convertToJWK(pk, true); | ||
break; | ||
case "buffer": | ||
pubKey = ecUtil.convertToBuffer(pk, true); | ||
break; | ||
} | ||
return Promise.resolve(pubKey); | ||
} | ||
// ### fallback implementation -- uses ecc + forge | ||
@@ -49,17 +66,21 @@ var fallback = function(key, props) { | ||
// assume {key} is privateKey | ||
// assume {props.public} is publicKey | ||
var privKey = ecUtil.convertToForge(key, false); | ||
// assume {props.public} is publicKey | ||
if (!props.public) { | ||
return Promise.reject(new Error("invalid EC public key")); | ||
} | ||
var pubKey = ecUtil.convertToForge(props.public, true); | ||
var secret = privKey.computeSecret(pubKey); | ||
if (keyLen) { | ||
// truncate to requested key length | ||
if (secret.length < keyLen) { | ||
return Promise.reject(new Error("key length too large: " + keyLen)); | ||
var p = validatePublic(props.public, "forge"); | ||
p = p.then(function(pubKey) { | ||
// {pubKey} is "forge" | ||
var secret = privKey.computeSecret(pubKey); | ||
if (keyLen) { | ||
// truncate to requested key length | ||
if (secret.length < keyLen) { | ||
return Promise.reject(new Error("key length too large: " + keyLen)); | ||
} | ||
secret = secret.slice(0, keyLen); | ||
} | ||
secret = secret.slice(0, keyLen); | ||
} | ||
return Promise.resolve(secret); | ||
return secret; | ||
}); | ||
return p; | ||
}; | ||
@@ -91,7 +112,6 @@ | ||
// assume {props.public} is publicKey | ||
if (!props.public) { | ||
return Promise.reject(new Error("invalid EC public key")); | ||
} | ||
var pubKey = ecUtil.convertToJWK(props.public, true); | ||
pubKey = helpers.subtleCrypto.importKey("jwk", | ||
var pubKey = validatePublic(props.public, "jwk"); | ||
pubKey = pubKey.then(function(pubKey) { | ||
// {pubKey} is "jwk" | ||
return helpers.subtleCrypto.importKey("jwk", | ||
pubKey, | ||
@@ -101,5 +121,6 @@ algParams, | ||
[]); | ||
}); | ||
var promise = Promise.all([privKey, pubKey]); | ||
promise = promise.then(function(keypair) { | ||
var p = Promise.all([privKey, pubKey]); | ||
p = p.then(function(keypair) { | ||
var privKey = keypair[0], | ||
@@ -113,7 +134,7 @@ pubKey = keypair[1]; | ||
}); | ||
promise = promise.then(function(result) { | ||
p = p.then(function(result) { | ||
result = new Buffer(result); | ||
return result; | ||
}); | ||
return promise; | ||
return p; | ||
}; | ||
@@ -144,19 +165,22 @@ | ||
// assume {key} is privateKey | ||
// assume {props.public} is publicKey | ||
var privKey = ecUtil.convertToBuffer(key, false); | ||
// assume {props.public} is publicKey | ||
var pubKey = ecUtil.convertToBuffer(props.public, true); | ||
var ecdh = helpers.nodeCrypto.createECDH(curve); | ||
// dummy call so computeSecret doesn't fail | ||
ecdh.generateKeys(); | ||
ecdh.setPrivateKey(privKey); | ||
var secret = ecdh.computeSecret(pubKey); | ||
if (keyLen) { | ||
if (secret.length < keyLen) { | ||
return Promise.reject(new Error("key length too large: " + keyLen)); | ||
var p = validatePublic(props.public, "buffer"); | ||
p = p.then(function(pubKey) { | ||
// {pubKey} is "buffer" | ||
var ecdh = helpers.nodeCrypto.createECDH(curve); | ||
// dummy call so computeSecret doesn't fail | ||
// ecdh.generateKeys(); | ||
ecdh.setPrivateKey(privKey); | ||
var secret = ecdh.computeSecret(pubKey); | ||
if (keyLen) { | ||
if (secret.length < keyLen) { | ||
return Promise.reject(new Error("key length too large: " + keyLen)); | ||
} | ||
secret = secret.slice(0, keyLen); | ||
} | ||
secret = secret.slice(0, keyLen); | ||
} | ||
return Promise.resolve(secret); | ||
return secret; | ||
}); | ||
return p; | ||
}; | ||
@@ -163,0 +187,0 @@ |
@@ -90,2 +90,7 @@ /** | ||
// basics | ||
ECPublicKey.prototype.isValid = function() { | ||
return this.params.curve.contains(this.point); | ||
} | ||
// ECDSA | ||
@@ -180,2 +185,11 @@ ECPublicKey.prototype.verify = function(md, sig) { | ||
// basics | ||
ECPrivateKey.prototype.isValid = function() { | ||
var d = bin2bn(this.d), | ||
n1 = params.getN().subtract(BigIneger.ONE); | ||
return (d.compareTo(BigInteger.ONE) >= 0) && | ||
(d.compareTo(n1) < 0); | ||
} | ||
// ECDH | ||
@@ -182,0 +196,0 @@ ECPrivateKey.prototype.computeSecret = function(pubkey) { |
@@ -30,3 +30,3 @@ /** | ||
// TODO if(x.compareTo(q) >= 0) error | ||
this.q = q; | ||
this.p = q; | ||
} | ||
@@ -38,3 +38,3 @@ | ||
} | ||
return (this.q.equals(other.q) && this.x.equals(other.x)); | ||
return (this.p.equals(other.p) && this.x.equals(other.x)); | ||
} | ||
@@ -47,23 +47,23 @@ | ||
function feFpNegate() { | ||
return new ECFieldElementFp(this.q, this.x.negate().mod(this.q)); | ||
return new ECFieldElementFp(this.p, this.x.negate().mod(this.p)); | ||
} | ||
function feFpAdd(b) { | ||
return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); | ||
return new ECFieldElementFp(this.p, this.x.add(b.toBigInteger()).mod(this.p)); | ||
} | ||
function feFpSubtract(b) { | ||
return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); | ||
return new ECFieldElementFp(this.p, this.x.subtract(b.toBigInteger()).mod(this.p)); | ||
} | ||
function feFpMultiply(b) { | ||
return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); | ||
return new ECFieldElementFp(this.p, this.x.multiply(b.toBigInteger()).mod(this.p)); | ||
} | ||
function feFpSquare() { | ||
return new ECFieldElementFp(this.q, this.x.square().mod(this.q)); | ||
return new ECFieldElementFp(this.p, this.x.square().mod(this.p)); | ||
} | ||
function feFpDivide(b) { | ||
return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); | ||
return new ECFieldElementFp(this.p, this.x.multiply(b.toBigInteger().modInverse(this.p)).mod(this.p)); | ||
} | ||
@@ -101,3 +101,3 @@ | ||
if(!this.zinv) { | ||
this.zinv = this.z.modInverse(this.curve.q); | ||
this.zinv = this.z.modInverse(this.curve.p); | ||
} | ||
@@ -111,3 +111,3 @@ var r = this.x.toBigInteger().multiply(this.zinv); | ||
if(!this.zinv) { | ||
this.zinv = this.z.modInverse(this.curve.q); | ||
this.zinv = this.z.modInverse(this.curve.p); | ||
} | ||
@@ -131,3 +131,3 @@ var r = this.y.toBigInteger().multiply(this.zinv); | ||
// u = Y2 * Z1 - Y1 * Z2 | ||
u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); | ||
u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.p); | ||
if (!u.equals(BigInteger.ZERO)) { | ||
@@ -137,3 +137,3 @@ return false; | ||
// v = X2 * Z1 - X1 * Z2 | ||
v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); | ||
v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.p); | ||
return v.equals(BigInteger.ZERO); | ||
@@ -162,5 +162,5 @@ } | ||
// u = Y2 * Z1 - Y1 * Z2 | ||
var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); | ||
var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.p); | ||
// v = X2 * Z1 - X1 * Z2 | ||
var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); | ||
var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.p); | ||
@@ -184,7 +184,7 @@ if (BigInteger.ZERO.equals(v)) { | ||
// x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) | ||
var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); | ||
var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.p); | ||
// y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 | ||
var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); | ||
var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.p); | ||
// z3 = v^3 * z1 * z2 | ||
var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); | ||
var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.p); | ||
@@ -208,3 +208,3 @@ return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); | ||
var y1z1 = y1.multiply(this.z); | ||
var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); | ||
var y1sqz1 = y1z1.multiply(y1).mod(this.curve.p); | ||
var a = this.curve.a.toBigInteger(); | ||
@@ -217,10 +217,10 @@ | ||
} | ||
w = w.mod(this.curve.q); | ||
w = w.mod(this.curve.p); | ||
//this.curve.reduce(w); | ||
// x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) | ||
var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); | ||
var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.p); | ||
// y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 | ||
var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); | ||
var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.p); | ||
// z3 = 8 * (y1 * z1)^3 | ||
var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); | ||
var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.p); | ||
@@ -307,12 +307,12 @@ return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); | ||
// constructor | ||
function ECCurveFp(q, a, b) { | ||
this.q = q; | ||
function ECCurveFp(p, a, b) { | ||
this.p = p; | ||
this.a = this.fromBigInteger(a); | ||
this.b = this.fromBigInteger(b); | ||
this.infinity = new ECPointFp(this, null, null); | ||
this.reducer = new Barrett(this.q); | ||
this.reducer = new Barrett(this.p); | ||
} | ||
function curveFpGetQ() { | ||
return this.q; | ||
function curveFpgetP() { | ||
return this.p; | ||
} | ||
@@ -332,5 +332,19 @@ | ||
} | ||
return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); | ||
return (this.p.equals(other.p) && this.a.equals(other.a) && this.b.equals(other.b)); | ||
} | ||
function curveFpContains(pt) { | ||
// y^2 = x^3 + a*x + b mod p | ||
var x = pt.getX().toBigInteger(), | ||
y = pt.getY().toBigInteger(), | ||
a = this.a.toBigInteger(), | ||
b = this.b.toBigInteger(), | ||
p = this.p; | ||
var left = y.pow(2).mod(p), | ||
right = x.pow(3).add(a.multiply(x)).add(b).mod(p) | ||
return left.equals(right); | ||
} | ||
function curveFpGetInfinity() { | ||
@@ -341,3 +355,3 @@ return this.infinity; | ||
function curveFpFromBigInteger(x) { | ||
return new ECFieldElementFp(this.q, x); | ||
return new ECFieldElementFp(this.p, x); | ||
} | ||
@@ -381,3 +395,3 @@ | ||
var yHex = p.getY().toBigInteger().toString(16); | ||
var oLen = this.getQ().toString(16).length; | ||
var oLen = this.getP().toString(16).length; | ||
if ((oLen % 2) !== 0) { | ||
@@ -395,6 +409,7 @@ oLen++; | ||
ECCurveFp.prototype.getQ = curveFpGetQ; | ||
ECCurveFp.prototype.getP = curveFpgetP; | ||
ECCurveFp.prototype.getA = curveFpGetA; | ||
ECCurveFp.prototype.getB = curveFpGetB; | ||
ECCurveFp.prototype.equals = curveFpEquals; | ||
ECCurveFp.prototype.contains = curveFpContains; | ||
ECCurveFp.prototype.getInfinity = curveFpGetInfinity; | ||
@@ -401,0 +416,0 @@ ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger; |
{ | ||
"name": "node-jose", | ||
"version": "0.9.2", | ||
"version": "0.9.3", | ||
"description": "A JavaScript implementation of the JSON Object Signing and Encryption (JOSE) for current web browsers and node.js-based servers", | ||
@@ -29,4 +29,4 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"es6-promise": "^3.1.2", | ||
"jsbn": "^0.1.0", | ||
"es6-promise": "^4.0.5", | ||
"jsbn": "^1.1.0", | ||
"lodash.assign": "^4.0.8", | ||
@@ -45,3 +45,3 @@ "lodash.clone": "^4.3.2", | ||
"urlsafe-base64": "https://github.com/linuxwolf/urlsafe-base64/archive/encoding.tar.gz", | ||
"uuid": "^2.0.1" | ||
"uuid": "^3.0.1" | ||
}, | ||
@@ -54,7 +54,7 @@ "devDependencies": { | ||
"gulp": "^3.8.10", | ||
"gulp-eslint": "^2.0.0", | ||
"gulp-istanbul": "^0.10.4", | ||
"gulp-mocha": "^2.0.0", | ||
"gulp-eslint": "^3.0.1", | ||
"gulp-istanbul": "^1.1.1", | ||
"gulp-mocha": "^4.0.0", | ||
"gulp-rename": "^1.2.0", | ||
"gulp-uglify": "^1.1.0", | ||
"gulp-uglify": "^2.0.1", | ||
"gulp-util": "^3.0.7", | ||
@@ -65,20 +65,20 @@ "istanbul": "^0.4.0", | ||
"karma": "^1.2.0", | ||
"karma-chrome-launcher": "^0.2.3", | ||
"karma-coverage": "^0.5.3", | ||
"karma-firefox-launcher": "^0.1.4", | ||
"karma-ie-launcher": "^0.2.0", | ||
"karma-mocha": "^0.2.2", | ||
"karma-chrome-launcher": "^2.0.0", | ||
"karma-coverage": "^1.1.1", | ||
"karma-firefox-launcher": "^1.0.0", | ||
"karma-ie-launcher": "^1.0.0", | ||
"karma-mocha": "^1.3.0", | ||
"karma-mocha-reporter": "^2.0.0", | ||
"karma-safari-launcher": "^0.1.1", | ||
"karma-sauce-launcher": "^0.3.1", | ||
"karma-webpack": "^1.8.0", | ||
"karma-safari-launcher": "^1.0.0", | ||
"karma-sauce-launcher": "^1.1.0", | ||
"karma-webpack": "^2.0.2", | ||
"lodash.bind": "^4.1.3", | ||
"lodash.clonedeep": "^4.3.2", | ||
"lodash.foreach": "^4.2.0", | ||
"mocha": "^2.1.0", | ||
"mocha": "^3.2.0", | ||
"run-sequence": "^1.0.2", | ||
"watchify": "^3.7.0", | ||
"webpack": "^1.13.2", | ||
"webpack": "^2.2.1", | ||
"webpack-stream": "^3.2.0", | ||
"yargs": "^4.6.0" | ||
"yargs": "^6.6.0" | ||
}, | ||
@@ -85,0 +85,0 @@ "browser": { |
# node-jose # | ||
[![Greenkeeper badge](https://badges.greenkeeper.io/cisco/node-jose.svg)](https://greenkeeper.io/) | ||
A JavaScript implementation of the JSON Object Signing and Encryption (JOSE) for current web browsers and node.js-based servers. This library implements (wherever possible) all algorithms, formats, and options in [JWS](https://tools.ietf.org/html/rfc7515 "Jones, M., J. Bradley and N. Sakimura, 'JSON Web Signature (JWS)' RFC 7515, May 2015"), [JWE](https://tools.ietf.org/html/rfc7516 "Jones, M. and J. Hildebrand 'JSON Web Encryption (JWE)', RFC 7516, May 2015"), [JWK](https://tools.ietf/html/rfc7517 "Jones, M., 'JSON Web Key (JWK)', RFC 7517, May 2015"), and [JWA](https://tools.ietf/html/rfc7518 "Jones, M., 'JSON Web Algorithms (JWA)', RFC 7518, May 2015") and uses native cryptographic support ([WebCrypto API](http://www.w3.org/TR/WebCryptoAPI/) or node.js' "[crypto](https://nodejs.org/api/crypto.html)" module) where feasible. | ||
@@ -62,5 +64,5 @@ | ||
This library supports [Browserify](http://browserify.org/). To use in a web browser, `require('node-jose')` and bundle with the rest of your app. | ||
This library supports [Browserify](http://browserify.org/) and [Webpack](https://webpack.github.io/). To use in a web browser, `require('node-jose')` and bundle with the rest of your app. | ||
The content to be signed/encrypted or returned from being verified/decrypted are [Buffer](https://nodejs.org/api/buffer.html) objects. | ||
The content to be signed/encrypted -- or returned from being verified/decrypted -- are [Buffer](https://nodejs.org/api/buffer.html) objects. | ||
@@ -67,0 +69,0 @@ ## Keys and Key Stores ## |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
313671
9184
699
+ Addedes6-promise@4.2.8(transitive)
+ Addedjsbn@1.1.0(transitive)
+ Addeduuid@3.4.0(transitive)
- Removedes6-promise@3.3.1(transitive)
- Removedjsbn@0.1.1(transitive)
- Removeduuid@2.0.3(transitive)
Updatedes6-promise@^4.0.5
Updatedjsbn@^1.1.0
Updateduuid@^3.0.1