Comparing version 0.9.3 to 0.9.4
@@ -0,1 +1,24 @@ | ||
# Release Notes | ||
<a name="0.9.4"></a> | ||
## [0.9.4](https://github.com/cisco/node-jose/compare/0.9.3...0.9.4) (2017-04-13) | ||
### Update | ||
* Use native RSA/OpenSSL crypto whenever possible ([0d1a8cdc351988d74ac42398c3d973902db3d808](https://github.com/cisco/node-jose/commit/0d1a8cdc351988d74ac42398c3d973902db3d808)) | ||
* use npm-published base64url implementation ([c6b30c91502ffef9b9d3addc8bdb1b8b0cc36e69](https://github.com/cisco/node-jose/commit/c6b30c91502ffef9b9d3addc8bdb1b8b0cc36e69)), closes [#96](https://github.com/cisco/node-jose/issues/96) | ||
* use npm-published node-forge implementation ([0f4e0ab57839eaf6dd40c46be511afe3aec9ca44](https://github.com/cisco/node-jose/commit/0f4e0ab57839eaf6dd40c46be511afe3aec9ca44)), closes [#96](https://github.com/cisco/node-jose/issues/96) * Use WebCrypto API for PBKDF2 ([5e5b9d376f334fa50bb69331e3065e2011c8e9c7](https://github.com/cisco/node-jose/commit/5e5b9d376f334fa50bb69331e3065e2011c8e9c7)) | ||
### Build | ||
* sourcemaps for karma tests ([a571bd107d87df12bd9f076ade2a875c01b4b24d](https://github.com/cisco/node-jose/commit/a571bd107d87df12bd9f076ade2a875c01b4b24d)) | ||
* update karma-firefox-launcher to version 1.0.1 ([84f5f531783e4e50674532fa5c809dff4e6dc25c](https://github.com/cisco/node-jose/commit/84f5f531783e4e50674532fa5c809dff4e6dc25c)) | ||
* update travis-ci for newer environments ([55b91bb0b4bb158d9275dfc89c1de688e14163ed](https://github.com/cisco/node-jose/commit/55b91bb0b4bb158d9275dfc89c1de688e14163ed)) | ||
* update yargs to version 7.0.1 ([af24f9e951b1078a088caf50acc13296c0076f68](https://github.com/cisco/node-jose/commit/af24f9e951b1078a088caf50acc13296c0076f68)) | ||
### Doc | ||
* Fix wrong links to JWA and JWK specifications ([538829dd4af480989422efec20a2c60f809d8d5c](https://github.com/cisco/node-jose/commit/538829dd4af480989422efec20a2c60f809d8d5c)), closes [#102](https://github.com/cisco/node-jose/issues/102) | ||
<a name="0.9.3"></a> | ||
@@ -25,4 +48,2 @@ ## [0.9.3](https://github.com/cisco/node-jose/compare/0.9.2...v0.9.3) (2017-02-20) | ||
# Release Notes | ||
<a name="0.9.2"></a> | ||
@@ -29,0 +50,0 @@ ## [0.9.2](https://github.com/cisco/node-jose/compare/0.9.1...0.9.2) (2016-12-29) |
@@ -73,5 +73,60 @@ /*! | ||
// NOTE: WebCrypto API missing until there's better support | ||
var webcrypto = null; | ||
var webcrypto = function(key, pdata, props) { | ||
var salt = util.asBuffer(props.p2s || new Buffer(0), "base64url"), | ||
itrs = props.p2c || 0; | ||
if (0 >= itrs) { | ||
return Promise.reject(new Error("invalid iteration count")); | ||
} | ||
if (8 > salt.length) { | ||
return Promise.reject(new Error("salt too small")); | ||
} | ||
salt = fixSalt(hmac, kw, salt); | ||
var promise; | ||
// STEP 1: derive shared key | ||
var hash = hmac.replace("HS", "SHA-"); | ||
promise = Promise.resolve(key); | ||
promise = promise.then(function(keyval) { | ||
return helpers.subtleCrypto.importKey("raw", keyval, "PBKDF2", false, ["deriveKey"]); | ||
}); | ||
promise = promise.then(function(key) { | ||
var mainAlgo = { | ||
name: "PBKDF2", | ||
salt: salt, | ||
iterations: itrs, | ||
hash: hash | ||
}; | ||
var deriveAlgo = { | ||
name: "AES-KW", | ||
length: keyLen * 8 | ||
}; | ||
return helpers.subtleCrypto.deriveKey(mainAlgo, key, deriveAlgo, true, ["wrapKey", "unwrapKey"]); | ||
}); | ||
// STEP 2: encrypt cek | ||
promise = promise.then(function(dk) { | ||
// assume subtleCrypto for keywrap | ||
return Promise.all([ | ||
helpers.subtleCrypto.importKey("raw", pdata, { name: "HMAC", hash: "SHA-256" }, true, ["sign"]), | ||
dk | ||
]); | ||
}); | ||
promise = promise.then(function(keys) { | ||
return helpers.subtleCrypto.wrapKey("raw", | ||
keys[0], // key | ||
keys[1], // wrappingKey | ||
"AES-KW"); | ||
}); | ||
promise = promise.then(function(result) { | ||
result = new Buffer(result); | ||
return { | ||
data: result | ||
}; | ||
}); | ||
return promise; | ||
}; | ||
var nodejs = function(key, pdata, props) { | ||
@@ -169,5 +224,52 @@ if (6 > helpers.nodeCrypto.pbkdf2.length) { | ||
// NOTE: WebCrypto API missing until there's better support | ||
var webcrypto = null; | ||
var webcrypto = function(key, cdata, props) { | ||
props = props || {}; | ||
var salt = util.asBuffer(props.p2s || new Buffer(0), "base64url"), | ||
itrs = props.p2c || 0; | ||
if (0 >= itrs) { | ||
return Promise.reject(new Error("invalid iteration count")); | ||
} | ||
if (8 > salt.length) { | ||
return Promise.reject(new Error("salt too small")); | ||
} | ||
salt = fixSalt(hmac, kw, salt); | ||
var hash = hmac.replace("HS", "SHA-"); | ||
var promise; | ||
promise = Promise.resolve(key); | ||
promise = promise.then(function(keyval) { | ||
return helpers.subtleCrypto.importKey("raw", keyval, "PBKDF2", false, ["deriveKey"]); | ||
}); | ||
promise = promise.then(function(key) { | ||
var mainAlgo = { | ||
name: "PBKDF2", | ||
salt: salt, | ||
iterations: itrs, | ||
hash: hash | ||
}; | ||
var deriveAlgo = { | ||
name: "AES-KW", | ||
length: keyLen * 8 | ||
}; | ||
return helpers.subtleCrypto.deriveKey(mainAlgo, key, deriveAlgo, true, ["wrapKey", "unwrapKey"]); | ||
}); | ||
// STEP 2: decrypt cek | ||
promise = promise.then(function(key) { | ||
return helpers.subtleCrypto.unwrapKey("raw", cdata, key, "AES-KW", {name: "HMAC", hash: "SHA-256"}, true, ["sign"]); | ||
}); | ||
promise = promise.then(function(result) { | ||
// unwrapped CryptoKey -- extract raw | ||
return helpers.subtleCrypto.exportKey("raw", result); | ||
}); | ||
promise = promise.then(function(result) { | ||
result = new Buffer(result); | ||
return result; | ||
}); | ||
return promise; | ||
}; | ||
var nodejs = function(key, cdata, props) { | ||
@@ -174,0 +276,0 @@ if (6 > helpers.nodeCrypto.pbkdf2.length) { |
@@ -26,2 +26,3 @@ /*! | ||
} | ||
function convertToJWK(key, isPublic) { | ||
@@ -53,5 +54,22 @@ var result = clone(key); | ||
function convertToPem(key, isPublic) { | ||
if (key.__cachedPem) { | ||
return key.__cachedPem; | ||
} | ||
var value; | ||
if (isPublic) { | ||
value = forge.pki.publicKeyToPem(convertToForge(key, isPublic)); | ||
} else { | ||
value = forge.pki.privateKeyToPem(convertToForge(key, isPublic)); | ||
} | ||
Object.defineProperty(key, '__cachedPem', { value: value }); | ||
return value; | ||
} | ||
module.exports = { | ||
convertToForge: convertToForge, | ||
convertToJWK: convertToJWK | ||
convertToJWK: convertToJWK, | ||
convertToPem: convertToPem | ||
}; |
@@ -141,3 +141,11 @@ /*! | ||
return helpers.setupFallback(null, webcrypto, fallback); | ||
var nodejs; | ||
if (helpers.nodeCrypto && name === "RSA-OAEP") { // node only support SHA1, plain RSA-OAEP | ||
nodejs = function(key, pdata) { | ||
key = rsaUtil.convertToPem(key, false); | ||
return helpers.nodeCrypto.privateDecrypt(key, pdata); | ||
}; | ||
} | ||
return helpers.setupFallback(nodejs, webcrypto, fallback); | ||
} | ||
@@ -144,0 +152,0 @@ |
@@ -63,3 +63,17 @@ /*! | ||
return helpers.setupFallback(null, webcrypto, fallback); | ||
var nodejs; | ||
if (helpers.nodeCrypto && helpers.nodeCrypto.getHashes().indexOf(hash) > -1) { | ||
nodejs = function(key, pdata) { | ||
key = rsaUtil.convertToPem(key, false); | ||
var sign = helpers.nodeCrypto.createSign(hash); | ||
sign.update(pdata); | ||
return { | ||
data: pdata, | ||
mac: sign.sign(rsaUtil.convertToPem(key, false)) | ||
}; | ||
}; | ||
} | ||
return helpers.setupFallback(nodejs, webcrypto, fallback); | ||
} | ||
@@ -122,3 +136,22 @@ | ||
return helpers.setupFallback(null, webcrypto, fallback); | ||
var nodejs; | ||
if (helpers.nodeCrypto && helpers.nodeCrypto.getHashes().indexOf(md) > -1) { | ||
nodejs = function(key, pdata, mac) { | ||
var verify = helpers.nodeCrypto.createVerify(md); | ||
verify.update(pdata); | ||
verify.end(); | ||
var result = verify.verify(rsaUtil.convertToPem(key, true), mac); | ||
if (!result) { | ||
return Promise.reject(new Error("verification failed")); | ||
} | ||
return { | ||
data: pdata, | ||
mac: mac, | ||
valid: true, | ||
}; | ||
}; | ||
} | ||
return helpers.setupFallback(nodejs, webcrypto, fallback); | ||
} | ||
@@ -125,0 +158,0 @@ |
@@ -15,3 +15,3 @@ /** | ||
var BigInteger = require("jsbn").BigInteger, | ||
var BigInteger = require("../../deps/forge").jsbn.BigInteger, | ||
ec = require("./math.js"); | ||
@@ -18,0 +18,0 @@ |
@@ -9,3 +9,3 @@ /** | ||
var forge = require("../../deps/forge"), | ||
BigInteger = require("jsbn").BigInteger, | ||
BigInteger = forge.jsbn.BigInteger, | ||
ec = require("./math.js"), | ||
@@ -12,0 +12,0 @@ CURVES = require("./curves.js"); |
@@ -17,9 +17,56 @@ /** | ||
// Requires jsbn.js and jsbn2.js | ||
var jsbn = require("jsbn"); | ||
var BigInteger = require("../../deps/forge").jsbn.BigInteger; | ||
var BigInteger = jsbn.BigInteger, | ||
Barrett = BigInteger.prototype.Barrett; | ||
// ---------------- | ||
// Helpers | ||
function nbi() { | ||
return new BigInteger(null); | ||
} | ||
// ---------------- | ||
// Barrett modular reduction | ||
// constructor | ||
function Barrett(m) { | ||
// setup Barrett | ||
this.r2 = nbi(); | ||
this.q3 = nbi(); | ||
BigInteger.ONE.dlShiftTo(2*m.t,this.r2); | ||
this.mu = this.r2.divide(m); | ||
this.m = m; | ||
} | ||
function barrettConvert(x) { | ||
if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); | ||
else if(x.compareTo(this.m) < 0) return x; | ||
else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } | ||
} | ||
function barrettRevert(x) { return x; } | ||
// x = x mod m (HAC 14.42) | ||
function barrettReduce(x) { | ||
x.drShiftTo(this.m.t-1,this.r2); | ||
if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } | ||
this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); | ||
this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); | ||
while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); | ||
x.subTo(this.r2,x); | ||
while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); | ||
} | ||
// r = x^2 mod m; x != r | ||
function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } | ||
// r = x*y mod m; x,y != r | ||
function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } | ||
Barrett.prototype.convert = barrettConvert; | ||
Barrett.prototype.revert = barrettRevert; | ||
Barrett.prototype.reduce = barrettReduce; | ||
Barrett.prototype.mulTo = barrettMulTo; | ||
Barrett.prototype.sqrTo = barrettSqrTo; | ||
// ---------------- | ||
// ECFieldElementFp | ||
@@ -62,3 +109,3 @@ | ||
function feFpSquare() { | ||
return new ECFieldElementFp(this.p, this.x.square().mod(this.p)); | ||
return new ECFieldElementFp(this.p, this.x.pow(2).mod(this.p)); | ||
} | ||
@@ -172,6 +219,6 @@ | ||
var v2 = v.square(); | ||
var v2 = v.pow(2); | ||
var v3 = v2.multiply(v); | ||
var x1v2 = x1.multiply(v2); | ||
var zu2 = u.square().multiply(this.z); | ||
var zu2 = u.pow(2).multiply(this.z); | ||
@@ -206,5 +253,5 @@ // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) | ||
// w = 3 * x1^2 + a * z1^2 | ||
var w = x1.square().multiply(THREE); | ||
var w = x1.pow(2).multiply(THREE); | ||
if (!BigInteger.ZERO.equals(a)) { | ||
w = w.add(this.z.square().multiply(a)); | ||
w = w.add(this.z.pow(2).multiply(a)); | ||
} | ||
@@ -214,7 +261,7 @@ w = w.mod(this.curve.p); | ||
// 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.p); | ||
var x3 = w.pow(2).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.p); | ||
var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.pow(2).multiply(w)).mod(this.curve.p); | ||
// z3 = 8 * (y1 * z1)^3 | ||
var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.p); | ||
var z3 = y1z1.pow(2).multiply(y1z1).shiftLeft(3).mod(this.curve.p); | ||
@@ -221,0 +268,0 @@ return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); |
@@ -8,34 +8,22 @@ /*! | ||
var forge = { | ||
aes: require("node-forge/js/aes"), | ||
asn1: require("node-forge/js/asn1"), | ||
cipher: require("node-forge/js/cipher"), | ||
hmac: require("node-forge/js/hmac"), | ||
jsbn: require("node-forge/js/jsbn"), | ||
md: require("node-forge/js/md"), | ||
mgf: require("node-forge/js/mgf"), | ||
pem: require("node-forge/js/pem"), | ||
pkcs1: require("node-forge/js/pkcs1"), | ||
pkcs5: require("node-forge/js/pkcs5"), | ||
pkcs7: require("node-forge/js/pkcs7"), | ||
pki: require("node-forge/js/x509"), | ||
prime: require("node-forge/js/prime"), | ||
prng: require("node-forge/js/prng"), | ||
pss: require("node-forge/js/pss"), | ||
random: require("node-forge/js/random"), | ||
util: require("node-forge/js/util") | ||
}; | ||
var forge = require("node-forge/lib/forge"); | ||
require("node-forge/lib/aes"); | ||
require("node-forge/lib/asn1"); | ||
require("node-forge/lib/cipher"); | ||
require("node-forge/lib/hmac"); | ||
require("node-forge/lib/mgf1"); | ||
require("node-forge/lib/pbkdf2"); | ||
require("node-forge/lib/pem"); | ||
require("node-forge/lib/pkcs1"); | ||
require("node-forge/lib/pkcs7"); | ||
require("node-forge/lib/pki"); | ||
require("node-forge/lib/prime"); | ||
require("node-forge/lib/prng"); | ||
require("node-forge/lib/pss"); | ||
require("node-forge/lib/random"); | ||
require("node-forge/lib/sha1"); | ||
require("node-forge/lib/sha256"); | ||
require("node-forge/lib/sha512"); | ||
require("node-forge/lib/util"); | ||
// load hash algorithms | ||
require("node-forge/js/sha1"); | ||
require("node-forge/js/sha256"); | ||
require("node-forge/js/sha512"); | ||
// load symmetric cipherModes | ||
require("node-forge/js/cipherModes"); | ||
// load AES cipher suites | ||
// TODO: move this to a separate file | ||
require("node-forge/js/aesCipherSuites"); | ||
// Define AES "raw" cipher mode | ||
@@ -54,3 +42,7 @@ function modeRaw(options) { | ||
modeRaw.prototype.encrypt = function(input, output) { | ||
modeRaw.prototype.encrypt = function(input, output, finish) { | ||
if(input.length() < this.blockSize && !(finish && input.length() > 0)) { | ||
return true; | ||
} | ||
var i; | ||
@@ -72,3 +64,7 @@ | ||
modeRaw.prototype.decrypt = function(input, output) { | ||
modeRaw.prototype.decrypt = function(input, output, finish) { | ||
if(input.length() < this.blockSize && !(finish && input.length() > 0)) { | ||
return true; | ||
} | ||
var i; | ||
@@ -75,0 +71,0 @@ |
@@ -8,3 +8,3 @@ /*! | ||
var impl = require("urlsafe-base64"); | ||
var impl = require("base64url"); | ||
@@ -29,3 +29,13 @@ /** | ||
*/ | ||
encode: impl.encode, | ||
encode: function encode(buffer, encoding) { | ||
if (buffer instanceof ArrayBuffer) { | ||
buffer = new Uint8Array(buffer); | ||
} | ||
if (!Buffer.isBuffer(buffer)) { | ||
buffer = new Buffer(buffer, encoding); | ||
} | ||
return impl.encode(buffer); | ||
}, | ||
/** | ||
@@ -38,5 +48,5 @@ * @function | ||
*/ | ||
decode: impl.decode | ||
decode: impl.toBuffer | ||
}; | ||
module.exports = base64url; |
{ | ||
"name": "node-jose", | ||
"version": "0.9.3", | ||
"version": "0.9.4", | ||
"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": { | ||
"base64url": "^2.0.0", | ||
"es6-promise": "^4.0.5", | ||
"jsbn": "^1.1.0", | ||
"lodash.assign": "^4.0.8", | ||
@@ -43,4 +43,3 @@ "lodash.clone": "^4.3.2", | ||
"long": "^3.1.0", | ||
"node-forge": "https://github.com/linuxwolf/forge/archive/browserify.tar.gz", | ||
"urlsafe-base64": "https://github.com/linuxwolf/urlsafe-base64/archive/encoding.tar.gz", | ||
"node-forge": "^0.7.1", | ||
"uuid": "^3.0.1" | ||
@@ -66,3 +65,3 @@ }, | ||
"karma-coverage": "^1.1.1", | ||
"karma-firefox-launcher": "^1.0.0", | ||
"karma-firefox-launcher": "^1.0.1", | ||
"karma-ie-launcher": "^1.0.0", | ||
@@ -73,2 +72,3 @@ "karma-mocha": "^1.3.0", | ||
"karma-sauce-launcher": "^1.1.0", | ||
"karma-sourcemap-loader": "^0.3.7", | ||
"karma-webpack": "^2.0.2", | ||
@@ -83,3 +83,3 @@ "lodash.bind": "^4.1.3", | ||
"webpack-stream": "^3.2.0", | ||
"yargs": "^6.6.0" | ||
"yargs": "^7.0.1" | ||
}, | ||
@@ -86,0 +86,0 @@ "browser": { |
@@ -5,3 +5,3 @@ # node-jose # | ||
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. | ||
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.org/html/rfc7517 "Jones, M., 'JSON Web Key (JWK)', RFC 7517, May 2015"), and [JWA](https://tools.ietf.org/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. | ||
@@ -8,0 +8,0 @@ <!-- START doctoc generated TOC please keep comment here to allow auto update --> |
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
HTTP dependency
Supply chain riskContains a dependency which resolves to a remote HTTP URL which could be used to inject untrusted code and reduce overall package reliability.
Found 2 instances in 1 package
321383
15
9369
0
34
+ Addedbase64url@^2.0.0
+ Addedbase64url@2.0.0(transitive)
+ Addednode-forge@0.7.6(transitive)
- Removedjsbn@^1.1.0
- Removedurlsafe-base64@https://github.com/linuxwolf/urlsafe-base64/archive/encoding.tar.gz
- Removedjsbn@1.1.0(transitive)
Updatednode-forge@^0.7.1