Comparing version 0.10.0 to 0.11.0
@@ -0,1 +1,17 @@ | ||
<a name="0.11.0"></a> | ||
# [0.11.0](https://github.com/cisco/node-jose/compare/0.10.0...0.11.0) (2017-11-30) | ||
**NOTICE** This release includes a potentially breaking change. The default of `jose.JWS.Verifier.verify()` before `0.11.0` was to successfully verify if an embedded key was present and verification succeeds. Now the default is to instead fail verification. Applications that rely on embedded keys for JWS verification now must provide an `opts` Object to either `jose.JWS.createVerify()` or `jose.JWS.Verifier.verify()`, with the member `allowEmbeddedKeys` set to `true`. | ||
### Update | ||
* configure if embedded keys can be used for signature verification; contributed by Fraser Winterborn of BlackBerry's Security Research Group ([959a61d707ed2c8cf6582139a5605119283e4acb](https://github.com/cisco/node-jose/commit/959a61d707ed2c8cf6582139a5605119283e4acb)) | ||
* configure option for allowed algorithm ([9a86dd6dac3687ab58c806dfed6deca5a7d73dbb](https://github.com/cisco/node-jose/commit/9a86dd6dac3687ab58c806dfed6deca5a7d73dbb)) | ||
### Doc | ||
* Enable syntax highlighting on code areas in README ([be18233154544cd160c185077cfaf77abea27507](https://github.com/cisco/node-jose/commit/be18233154544cd160c185077cfaf77abea27507)) | ||
<a name="0.10.0"></a> | ||
@@ -2,0 +18,0 @@ # [0.10.0](https://github.com/cisco/node-jose/compare/0.9.5...0.10.0) (2017-09-29) |
@@ -9,2 +9,3 @@ /*! | ||
var base64url = require("../util/base64url"), | ||
AlgConfig = require("../util/algconfig"), | ||
JWK = require("../jwk"), | ||
@@ -14,2 +15,6 @@ merge = require("../util/merge"), | ||
var DEFAULT_OPTIONS = { | ||
algorithms: "*" | ||
}; | ||
/** | ||
@@ -36,3 +41,3 @@ * @class JWE.Decrypter | ||
globalOpts = merge({}, globalOpts); | ||
globalOpts = merge(DEFAULT_OPTIONS, globalOpts); | ||
@@ -65,2 +70,3 @@ /** | ||
var handlerKeys = Object.keys(extraHandlers); | ||
var algSpec = new AlgConfig(opts.algorithms); | ||
@@ -135,2 +141,15 @@ /* eslint camelcase: [0] */ | ||
r.protected = protect; | ||
// check on allowed algorithms | ||
if (!algSpec.match(header.alg)) { | ||
promise = promise.then(function() { | ||
return Promise.reject(new Error("Algorithm not allowed: " + header.alg)); | ||
}); | ||
} | ||
if (!algSpec.match(header.enc)) { | ||
promise = promise.then(function () { | ||
return Promise.reject(new Error("Algorithm not allowed: " + header.enc)); | ||
}); | ||
} | ||
if (header.epk) { | ||
@@ -137,0 +156,0 @@ promise = promise.then(function() { |
@@ -11,4 +11,10 @@ /*! | ||
base64url = require("../util/base64url"), | ||
AlgConfig = require("../util/algconfig"), | ||
JWK = require("../jwk"); | ||
var DEFAULT_OPTIONS = { | ||
algorithms: "*", | ||
allowEmbeddedKey: false | ||
}; | ||
/** | ||
@@ -35,3 +41,3 @@ * @class JWS.Verifier | ||
globalOpts = merge({}, globalOpts); | ||
globalOpts = merge(DEFAULT_OPTIONS, globalOpts); | ||
@@ -52,2 +58,3 @@ Object.defineProperty(this, "defaultKey", { | ||
var handlerKeys = Object.keys(extraHandlers); | ||
var algSpec = new AlgConfig(opts.algorithms); | ||
@@ -92,2 +99,7 @@ if ("string" === typeof input) { | ||
// process allowed algorithims | ||
if (!algSpec.match(header.alg)) { | ||
return Promise.reject(new Error("Algorithm not allowed: " + header.alg)); | ||
} | ||
// process "crit" first | ||
@@ -135,5 +147,5 @@ var crit = protect.crit; | ||
// TODO: resolve jku, x5c, x5u | ||
if (sig.header.jwk) { | ||
if (opts.allowEmbeddedKey && sig.header.jwk) { | ||
algKey = JWK.asKey(sig.header.jwk); | ||
} else if (sig.header.x5c) { | ||
} else if (opts.allowEmbeddedKey && sig.header.x5c) { | ||
algKey = sig.header.x5c[0]; | ||
@@ -255,4 +267,4 @@ algKey = new Buffer(algKey, "base64"); | ||
*/ | ||
function createVerify(ks) { | ||
var vfy = new JWSVerifier(ks); | ||
function createVerify(ks, opts) { | ||
var vfy = new JWSVerifier(ks, opts); | ||
@@ -259,0 +271,0 @@ return vfy; |
@@ -22,5 +22,5 @@ /*! | ||
type = "JWS"; | ||
op = function(ks) { | ||
op = function(ks, opts) { | ||
return jose.JWS.createVerify(ks). | ||
verify(input); | ||
verify(input, opts); | ||
}; | ||
@@ -30,5 +30,5 @@ } else if (5 === parts.length) { | ||
type = "JWE"; | ||
op = function(ks) { | ||
op = function(ks, opts) { | ||
return jose.JWE.createDecrypt(ks). | ||
decrypt(input); | ||
decrypt(input, opts); | ||
}; | ||
@@ -35,0 +35,0 @@ } else { |
@@ -24,5 +24,5 @@ /*! | ||
type = "JWS"; | ||
op = function(ks) { | ||
op = function(ks, opts) { | ||
return jose.JWS.createVerify(ks). | ||
verify(input); | ||
verify(input, opts); | ||
}; | ||
@@ -55,5 +55,5 @@ // headers can be (signatures[].protected, signatures[].header, signature.protected, signature.header) | ||
type = "JWE"; | ||
op = function(ks) { | ||
op = function(ks, opts) { | ||
return jose.JWE.createDecrypt(ks). | ||
decrypt(input); | ||
decrypt(input, opts); | ||
}; | ||
@@ -60,0 +60,0 @@ // headers can be (protected, unprotected, recipients[].header) |
{ | ||
"name": "node-jose", | ||
"version": "0.10.0", | ||
"version": "0.11.0", | ||
"description": "A JavaScript implementation of the JSON Object Signing and Encryption (JOSE) for current web browsers and node.js-based servers", | ||
@@ -46,3 +46,3 @@ "main": "lib/index.js", | ||
"devDependencies": { | ||
"browserify-istanbul": "^2.0.0", | ||
"browserify-istanbul": "^3.0.0", | ||
"chai": "^4.0.1", | ||
@@ -75,3 +75,3 @@ "conventional-changelog": "^1.1.0", | ||
"lodash.foreach": "^4.2.0", | ||
"mocha": "^3.2.0", | ||
"mocha": "^4.0.0", | ||
"run-sequence": "^2.0.0", | ||
@@ -81,3 +81,3 @@ "watchify": "^3.7.0", | ||
"webpack-stream": "^4.0.0", | ||
"yargs": "^9.0.1" | ||
"yargs": "^10.0.3" | ||
}, | ||
@@ -84,0 +84,0 @@ "browser": { |
185
README.md
@@ -26,2 +26,3 @@ # node-jose # | ||
- [Verifying a JWS](#verifying-a-jws) | ||
- [Allowing (or Disallowing) Signature Algorithms](#allowing-or-disallowing-signature-algorithms) | ||
- [Handling `crit` Header Members](#handling-crit-header-members) | ||
@@ -32,2 +33,3 @@ - [Encryption](#encryption) | ||
- [Decrypting a JWE](#decrypting-a-jwe) | ||
- [Allowing (or Disallowing) Encryption Algorithms](#allowing-or-disallowing-encryption-algorithms) | ||
- [Handling `crit` Header Members](#handling-crit-header-members-1) | ||
@@ -45,3 +47,3 @@ - [Useful Utilities](#useful-utilities) | ||
``` | ||
```shell | ||
npm install node-jose | ||
@@ -52,3 +54,3 @@ ``` | ||
``` | ||
```shell | ||
npm install node-jose@0.3.0 | ||
@@ -59,3 +61,3 @@ ``` | ||
``` | ||
```shell | ||
npm install git+https://github.com/cisco/node-jose.git | ||
@@ -68,3 +70,3 @@ ``` | ||
``` | ||
```javascript | ||
var jose = require('node-jose'); | ||
@@ -93,3 +95,3 @@ ``` | ||
``` | ||
```javascript | ||
keystore = jose.JWK.createKeyStore(); | ||
@@ -100,3 +102,3 @@ ``` | ||
``` | ||
```javascript | ||
// {input} is a String or JSON object representing the JWK-set | ||
@@ -114,3 +116,3 @@ jose.JWK.asKeyStore(input). | ||
``` | ||
```javascript | ||
output = keystore.toJSON(); | ||
@@ -121,3 +123,3 @@ ``` | ||
``` | ||
```javascript | ||
output = keystore.toJSON(true); | ||
@@ -130,3 +132,3 @@ ``` | ||
``` | ||
```javascript | ||
// by 'kid' | ||
@@ -138,3 +140,3 @@ key = keystore.get(kid); | ||
``` | ||
```javascript | ||
// ... and by 'kty' | ||
@@ -160,3 +162,3 @@ key = keystore.get(kid, { kty: 'RSA' }); | ||
``` | ||
```javascript | ||
everything = keystore.all(); | ||
@@ -167,3 +169,3 @@ ``` | ||
``` | ||
```javascript | ||
// filter by 'kid' | ||
@@ -189,3 +191,3 @@ everything = keystore.all({ kid: kid }); | ||
``` | ||
```javascript | ||
// input is either a: | ||
@@ -203,3 +205,3 @@ // * jose.JWK.Key to copy from; or | ||
``` | ||
```javascript | ||
// input is either a: | ||
@@ -225,3 +227,3 @@ // * String serialization of a JSON JWK/(base64-encoded) PEM/(binary-encoded) DER | ||
``` | ||
```javascript | ||
// first argument is the key type (kty) | ||
@@ -249,3 +251,3 @@ // second is the key size (in bits) or named curve ('crv') for "EC" | ||
To remove a Key from its Keystore: | ||
``` | ||
```javascript | ||
keystore.remove(key); | ||
@@ -259,3 +261,3 @@ // NOTE: key.keystore does not change!! | ||
``` | ||
```javascript | ||
// where input is either a: | ||
@@ -289,3 +291,3 @@ // * jose.JWK.Key instance | ||
``` | ||
```javascript | ||
var output = key.toJSON(); | ||
@@ -296,3 +298,3 @@ ``` | ||
``` | ||
```javascript | ||
var output = key.toJSON(true); | ||
@@ -305,3 +307,3 @@ ``` | ||
``` | ||
```javascript | ||
// where hash is a supported algorithm, currently one of: | ||
@@ -340,3 +342,3 @@ // * SHA-1 | ||
``` | ||
```javascript | ||
// {input} is a Buffer | ||
@@ -355,3 +357,3 @@ jose.JWS.createSign(key). | ||
``` | ||
```javascript | ||
jose.JWS.createSign({ format: 'flattened' }, key). | ||
@@ -373,3 +375,3 @@ update(input). | ||
To create a JWS using a specific algorithm: | ||
``` | ||
```javascript | ||
jose.JWS.createSign({ alg: 'PS256' }, key). | ||
@@ -385,3 +387,3 @@ update(input). | ||
``` | ||
```javascript | ||
jose.JWS.createSign({ fields: { cty: 'jwk+json' } }, key). | ||
@@ -397,3 +399,3 @@ update(input). | ||
``` | ||
```javascript | ||
jose.JWS.createSign(key). | ||
@@ -409,3 +411,3 @@ update(input, "utf8"). | ||
``` | ||
```javascript | ||
// {keys} is an Array of jose.JWK.Key instances | ||
@@ -424,3 +426,3 @@ jose.JWS.createSign(keys). | ||
``` | ||
```javascript | ||
jose.JWS.createVerify(keystore). | ||
@@ -439,3 +441,3 @@ verify(input). | ||
``` | ||
```javascript | ||
// {key} can be: | ||
@@ -453,5 +455,5 @@ // * jose.JWK.Key | ||
``` | ||
```javascript | ||
jose.JWS.createVerify(). | ||
verify(input). | ||
verify(input, { allowEmbeddedKey: true }). | ||
then(function(result) { | ||
@@ -462,6 +464,54 @@ // ... | ||
Alternatively, a cached `createVerify()` can be configured to allow an embedded key: | ||
```javascript | ||
var verifier = jose.JWS.createVerify({ allowEmbeddedKey: true }); | ||
verifier.verify(input). | ||
then(function(result) { | ||
// ... | ||
}); | ||
``` | ||
The key can be embedded using either 'jwk' or 'x5c', and can be located in either the JWS Unprotected Header or JWS Protected Header. | ||
**NOTE:** `verify()` will use the embedded key (if found) instead of any other key. | ||
**NOTE:** `verify()` will use the embedded key (if found and permitted) instead of any other key. | ||
#### Allowing (or Disallowing) Signature Algorithms ### | ||
To restrict what signature algorithms are allowed when verifying, add the `allowAlgs` member to the `options` Object. The `allowAlgs` member is either a string or an array of strings, where the string value(s) can be one of the following: | ||
* `"*"`: accept all supported algorithms | ||
* **`<alg name>`** (e.g., `"PS256"`): accept the specific algorithm (can have a single '*' to match a range of algorithms) | ||
* **`!<alg name>`** (e.g., `"!RS256"`): *do not* accept the specific algorithm (can have a single '*' to match a range of algorithms) | ||
The negation is intended to be used with the wildcard accept string, and disallow takes precedence over allowed. | ||
To only accept RSA-PSS sigatures: | ||
```javascript | ||
var opts = { | ||
algorithms: ["PS*"] | ||
}; | ||
jose.JWS.createVerify(key, opts). | ||
verify(input). | ||
then(function(result) { | ||
// ... | ||
}); | ||
``` | ||
To accept any algorithm, but disallow HMAC-based signatures: | ||
```javascript | ||
var opts = { | ||
algorithms: ["*", "!HS*"] | ||
}; | ||
jose.JWS.createVerify(key, opts). | ||
verify(input). | ||
then(input). | ||
then(function(result) { | ||
// ... | ||
}); | ||
``` | ||
#### Handling `crit` Header Members #### | ||
@@ -481,3 +531,3 @@ | ||
``` | ||
```javascript | ||
var opts = { | ||
@@ -497,3 +547,3 @@ handlers: { | ||
``` | ||
```javascript | ||
var opts = { | ||
@@ -516,3 +566,3 @@ handlers: { | ||
``` | ||
```javascript | ||
var opts = { | ||
@@ -556,3 +606,3 @@ handlers: { | ||
``` | ||
```javascript | ||
// {input} is a Buffer | ||
@@ -575,3 +625,3 @@ jose.JWE.createEncrypt(key). | ||
``` | ||
```javascript | ||
jose.JWE.createEncrypt({ format: 'compact' }, key). | ||
@@ -594,3 +644,3 @@ update(input). | ||
``` | ||
```javascript | ||
jose.JWE.createEncrypt({ zip: true }, key). | ||
@@ -606,3 +656,3 @@ update(input). | ||
``` | ||
```javascript | ||
jose.JWE.createEncrypt({ fields: { cty : 'jwk+json' } }, key). | ||
@@ -618,3 +668,3 @@ update(input). | ||
``` | ||
```javascript | ||
// {keys} is an Array of jose.JWK.Key instances | ||
@@ -633,3 +683,3 @@ jose.JWE.createEncrypt(keys). | ||
``` | ||
```javascript | ||
jose.JWE.createDecrypt(keystore). | ||
@@ -649,3 +699,3 @@ decrypt(input). | ||
``` | ||
```javascript | ||
jose.JWE.createDecrypt(key). | ||
@@ -658,2 +708,39 @@ decrypt(input). | ||
#### Allowing (or Disallowing) Encryption Algorithms ### | ||
To restrict what encryption algorithms are allowed when verifying, add the `allowAlgs` member to the `options` Object. The `allowAlgs` member is either a string or an array of strings, where the string value(s) can be one of the following: | ||
* `"*"`: accept all supported algorithms | ||
* **`<alg name>`** (e.g., `"A128KW"`): accept the specific algorithm (can have a single '*' to match a range of similar algorithms) | ||
* **`!<alg name>`** (e.g., `"!RSA1_5"`): *do not* accept the specific algorithm (can have a single '*' to match a range of similar algorithms) | ||
The negation is intended to be used with the wildcard accept string, and disallow takes precedence over allowed. | ||
To only accept "dir" and AES-GCM encryption: | ||
```javascript | ||
var opts = { | ||
algorithms: ["dir", "A*GCM"] | ||
}; | ||
jose.JWE.createDecrypt(key, opts). | ||
decrypt(input). | ||
then(function(result) { | ||
// ... | ||
}); | ||
``` | ||
To accept any algorithm, but disallow RSA-based encryption: | ||
```javascript | ||
var opts = { | ||
algorithms: ["*", "!RSA*"] | ||
}; | ||
jose.JWS.createVerify(key, opts). | ||
verify(input). | ||
then(input). | ||
then(function(result) { | ||
// ... | ||
}); | ||
``` | ||
#### Handling `crit` Header Members #### | ||
@@ -673,3 +760,3 @@ | ||
``` | ||
```javascript | ||
var opts = { | ||
@@ -689,3 +776,3 @@ handlers: { | ||
``` | ||
```javascript | ||
var opts = { | ||
@@ -708,3 +795,3 @@ handlers: { | ||
``` | ||
```javascript | ||
var opts = { | ||
@@ -733,3 +820,3 @@ handlers: { | ||
``` | ||
```javascript | ||
buff = jose.util.asBuffer(input); | ||
@@ -744,3 +831,3 @@ ``` | ||
``` | ||
```javascript | ||
var output = jose.util.base64url.encode(input); | ||
@@ -751,3 +838,3 @@ ``` | ||
``` | ||
```javascript | ||
// explicit encoding | ||
@@ -762,3 +849,3 @@ output = jose.util.base64url.encode(input, "utf8"); | ||
``` | ||
```javascript | ||
var output = jose.util.base64url.decode(input); | ||
@@ -771,3 +858,3 @@ ``` | ||
``` | ||
```javascript | ||
// argument is size (in bytes) | ||
@@ -774,0 +861,0 @@ var rnd = jose.util.randomBytes(32); |
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
336412
61
9631
818