Skip to content

Commit 0e11b7c

Browse files
Merge pull request #35 from martinthomson/release
Release
2 parents 7b0610b + 46a5de1 commit 0e11b7c

File tree

6 files changed

+158
-271
lines changed

6 files changed

+158
-271
lines changed

nodejs/ece.js

Lines changed: 13 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@
2020
var crypto = require('crypto');
2121
var base64 = require('urlsafe-base64');
2222

23-
var saved = {
24-
keymap: {},
25-
keylabels: {}
26-
};
2723
var AES_GCM = 'aes-128-gcm';
2824
var PAD_SIZE = { 'aes128gcm': 1, 'aesgcm': 2, 'aesgcm128': 1 };
2925
var TAG_LENGTH = 16;
@@ -102,15 +98,6 @@ function lengthPrefix(buffer) {
10298

10399
function extractDH(header, mode) {
104100
var key = header.privateKey;
105-
if (!key) {
106-
if (!header.keymap || !header.keyid || !header.keymap[header.keyid]) {
107-
throw new Error('No known DH key for ' + header.keyid);
108-
}
109-
key = header.keymap[header.keyid];
110-
}
111-
if (!header.keylabels[header.keyid]) {
112-
throw new Error('No known DH key label for ' + header.keyid);
113-
}
114101
var senderPubKey, receiverPubKey;
115102
if (mode === MODE_ENCRYPT) {
116103
senderPubKey = key.getPublicKey();
@@ -125,7 +112,7 @@ function extractDH(header, mode) {
125112
return {
126113
secret: key.computeSecret(header.dh),
127114
context: Buffer.concat([
128-
Buffer.from(header.keylabels[header.keyid], 'ascii'),
115+
Buffer.from(header.keylabel, 'ascii'),
129116
Buffer.from([0]),
130117
lengthPrefix(receiverPubKey), // user agent
131118
lengthPrefix(senderPubKey) // application server
@@ -248,12 +235,8 @@ function deriveKeyAndNonce(header, mode) {
248235
/* Parse command-line arguments. */
249236
function parseParams(params) {
250237
var header = {};
251-
if (params.version) {
252-
header.version = params.version;
253-
} else {
254-
header.version = (params.padSize === 1) ? 'aesgcm128' : 'aesgcm';
255-
}
256238

239+
header.version = params.version || 'aes128gcm';
257240
header.rs = parseInt(params.rs, 10);
258241
if (isNaN(header.rs)) {
259242
header.rs = 4096;
@@ -281,7 +264,7 @@ function parseParams(params) {
281264
header.keymap = params.keymap || saved.keymap;
282265
}
283266
if (header.version !== 'aes128gcm') {
284-
header.keylabels = params.keylabels || saved.keylabels;
267+
header.keylabel = params.keylabel || 'P-256';
285268
}
286269
if (params.dh) {
287270
header.dh = decode(params.dh);
@@ -362,28 +345,21 @@ function decryptRecord(key, counter, buffer, header, last) {
362345
return unpad(data, last);
363346
}
364347

365-
// TODO: this really should use the node streams stuff
366-
367348
/**
368349
* Decrypt some bytes. This uses the parameters to determine the key and block
369350
* size, which are described in the draft. Binary values are base64url encoded.
370351
*
371352
* |params.version| contains the version of encoding to use: aes128gcm is the latest,
372353
* but aesgcm and aesgcm128 are also accepted (though the latter two might
373-
* disappear in a future release). If omitted, assume aesgcm, unless
374-
* |params.padSize| is set to 1, which means aesgcm128.
354+
* disappear in a future release). If omitted, assume aes128gcm.
375355
*
376356
* If |params.key| is specified, that value is used as the key.
377357
*
378-
* If |params.keyid| is specified without |params.dh|, the keyid value is used
379-
* to lookup the |params.keymap| for a buffer containing the key.
358+
* If the version is aes128gcm, the keyid is extracted from the header and used
359+
* as the ECDH public key of the sender. For version aesgcm and aesgcm128,
360+
* |params.dh| needs to be provided with the public key of the sender.
380361
*
381-
* For version aesgcm and aesgcm128, |params.dh| includes the public key of the sender. The ECDH key
382-
* pair used to decrypt is looked up using |params.keymap[params.keyid]|.
383-
*
384-
* Version aes128gcm is stricter. The |params.privateKey| includes the private
385-
* key of the receiver. The keyid is extracted from the header and used as the
386-
* ECDH public key of the sender.
362+
* The |params.privateKey| includes the private key of the receiver.
387363
*/
388364
function decrypt(buffer, params) {
389365
var header = parseParams(params);
@@ -470,21 +446,13 @@ function writeHeader(header) {
470446
*
471447
* |params.version| contains the version of encoding to use: aes128gcm is the latest,
472448
* but aesgcm and aesgcm128 are also accepted (though the latter two might
473-
* disappear in a future release). If omitted, assume aesgcm, unless
474-
* |params.padSize| is set to 1, which means aesgcm128.
449+
* disappear in a future release). If omitted, assume aes128gcm.
475450
*
476451
* If |params.key| is specified, that value is used as the key.
477452
*
478-
* If |params.keyid| is specified without |params.dh|, the keyid value is used
479-
* to lookup the |params.keymap| for a buffer containing the key. This feature
480-
* is deprecated in favour of just including |params.key| or |params.privateKey|.
481-
*
482453
* For Diffie-Hellman (WebPush), |params.dh| includes the public key of the
483-
* receiver. |params.privateKey| is used to establish a shared secret. For
484-
* versions aesgcm and aesgcm128, if a private key is not provided, the ECDH key
485-
* pair used to encrypt is looked up using |params.keymap[params.keyid]|, and
486-
* |params.keymap| defaults to the values saved with saveKey(). Key pairs can
487-
* be created using |crypto.createECDH()|.
454+
* receiver. |params.privateKey| is used to establish a shared secret. Key
455+
* pairs can be created using |crypto.createECDH()|.
488456
*/
489457
function encrypt(buffer, params) {
490458
if (!Buffer.isBuffer(buffer)) {
@@ -497,7 +465,7 @@ function encrypt(buffer, params) {
497465

498466
var result;
499467
if (header.version === 'aes128gcm') {
500-
// Save the DH public key in the header.
468+
// Save the DH public key in the header unless keyid is set.
501469
if (header.privateKey && !header.keyid) {
502470
header.keyid = header.privateKey.getPublicKey();
503471
}
@@ -548,18 +516,7 @@ function encrypt(buffer, params) {
548516
return result;
549517
}
550518

551-
/**
552-
* Deprecated. Use the keymap and keylabels arguments to encrypt()/decrypt().
553-
*/
554-
function saveKey(id, key, dhLabel) {
555-
saved.keymap[id] = key;
556-
if (dhLabel) {
557-
saved.keylabels[id] = dhLabel;
558-
}
559-
}
560-
561519
module.exports = {
562520
decrypt: decrypt,
563-
encrypt: encrypt,
564-
saveKey: saveKey
521+
encrypt: encrypt
565522
};

nodejs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "http_ece",
3-
"version": "0.7.2",
3+
"version": "1.0.0",
44
"description": "Encrypted Content-Encoding for HTTP",
55
"homepage": "https://github.com/martinthomson/encrypted-content-encoding",
66
"bugs": "https://github.com/martinthomson/encrypted-content-encoding/issues",

nodejs/test.js

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,21 @@ function logbuf(msg, buf) {
6767

6868
function reallySaveDump(data){
6969
if (dumpFile && data.version) {
70-
dumpData.push(data);
70+
function dumpFix(d) {
71+
var r = {};
72+
Object.keys(d).forEach(function(k) {
73+
if (Buffer.isBuffer(d[k])) {
74+
r[k] = base64.encode(d[k]);
75+
} else if (d[k] instanceof Object) {
76+
r[k] = dumpFix(d[k]);
77+
} else {
78+
r[k] = d[k];
79+
}
80+
});
81+
return r;
82+
}
83+
84+
dumpData.push(dumpFix(data));
7185
}
7286
}
7387
var saveDump = reallySaveDump;
@@ -128,7 +142,7 @@ function encryptDecrypt(input, encryptParams, decryptParams, keys) {
128142
assert.equal(encryptParams.authSecret, decryptParams.authSecret);
129143

130144
// Always fill in the salt so we can log it.
131-
decryptParams.salt = base64.encode(crypto.randomBytes(16));
145+
decryptParams.salt = crypto.randomBytes(16);
132146
encryptParams.salt = decryptParams.salt;
133147
logbuf('Salt', encryptParams.salt);
134148

@@ -140,11 +154,11 @@ function encryptDecrypt(input, encryptParams, decryptParams, keys) {
140154

141155
saveDump({
142156
version: encryptParams.version,
143-
input: base64.encode(input),
144-
encrypted: base64.encode(encrypted),
157+
input: input,
158+
encrypted: encrypted,
145159
params: {
146160
encrypt: encryptParams,
147-
decrypt: decryptParams,
161+
decrypt: decryptParams
148162
},
149163
keys: keys
150164
});
@@ -154,7 +168,7 @@ function useExplicitKey(version) {
154168
var input = generateInput();
155169
var params = {
156170
version: version,
157-
key: base64.encode(crypto.randomBytes(16))
171+
key: crypto.randomBytes(16)
158172
};
159173
logbuf('Key', params.key);
160174
encryptDecrypt(input, params, params);
@@ -164,8 +178,8 @@ function authenticationSecret(version) {
164178
var input = generateInput();
165179
var params = {
166180
version: version,
167-
key: base64.encode(crypto.randomBytes(16)),
168-
authSecret: base64.encode(crypto.randomBytes(16))
181+
key: crypto.randomBytes(16),
182+
authSecret: crypto.randomBytes(16)
169183
};
170184
logbuf('Key', params.key);
171185
logbuf('Context', params.authSecret);
@@ -176,7 +190,7 @@ function exactlyOneRecord(version) {
176190
var input = generateInput(1);
177191
var params = {
178192
version: version,
179-
key: base64.encode(crypto.randomBytes(16)),
193+
key: crypto.randomBytes(16),
180194
rs: input.length + rsoverhead(version)
181195
};
182196
encryptDecrypt(input, params, params);
@@ -188,7 +202,7 @@ function padTinyRecord(version) {
188202
var input = generateInput(1);
189203
var params = {
190204
version: version,
191-
key: base64.encode(crypto.randomBytes(16)),
205+
key: crypto.randomBytes(16),
192206
rs: rsoverhead(version) + 1,
193207
pad: 2
194208
};
@@ -207,7 +221,7 @@ function tooMuchPadding(version) {
207221
var input = generateInput(1);
208222
var params = {
209223
version: version,
210-
key: base64.encode(crypto.randomBytes(16)),
224+
key: crypto.randomBytes(16),
211225
rs: rs,
212226
pad: rs
213227
};
@@ -231,7 +245,7 @@ function detectTruncation(version) {
231245
var input = generateInput(2);
232246
var params = {
233247
version: version,
234-
key: base64.encode(crypto.randomBytes(16)),
248+
key: crypto.randomBytes(16),
235249
rs: input.length + rsoverhead(version) - 1
236250
};
237251
var headerLen = (version === 'aes128gcm') ? 21 : 0;
@@ -255,20 +269,6 @@ function detectTruncation(version) {
255269
}
256270
}
257271

258-
function useKeyId(version) {
259-
var input = generateInput();
260-
var keyid = base64.encode(crypto.randomBytes(16));
261-
var key = crypto.randomBytes(16);
262-
var keymap = {};
263-
keymap[keyid] = key;
264-
var params = {
265-
keyid: keyid,
266-
keymap: keymap
267-
};
268-
269-
encryptDecrypt(input, params, params);
270-
}
271-
272272
function useDH(version) {
273273
// the static key is used by the receiver
274274
var staticKey = crypto.createECDH('prime256v1');
@@ -289,25 +289,20 @@ function useDH(version) {
289289
var input = generateInput();
290290
var encryptParams = {
291291
version: version,
292-
authSecret: base64.encode(crypto.randomBytes(16)),
293-
dh: base64.encode(staticKey.getPublicKey())
292+
authSecret: crypto.randomBytes(16),
293+
dh: staticKey.getPublicKey()
294294
};
295295
var decryptParams = {
296296
version: version,
297297
authSecret: encryptParams.authSecret
298298
};
299-
if (version === 'aes128gcm') {
300-
encryptParams.privateKey = ephemeralKey;
301-
decryptParams.privateKey = staticKey;
302-
} else {
303-
encryptParams.keyid = 'k';
304-
encryptParams.keymap = { k: ephemeralKey };
305-
encryptParams.keylabels = { k: 'P-256' };
306-
307-
decryptParams.dh = base64.encode(ephemeralKey.getPublicKey());
308-
decryptParams.keyid = 'k';
309-
decryptParams.keymap = { k: staticKey };
310-
decryptParams.keylabels = encryptParams.keylabels;
299+
encryptParams.privateKey = ephemeralKey;
300+
decryptParams.privateKey = staticKey;
301+
if (version !== 'aes128gcm') {
302+
encryptParams.keylabel = 'P-256';
303+
304+
decryptParams.dh = ephemeralKey.getPublicKey();
305+
decryptParams.keylabel = 'P-256';
311306
}
312307

313308

@@ -379,7 +374,6 @@ filterTests([ 'aesgcm128', 'aesgcm', 'aes128gcm' ])
379374
exactlyOneRecord,
380375
padTinyRecord,
381376
detectTruncation,
382-
useKeyId,
383377
useDH,
384378
checkExamples,
385379
])

0 commit comments

Comments
 (0)