@webex/internal-plugin-encryption 1.161.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/encryption.js +1 -1
- package/dist/kms.js +251 -67
- package/dist/kms.js.map +1 -1
- package/package.json +8 -7
- package/src/kms.js +165 -0
- package/test/integration/spec/kms.js +85 -1
package/dist/encryption.js
CHANGED
package/dist/kms.js
CHANGED
|
@@ -46,6 +46,8 @@ var _nodeKms = require("node-kms");
|
|
|
46
46
|
|
|
47
47
|
var _nodeJose = _interopRequireDefault(require("node-jose"));
|
|
48
48
|
|
|
49
|
+
var _uuid = _interopRequireDefault(require("uuid"));
|
|
50
|
+
|
|
49
51
|
var _kmsBatcher = _interopRequireWildcard(require("./kms-batcher"));
|
|
50
52
|
|
|
51
53
|
var _kmsCertificateValidation = _interopRequireWildcard(require("./kms-certificate-validation"));
|
|
@@ -318,11 +320,193 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
318
320
|
return _promise.default.all(res.keys.map(_this6.asKey));
|
|
319
321
|
});
|
|
320
322
|
},
|
|
321
|
-
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* @typedef {Object} FetchPublicKeyResponse
|
|
326
|
+
* @property {number} status 200,400(Bad Request: Request payload missing info),404(Not Found: HSM Public Key not found),501(Not Implemented: This KMS does not support BYOK),502(Bad Gateway: KMS could not communicate with HSM)
|
|
327
|
+
* @property {UUID} requestId this is should be unique, used for debug.
|
|
328
|
+
* @property {string} publicKey
|
|
329
|
+
*/
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* get public key from kms
|
|
333
|
+
* @param {Object} options
|
|
334
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
335
|
+
* @returns {Promise.<FetchPublicKeyResponse>} response of get public key api
|
|
336
|
+
*/
|
|
337
|
+
fetchPublicKey: function fetchPublicKey(_ref8) {
|
|
322
338
|
var _this7 = this;
|
|
323
339
|
|
|
324
|
-
var
|
|
325
|
-
|
|
340
|
+
var assignedOrgId = _ref8.assignedOrgId;
|
|
341
|
+
this.logger.info('kms: fetch public key for byok');
|
|
342
|
+
return this.request({
|
|
343
|
+
method: 'retrieve',
|
|
344
|
+
uri: '/publicKey',
|
|
345
|
+
assignedOrgId: assignedOrgId
|
|
346
|
+
}).then(function (res) {
|
|
347
|
+
_this7.logger.info('kms: received public key');
|
|
348
|
+
|
|
349
|
+
return res.publicKey;
|
|
350
|
+
});
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* @typedef {Object} UploadCmkResponse
|
|
355
|
+
* @property {number} status
|
|
356
|
+
* @property {UUID} requestId
|
|
357
|
+
* @property {string} uri
|
|
358
|
+
* @property {string} keysState
|
|
359
|
+
*/
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* upload master key for one org.
|
|
363
|
+
* @param {Object} options
|
|
364
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
365
|
+
* @param {string} options.customerMasterKey the master key
|
|
366
|
+
* @returns {Promise.<UploadCmkResponse>} response of upload CMK api
|
|
367
|
+
*/
|
|
368
|
+
uploadCustomerMasterKey: function uploadCustomerMasterKey(_ref9) {
|
|
369
|
+
var _this8 = this;
|
|
370
|
+
|
|
371
|
+
var assignedOrgId = _ref9.assignedOrgId,
|
|
372
|
+
customerMasterKey = _ref9.customerMasterKey;
|
|
373
|
+
this.logger.info('kms: upload customer master key for byok');
|
|
374
|
+
return this.request({
|
|
375
|
+
method: 'create',
|
|
376
|
+
uri: '/cmk',
|
|
377
|
+
assignedOrgId: assignedOrgId,
|
|
378
|
+
customerMasterKey: customerMasterKey,
|
|
379
|
+
requestId: _uuid.default.v4()
|
|
380
|
+
}).then(function (res) {
|
|
381
|
+
_this8.logger.info('kms: finish to upload customer master key');
|
|
382
|
+
|
|
383
|
+
return res;
|
|
384
|
+
});
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* get all customer master keys for one org.
|
|
389
|
+
* @param {Object} options
|
|
390
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
391
|
+
* @returns {Promise.<ActivateCmkResponse>} response of list CMKs api
|
|
392
|
+
*/
|
|
393
|
+
listAllCustomerMasterKey: function listAllCustomerMasterKey(_ref10) {
|
|
394
|
+
var _this9 = this;
|
|
395
|
+
|
|
396
|
+
var assignedOrgId = _ref10.assignedOrgId;
|
|
397
|
+
this.logger.info('kms: get all customer master keys for byok');
|
|
398
|
+
return this.request({
|
|
399
|
+
method: 'retrieve',
|
|
400
|
+
uri: '/cmk',
|
|
401
|
+
assignedOrgId: assignedOrgId,
|
|
402
|
+
requestId: _uuid.default.v4()
|
|
403
|
+
}).then(function (res) {
|
|
404
|
+
_this9.logger.info('kms: finish to get all customer master keys');
|
|
405
|
+
|
|
406
|
+
return res;
|
|
407
|
+
});
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* @typedef {Object} ActivateCmkResponse
|
|
412
|
+
* @property {number} status
|
|
413
|
+
* @property {UUID} requestId
|
|
414
|
+
* @property {Array<CMK>} customerMasterKeys
|
|
415
|
+
*/
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
*
|
|
419
|
+
* @typedef {Object} CMK
|
|
420
|
+
* @property {string} usageState
|
|
421
|
+
* @property {UUID} assignedOrgId
|
|
422
|
+
* @property {string} uri
|
|
423
|
+
* @property {string} source
|
|
424
|
+
* @property {Date | undefined} stateUpdatedOn
|
|
425
|
+
* @property {Date | undefined} rotation
|
|
426
|
+
*/
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* change one customer master key state for one org.
|
|
430
|
+
* delete pending key, then the keyState should be 'removedclean';
|
|
431
|
+
* active pending key, then the keyState should be 'active';
|
|
432
|
+
*
|
|
433
|
+
* @param {Object} options
|
|
434
|
+
* @param {string} options.keyId the id of one customer master key, it should be a url
|
|
435
|
+
* @param {string} options.keyState one of the following: PENDING, RECOVERING,ACTIVE,REVOKED,DEACTIVATED,REENCRYPTING,RETIRED,DELETED,DISABLED,REMOVEDCLEAN,REMOVEDDIRTY;
|
|
436
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
437
|
+
* @returns {Promise.<ActivateCmkResponse>} response of list CMKs api
|
|
438
|
+
*/
|
|
439
|
+
changeCustomerMasterKeyState: function changeCustomerMasterKeyState(_ref11) {
|
|
440
|
+
var _this10 = this;
|
|
441
|
+
|
|
442
|
+
var keyId = _ref11.keyId,
|
|
443
|
+
keyState = _ref11.keyState,
|
|
444
|
+
assignedOrgId = _ref11.assignedOrgId;
|
|
445
|
+
this.logger.info('kms: change one customer master key state for byok');
|
|
446
|
+
return this.request({
|
|
447
|
+
method: 'update',
|
|
448
|
+
uri: keyId,
|
|
449
|
+
keyState: keyState,
|
|
450
|
+
assignedOrgId: assignedOrgId,
|
|
451
|
+
requestId: _uuid.default.v4()
|
|
452
|
+
}).then(function (res) {
|
|
453
|
+
_this10.logger.info('kms: finish to change the customer master key state to {}', keyState);
|
|
454
|
+
|
|
455
|
+
return res;
|
|
456
|
+
});
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* this is for test case. it will delete all CMKs, no matter what their status is. This is mainly for test purpose
|
|
461
|
+
* @param {Object} options
|
|
462
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
463
|
+
* @returns {Promise.<{status, requestId}>}
|
|
464
|
+
*/
|
|
465
|
+
deleteAllCustomerMasterKeys: function deleteAllCustomerMasterKeys(_ref12) {
|
|
466
|
+
var _this11 = this;
|
|
467
|
+
|
|
468
|
+
var assignedOrgId = _ref12.assignedOrgId;
|
|
469
|
+
this.logger.info('kms: delete all customer master keys at the same time');
|
|
470
|
+
return this.request({
|
|
471
|
+
method: 'delete',
|
|
472
|
+
uri: '/cmk',
|
|
473
|
+
assignedOrgId: assignedOrgId,
|
|
474
|
+
requestId: _uuid.default.v4()
|
|
475
|
+
}).then(function (res) {
|
|
476
|
+
_this11.logger.info('kms: finish to delete all customer master keys');
|
|
477
|
+
|
|
478
|
+
return res;
|
|
479
|
+
});
|
|
480
|
+
},
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* return to use global master key for one org.
|
|
484
|
+
* @param {Object} options
|
|
485
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
486
|
+
* @returns {Promise.<ActivateCmkResponse>} response of activate CMK api
|
|
487
|
+
*/
|
|
488
|
+
useGlobalMasterKey: function useGlobalMasterKey(_ref13) {
|
|
489
|
+
var _this12 = this;
|
|
490
|
+
|
|
491
|
+
var assignedOrgId = _ref13.assignedOrgId;
|
|
492
|
+
this.logger.info('kms: return to use global master key');
|
|
493
|
+
return this.request({
|
|
494
|
+
method: 'update',
|
|
495
|
+
uri: 'default',
|
|
496
|
+
keyState: 'ACTIVE',
|
|
497
|
+
assignedOrgId: assignedOrgId,
|
|
498
|
+
requestId: _uuid.default.v4()
|
|
499
|
+
}).then(function (res) {
|
|
500
|
+
_this12.logger.info('kms: finish to return to global master key');
|
|
501
|
+
|
|
502
|
+
return res;
|
|
503
|
+
});
|
|
504
|
+
},
|
|
505
|
+
fetchKey: function fetchKey(_ref14) {
|
|
506
|
+
var _this13 = this;
|
|
507
|
+
|
|
508
|
+
var uri = _ref14.uri,
|
|
509
|
+
onBehalfOf = _ref14.onBehalfOf;
|
|
326
510
|
|
|
327
511
|
/* istanbul ignore if */
|
|
328
512
|
if (!uri) {
|
|
@@ -336,9 +520,9 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
336
520
|
}, {
|
|
337
521
|
onBehalfOf: onBehalfOf
|
|
338
522
|
}).then(function (res) {
|
|
339
|
-
|
|
523
|
+
_this13.logger.info('kms: fetched key');
|
|
340
524
|
|
|
341
|
-
return
|
|
525
|
+
return _this13.asKey(res.key);
|
|
342
526
|
});
|
|
343
527
|
},
|
|
344
528
|
|
|
@@ -372,17 +556,17 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
372
556
|
* @returns {Promise<KMS.Request>}
|
|
373
557
|
*/
|
|
374
558
|
prepareRequest: function prepareRequest(payload, onBehalfOf) {
|
|
375
|
-
var
|
|
559
|
+
var _this14 = this;
|
|
376
560
|
|
|
377
561
|
var isECDHRequest = payload.method === 'create' && payload.uri.includes('/ecdhe');
|
|
378
562
|
return _promise.default.resolve(isECDHRequest ? partialContexts.get(this) : this._getContext()).then(function (context) {
|
|
379
|
-
|
|
563
|
+
_this14.logger.info("kms: wrapping ".concat(isECDHRequest ? 'ephemeral key' : 'kms', " request"));
|
|
380
564
|
|
|
381
565
|
var req = new _nodeKms.Request(payload);
|
|
382
566
|
var requestContext = context;
|
|
383
567
|
|
|
384
568
|
if (onBehalfOf) {
|
|
385
|
-
requestContext =
|
|
569
|
+
requestContext = _this14._contextOnBehalfOf(context, onBehalfOf);
|
|
386
570
|
}
|
|
387
571
|
|
|
388
572
|
return req.wrap(requestContext, {
|
|
@@ -390,7 +574,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
390
574
|
}).then(function () {
|
|
391
575
|
/* istanbul ignore else */
|
|
392
576
|
if (process.env.NODE_ENV !== 'production') {
|
|
393
|
-
|
|
577
|
+
_this14.logger.info('kms: request payload', _util.default.inspect((0, _omit2.default)(JSON.parse((0, _stringify.default)(req)), 'wrapped'), {
|
|
394
578
|
depth: null
|
|
395
579
|
}));
|
|
396
580
|
}
|
|
@@ -406,21 +590,21 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
406
590
|
* @returns {Promise<Object>}
|
|
407
591
|
*/
|
|
408
592
|
processKmsMessageEvent: function processKmsMessageEvent(event) {
|
|
409
|
-
var
|
|
593
|
+
var _this15 = this;
|
|
410
594
|
|
|
411
595
|
this.logger.info('kms: received kms message');
|
|
412
596
|
return _promise.default.all(event.encryption.kmsMessages.map(function (kmsMessage, index) {
|
|
413
|
-
return
|
|
414
|
-
|
|
597
|
+
return _this15._isECDHEMessage(kmsMessage).then(function (isECDHMessage) {
|
|
598
|
+
_this15.logger.info("kms: received ".concat(isECDHMessage ? 'ecdhe' : 'normal', " message"));
|
|
415
599
|
|
|
416
600
|
var res = new _nodeKms.Response(kmsMessage);
|
|
417
|
-
return _promise.default.resolve(isECDHMessage ? partialContexts.get(
|
|
601
|
+
return _promise.default.resolve(isECDHMessage ? partialContexts.get(_this15) : contexts.get(_this15)) // eslint-disable-next-line max-nested-callbacks
|
|
418
602
|
.then(function (context) {
|
|
419
603
|
return res.unwrap(context);
|
|
420
604
|
}) // eslint-disable-next-line max-nested-callbacks
|
|
421
605
|
.then(function () {
|
|
422
606
|
if (process.env.NODE_ENV !== 'production') {
|
|
423
|
-
|
|
607
|
+
_this15.logger.info('kms: response payload', _util.default.inspect((0, _omit2.default)(JSON.parse((0, _stringify.default)(res)), 'wrapped'), {
|
|
424
608
|
depth: null
|
|
425
609
|
}));
|
|
426
610
|
}
|
|
@@ -433,9 +617,9 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
433
617
|
});
|
|
434
618
|
});
|
|
435
619
|
})).then(function () {
|
|
436
|
-
return
|
|
620
|
+
return _this15.batcher.processKmsMessageEvent(event);
|
|
437
621
|
}).catch(function (reason) {
|
|
438
|
-
|
|
622
|
+
_this15.logger.error('kms: decrypt failed', reason.stack);
|
|
439
623
|
|
|
440
624
|
return _promise.default.reject(reason);
|
|
441
625
|
}).then(function () {
|
|
@@ -484,34 +668,34 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
484
668
|
* @returns {Promise<Object>}
|
|
485
669
|
*/
|
|
486
670
|
request: function request(payload) {
|
|
487
|
-
var
|
|
671
|
+
var _this16 = this;
|
|
488
672
|
|
|
489
|
-
var
|
|
490
|
-
timeout =
|
|
491
|
-
onBehalfOf =
|
|
673
|
+
var _ref15 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
674
|
+
timeout = _ref15.timeout,
|
|
675
|
+
onBehalfOf = _ref15.onBehalfOf;
|
|
492
676
|
|
|
493
677
|
timeout = timeout || this.config.kmsInitialTimeout; // Note: this should only happen when we're using the async kms batcher;
|
|
494
678
|
// once we implement the sync batcher, this'll need to be smarter.
|
|
495
679
|
|
|
496
680
|
return this.webex.internal.mercury.connect().then(function () {
|
|
497
|
-
return
|
|
681
|
+
return _this16.prepareRequest(payload, onBehalfOf);
|
|
498
682
|
}).then(function (req) {
|
|
499
683
|
req[_kmsBatcher.TIMEOUT_SYMBOL] = timeout;
|
|
500
|
-
return
|
|
684
|
+
return _this16.batcher.request(req);
|
|
501
685
|
}) // High complexity is due to attempt at test mode resiliency
|
|
502
686
|
// eslint-disable-next-line complexity
|
|
503
687
|
.catch(function (reason) {
|
|
504
688
|
if (process.env.NODE_ENV === 'test' && (reason.status === 403 || reason.statusCode === 403) && reason.message.match(/Failed to resolve authorization token in KmsMessage request for user/)) {
|
|
505
|
-
|
|
689
|
+
_this16.logger.warn('kms: rerequested key due to test-mode kms auth failure');
|
|
506
690
|
|
|
507
|
-
return
|
|
691
|
+
return _this16.request(payload, {
|
|
508
692
|
onBehalfOf: onBehalfOf
|
|
509
693
|
});
|
|
510
694
|
} // KMS Error. Notify the user
|
|
511
695
|
|
|
512
696
|
|
|
513
697
|
if (reason instanceof _kmsCertificateValidation.KMSError) {
|
|
514
|
-
|
|
698
|
+
_this16.webex.trigger('client:InvalidRequestError');
|
|
515
699
|
|
|
516
700
|
return _promise.default.reject(reason);
|
|
517
701
|
} // Ideally, most or all of the code below would go in kms-batcher, but
|
|
@@ -523,14 +707,14 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
523
707
|
/* istanbul ignore else */
|
|
524
708
|
if (process.env.NODE_ENV !== 'production') {
|
|
525
709
|
/* istanbul ignore next: reason.stack vs stack difficult to control in test */
|
|
526
|
-
|
|
710
|
+
_this16.logger.info('kms: request error', reason.stack || reason);
|
|
527
711
|
}
|
|
528
712
|
|
|
529
713
|
consoleDebug("timeout ".concat(timeout));
|
|
530
714
|
timeout *= 2;
|
|
531
715
|
|
|
532
|
-
if (timeout >=
|
|
533
|
-
|
|
716
|
+
if (timeout >= _this16.config.ecdhMaxTimeout) {
|
|
717
|
+
_this16.logger.info('kms: exceeded maximum KMS request retries');
|
|
534
718
|
|
|
535
719
|
return _promise.default.reject(reason);
|
|
536
720
|
} // Peek ahead to make sure we don't reset the timeout if the next timeout
|
|
@@ -539,20 +723,20 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
539
723
|
|
|
540
724
|
var nextTimeout = timeout * 2;
|
|
541
725
|
|
|
542
|
-
if (timeout >=
|
|
543
|
-
|
|
726
|
+
if (timeout >= _this16.config.kmsMaxTimeout && nextTimeout < _this16.config.ecdhMaxTimeout) {
|
|
727
|
+
_this16.logger.info('kms: exceeded maximum KMS request retries; negotiating new ecdh key');
|
|
544
728
|
/* istanbul ignore else */
|
|
545
729
|
|
|
546
730
|
|
|
547
731
|
if (process.env.NODE_ENV !== 'production') {
|
|
548
|
-
|
|
732
|
+
_this16.logger.info('kms: timeout/maxtimeout', timeout, _this16.config.kmsMaxTimeout);
|
|
549
733
|
}
|
|
550
734
|
|
|
551
|
-
contexts.delete(
|
|
735
|
+
contexts.delete(_this16);
|
|
552
736
|
timeout = 0;
|
|
553
737
|
}
|
|
554
738
|
|
|
555
|
-
return
|
|
739
|
+
return _this16.request(payload, {
|
|
556
740
|
timeout: timeout,
|
|
557
741
|
onBehalfOf: onBehalfOf
|
|
558
742
|
});
|
|
@@ -578,7 +762,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
578
762
|
* @returns {Promise<Object>}
|
|
579
763
|
*/
|
|
580
764
|
_getContext: function _getContext() {
|
|
581
|
-
var
|
|
765
|
+
var _this17 = this;
|
|
582
766
|
|
|
583
767
|
var promise = contexts.get(this);
|
|
584
768
|
|
|
@@ -588,15 +772,15 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
588
772
|
promise.then(function (context) {
|
|
589
773
|
var expiresIn = context.ephemeralKey.expirationDate - (0, _now.default)() - 30000;
|
|
590
774
|
(0, _commonTimers.safeSetTimeout)(function () {
|
|
591
|
-
return contexts.delete(
|
|
775
|
+
return contexts.delete(_this17);
|
|
592
776
|
}, expiresIn);
|
|
593
777
|
});
|
|
594
778
|
}
|
|
595
779
|
|
|
596
|
-
return _promise.default.all([promise, this._getAuthorization()]).then(function (
|
|
597
|
-
var
|
|
598
|
-
context =
|
|
599
|
-
authorization =
|
|
780
|
+
return _promise.default.all([promise, this._getAuthorization()]).then(function (_ref16) {
|
|
781
|
+
var _ref17 = (0, _slicedToArray2.default)(_ref16, 2),
|
|
782
|
+
context = _ref17[0],
|
|
783
|
+
authorization = _ref17[1];
|
|
600
784
|
|
|
601
785
|
context.clientInfo.credential.bearer = authorization;
|
|
602
786
|
return context;
|
|
@@ -609,8 +793,8 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
609
793
|
*/
|
|
610
794
|
_getKMSCluster: function _getKMSCluster() {
|
|
611
795
|
this.logger.info('kms: retrieving KMS cluster');
|
|
612
|
-
return this._getKMSDetails().then(function (
|
|
613
|
-
var kmsCluster =
|
|
796
|
+
return this._getKMSDetails().then(function (_ref18) {
|
|
797
|
+
var kmsCluster = _ref18.kmsCluster;
|
|
614
798
|
return kmsCluster;
|
|
615
799
|
});
|
|
616
800
|
},
|
|
@@ -620,7 +804,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
620
804
|
* @returns {Promise<Object>}
|
|
621
805
|
*/
|
|
622
806
|
_getKMSDetails: function _getKMSDetails() {
|
|
623
|
-
var
|
|
807
|
+
var _this18 = this;
|
|
624
808
|
|
|
625
809
|
var details = kmsDetails.get(this);
|
|
626
810
|
|
|
@@ -630,13 +814,13 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
630
814
|
service: 'encryption',
|
|
631
815
|
resource: "/kms/".concat(this.webex.internal.device.userId)
|
|
632
816
|
}).then(function (res) {
|
|
633
|
-
|
|
817
|
+
_this18.logger.info('kms: fetched KMS details');
|
|
634
818
|
|
|
635
819
|
var body = res.body;
|
|
636
820
|
body.rsaPublicKey = JSON.parse(body.rsaPublicKey);
|
|
637
821
|
return body;
|
|
638
822
|
}).catch(function (reason) {
|
|
639
|
-
|
|
823
|
+
_this18.logger.error('kms: failed to fetch KMS details', reason);
|
|
640
824
|
|
|
641
825
|
return _promise.default.reject(reason);
|
|
642
826
|
});
|
|
@@ -652,8 +836,8 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
652
836
|
*/
|
|
653
837
|
_getKMSStaticPubKey: function _getKMSStaticPubKey() {
|
|
654
838
|
this.logger.info('kms: retrieving KMS static public key');
|
|
655
|
-
return this._getKMSDetails().then(function (
|
|
656
|
-
var rsaPublicKey =
|
|
839
|
+
return this._getKMSDetails().then(function (_ref19) {
|
|
840
|
+
var rsaPublicKey = _ref19.rsaPublicKey;
|
|
657
841
|
return rsaPublicKey;
|
|
658
842
|
});
|
|
659
843
|
},
|
|
@@ -663,19 +847,19 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
663
847
|
* @returns {Promise<Object>}
|
|
664
848
|
*/
|
|
665
849
|
_prepareContext: function _prepareContext() {
|
|
666
|
-
var
|
|
850
|
+
var _this19 = this;
|
|
667
851
|
|
|
668
852
|
this.logger.info('kms: creating context');
|
|
669
853
|
var context = new _nodeKms.Context();
|
|
670
|
-
return _promise.default.all([this._getKMSStaticPubKey().then((0, _kmsCertificateValidation.default)(this.config.caroots)), this._getAuthorization()]).then(function (
|
|
671
|
-
var
|
|
672
|
-
kmsStaticPubKey =
|
|
673
|
-
authorization =
|
|
854
|
+
return _promise.default.all([this._getKMSStaticPubKey().then((0, _kmsCertificateValidation.default)(this.config.caroots)), this._getAuthorization()]).then(function (_ref20) {
|
|
855
|
+
var _ref21 = (0, _slicedToArray2.default)(_ref20, 2),
|
|
856
|
+
kmsStaticPubKey = _ref21[0],
|
|
857
|
+
authorization = _ref21[1];
|
|
674
858
|
|
|
675
859
|
context.clientInfo = {
|
|
676
|
-
clientId:
|
|
860
|
+
clientId: _this19.webex.internal.device.url,
|
|
677
861
|
credential: {
|
|
678
|
-
userId:
|
|
862
|
+
userId: _this19.webex.internal.device.userId,
|
|
679
863
|
bearer: authorization
|
|
680
864
|
}
|
|
681
865
|
};
|
|
@@ -683,38 +867,38 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
683
867
|
key: kmsStaticPubKey
|
|
684
868
|
};
|
|
685
869
|
|
|
686
|
-
|
|
870
|
+
_this19.logger.info('kms: creating local ephemeral key');
|
|
687
871
|
|
|
688
872
|
return context.createECDHKey();
|
|
689
873
|
}).then(function (localECDHKey) {
|
|
690
874
|
context.ephemeralKey = localECDHKey;
|
|
691
|
-
partialContexts.set(
|
|
692
|
-
return _promise.default.all([localECDHKey.asKey(),
|
|
693
|
-
}).then(function (
|
|
694
|
-
var
|
|
695
|
-
localECDHKey =
|
|
696
|
-
cluster =
|
|
875
|
+
partialContexts.set(_this19, context);
|
|
876
|
+
return _promise.default.all([localECDHKey.asKey(), _this19._getKMSCluster()]);
|
|
877
|
+
}).then(function (_ref22) {
|
|
878
|
+
var _ref23 = (0, _slicedToArray2.default)(_ref22, 2),
|
|
879
|
+
localECDHKey = _ref23[0],
|
|
880
|
+
cluster = _ref23[1];
|
|
697
881
|
|
|
698
|
-
|
|
882
|
+
_this19.logger.info('kms: submitting ephemeral key request');
|
|
699
883
|
|
|
700
|
-
return
|
|
884
|
+
return _this19.request({
|
|
701
885
|
uri: "".concat(cluster, "/ecdhe"),
|
|
702
886
|
method: 'create',
|
|
703
887
|
jwk: localECDHKey.toJSON()
|
|
704
888
|
});
|
|
705
889
|
}).then(function (res) {
|
|
706
|
-
|
|
890
|
+
_this19.logger.info('kms: deriving final ephemeral key');
|
|
707
891
|
|
|
708
892
|
return context.deriveEphemeralKey(res.key);
|
|
709
893
|
}).then(function (key) {
|
|
710
894
|
context.ephemeralKey = key;
|
|
711
|
-
partialContexts.delete(
|
|
895
|
+
partialContexts.delete(_this19);
|
|
712
896
|
|
|
713
|
-
|
|
897
|
+
_this19.logger.info('kms: derived final ephemeral key');
|
|
714
898
|
|
|
715
899
|
return context;
|
|
716
900
|
}).catch(function (reason) {
|
|
717
|
-
|
|
901
|
+
_this19.logger.error('kms: failed to negotiate ephemeral key', reason);
|
|
718
902
|
|
|
719
903
|
return _promise.default.reject(reason);
|
|
720
904
|
});
|
|
@@ -747,7 +931,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
747
931
|
context.ephemeralKey = originalContext.ephemeralKey;
|
|
748
932
|
return context;
|
|
749
933
|
},
|
|
750
|
-
version: "
|
|
934
|
+
version: "2.2.0"
|
|
751
935
|
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "fetchKey", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "fetchKey"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "_getContext", [_common.oneFlight], (0, _getOwnPropertyDescriptor.default)(_obj, "_getContext"), _obj)), _obj)));
|
|
752
936
|
|
|
753
937
|
var _default = KMS;
|
package/dist/kms.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["contexts","kmsDetails","partialContexts","consoleDebug","require","KMS","WebexPlugin","extend","keyFactory","uri","onBehalfOf","namespace","children","batcher","KMSBatcher","bindKey","kro","kroUri","key","keyUri","logger","info","reject","Error","request","method","resourceUri","then","res","createResource","userIds","keyUris","keys","reduce","uris","k","push","length","resource","addAuthorization","authIds","concat","authorizations","listAuthorizations","removeAuthorization","authId","userId","querystring","stringify","createUnboundKeys","count","all","map","asKey","fetchKey","ping","jose","JWK","jwk","prepareRequest","payload","isECDHRequest","includes","resolve","get","_getContext","context","req","Request","requestContext","_contextOnBehalfOf","wrap","serverKey","process","env","NODE_ENV","util","inspect","JSON","parse","depth","processKmsMessageEvent","event","encryption","kmsMessages","kmsMessage","index","_isECDHEMessage","isECDHMessage","Response","unwrap","catch","reason","error","stack","decryptKmsMessage","body","_getKMSStaticPubKey","kmsStaticPubKey","fields","split","header","base64url","decode","kid","timeout","config","kmsInitialTimeout","webex","internal","mercury","connect","TIMEOUT_SYMBOL","status","statusCode","message","match","warn","KMSError","trigger","ecdhMaxTimeout","nextTimeout","kmsMaxTimeout","delete","_getAuthorization","credentials","getUserToken","token","access_token","promise","_prepareContext","set","expiresIn","ephemeralKey","expirationDate","authorization","clientInfo","credential","bearer","_getKMSCluster","_getKMSDetails","kmsCluster","details","service","device","rsaPublicKey","Context","caroots","clientId","url","serverInfo","createECDHKey","localECDHKey","cluster","toJSON","deriveEphemeralKey","originalContext","oneFlight"],"sources":["kms.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport querystring from 'querystring';\nimport util from 'util';\n\nimport {safeSetTimeout} from '@webex/common-timers';\nimport {oneFlight} from '@webex/common';\nimport {WebexPlugin} from '@webex/webex-core';\nimport {Context, Request, Response} from 'node-kms';\nimport jose from 'node-jose';\nimport {omit} from 'lodash';\n\nimport KMSBatcher, {TIMEOUT_SYMBOL} from './kms-batcher';\nimport validateKMS, {KMSError} from './kms-certificate-validation';\n\nconst contexts = new WeakMap();\nconst kmsDetails = new WeakMap();\nconst partialContexts = new WeakMap();\n\nconst consoleDebug = require('debug')('kms');\n\n/**\n * @class\n */\nconst KMS = WebexPlugin.extend({\n namespace: 'Encryption',\n\n children: {\n batcher: KMSBatcher\n },\n\n /**\n * Binds a key to a resource\n * @param {Object} options\n * @param {KMSResourceObject} options.kro\n * @param {string} options.kroUri\n * @param {Key} options.key\n * @param {string} options.keyUri\n * @returns {Promise<Key>}\n */\n bindKey({\n kro, kroUri, key, keyUri\n }) {\n kroUri = kroUri || kro.uri;\n keyUri = keyUri || key.uri;\n\n this.logger.info('kms: binding key to resource');\n\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n /* istanbul ignore if */\n if (!keyUri) {\n return Promise.reject(new Error('`key` or `keyUri` is required'));\n }\n\n return this.request({\n method: 'update',\n resourceUri: kroUri,\n uri: keyUri\n })\n .then((res) => {\n this.logger.info('kms: bound key to resource');\n\n return res.key;\n });\n },\n\n /**\n * Creates a new KMS Resource\n * @param {Object} options\n * @param {Array<string>} options.userIds\n * @param {Array<string>} options.keyUris\n * @param {Key} options.key\n * @param {Array<Keys>} options.keys\n * @returns {Promise<KMSResourceObject>}\n */\n createResource({\n userIds, keyUris, key, keys\n }) {\n keyUris = keyUris || [];\n /* istanbul ignore if */\n if (keys) {\n keyUris = keys.reduce((uris, k) => {\n uris.push(k.uri);\n\n return uris;\n }, keyUris);\n }\n\n /* istanbul ignore else */\n if (key) {\n keyUris.push(key.uri);\n }\n\n /* istanbul ignore if */\n if (keyUris.length === 0) {\n return Promise.reject(new Error('Cannot create KMS Resource without at least one keyUri'));\n }\n\n this.logger.info('kms: creating resource');\n\n return this.request({\n method: 'create',\n uri: '/resources',\n userIds,\n keyUris\n })\n .then((res) => {\n this.logger.info('kms: created resource');\n\n return res.resource;\n });\n },\n\n /**\n * Authorizes a user or KRO to a KRO\n * @param {Object} options\n * @param {Array<string>} options.userIds\n * @param {Array<string>} options.authIds interchangable with userIds\n * @param {KMSResourceObject} options.kro the target kro\n * @param {string} options.kroUri\n * @returns {Promise<KMSAuthorizationObject>}\n */\n addAuthorization({\n userIds, authIds, kro, kroUri\n }) {\n userIds = userIds || [];\n kroUri = kroUri || kro.uri;\n\n if (authIds) {\n userIds = userIds.concat(authIds);\n }\n\n /* istanbul ignore if */\n if (userIds.length === 0) {\n return Promise.reject(new Error('Cannot add authorization without userIds or authIds'));\n }\n\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n this.logger.info('kms: adding authorization to kms resource');\n\n return this.request({\n method: 'create',\n uri: '/authorizations',\n resourceUri: kroUri,\n userIds\n })\n .then((res) => {\n this.logger.info('kms: added authorization');\n\n return res.authorizations;\n });\n },\n\n /**\n * Retrieve a list of users that have been authorized to the KRO\n * @param {Object} options\n * @param {KMSResourceObject} options.kro the target kro\n * @param {string} options.kroUri\n * @returns {Array<authId>}\n */\n listAuthorizations({kro, kroUri}) {\n kroUri = kroUri || kro.uri;\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n return this.request({\n method: 'retrieve',\n uri: `${kroUri}/authorizations`\n })\n .then((res) => {\n this.logger.info('kms: retrieved authorization list');\n\n return res.authorizations;\n });\n },\n\n /**\n * Deauthorizes a user or KRO from a KRO\n * @param {Object} options\n * @param {string} options.userId\n * @param {string} options.authId interchangable with userIds\n * @param {KMSResourceObject} options.kro the target kro\n * @param {string} options.kroUri\n * @returns {Promise<KMSAuthorizationObject>}\n */\n removeAuthorization({\n authId, userId, kro, kroUri\n }) {\n authId = authId || userId;\n kroUri = kroUri || kro.uri;\n\n /* istanbul ignore if */\n if (!authId) {\n return Promise.reject(new Error('Cannot remove authorization without authId'));\n }\n\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n this.logger.info('kms: removing authorization from kms resource');\n\n return this.request({\n method: 'delete',\n uri: `${kroUri}/authorizations?${querystring.stringify({authId})}`\n })\n .then((res) => {\n this.logger.info('kms: removed authorization');\n\n return res.authorizations;\n });\n },\n\n /**\n * Requests `count` unbound keys from the kms\n * @param {Object} options\n * @param {Number} options.count\n * @returns {Array<Key>}\n */\n createUnboundKeys({count}) {\n this.logger.info(`kms: request ${count} unbound keys`);\n\n /* istanbul ignore if */\n if (!count) {\n return Promise.reject(new Error('`options.count` is required'));\n }\n\n return this.request({\n method: 'create',\n uri: '/keys',\n count\n })\n .then((res) => {\n this.logger.info('kms: received unbound keys');\n\n return Promise.all(res.keys.map(this.asKey));\n });\n },\n\n /**\n * Fetches the specified key from the kms\n * @param {Object} options\n * @param {string} options.uri\n * @param {string} options.onBehalfOf The id of a user, upon whose behalf, the key is to be retrieved or undefined if retrieval is for the active user\n * @returns {Promise<Key>}\n */\n // Ideally, this would be done via the kms batcher, but other than request id,\n // there isn't any other userful key in a kms response to match it to a\n // request. as such, we need the batcher to group requests, but one flight to\n // make sure we don't make the same request multiple times.\n @oneFlight({\n keyFactory: ({uri, onBehalfOf}) => `${uri}/${onBehalfOf}`\n })\n fetchKey({uri, onBehalfOf}) {\n /* istanbul ignore if */\n if (!uri) {\n return Promise.reject(new Error('`options.uri` is required'));\n }\n\n this.logger.info('kms: fetching key');\n\n return this.request({\n method: 'retrieve',\n uri\n }, {onBehalfOf})\n .then((res) => {\n this.logger.info('kms: fetched key');\n\n return this.asKey(res.key);\n });\n },\n\n /**\n * Pings the kms. Mostly for testing\n * @returns {Promise}\n */\n ping() {\n return this.request({\n method: 'update',\n uri: '/ping'\n });\n },\n\n /**\n * Ensures a key obect is Key instance\n * @param {Object} key\n * @returns {Promise<Key>}\n */\n asKey(key) {\n return jose.JWK.asKey(key.jwk)\n .then((jwk) => {\n key.jwk = jwk;\n\n return key;\n });\n },\n\n /**\n * Adds appropriate metadata to the KMS request\n * @param {Object} payload\n * @param {Object} onBehalfOf Optional parameter to prepare the request on behalf of another user\n * @returns {Promise<KMS.Request>}\n */\n prepareRequest(payload, onBehalfOf) {\n const isECDHRequest = payload.method === 'create' && payload.uri.includes('/ecdhe');\n\n return Promise.resolve(isECDHRequest ? partialContexts.get(this) : this._getContext())\n .then((context) => {\n this.logger.info(`kms: wrapping ${isECDHRequest ? 'ephemeral key' : 'kms'} request`);\n const req = new Request(payload);\n let requestContext = context;\n\n if (onBehalfOf) {\n requestContext = this._contextOnBehalfOf(context, onBehalfOf);\n }\n\n return req.wrap(requestContext, {serverKey: isECDHRequest})\n .then(() => {\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info('kms: request payload', util.inspect(omit(JSON.parse(JSON.stringify(req)), 'wrapped'), {depth: null}));\n }\n\n return req;\n });\n });\n },\n\n /**\n * Accepts a kms message event, decrypts it, and passes it to the batcher\n * @param {Object} event\n * @returns {Promise<Object>}\n */\n processKmsMessageEvent(event) {\n this.logger.info('kms: received kms message');\n\n return Promise.all(event.encryption.kmsMessages.map((kmsMessage, index) => this._isECDHEMessage(kmsMessage)\n .then((isECDHMessage) => {\n this.logger.info(`kms: received ${isECDHMessage ? 'ecdhe' : 'normal'} message`);\n const res = new Response(kmsMessage);\n\n return Promise.resolve(isECDHMessage ? partialContexts.get(this) : contexts.get(this))\n // eslint-disable-next-line max-nested-callbacks\n .then((context) => res.unwrap(context))\n // eslint-disable-next-line max-nested-callbacks\n .then(() => {\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info('kms: response payload', util.inspect(omit(JSON.parse(JSON.stringify(res)), 'wrapped'), {depth: null}));\n }\n })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => { event.encryption.kmsMessages[index] = res; })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => res);\n })))\n .then(() => this.batcher.processKmsMessageEvent(event))\n .catch((reason) => {\n this.logger.error('kms: decrypt failed', reason.stack);\n\n return Promise.reject(reason);\n })\n .then(() => event);\n },\n\n /**\n * Decrypts a kms message\n * @param {Object} kmsMessage\n * @returns {Promise<Object>}\n */\n decryptKmsMessage(kmsMessage) {\n const res = new Response(kmsMessage);\n\n return contexts.get(this)\n .then((context) => res.unwrap(context))\n .then(() => res.body);\n },\n\n /**\n * Determines if the kms message is an ecdhe message or a normal message\n * @param {Object} kmsMessage\n * @returns {Promise<boolean>}\n */\n _isECDHEMessage(kmsMessage) {\n return this._getKMSStaticPubKey()\n .then((kmsStaticPubKey) => {\n const fields = kmsMessage.split('.');\n\n if (fields.length !== 3) {\n return false;\n }\n\n const header = JSON.parse(jose.util.base64url.decode(fields[0]));\n\n return header.kid === kmsStaticPubKey.kid;\n });\n },\n\n /**\n * Sends a request to the kms\n * @param {Object} payload\n * @param {Object} options\n * @param {Number} options.timeout (internal)\n * @param {string} options.onBehalfOf Run the request on behalf of another user (UUID), used in compliance scenarios\n * @returns {Promise<Object>}\n */\n request(payload, {timeout, onBehalfOf} = {}) {\n timeout = timeout || this.config.kmsInitialTimeout;\n\n // Note: this should only happen when we're using the async kms batcher;\n // once we implement the sync batcher, this'll need to be smarter.\n return this.webex.internal.mercury.connect()\n .then(() => this.prepareRequest(payload, onBehalfOf))\n .then((req) => {\n req[TIMEOUT_SYMBOL] = timeout;\n\n return this.batcher.request(req);\n })\n // High complexity is due to attempt at test mode resiliency\n // eslint-disable-next-line complexity\n .catch((reason) => {\n if (process.env.NODE_ENV === 'test' && (reason.status === 403 || reason.statusCode === 403) && reason.message.match(/Failed to resolve authorization token in KmsMessage request for user/)) {\n this.logger.warn('kms: rerequested key due to test-mode kms auth failure');\n\n return this.request(payload, {onBehalfOf});\n }\n\n // KMS Error. Notify the user\n if (reason instanceof KMSError) {\n this.webex.trigger('client:InvalidRequestError');\n\n return Promise.reject(reason);\n }\n\n // Ideally, most or all of the code below would go in kms-batcher, but\n // but batching needs at least one more round of refactoring for that to\n // work.\n if (!reason.statusCode && !reason.status) {\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n /* istanbul ignore next: reason.stack vs stack difficult to control in test */\n this.logger.info('kms: request error', reason.stack || reason);\n }\n\n consoleDebug(`timeout ${timeout}`);\n timeout *= 2;\n\n if (timeout >= this.config.ecdhMaxTimeout) {\n this.logger.info('kms: exceeded maximum KMS request retries');\n\n return Promise.reject(reason);\n }\n\n // Peek ahead to make sure we don't reset the timeout if the next timeout\n // will exceed the maximum timeout for renegotiating ECDH keys.\n const nextTimeout = timeout * 2;\n\n if (timeout >= this.config.kmsMaxTimeout && nextTimeout < this.config.ecdhMaxTimeout) {\n this.logger.info('kms: exceeded maximum KMS request retries; negotiating new ecdh key');\n\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info('kms: timeout/maxtimeout', timeout, this.config.kmsMaxTimeout);\n }\n\n contexts.delete(this);\n timeout = 0;\n }\n\n return this.request(payload, {timeout, onBehalfOf});\n }\n\n return Promise.reject(reason);\n });\n },\n\n /**\n * @private\n * @returns {Promise<string>}\n */\n _getAuthorization() {\n return this.webex.credentials.getUserToken('spark:kms')\n .then((token) => token.access_token);\n },\n\n @oneFlight\n /**\n * @private\n * @param {String} onBehalfOf create context on behalf of another user, undefined when this is not necessary\n * @returns {Promise<Object>}\n */\n _getContext() {\n let promise = contexts.get(this);\n\n if (!promise) {\n promise = this._prepareContext();\n contexts.set(this, promise);\n promise.then((context) => {\n const expiresIn = context.ephemeralKey.expirationDate - Date.now() - 30000;\n\n safeSetTimeout(() => contexts.delete(this), expiresIn);\n });\n }\n\n return Promise.all([\n promise,\n this._getAuthorization()\n ])\n .then(([context, authorization]) => {\n context.clientInfo.credential.bearer = authorization;\n\n return context;\n });\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _getKMSCluster() {\n this.logger.info('kms: retrieving KMS cluster');\n\n return this._getKMSDetails()\n .then(({kmsCluster}) => kmsCluster);\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _getKMSDetails() {\n let details = kmsDetails.get(this);\n\n if (!details) {\n this.logger.info('kms: fetching KMS details');\n details = this.webex.request({\n service: 'encryption',\n resource: `/kms/${this.webex.internal.device.userId}`\n })\n .then((res) => {\n this.logger.info('kms: fetched KMS details');\n const {body} = res;\n\n body.rsaPublicKey = JSON.parse(body.rsaPublicKey);\n\n return body;\n })\n .catch((reason) => {\n this.logger.error('kms: failed to fetch KMS details', reason);\n\n return Promise.reject(reason);\n });\n\n kmsDetails.set(this, details);\n }\n\n return details;\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _getKMSStaticPubKey() {\n this.logger.info('kms: retrieving KMS static public key');\n\n return this._getKMSDetails()\n .then(({rsaPublicKey}) => rsaPublicKey);\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _prepareContext() {\n this.logger.info('kms: creating context');\n const context = new Context();\n\n return Promise.all([\n this._getKMSStaticPubKey().then(validateKMS(this.config.caroots)),\n this._getAuthorization()\n ])\n .then(([kmsStaticPubKey, authorization]) => {\n context.clientInfo = {\n clientId: this.webex.internal.device.url,\n credential: {\n userId: this.webex.internal.device.userId,\n bearer: authorization\n }\n };\n\n context.serverInfo = {\n key: kmsStaticPubKey\n };\n\n this.logger.info('kms: creating local ephemeral key');\n\n return context.createECDHKey();\n })\n .then((localECDHKey) => {\n context.ephemeralKey = localECDHKey;\n partialContexts.set(this, context);\n\n return Promise.all([localECDHKey.asKey(), this._getKMSCluster()]);\n })\n .then(([localECDHKey, cluster]) => {\n this.logger.info('kms: submitting ephemeral key request');\n\n return this.request({\n uri: `${cluster}/ecdhe`,\n method: 'create',\n jwk: localECDHKey.toJSON()\n });\n })\n .then((res) => {\n this.logger.info('kms: deriving final ephemeral key');\n\n return context.deriveEphemeralKey(res.key);\n })\n .then((key) => {\n context.ephemeralKey = key;\n partialContexts.delete(this);\n this.logger.info('kms: derived final ephemeral key');\n\n return context;\n })\n .catch((reason) => {\n this.logger.error('kms: failed to negotiate ephemeral key', reason);\n\n return Promise.reject(reason);\n });\n },\n\n /**\n * KMS 'retrieve' requests can be made on behalf of another user. This is useful\n * for scenarios such as eDiscovery. i.e. Where an authorized compliance officer is\n * entitled to retrieve content generated by any organisational user.\n * As the KMSContext is cached, updating it will affect separate requests. Hence when\n * making a request onBehalfOf another user create a new context for just this request.\n * However this context will be 'light' as it only needs to change one field.\n * @param {Object} originalContext - The base context to 'copy'\n * @param {String} onBehalfOf - The user specified in the new context\n * @returns {Context} A 'copy' of the existing context with a new user specified\n * @private\n */\n _contextOnBehalfOf(originalContext, onBehalfOf) {\n const context = new Context();\n\n context.clientInfo = context.clientInfo = {\n clientId: originalContext.clientInfo.clientId,\n credential: {\n userId: onBehalfOf,\n onBehalfOf, // Supports running onBehalfOf self. i.e. A CO which calls onBehalfOf with CO.id.\n bearer: originalContext.clientInfo.credential.bearer\n }\n };\n context.serverInfo = originalContext.serverInfo;\n context.ephemeralKey = originalContext.ephemeralKey;\n\n return context;\n }\n});\n\nexport default KMS;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["contexts","kmsDetails","partialContexts","consoleDebug","require","KMS","WebexPlugin","extend","keyFactory","uri","onBehalfOf","namespace","children","batcher","KMSBatcher","bindKey","kro","kroUri","key","keyUri","logger","info","reject","Error","request","method","resourceUri","then","res","createResource","userIds","keyUris","keys","reduce","uris","k","push","length","resource","addAuthorization","authIds","concat","authorizations","listAuthorizations","removeAuthorization","authId","userId","querystring","stringify","createUnboundKeys","count","all","map","asKey","fetchPublicKey","assignedOrgId","publicKey","uploadCustomerMasterKey","customerMasterKey","requestId","uuid","v4","listAllCustomerMasterKey","changeCustomerMasterKeyState","keyId","keyState","deleteAllCustomerMasterKeys","useGlobalMasterKey","fetchKey","ping","jose","JWK","jwk","prepareRequest","payload","isECDHRequest","includes","resolve","get","_getContext","context","req","Request","requestContext","_contextOnBehalfOf","wrap","serverKey","process","env","NODE_ENV","util","inspect","JSON","parse","depth","processKmsMessageEvent","event","encryption","kmsMessages","kmsMessage","index","_isECDHEMessage","isECDHMessage","Response","unwrap","catch","reason","error","stack","decryptKmsMessage","body","_getKMSStaticPubKey","kmsStaticPubKey","fields","split","header","base64url","decode","kid","timeout","config","kmsInitialTimeout","webex","internal","mercury","connect","TIMEOUT_SYMBOL","status","statusCode","message","match","warn","KMSError","trigger","ecdhMaxTimeout","nextTimeout","kmsMaxTimeout","delete","_getAuthorization","credentials","getUserToken","token","access_token","promise","_prepareContext","set","expiresIn","ephemeralKey","expirationDate","authorization","clientInfo","credential","bearer","_getKMSCluster","_getKMSDetails","kmsCluster","details","service","device","rsaPublicKey","Context","caroots","clientId","url","serverInfo","createECDHKey","localECDHKey","cluster","toJSON","deriveEphemeralKey","originalContext","oneFlight"],"sources":["kms.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport querystring from 'querystring';\nimport util from 'util';\n\nimport {safeSetTimeout} from '@webex/common-timers';\nimport {oneFlight} from '@webex/common';\nimport {WebexPlugin} from '@webex/webex-core';\nimport {Context, Request, Response} from 'node-kms';\nimport jose from 'node-jose';\nimport {omit} from 'lodash';\nimport uuid from 'uuid';\n\nimport KMSBatcher, {TIMEOUT_SYMBOL} from './kms-batcher';\nimport validateKMS, {KMSError} from './kms-certificate-validation';\n\nconst contexts = new WeakMap();\nconst kmsDetails = new WeakMap();\nconst partialContexts = new WeakMap();\n\nconst consoleDebug = require('debug')('kms');\n\n/**\n * @class\n */\nconst KMS = WebexPlugin.extend({\n namespace: 'Encryption',\n\n children: {\n batcher: KMSBatcher\n },\n\n /**\n * Binds a key to a resource\n * @param {Object} options\n * @param {KMSResourceObject} options.kro\n * @param {string} options.kroUri\n * @param {Key} options.key\n * @param {string} options.keyUri\n * @returns {Promise<Key>}\n */\n bindKey({\n kro, kroUri, key, keyUri\n }) {\n kroUri = kroUri || kro.uri;\n keyUri = keyUri || key.uri;\n\n this.logger.info('kms: binding key to resource');\n\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n /* istanbul ignore if */\n if (!keyUri) {\n return Promise.reject(new Error('`key` or `keyUri` is required'));\n }\n\n return this.request({\n method: 'update',\n resourceUri: kroUri,\n uri: keyUri\n })\n .then((res) => {\n this.logger.info('kms: bound key to resource');\n\n return res.key;\n });\n },\n\n /**\n * Creates a new KMS Resource\n * @param {Object} options\n * @param {Array<string>} options.userIds\n * @param {Array<string>} options.keyUris\n * @param {Key} options.key\n * @param {Array<Keys>} options.keys\n * @returns {Promise<KMSResourceObject>}\n */\n createResource({\n userIds, keyUris, key, keys\n }) {\n keyUris = keyUris || [];\n /* istanbul ignore if */\n if (keys) {\n keyUris = keys.reduce((uris, k) => {\n uris.push(k.uri);\n\n return uris;\n }, keyUris);\n }\n\n /* istanbul ignore else */\n if (key) {\n keyUris.push(key.uri);\n }\n\n /* istanbul ignore if */\n if (keyUris.length === 0) {\n return Promise.reject(new Error('Cannot create KMS Resource without at least one keyUri'));\n }\n\n this.logger.info('kms: creating resource');\n\n return this.request({\n method: 'create',\n uri: '/resources',\n userIds,\n keyUris\n })\n .then((res) => {\n this.logger.info('kms: created resource');\n\n return res.resource;\n });\n },\n\n /**\n * Authorizes a user or KRO to a KRO\n * @param {Object} options\n * @param {Array<string>} options.userIds\n * @param {Array<string>} options.authIds interchangable with userIds\n * @param {KMSResourceObject} options.kro the target kro\n * @param {string} options.kroUri\n * @returns {Promise<KMSAuthorizationObject>}\n */\n addAuthorization({\n userIds, authIds, kro, kroUri\n }) {\n userIds = userIds || [];\n kroUri = kroUri || kro.uri;\n\n if (authIds) {\n userIds = userIds.concat(authIds);\n }\n\n /* istanbul ignore if */\n if (userIds.length === 0) {\n return Promise.reject(new Error('Cannot add authorization without userIds or authIds'));\n }\n\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n this.logger.info('kms: adding authorization to kms resource');\n\n return this.request({\n method: 'create',\n uri: '/authorizations',\n resourceUri: kroUri,\n userIds\n })\n .then((res) => {\n this.logger.info('kms: added authorization');\n\n return res.authorizations;\n });\n },\n\n /**\n * Retrieve a list of users that have been authorized to the KRO\n * @param {Object} options\n * @param {KMSResourceObject} options.kro the target kro\n * @param {string} options.kroUri\n * @returns {Array<authId>}\n */\n listAuthorizations({kro, kroUri}) {\n kroUri = kroUri || kro.uri;\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n return this.request({\n method: 'retrieve',\n uri: `${kroUri}/authorizations`\n })\n .then((res) => {\n this.logger.info('kms: retrieved authorization list');\n\n return res.authorizations;\n });\n },\n\n /**\n * Deauthorizes a user or KRO from a KRO\n * @param {Object} options\n * @param {string} options.userId\n * @param {string} options.authId interchangable with userIds\n * @param {KMSResourceObject} options.kro the target kro\n * @param {string} options.kroUri\n * @returns {Promise<KMSAuthorizationObject>}\n */\n removeAuthorization({\n authId, userId, kro, kroUri\n }) {\n authId = authId || userId;\n kroUri = kroUri || kro.uri;\n\n /* istanbul ignore if */\n if (!authId) {\n return Promise.reject(new Error('Cannot remove authorization without authId'));\n }\n\n /* istanbul ignore if */\n if (!kroUri) {\n return Promise.reject(new Error('`kro` or `kroUri` is required'));\n }\n\n this.logger.info('kms: removing authorization from kms resource');\n\n return this.request({\n method: 'delete',\n uri: `${kroUri}/authorizations?${querystring.stringify({authId})}`\n })\n .then((res) => {\n this.logger.info('kms: removed authorization');\n\n return res.authorizations;\n });\n },\n\n /**\n * Requests `count` unbound keys from the kms\n * @param {Object} options\n * @param {Number} options.count\n * @returns {Array<Key>}\n */\n createUnboundKeys({count}) {\n this.logger.info(`kms: request ${count} unbound keys`);\n\n /* istanbul ignore if */\n if (!count) {\n return Promise.reject(new Error('`options.count` is required'));\n }\n\n return this.request({\n method: 'create',\n uri: '/keys',\n count\n })\n .then((res) => {\n this.logger.info('kms: received unbound keys');\n\n return Promise.all(res.keys.map(this.asKey));\n });\n },\n\n /**\n * @typedef {Object} FetchPublicKeyResponse\n * @property {number} status 200,400(Bad Request: Request payload missing info),404(Not Found: HSM Public Key not found),501(Not Implemented: This KMS does not support BYOK),502(Bad Gateway: KMS could not communicate with HSM)\n * @property {UUID} requestId this is should be unique, used for debug.\n * @property {string} publicKey\n */\n /**\n * get public key from kms\n * @param {Object} options\n * @param {UUID} options.assignedOrgId the orgId\n * @returns {Promise.<FetchPublicKeyResponse>} response of get public key api\n */\n fetchPublicKey({assignedOrgId}) {\n this.logger.info('kms: fetch public key for byok');\n\n return this.request({\n method: 'retrieve',\n uri: '/publicKey',\n assignedOrgId\n })\n .then((res) => {\n this.logger.info('kms: received public key');\n\n return res.publicKey;\n });\n },\n\n /**\n * @typedef {Object} UploadCmkResponse\n * @property {number} status\n * @property {UUID} requestId\n * @property {string} uri\n * @property {string} keysState\n */\n /**\n * upload master key for one org.\n * @param {Object} options\n * @param {UUID} options.assignedOrgId the orgId\n * @param {string} options.customerMasterKey the master key\n * @returns {Promise.<UploadCmkResponse>} response of upload CMK api\n */\n uploadCustomerMasterKey({assignedOrgId, customerMasterKey}) {\n this.logger.info('kms: upload customer master key for byok');\n\n return this.request({\n method: 'create',\n uri: '/cmk',\n assignedOrgId,\n customerMasterKey,\n requestId: uuid.v4()\n }).then((res) => {\n this.logger.info('kms: finish to upload customer master key');\n\n return res;\n });\n },\n\n /**\n * get all customer master keys for one org.\n * @param {Object} options\n * @param {UUID} options.assignedOrgId the orgId\n * @returns {Promise.<ActivateCmkResponse>} response of list CMKs api\n */\n listAllCustomerMasterKey({assignedOrgId}) {\n this.logger.info('kms: get all customer master keys for byok');\n\n return this.request({\n method: 'retrieve',\n uri: '/cmk',\n assignedOrgId,\n requestId: uuid.v4()\n }).then((res) => {\n this.logger.info('kms: finish to get all customer master keys');\n\n return res;\n });\n },\n\n /**\n * @typedef {Object} ActivateCmkResponse\n * @property {number} status\n * @property {UUID} requestId\n * @property {Array<CMK>} customerMasterKeys\n */\n /**\n *\n * @typedef {Object} CMK\n * @property {string} usageState\n * @property {UUID} assignedOrgId\n * @property {string} uri\n * @property {string} source\n * @property {Date | undefined} stateUpdatedOn\n * @property {Date | undefined} rotation\n */\n /**\n * change one customer master key state for one org.\n * delete pending key, then the keyState should be 'removedclean';\n * active pending key, then the keyState should be 'active';\n *\n * @param {Object} options\n * @param {string} options.keyId the id of one customer master key, it should be a url\n * @param {string} options.keyState one of the following: PENDING, RECOVERING,ACTIVE,REVOKED,DEACTIVATED,REENCRYPTING,RETIRED,DELETED,DISABLED,REMOVEDCLEAN,REMOVEDDIRTY;\n * @param {UUID} options.assignedOrgId the orgId\n * @returns {Promise.<ActivateCmkResponse>} response of list CMKs api\n */\n changeCustomerMasterKeyState({keyId, keyState, assignedOrgId}) {\n this.logger.info('kms: change one customer master key state for byok');\n\n return this.request({\n method: 'update',\n uri: keyId,\n keyState,\n assignedOrgId,\n requestId: uuid.v4()\n }).then((res) => {\n this.logger.info('kms: finish to change the customer master key state to {}', keyState);\n\n return res;\n });\n },\n\n /**\n * this is for test case. it will delete all CMKs, no matter what their status is. This is mainly for test purpose\n * @param {Object} options\n * @param {UUID} options.assignedOrgId the orgId\n * @returns {Promise.<{status, requestId}>}\n */\n deleteAllCustomerMasterKeys({assignedOrgId}) {\n this.logger.info('kms: delete all customer master keys at the same time');\n\n return this.request({\n method: 'delete',\n uri: '/cmk',\n assignedOrgId,\n requestId: uuid.v4()\n }).then((res) => {\n this.logger.info('kms: finish to delete all customer master keys');\n\n return res;\n });\n },\n\n /**\n * return to use global master key for one org.\n * @param {Object} options\n * @param {UUID} options.assignedOrgId the orgId\n * @returns {Promise.<ActivateCmkResponse>} response of activate CMK api\n */\n useGlobalMasterKey({assignedOrgId}) {\n this.logger.info('kms: return to use global master key');\n\n return this.request({\n method: 'update',\n uri: 'default',\n keyState: 'ACTIVE',\n assignedOrgId,\n requestId: uuid.v4()\n }).then((res) => {\n this.logger.info('kms: finish to return to global master key');\n\n return res;\n });\n },\n\n /**\n * Fetches the specified key from the kms\n * @param {Object} options\n * @param {string} options.uri\n * @param {string} options.onBehalfOf The id of a user, upon whose behalf, the key is to be retrieved or undefined if retrieval is for the active user\n * @returns {Promise<Key>}\n */\n // Ideally, this would be done via the kms batcher, but other than request id,\n // there isn't any other userful key in a kms response to match it to a\n // request. as such, we need the batcher to group requests, but one flight to\n // make sure we don't make the same request multiple times.\n @oneFlight({\n keyFactory: ({uri, onBehalfOf}) => `${uri}/${onBehalfOf}`\n })\n fetchKey({uri, onBehalfOf}) {\n /* istanbul ignore if */\n if (!uri) {\n return Promise.reject(new Error('`options.uri` is required'));\n }\n\n this.logger.info('kms: fetching key');\n\n return this.request({\n method: 'retrieve',\n uri\n }, {onBehalfOf})\n .then((res) => {\n this.logger.info('kms: fetched key');\n\n return this.asKey(res.key);\n });\n },\n\n /**\n * Pings the kms. Mostly for testing\n * @returns {Promise}\n */\n ping() {\n return this.request({\n method: 'update',\n uri: '/ping'\n });\n },\n\n /**\n * Ensures a key obect is Key instance\n * @param {Object} key\n * @returns {Promise<Key>}\n */\n asKey(key) {\n return jose.JWK.asKey(key.jwk)\n .then((jwk) => {\n key.jwk = jwk;\n\n return key;\n });\n },\n\n /**\n * Adds appropriate metadata to the KMS request\n * @param {Object} payload\n * @param {Object} onBehalfOf Optional parameter to prepare the request on behalf of another user\n * @returns {Promise<KMS.Request>}\n */\n prepareRequest(payload, onBehalfOf) {\n const isECDHRequest = payload.method === 'create' && payload.uri.includes('/ecdhe');\n\n return Promise.resolve(isECDHRequest ? partialContexts.get(this) : this._getContext())\n .then((context) => {\n this.logger.info(`kms: wrapping ${isECDHRequest ? 'ephemeral key' : 'kms'} request`);\n const req = new Request(payload);\n let requestContext = context;\n\n if (onBehalfOf) {\n requestContext = this._contextOnBehalfOf(context, onBehalfOf);\n }\n\n return req.wrap(requestContext, {serverKey: isECDHRequest})\n .then(() => {\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info('kms: request payload', util.inspect(omit(JSON.parse(JSON.stringify(req)), 'wrapped'), {depth: null}));\n }\n\n return req;\n });\n });\n },\n\n /**\n * Accepts a kms message event, decrypts it, and passes it to the batcher\n * @param {Object} event\n * @returns {Promise<Object>}\n */\n processKmsMessageEvent(event) {\n this.logger.info('kms: received kms message');\n\n return Promise.all(event.encryption.kmsMessages.map((kmsMessage, index) => this._isECDHEMessage(kmsMessage)\n .then((isECDHMessage) => {\n this.logger.info(`kms: received ${isECDHMessage ? 'ecdhe' : 'normal'} message`);\n const res = new Response(kmsMessage);\n\n return Promise.resolve(isECDHMessage ? partialContexts.get(this) : contexts.get(this))\n // eslint-disable-next-line max-nested-callbacks\n .then((context) => res.unwrap(context))\n // eslint-disable-next-line max-nested-callbacks\n .then(() => {\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info('kms: response payload', util.inspect(omit(JSON.parse(JSON.stringify(res)), 'wrapped'), {depth: null}));\n }\n })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => { event.encryption.kmsMessages[index] = res; })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => res);\n })))\n .then(() => this.batcher.processKmsMessageEvent(event))\n .catch((reason) => {\n this.logger.error('kms: decrypt failed', reason.stack);\n\n return Promise.reject(reason);\n })\n .then(() => event);\n },\n\n /**\n * Decrypts a kms message\n * @param {Object} kmsMessage\n * @returns {Promise<Object>}\n */\n decryptKmsMessage(kmsMessage) {\n const res = new Response(kmsMessage);\n\n return contexts.get(this)\n .then((context) => res.unwrap(context))\n .then(() => res.body);\n },\n\n /**\n * Determines if the kms message is an ecdhe message or a normal message\n * @param {Object} kmsMessage\n * @returns {Promise<boolean>}\n */\n _isECDHEMessage(kmsMessage) {\n return this._getKMSStaticPubKey()\n .then((kmsStaticPubKey) => {\n const fields = kmsMessage.split('.');\n\n if (fields.length !== 3) {\n return false;\n }\n\n const header = JSON.parse(jose.util.base64url.decode(fields[0]));\n\n return header.kid === kmsStaticPubKey.kid;\n });\n },\n\n /**\n * Sends a request to the kms\n * @param {Object} payload\n * @param {Object} options\n * @param {Number} options.timeout (internal)\n * @param {string} options.onBehalfOf Run the request on behalf of another user (UUID), used in compliance scenarios\n * @returns {Promise<Object>}\n */\n request(payload, {timeout, onBehalfOf} = {}) {\n timeout = timeout || this.config.kmsInitialTimeout;\n\n // Note: this should only happen when we're using the async kms batcher;\n // once we implement the sync batcher, this'll need to be smarter.\n return this.webex.internal.mercury.connect()\n .then(() => this.prepareRequest(payload, onBehalfOf))\n .then((req) => {\n req[TIMEOUT_SYMBOL] = timeout;\n\n return this.batcher.request(req);\n })\n // High complexity is due to attempt at test mode resiliency\n // eslint-disable-next-line complexity\n .catch((reason) => {\n if (process.env.NODE_ENV === 'test' && (reason.status === 403 || reason.statusCode === 403) && reason.message.match(/Failed to resolve authorization token in KmsMessage request for user/)) {\n this.logger.warn('kms: rerequested key due to test-mode kms auth failure');\n\n return this.request(payload, {onBehalfOf});\n }\n\n // KMS Error. Notify the user\n if (reason instanceof KMSError) {\n this.webex.trigger('client:InvalidRequestError');\n\n return Promise.reject(reason);\n }\n\n // Ideally, most or all of the code below would go in kms-batcher, but\n // but batching needs at least one more round of refactoring for that to\n // work.\n if (!reason.statusCode && !reason.status) {\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n /* istanbul ignore next: reason.stack vs stack difficult to control in test */\n this.logger.info('kms: request error', reason.stack || reason);\n }\n\n consoleDebug(`timeout ${timeout}`);\n timeout *= 2;\n\n if (timeout >= this.config.ecdhMaxTimeout) {\n this.logger.info('kms: exceeded maximum KMS request retries');\n\n return Promise.reject(reason);\n }\n\n // Peek ahead to make sure we don't reset the timeout if the next timeout\n // will exceed the maximum timeout for renegotiating ECDH keys.\n const nextTimeout = timeout * 2;\n\n if (timeout >= this.config.kmsMaxTimeout && nextTimeout < this.config.ecdhMaxTimeout) {\n this.logger.info('kms: exceeded maximum KMS request retries; negotiating new ecdh key');\n\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info('kms: timeout/maxtimeout', timeout, this.config.kmsMaxTimeout);\n }\n\n contexts.delete(this);\n timeout = 0;\n }\n\n return this.request(payload, {timeout, onBehalfOf});\n }\n\n return Promise.reject(reason);\n });\n },\n\n /**\n * @private\n * @returns {Promise<string>}\n */\n _getAuthorization() {\n return this.webex.credentials.getUserToken('spark:kms')\n .then((token) => token.access_token);\n },\n\n @oneFlight\n /**\n * @private\n * @param {String} onBehalfOf create context on behalf of another user, undefined when this is not necessary\n * @returns {Promise<Object>}\n */\n _getContext() {\n let promise = contexts.get(this);\n\n if (!promise) {\n promise = this._prepareContext();\n contexts.set(this, promise);\n promise.then((context) => {\n const expiresIn = context.ephemeralKey.expirationDate - Date.now() - 30000;\n\n safeSetTimeout(() => contexts.delete(this), expiresIn);\n });\n }\n\n return Promise.all([\n promise,\n this._getAuthorization()\n ])\n .then(([context, authorization]) => {\n context.clientInfo.credential.bearer = authorization;\n\n return context;\n });\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _getKMSCluster() {\n this.logger.info('kms: retrieving KMS cluster');\n\n return this._getKMSDetails()\n .then(({kmsCluster}) => kmsCluster);\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _getKMSDetails() {\n let details = kmsDetails.get(this);\n\n if (!details) {\n this.logger.info('kms: fetching KMS details');\n details = this.webex.request({\n service: 'encryption',\n resource: `/kms/${this.webex.internal.device.userId}`\n })\n .then((res) => {\n this.logger.info('kms: fetched KMS details');\n const {body} = res;\n\n body.rsaPublicKey = JSON.parse(body.rsaPublicKey);\n\n return body;\n })\n .catch((reason) => {\n this.logger.error('kms: failed to fetch KMS details', reason);\n\n return Promise.reject(reason);\n });\n\n kmsDetails.set(this, details);\n }\n\n return details;\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _getKMSStaticPubKey() {\n this.logger.info('kms: retrieving KMS static public key');\n\n return this._getKMSDetails()\n .then(({rsaPublicKey}) => rsaPublicKey);\n },\n\n /**\n * @private\n * @returns {Promise<Object>}\n */\n _prepareContext() {\n this.logger.info('kms: creating context');\n const context = new Context();\n\n return Promise.all([\n this._getKMSStaticPubKey().then(validateKMS(this.config.caroots)),\n this._getAuthorization()\n ])\n .then(([kmsStaticPubKey, authorization]) => {\n context.clientInfo = {\n clientId: this.webex.internal.device.url,\n credential: {\n userId: this.webex.internal.device.userId,\n bearer: authorization\n }\n };\n\n context.serverInfo = {\n key: kmsStaticPubKey\n };\n\n this.logger.info('kms: creating local ephemeral key');\n\n return context.createECDHKey();\n })\n .then((localECDHKey) => {\n context.ephemeralKey = localECDHKey;\n partialContexts.set(this, context);\n\n return Promise.all([localECDHKey.asKey(), this._getKMSCluster()]);\n })\n .then(([localECDHKey, cluster]) => {\n this.logger.info('kms: submitting ephemeral key request');\n\n return this.request({\n uri: `${cluster}/ecdhe`,\n method: 'create',\n jwk: localECDHKey.toJSON()\n });\n })\n .then((res) => {\n this.logger.info('kms: deriving final ephemeral key');\n\n return context.deriveEphemeralKey(res.key);\n })\n .then((key) => {\n context.ephemeralKey = key;\n partialContexts.delete(this);\n this.logger.info('kms: derived final ephemeral key');\n\n return context;\n })\n .catch((reason) => {\n this.logger.error('kms: failed to negotiate ephemeral key', reason);\n\n return Promise.reject(reason);\n });\n },\n\n /**\n * KMS 'retrieve' requests can be made on behalf of another user. This is useful\n * for scenarios such as eDiscovery. i.e. Where an authorized compliance officer is\n * entitled to retrieve content generated by any organisational user.\n * As the KMSContext is cached, updating it will affect separate requests. Hence when\n * making a request onBehalfOf another user create a new context for just this request.\n * However this context will be 'light' as it only needs to change one field.\n * @param {Object} originalContext - The base context to 'copy'\n * @param {String} onBehalfOf - The user specified in the new context\n * @returns {Context} A 'copy' of the existing context with a new user specified\n * @private\n */\n _contextOnBehalfOf(originalContext, onBehalfOf) {\n const context = new Context();\n\n context.clientInfo = context.clientInfo = {\n clientId: originalContext.clientInfo.clientId,\n credential: {\n userId: onBehalfOf,\n onBehalfOf, // Supports running onBehalfOf self. i.e. A CO which calls onBehalfOf with CO.id.\n bearer: originalContext.clientInfo.credential.bearer\n }\n };\n context.serverInfo = originalContext.serverInfo;\n context.ephemeralKey = originalContext.ephemeralKey;\n\n return context;\n }\n});\n\nexport default KMS;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-encryption",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ian W. Remmel <iremmel@cisco.com>",
|
|
@@ -22,21 +22,22 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@babel/runtime-corejs2": "^7.14.8",
|
|
24
24
|
"lodash": "^4.17.21",
|
|
25
|
-
"@webex/webex-core": "
|
|
26
|
-
"@webex/common": "
|
|
25
|
+
"@webex/webex-core": "2.2.0",
|
|
26
|
+
"@webex/common": "2.2.0",
|
|
27
27
|
"node-jose": "^2.0.0",
|
|
28
28
|
"node-scr": "^0.3.0",
|
|
29
|
-
"@webex/common-timers": "
|
|
29
|
+
"@webex/common-timers": "2.2.0",
|
|
30
30
|
"node-kms": "^0.4.0",
|
|
31
|
+
"uuid": "^3.3.2",
|
|
31
32
|
"valid-url": "^1.0.9",
|
|
32
33
|
"asn1js": "^2.0.26",
|
|
33
34
|
"pkijs": "^2.1.84",
|
|
34
35
|
"isomorphic-webcrypto": "^2.3.8",
|
|
35
36
|
"safe-buffer": "^5.2.0",
|
|
36
37
|
"debug": "^3.2.6",
|
|
37
|
-
"@webex/internal-plugin-device": "
|
|
38
|
-
"@webex/internal-plugin-mercury": "
|
|
39
|
-
"@webex/http-core": "
|
|
38
|
+
"@webex/internal-plugin-device": "2.2.0",
|
|
39
|
+
"@webex/internal-plugin-mercury": "2.2.0",
|
|
40
|
+
"@webex/http-core": "2.2.0",
|
|
40
41
|
"envify": "^4.1.0"
|
|
41
42
|
}
|
|
42
43
|
}
|
package/src/kms.js
CHANGED
|
@@ -11,6 +11,7 @@ import {WebexPlugin} from '@webex/webex-core';
|
|
|
11
11
|
import {Context, Request, Response} from 'node-kms';
|
|
12
12
|
import jose from 'node-jose';
|
|
13
13
|
import {omit} from 'lodash';
|
|
14
|
+
import uuid from 'uuid';
|
|
14
15
|
|
|
15
16
|
import KMSBatcher, {TIMEOUT_SYMBOL} from './kms-batcher';
|
|
16
17
|
import validateKMS, {KMSError} from './kms-certificate-validation';
|
|
@@ -250,6 +251,170 @@ const KMS = WebexPlugin.extend({
|
|
|
250
251
|
});
|
|
251
252
|
},
|
|
252
253
|
|
|
254
|
+
/**
|
|
255
|
+
* @typedef {Object} FetchPublicKeyResponse
|
|
256
|
+
* @property {number} status 200,400(Bad Request: Request payload missing info),404(Not Found: HSM Public Key not found),501(Not Implemented: This KMS does not support BYOK),502(Bad Gateway: KMS could not communicate with HSM)
|
|
257
|
+
* @property {UUID} requestId this is should be unique, used for debug.
|
|
258
|
+
* @property {string} publicKey
|
|
259
|
+
*/
|
|
260
|
+
/**
|
|
261
|
+
* get public key from kms
|
|
262
|
+
* @param {Object} options
|
|
263
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
264
|
+
* @returns {Promise.<FetchPublicKeyResponse>} response of get public key api
|
|
265
|
+
*/
|
|
266
|
+
fetchPublicKey({assignedOrgId}) {
|
|
267
|
+
this.logger.info('kms: fetch public key for byok');
|
|
268
|
+
|
|
269
|
+
return this.request({
|
|
270
|
+
method: 'retrieve',
|
|
271
|
+
uri: '/publicKey',
|
|
272
|
+
assignedOrgId
|
|
273
|
+
})
|
|
274
|
+
.then((res) => {
|
|
275
|
+
this.logger.info('kms: received public key');
|
|
276
|
+
|
|
277
|
+
return res.publicKey;
|
|
278
|
+
});
|
|
279
|
+
},
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @typedef {Object} UploadCmkResponse
|
|
283
|
+
* @property {number} status
|
|
284
|
+
* @property {UUID} requestId
|
|
285
|
+
* @property {string} uri
|
|
286
|
+
* @property {string} keysState
|
|
287
|
+
*/
|
|
288
|
+
/**
|
|
289
|
+
* upload master key for one org.
|
|
290
|
+
* @param {Object} options
|
|
291
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
292
|
+
* @param {string} options.customerMasterKey the master key
|
|
293
|
+
* @returns {Promise.<UploadCmkResponse>} response of upload CMK api
|
|
294
|
+
*/
|
|
295
|
+
uploadCustomerMasterKey({assignedOrgId, customerMasterKey}) {
|
|
296
|
+
this.logger.info('kms: upload customer master key for byok');
|
|
297
|
+
|
|
298
|
+
return this.request({
|
|
299
|
+
method: 'create',
|
|
300
|
+
uri: '/cmk',
|
|
301
|
+
assignedOrgId,
|
|
302
|
+
customerMasterKey,
|
|
303
|
+
requestId: uuid.v4()
|
|
304
|
+
}).then((res) => {
|
|
305
|
+
this.logger.info('kms: finish to upload customer master key');
|
|
306
|
+
|
|
307
|
+
return res;
|
|
308
|
+
});
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* get all customer master keys for one org.
|
|
313
|
+
* @param {Object} options
|
|
314
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
315
|
+
* @returns {Promise.<ActivateCmkResponse>} response of list CMKs api
|
|
316
|
+
*/
|
|
317
|
+
listAllCustomerMasterKey({assignedOrgId}) {
|
|
318
|
+
this.logger.info('kms: get all customer master keys for byok');
|
|
319
|
+
|
|
320
|
+
return this.request({
|
|
321
|
+
method: 'retrieve',
|
|
322
|
+
uri: '/cmk',
|
|
323
|
+
assignedOrgId,
|
|
324
|
+
requestId: uuid.v4()
|
|
325
|
+
}).then((res) => {
|
|
326
|
+
this.logger.info('kms: finish to get all customer master keys');
|
|
327
|
+
|
|
328
|
+
return res;
|
|
329
|
+
});
|
|
330
|
+
},
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* @typedef {Object} ActivateCmkResponse
|
|
334
|
+
* @property {number} status
|
|
335
|
+
* @property {UUID} requestId
|
|
336
|
+
* @property {Array<CMK>} customerMasterKeys
|
|
337
|
+
*/
|
|
338
|
+
/**
|
|
339
|
+
*
|
|
340
|
+
* @typedef {Object} CMK
|
|
341
|
+
* @property {string} usageState
|
|
342
|
+
* @property {UUID} assignedOrgId
|
|
343
|
+
* @property {string} uri
|
|
344
|
+
* @property {string} source
|
|
345
|
+
* @property {Date | undefined} stateUpdatedOn
|
|
346
|
+
* @property {Date | undefined} rotation
|
|
347
|
+
*/
|
|
348
|
+
/**
|
|
349
|
+
* change one customer master key state for one org.
|
|
350
|
+
* delete pending key, then the keyState should be 'removedclean';
|
|
351
|
+
* active pending key, then the keyState should be 'active';
|
|
352
|
+
*
|
|
353
|
+
* @param {Object} options
|
|
354
|
+
* @param {string} options.keyId the id of one customer master key, it should be a url
|
|
355
|
+
* @param {string} options.keyState one of the following: PENDING, RECOVERING,ACTIVE,REVOKED,DEACTIVATED,REENCRYPTING,RETIRED,DELETED,DISABLED,REMOVEDCLEAN,REMOVEDDIRTY;
|
|
356
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
357
|
+
* @returns {Promise.<ActivateCmkResponse>} response of list CMKs api
|
|
358
|
+
*/
|
|
359
|
+
changeCustomerMasterKeyState({keyId, keyState, assignedOrgId}) {
|
|
360
|
+
this.logger.info('kms: change one customer master key state for byok');
|
|
361
|
+
|
|
362
|
+
return this.request({
|
|
363
|
+
method: 'update',
|
|
364
|
+
uri: keyId,
|
|
365
|
+
keyState,
|
|
366
|
+
assignedOrgId,
|
|
367
|
+
requestId: uuid.v4()
|
|
368
|
+
}).then((res) => {
|
|
369
|
+
this.logger.info('kms: finish to change the customer master key state to {}', keyState);
|
|
370
|
+
|
|
371
|
+
return res;
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* this is for test case. it will delete all CMKs, no matter what their status is. This is mainly for test purpose
|
|
377
|
+
* @param {Object} options
|
|
378
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
379
|
+
* @returns {Promise.<{status, requestId}>}
|
|
380
|
+
*/
|
|
381
|
+
deleteAllCustomerMasterKeys({assignedOrgId}) {
|
|
382
|
+
this.logger.info('kms: delete all customer master keys at the same time');
|
|
383
|
+
|
|
384
|
+
return this.request({
|
|
385
|
+
method: 'delete',
|
|
386
|
+
uri: '/cmk',
|
|
387
|
+
assignedOrgId,
|
|
388
|
+
requestId: uuid.v4()
|
|
389
|
+
}).then((res) => {
|
|
390
|
+
this.logger.info('kms: finish to delete all customer master keys');
|
|
391
|
+
|
|
392
|
+
return res;
|
|
393
|
+
});
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* return to use global master key for one org.
|
|
398
|
+
* @param {Object} options
|
|
399
|
+
* @param {UUID} options.assignedOrgId the orgId
|
|
400
|
+
* @returns {Promise.<ActivateCmkResponse>} response of activate CMK api
|
|
401
|
+
*/
|
|
402
|
+
useGlobalMasterKey({assignedOrgId}) {
|
|
403
|
+
this.logger.info('kms: return to use global master key');
|
|
404
|
+
|
|
405
|
+
return this.request({
|
|
406
|
+
method: 'update',
|
|
407
|
+
uri: 'default',
|
|
408
|
+
keyState: 'ACTIVE',
|
|
409
|
+
assignedOrgId,
|
|
410
|
+
requestId: uuid.v4()
|
|
411
|
+
}).then((res) => {
|
|
412
|
+
this.logger.info('kms: finish to return to global master key');
|
|
413
|
+
|
|
414
|
+
return res;
|
|
415
|
+
});
|
|
416
|
+
},
|
|
417
|
+
|
|
253
418
|
/**
|
|
254
419
|
* Fetches the specified key from the kms
|
|
255
420
|
* @param {Object} options
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-env browser */
|
|
1
2
|
/*!
|
|
2
3
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
4
|
*/
|
|
@@ -9,6 +10,7 @@ import sinon from 'sinon';
|
|
|
9
10
|
import WebexCore from '@webex/webex-core';
|
|
10
11
|
import testUsers from '@webex/test-helper-test-users';
|
|
11
12
|
import uuid from 'uuid';
|
|
13
|
+
import {skipInBrowser} from '@webex/test-helper-mocha';
|
|
12
14
|
|
|
13
15
|
const debug = require('debug')('kms');
|
|
14
16
|
|
|
@@ -17,7 +19,30 @@ describe('Encryption', function () {
|
|
|
17
19
|
describe('KMS', () => {
|
|
18
20
|
let mccoy, webex, spock;
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
function str2ab(str) {
|
|
23
|
+
const buf = new ArrayBuffer(str.length);
|
|
24
|
+
const bufView = new Uint8Array(buf);
|
|
25
|
+
|
|
26
|
+
for (let i = 0, strLen = str.length; i < strLen; i += 1) {
|
|
27
|
+
bufView[i] = str.charCodeAt(i);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return buf;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function arrayBufferToBase64(buffer) {
|
|
34
|
+
let binary = '';
|
|
35
|
+
const bytes = new Uint8Array(buffer);
|
|
36
|
+
const len = bytes.byteLength;
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < len; i += 1) {
|
|
39
|
+
binary += String.fromCharCode(bytes[i]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return window.btoa(binary);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
before('create test user', () => testUsers.create({count: 2, config: {roles: [{name: 'id_full_admin'}]}})
|
|
21
46
|
.then((users) => {
|
|
22
47
|
spock = users[0];
|
|
23
48
|
webex = new WebexCore({
|
|
@@ -314,6 +339,65 @@ describe('Encryption', function () {
|
|
|
314
339
|
}));
|
|
315
340
|
});
|
|
316
341
|
|
|
342
|
+
describe('upload customer master key', () => {
|
|
343
|
+
let uploadedkeyId;
|
|
344
|
+
|
|
345
|
+
/* eslint-disable no-unused-expressions */
|
|
346
|
+
skipInBrowser(it)('upload customer master key', () => (webex.internal.encryption.kms.deleteAllCustomerMasterKeys({assignedOrgId: spock.orgId})
|
|
347
|
+
.then(() => webex.internal.encryption.kms.fetchPublicKey({assignedOrgId: spock.orgId}))
|
|
348
|
+
.then((publicKey) => {
|
|
349
|
+
assert.isNotEmpty(publicKey);
|
|
350
|
+
const pemHeader = '-----BEGIN PUBLIC KEY-----';
|
|
351
|
+
const pemFooter = '-----END PUBLIC KEY-----';
|
|
352
|
+
const publicContent = publicKey.substring(pemHeader.length, publicKey.length - pemFooter.length);
|
|
353
|
+
const binaryDerString = window.atob(publicContent);
|
|
354
|
+
// convert from a binary string to an ArrayBuffer
|
|
355
|
+
const binaryDer = str2ab(binaryDerString);
|
|
356
|
+
|
|
357
|
+
return window.crypto.subtle.importKey(
|
|
358
|
+
'spki',
|
|
359
|
+
binaryDer,
|
|
360
|
+
{
|
|
361
|
+
name: 'RSA-OAEP',
|
|
362
|
+
hash: 'SHA-256'
|
|
363
|
+
},
|
|
364
|
+
true,
|
|
365
|
+
['encrypt']
|
|
366
|
+
);
|
|
367
|
+
})
|
|
368
|
+
.then((publicKey) => {
|
|
369
|
+
const buf = window.crypto.getRandomValues(new Uint8Array(16));
|
|
370
|
+
|
|
371
|
+
return window.crypto.subtle.encrypt(
|
|
372
|
+
{
|
|
373
|
+
name: 'RSA-OAEP'
|
|
374
|
+
},
|
|
375
|
+
publicKey,
|
|
376
|
+
buf
|
|
377
|
+
);
|
|
378
|
+
})
|
|
379
|
+
.then((encryptedData) => webex.internal.encryption.kms.uploadCustomerMasterKey({assignedOrgId: spock.orgId, customerMasterKey: arrayBufferToBase64(encryptedData)}))
|
|
380
|
+
.then((uploadRes) => {
|
|
381
|
+
uploadedkeyId = uploadRes.customerMasterKeys[0].uri;
|
|
382
|
+
|
|
383
|
+
return webex.internal.encryption.kms.listAllCustomerMasterKey({assignedOrgId: spock.orgId});
|
|
384
|
+
})
|
|
385
|
+
.then((listCmksRes) => {
|
|
386
|
+
const cmks = listCmksRes.customerMasterKeys;
|
|
387
|
+
const uploadedCmk = cmks.find((cmk) => cmk.uri === uploadedkeyId);
|
|
388
|
+
|
|
389
|
+
expect(uploadedCmk).to.not.be.null;
|
|
390
|
+
|
|
391
|
+
return webex.internal.encryption.kms.changeCustomerMasterKeyState({keyId: uploadedkeyId, keyState: 'ACTIVE', assignedOrgId: spock.orgId});
|
|
392
|
+
})
|
|
393
|
+
.then((activeRes) => {
|
|
394
|
+
expect(activeRes.customerMasterKeys[0].usageState).to.have.string('ACTIVE');
|
|
395
|
+
|
|
396
|
+
// return webex.internal.encryption.kms.useGlobalMasterKey({assignedOrgId: spock.orgId});
|
|
397
|
+
return webex.internal.encryption.kms.deleteAllCustomerMasterKeys({assignedOrgId: spock.orgId});
|
|
398
|
+
})));
|
|
399
|
+
});
|
|
400
|
+
|
|
317
401
|
describe('#fetchKey()', () => {
|
|
318
402
|
let key;
|
|
319
403
|
|