Skip to content

Commit 3ecb7be

Browse files
committed
Bug: JWE encryption fails for ECDH keys (fix #3)
1 parent 02e4598 commit 3ecb7be

File tree

5 files changed

+123
-2
lines changed

5 files changed

+123
-2
lines changed

lib/jwe/encrypt.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ function JWEEncrypter(cfg, fields, recipients) {
210210
p = encKey.then(function(jwk) {
211211
// fixup encAlg
212212
if (!encAlg) {
213-
fields.enc = encAlg = jwk.algorithms(JWK.MODE_ENCRYPT)[0];
213+
props.enc = fields.enc = encAlg = jwk.algorithms(JWK.MODE_ENCRYPT)[0];
214214
}
215215
return {
216216
once: true,
@@ -220,7 +220,7 @@ function JWEEncrypter(cfg, fields, recipients) {
220220
} else {
221221
if (!encKey) {
222222
if (!encAlg) {
223-
fields.enc = encAlg = cfg.contentAlg;
223+
props.enc = fields.enc = encAlg = cfg.contentAlg;
224224
}
225225
encKey = generateCEK(encAlg);
226226
}

lib/jwk/keystore.js

+13
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,19 @@ var JWKStore = function(registry, parent) {
308308
}
309309
});
310310

311+
/**
312+
* @method JWK.KeyStore#temp
313+
* @description
314+
* Creates a temporary KeyStore based on this KeyStore.
315+
*
316+
* @returns {JWK.KeyStore} The temporary KeyStore.
317+
*/
318+
Object.defineProperty(this, "temp", {
319+
value: function() {
320+
return new JWKStore(registry, this);
321+
}
322+
});
323+
311324
/**
312325
* @method JWK.KeyStore#toJSON
313326
* @description

test/jwe/jwe-test.js

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var fixtures = {
1818
"5_2.key_encryption_using_rsa-oaep_with_aes-gcm": cloneDeep(require("jose-cookbook/jwe/5_2.key_encryption_using_rsa-oaep_with_aes-gcm.json")),
1919
"5_3.key_wrap_using_pbes2-aes-keywrap_with-aes-cbc-hmac-sha2": cloneDeep(require("jose-cookbook/jwe/5_3.key_wrap_using_pbes2-aes-keywrap_with-aes-cbc-hmac-sha2.json")),
2020
"5_4.key_agreement_with_key_wrapping_using_ecdh-es_and_aes-keywrap_with_aes-gcm": cloneDeep(require("jose-cookbook/jwe/5_4.key_agreement_with_key_wrapping_using_ecdh-es_and_aes-keywrap_with_aes-gcm.json")),
21+
"5_5.key_agreement_using_ecdh-es_with_aes-cbc-hmac-sha2": cloneDeep(require("jose-cookbook/jwe/5_5.key_agreement_using_ecdh-es_with_aes-cbc-hmac-sha2.json")),
2122
"5_6.direct_encryption_using_aes-gcm": cloneDeep(require("jose-cookbook/jwe/5_6.direct_encryption_using_aes-gcm.json")),
2223
"5_8.key_wrap_using_aes-keywrap_with_aes-gcm": cloneDeep(require("jose-cookbook/jwe/5_8.key_wrap_using_aes-keywrap_with_aes-gcm.json")),
2324
"5_9.compressed_content": cloneDeep(require("jose-cookbook/jwe/5_9.compressed_content.json")),

test/jwe/roundtrip-test.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"use strict";
2+
3+
var forEach = require("lodash.foreach");
4+
var chai = require("chai");
5+
6+
var JWE = require("../../lib/jwe"),
7+
JWK = require("../../lib/jwk");
8+
9+
var assert = chai.assert;
10+
11+
describe("jwe/roundtrip", function() {
12+
var vectors = [
13+
{
14+
desc: "ECDH-ES + A128CBC-HS256",
15+
jwk: {
16+
"kty": "EC",
17+
"kid": "3f7b122d-e9d2-4ff7-bdeb-a1487063d799",
18+
"crv": "P-256",
19+
"x": "Hx02_oMKJnNb1-bgXfzeuBHagkh20muzegMOGEU8G_g",
20+
"y": "Ez2IYifZI88vRiCpA4Y6W8oMKZOi2nhZStxilPYTDk0",
21+
"d": "FS9F8-SyMjTZFXwCH7F--D8Qq_GSpG6FBEM-Nb8ily0"
22+
},
23+
alg: "ECDH-ES",
24+
enc: "A128CBC-HS256",
25+
plaintext: new Buffer("hello world", "utf8")
26+
},
27+
{
28+
desc: "ECDH-ES+A128KW + A128GCM",
29+
jwk: {
30+
"kty": "EC",
31+
"kid": "3f7b122d-e9d2-4ff7-bdeb-a1487063d799",
32+
"crv": "P-256",
33+
"x": "Hx02_oMKJnNb1-bgXfzeuBHagkh20muzegMOGEU8G_g",
34+
"y": "Ez2IYifZI88vRiCpA4Y6W8oMKZOi2nhZStxilPYTDk0",
35+
"d": "FS9F8-SyMjTZFXwCH7F--D8Qq_GSpG6FBEM-Nb8ily0"
36+
},
37+
alg: "ECDH-ES+A128KW",
38+
enc: "A128GCM",
39+
plaintext: new Buffer("hello world", "utf8")
40+
}
41+
];
42+
forEach(vectors, function(v) {
43+
it("test " + v.desc + " encrypt + decrypt", function() {
44+
var promise,
45+
key;
46+
promise = JWK.asKey(v.jwk);
47+
promise = promise.then(function(jwk) {
48+
key = jwk;
49+
var cfg = {
50+
contentAlg: v.enc
51+
};
52+
var recipient = {
53+
key: key,
54+
header: {
55+
alg: v.alg
56+
}
57+
};
58+
var jwe = JWE.createEncrypt(cfg, recipient);
59+
return jwe.update(v.plaintext).final();
60+
});
61+
promise = promise.then(function(result) {
62+
assert.ok(result);
63+
var jwe = JWE.createDecrypt(key);
64+
return jwe.decrypt(result);
65+
});
66+
promise = promise.then(function(result) {
67+
assert.deepEqual(result.plaintext, v.plaintext);
68+
});
69+
return promise;
70+
});
71+
});
72+
});

test/jwk/keystore-test.js

+35
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,41 @@ describe("jwk/keystore", function() {
349349
});
350350
});
351351

352+
describe("temp", function() {
353+
var keystore;
354+
before(function() {
355+
var jwk = {
356+
"kty": "DUMMY",
357+
"kid": "someid",
358+
"use": "sig",
359+
"alg": "HS256",
360+
"pub": util.base64url.encode(new Buffer("a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5", "hex")),
361+
"prv": util.base64url.encode(new Buffer("bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc", "hex"))
362+
};
363+
keystore = createInstance();
364+
return keystore.add(jwk);
365+
});
366+
it("it creates a child keystore", function() {
367+
var tks = keystore.temp();
368+
assert.deepEqual(tks.all(), keystore.all());
369+
370+
var jwk = {
371+
"kty": "DUMMY",
372+
"kid": "diffid",
373+
"use": "enc",
374+
"alg": "A256GCM",
375+
"pub": util.base64url.encode(new Buffer("a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5", "hex")),
376+
"prv": util.base64url.encode(new Buffer("bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc", "hex"))
377+
};
378+
var promise = tks.add(jwk);
379+
promise = promise.then(function(key) {
380+
assert.strictEqual(tks.get("diffid"), key);
381+
assert.ok(!keystore.get("diffid"));
382+
});
383+
return promise;
384+
});
385+
});
386+
352387
describe("query", function() {
353388

354389
});

0 commit comments

Comments
 (0)