@@ -176,7 +176,13 @@ function webpushSecret(header, mode) {
176
176
SHA_256_LENGTH ) ) ;
177
177
}
178
178
179
- function extractSecret ( header , mode ) {
179
+ function extractSecret ( header , mode , keyLookupCallback ) {
180
+ if ( keyLookupCallback ) {
181
+ if ( ! isFunction ( keyLookupCallback ) ) {
182
+ throw new Error ( 'Callback is not a function' )
183
+ }
184
+ }
185
+
180
186
if ( header . key ) {
181
187
if ( header . key . length !== KEY_LENGTH ) {
182
188
throw new Error ( 'An explicit key must be ' + KEY_LENGTH + ' bytes' ) ;
@@ -186,7 +192,11 @@ function extractSecret(header, mode) {
186
192
187
193
if ( ! header . privateKey ) {
188
194
// Lookup based on keyid
189
- var key = header . keymap && header . keymap [ header . keyid ] ;
195
+ if ( ! keyLookupCallback ) {
196
+ var key = header . keymap && header . keymap [ header . keyid ] ;
197
+ } else {
198
+ var key = keyLookupCallback ( header . keyid )
199
+ }
190
200
if ( ! key ) {
191
201
throw new Error ( 'No saved key (keyid: "' + header . keyid + '")' ) ;
192
202
}
@@ -196,7 +206,7 @@ function extractSecret(header, mode) {
196
206
return webpushSecret ( header , mode ) ;
197
207
}
198
208
199
- function deriveKeyAndNonce ( header , mode ) {
209
+ function deriveKeyAndNonce ( header , mode , lookupKeyCallback ) {
200
210
if ( ! header . salt ) {
201
211
throw new Error ( 'must include a salt parameter for ' + header . version ) ;
202
212
}
@@ -207,18 +217,18 @@ function deriveKeyAndNonce(header, mode) {
207
217
// really old
208
218
keyInfo = 'Content-Encoding: aesgcm128' ;
209
219
nonceInfo = 'Content-Encoding: nonce' ;
210
- secret = extractSecretAndContext ( header , mode ) . secret ;
220
+ secret = extractSecretAndContext ( header , mode , lookupKeyCallback ) . secret ;
211
221
} else if ( header . version === 'aesgcm' ) {
212
222
// old
213
- var s = extractSecretAndContext ( header , mode ) ;
223
+ var s = extractSecretAndContext ( header , mode , lookupKeyCallback ) ;
214
224
keyInfo = info ( 'aesgcm' , s . context ) ;
215
225
nonceInfo = info ( 'nonce' , s . context ) ;
216
226
secret = s . secret ;
217
227
} else if ( header . version === 'aes128gcm' ) {
218
228
// latest
219
229
keyInfo = Buffer . from ( 'Content-Encoding: aes128gcm\0' ) ;
220
230
nonceInfo = Buffer . from ( 'Content-Encoding: nonce\0' ) ;
221
- secret = extractSecret ( header , mode ) ;
231
+ secret = extractSecret ( header , mode , lookupKeyCallback ) ;
222
232
} else {
223
233
throw new Error ( 'Unable to set context for mode ' + params . version ) ;
224
234
}
@@ -361,13 +371,13 @@ function decryptRecord(key, counter, buffer, header, last) {
361
371
*
362
372
* The |params.privateKey| includes the private key of the receiver.
363
373
*/
364
- function decrypt ( buffer , params ) {
374
+ function decrypt ( buffer , params , keyLookupCallback ) {
365
375
var header = parseParams ( params ) ;
366
376
if ( header . version === 'aes128gcm' ) {
367
377
var headerLength = readHeader ( buffer , header ) ;
368
378
buffer = buffer . slice ( headerLength ) ;
369
379
}
370
- var key = deriveKeyAndNonce ( header , MODE_DECRYPT ) ;
380
+ var key = deriveKeyAndNonce ( header , MODE_DECRYPT , keyLookupCallback ) ;
371
381
var start = 0 ;
372
382
var result = new Buffer ( 0 ) ;
373
383
@@ -454,7 +464,7 @@ function writeHeader(header) {
454
464
* receiver. |params.privateKey| is used to establish a shared secret. Key
455
465
* pairs can be created using |crypto.createECDH()|.
456
466
*/
457
- function encrypt ( buffer , params ) {
467
+ function encrypt ( buffer , params , keyLookupCallback ) {
458
468
if ( ! Buffer . isBuffer ( buffer ) ) {
459
469
throw new Error ( 'buffer argument must be a Buffer' ) ;
460
470
}
@@ -475,7 +485,7 @@ function encrypt(buffer, params) {
475
485
result = new Buffer ( 0 ) ;
476
486
}
477
487
478
- var key = deriveKeyAndNonce ( header , MODE_ENCRYPT ) ;
488
+ var key = deriveKeyAndNonce ( header , MODE_ENCRYPT , keyLookupCallback ) ;
479
489
var start = 0 ;
480
490
var padSize = PAD_SIZE [ header . version ] ;
481
491
var overhead = padSize ;
@@ -516,6 +526,11 @@ function encrypt(buffer, params) {
516
526
return result ;
517
527
}
518
528
529
+
530
+ function isFunction ( object ) {
531
+ return typeof ( object ) === 'function' ;
532
+ }
533
+
519
534
module . exports = {
520
535
decrypt : decrypt ,
521
536
encrypt : encrypt
0 commit comments