diff --git a/lib/index.js b/lib/index.js index 0ec3b56..9b7ac90 100644 --- a/lib/index.js +++ b/lib/index.js @@ -14,5 +14,6 @@ module.exports = { JWE: require("./jwe"), JWK: require("./jwk"), JWS: require("./jws"), - util: require("./util") + util: require("./util"), + parse: require("./parse") }; diff --git a/lib/parse/compact.js b/lib/parse/compact.js new file mode 100644 index 0000000..dd24993 --- /dev/null +++ b/lib/parse/compact.js @@ -0,0 +1,50 @@ +/*! + * parse/compact.js - JOSE Compact Serialization Parser + * + * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file. + */ +"use strict"; + +var jose = { + JWE: require("../jwe"), + JWS: require("../jws"), + util: require("../util") +}; + +function parseCompact(input) { + var parts = input.split("."); + + var type, + op; + if (3 === parts.length) { + // JWS + type = "JWS"; + op = function(ks) { + return jose.JWS.createVerify(ks). + verify(input); + }; + } else if (5 === parts.length) { + // JWE + type = "JWE"; + op = function(ks) { + return jose.JWE.createDecrypt(ks). + decrypt(input); + }; + } else { + throw new TypeError("invalid jose serialization"); + } + + // parse header + var header; + header = jose.util.base64url.decode(parts[0], "utf8"); + header = JSON.parse(header); + return { + type: type, + format: "compact", + input: input, + header: header, + perform: op + }; +} + +module.exports = parseCompact; diff --git a/lib/parse/index.js b/lib/parse/index.js new file mode 100644 index 0000000..89d7f49 --- /dev/null +++ b/lib/parse/index.js @@ -0,0 +1,22 @@ +/*! + * parse/index.js - JOSE Parser Entry Point + * + * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file. + */ +"use strict"; + +var compact = require("./compact"), + json = require("./json"); + +var parse = module.exports = function(input) { + if ("string" === typeof input) { + return compact(input); + } else if (input) { + return json(input); + } else { + throw new TypeError("invalid input"); + } +}; + +parse.compact = compact; +parse.json = json; diff --git a/lib/parse/json.js b/lib/parse/json.js new file mode 100644 index 0000000..a56b3c8 --- /dev/null +++ b/lib/parse/json.js @@ -0,0 +1,95 @@ +/*! + * parse/compact.js - JOSE Compact Serialization Parser + * + * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file. + */ +"use strict"; + +var merge = require("../util/merge"); + +var jose = { + JWE: require("../jwe"), + JWS: require("../jws"), + util: require("../util") +}; + +function parseJSON(input) { + var type, + op, + headers; + + if ("signatures" in input || "signature" in input) { + // JWS + type = "JWS"; + op = function(ks) { + return jose.JWS.createVerify(ks). + verify(input); + }; + // headers can be (signatures[].protected, signatures[].header, signature.protected, signature.header) + headers = input.signatures || + [ { + protected: input.protected, + header: input.header, + signature: input.signature + }]; + headers = headers.map(function(sig) { + var all = {}; + if (sig.header) { + all = merge(all, sig.header); + } + + var prot; + if (sig.protected) { + prot = sig.protected; + prot = jose.util.base64url.decode(prot, "utf8"); + prot = JSON.parse(prot); + all = merge(all, prot); + } + + return all; + }); + } else if ("ciphertext" in input) { + // JWE + type = "JWE"; + op = function(ks) { + return jose.JWE.createDecrypt(ks). + decrypt(input); + }; + // headers can be (protected, unprotected, recipients[].header) + var root = {}; + if (input.protected) { + root.protected = input.protected; + root.protected = jose.util.base64url.decode(root.protected, "utf8"); + root.protected = JSON.parse(root.protected); + } + if (input.unprotected) { + root.unprotected = input.unprotected; + } + + headers = input.recipients || [{}]; + headers = headers.map(function(rcpt) { + var all = {}; + if (rcpt.header) { + all = merge(all, rcpt.header); + } + if (root.unprotected) { + all = merge(all, root.unprotected); + } + if (root.protected) { + all = merge(all, root.protected); + } + + return all; + }); + } + + return { + type: type, + format: "json", + input: input, + all: headers, + perform: op + }; +} + +module.exports = parseJSON; diff --git a/test/index-test.js b/test/index-test.js index 6d5abd8..36e4592 100644 --- a/test/index-test.js +++ b/test/index-test.js @@ -67,4 +67,12 @@ describe("Public API", function() { assert.ok(util.utf8.decode); assert.ok(util.utf8.encode); }); + + it("exports parse", function() { + var parse = jose.parse; + + assert.strictEqual(typeof parse, "function"); + assert.strictEqual(typeof parse.compact, "function"); + assert.strictEqual(typeof parse.json, "function"); + }); }); diff --git a/test/parse/compact-test.js b/test/parse/compact-test.js new file mode 100644 index 0000000..5f5ae0d --- /dev/null +++ b/test/parse/compact-test.js @@ -0,0 +1,62 @@ +/** + * + * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file. + */ +"use strict"; + +var chai = require("chai"); +var assert = chai.assert; + +var cloneDeep = require("lodash.cloneDeep"); +var parseCompact = require("../../lib/parse/compact"); +var jose = { + JWK: require("../../lib/jwk") +}; + +var fixtures = { + "jws": cloneDeep(require("jose-cookbook/jws/4_1.rsa_v15_signature.json")), + "jwe": cloneDeep(require("jose-cookbook/jwe/5_1.key_encryption_using_rsa_v15_and_aes-hmac-sha2.json")) +}; + +describe("parse/compact", function() { + it("parses compact JWS", function() { + var fix = fixtures.jws; + var input = fixtures.jws.output.compact; + var output = parseCompact(input); + assert.strictEqual(output.format, "compact"); + assert.strictEqual(output.type, "JWS"); + assert.deepEqual(output.header, fix.signing.protected); + assert.strictEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + it("parses compact JWE", function() { + var fix = fixtures.jwe; + var input = fix.output.compact; + var output = parseCompact(input); + assert.strictEqual(output.format, "compact"); + assert.strictEqual(output.type, "JWE"); + assert.deepEqual(output.header, fix.encrypting_content.protected); + assert.strictEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); +}); diff --git a/test/parse/index-test.js b/test/parse/index-test.js new file mode 100644 index 0000000..fbd9551 --- /dev/null +++ b/test/parse/index-test.js @@ -0,0 +1,317 @@ +/** + * + * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file. + */ +"use strict"; + +var chai = require("chai"); +var assert = chai.assert; + +var cloneDeep = require("lodash.cloneDeep"); +var merge = require("../../lib/util/merge"); + +var jose = { + JWK: require("../../lib/jwk"), + parse: require("../../lib/parse") +}; + +var fixtures = { + jws: { + "basic": cloneDeep(require("jose-cookbook/jws/4_1.rsa_v15_signature.json")), + "full": cloneDeep(require("jose-cookbook/jws/4_6.protecting_specific_header_fields.json")), + "multi": cloneDeep(require("jose-cookbook/jws/4_8.multiple_signatures.json")) + }, + jwe: { + "basic": cloneDeep(require("jose-cookbook/jwe/5_6.direct_encryption_using_aes-gcm.json")), + "full": cloneDeep(require("jose-cookbook/jwe/5_11.protecting_specific_header_fields.json")), + "multi": cloneDeep(require("jose-cookbook/jwe/5_13.encrypting_to_multiple_recipients.json")) + } +}; + +describe("parse", function() { + describe("basic", function() { + it("parses JWS Compact Serialization", function() { + var fix = fixtures.jws.basic; + var input = fix.output.compact; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "compact"); + assert.deepEqual(output.header, fix.signing.protected); + assert.strictEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + it("parses JWS General JSON Serialization", function() { + var fix = fixtures.jws.basic; + var input = fix.output.json; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.signing.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + it("parses JWS Flattened JSON Serialization", function() { + var fix = fixtures.jws.basic; + var input = fix.output.json_flat; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.signing.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + + it("parses JWE Compact Serialization", function() { + var fix = fixtures.jwe.basic; + var input = fix.output.compact; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "compact"); + assert.deepEqual(output.header, fix.encrypting_content.protected); + assert.strictEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + it("parses JWE General JSON Serialization", function() { + var fix = fixtures.jwe.basic; + var input = fix.output.json; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.encrypting_content.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + it("parses JWE Flattened JSON Serialization", function() { + var fix = fixtures.jwe.basic; + var input = fix.output.json; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.encrypting_content.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + }); + + describe("full", function() { + it("parses JWS General JSON Serialization", function() { + var fix = fixtures.jws.full; + var input = fix.output.json; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.signing.unprotected); + expected = merge(expected, fix.signing.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + it("parses JWS Flattened JSON Serialization", function() { + var fix = fixtures.jws.full; + var input = fix.output.json_flat; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.signing.unprotected); + expected = merge(expected, fix.signing.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + + it("parses JWE General JSON Serialization", function() { + var fix = fixtures.jwe.full; + var input = fix.output.json; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.encrypting_content.unprotected); + expected = merge(expected, fix.encrypting_content.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + it("parses JWE Flattened JSON Serialization", function() { + var fix = fixtures.jwe.full; + var input = fix.output.json_flat; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.encrypting_content.unprotected); + expected = merge(expected, fix.encrypting_content.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + }); + + describe("multi", function() { + it("parses JWS General Serialization", function() { + var fix = fixtures.jws.multi; + var input = fix.output.json; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + var expected = fix.signing.map(function(s) { + var all = {}; + if (s.unprotected) { + all = merge(all, s.unprotected); + } + if (s.protected) { + all = merge(all, s.protected); + } + return all; + }); + assert.deepEqual(output.all, expected); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key[0]); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + it("parses JWE General Serialization", function() { + var fix = fixtures.jwe.multi; + var input = fix.output.json; + var output = jose.parse(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + var expected = fix.encrypting_key.map(function(e) { + var all = {}; + if (e.header) { + all = merge(all, e.header); + } + if (fix.encrypting_content.unprotected) { + all = merge(all, fix.encrypting_content.unprotected); + } + if (fix.encrypting_content.protected) { + all = merge(all, fix.encrypting_content.protected); + } + return all; + }); + assert.deepEqual(output.all, expected); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key[0]); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + }); +}); diff --git a/test/parse/json-test.js b/test/parse/json-test.js new file mode 100644 index 0000000..e78b468 --- /dev/null +++ b/test/parse/json-test.js @@ -0,0 +1,278 @@ +/** + * + * Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file. + */ +"use strict"; + +var chai = require("chai"); +var assert = chai.assert; + +var cloneDeep = require("lodash.cloneDeep"); +var merge = require("../../lib/util/merge"); +var parseJSON = require("../../lib/parse/json"); + +var jose = { + JWK: require("../../lib/jwk") +}; + +var fixtures = { + jws: { + "basic": cloneDeep(require("jose-cookbook/jws/4_1.rsa_v15_signature.json")), + "full": cloneDeep(require("jose-cookbook/jws/4_6.protecting_specific_header_fields.json")), + "multi": cloneDeep(require("jose-cookbook/jws/4_8.multiple_signatures.json")) + }, + jwe: { + "basic": cloneDeep(require("jose-cookbook/jwe/5_6.direct_encryption_using_aes-gcm.json")), + "full": cloneDeep(require("jose-cookbook/jwe/5_11.protecting_specific_header_fields.json")), + "multi": cloneDeep(require("jose-cookbook/jwe/5_13.encrypting_to_multiple_recipients.json")) + } +}; + +describe("parse/json", function() { + describe("basic", function() { + it("parses JWS General JSON Serialization", function() { + var fix = fixtures.jws.basic; + var input = fix.output.json; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.signing.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + it("parses JWS Flattened JSON Serialization", function() { + var fix = fixtures.jws.basic; + var input = fix.output.json_flat; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.signing.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + + it("parses JWE General JSON Serialization", function() { + var fix = fixtures.jwe.basic; + var input = fix.output.json; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.encrypting_content.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + it("parses JWE Flattened JSON Serialization", function() { + var fix = fixtures.jwe.basic; + var input = fix.output.json; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + assert.deepEqual(output.all, [ fix.encrypting_content.protected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + }); + + describe("full", function() { + it("parses JWS General JSON Serialization", function() { + var fix = fixtures.jws.full; + var input = fix.output.json; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.signing.unprotected); + expected = merge(expected, fix.signing.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + it("parses JWS Flattened JSON Serialization", function() { + var fix = fixtures.jws.full; + var input = fix.output.json_flat; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.signing.unprotected); + expected = merge(expected, fix.signing.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + + it("parses JWE General JSON Serialization", function() { + var fix = fixtures.jwe.full; + var input = fix.output.json; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.encrypting_content.unprotected); + expected = merge(expected, fix.encrypting_content.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + it("parses JWE Flattened JSON Serialization", function() { + var fix = fixtures.jwe.full; + var input = fix.output.json_flat; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + var expected = {}; + expected = merge(expected, fix.encrypting_content.unprotected); + expected = merge(expected, fix.encrypting_content.protected); + assert.deepEqual(output.all, [ expected ]); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + }); + + describe("multi", function() { + it("parses JWS General Serialization", function() { + var fix = fixtures.jws.multi; + var input = fix.output.json; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWS"); + assert.strictEqual(output.format, "json"); + var expected = fix.signing.map(function(s) { + var all = {}; + if (s.unprotected) { + all = merge(all, s.unprotected); + } + if (s.protected) { + all = merge(all, s.protected); + } + return all; + }); + assert.deepEqual(output.all, expected); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key[0]); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.payload.toString("utf8"), + fix.input.payload); + }); + return promise; + }); + + it("parses JWE General Serialization", function() { + var fix = fixtures.jwe.multi; + var input = fix.output.json; + var output = parseJSON(input); + assert.strictEqual(output.type, "JWE"); + assert.strictEqual(output.format, "json"); + var expected = fix.encrypting_key.map(function(e) { + var all = {}; + if (e.header) { + all = merge(all, e.header); + } + if (fix.encrypting_content.unprotected) { + all = merge(all, fix.encrypting_content.unprotected); + } + if (fix.encrypting_content.protected) { + all = merge(all, fix.encrypting_content.protected); + } + return all; + }); + assert.deepEqual(output.all, expected); + assert.deepEqual(output.input, input); + + assert.strictEqual(typeof output.perform, "function"); + var promise = jose.JWK.asKey(fix.input.key[0]); + promise = promise.then(function(key) { + return output.perform(key); + }); + promise = promise.then(function(result) { + assert.strictEqual(result.plaintext.toString("utf8"), + fix.input.plaintext); + }); + return promise; + }); + }); +});