@webex/internal-plugin-encryption 3.12.0-next.5 → 3.12.0-next.50

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/config.js CHANGED
@@ -45,7 +45,22 @@ var _default = exports.default = {
45
45
  * Debounce max wait before sending a kms metric
46
46
  * @type {Number}
47
47
  */
48
- batcherMaxWait: 150
48
+ batcherMaxWait: 150,
49
+ /**
50
+ * PEM encoded CA root bundle used to validate the KMS certificate chain.
51
+ * When omitted, the KMS certificate chain signature is not verified.
52
+ * @type {?string[]}
53
+ */
54
+ caroots: undefined,
55
+ /**
56
+ * An additional CA root bundle validated alongside `caroots`. Unlike
57
+ * `caroots`, a validation failure against these roots is reported as a
58
+ * metric instead of failing the ECDH negotiation. This allows a new CA
59
+ * root bundle to be trialled in parallel with the enforced `caroots`
60
+ * without risking total failure.
61
+ * @type {?string[]}
62
+ */
63
+ carootsReportOnly: undefined
49
64
  }
50
65
  };
51
66
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_default","exports","default","encryption","joseOptions","compact","contentAlg","protect","kmsInitialTimeout","kmsMaxTimeout","ecdhMaxTimeout","batcherWait","batcherMaxCalls","batcherMaxWait"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nexport default {\n encryption: {\n joseOptions: {\n compact: true,\n contentAlg: 'A256GCM',\n protect: '*',\n },\n\n /**\n * Initial timeout before contacting KMS with a new request\n * @type {Number}\n */\n kmsInitialTimeout: 6000,\n\n /**\n * Maximum timeout before negotiating a new ECDH key\n * and contacting KMS with a new request\n * @type {Number}\n */\n kmsMaxTimeout: 32000,\n\n /**\n * Maximum timeout after negotiating several ECDH keys\n * @type {Number}\n */\n ecdhMaxTimeout: 32000 * 3,\n\n /**\n * Debounce wait before sending a kms request\n * @type {Number}\n */\n batcherWait: 50,\n\n /**\n * Maximum queue size before sending a kms request\n * @type {Number}\n */\n batcherMaxCalls: 50,\n\n /**\n * Debounce max wait before sending a kms metric\n * @type {Number}\n */\n batcherMaxWait: 150,\n },\n};\n"],"mappings":";;;;;;;AAAA;AACA;AACA;AAFA,IAAAA,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAIe;EACbC,UAAU,EAAE;IACVC,WAAW,EAAE;MACXC,OAAO,EAAE,IAAI;MACbC,UAAU,EAAE,SAAS;MACrBC,OAAO,EAAE;IACX,CAAC;IAED;AACJ;AACA;AACA;IACIC,iBAAiB,EAAE,IAAI;IAEvB;AACJ;AACA;AACA;AACA;IACIC,aAAa,EAAE,KAAK;IAEpB;AACJ;AACA;AACA;IACIC,cAAc,EAAE,KAAK,GAAG,CAAC;IAEzB;AACJ;AACA;AACA;IACIC,WAAW,EAAE,EAAE;IAEf;AACJ;AACA;AACA;IACIC,eAAe,EAAE,EAAE;IAEnB;AACJ;AACA;AACA;IACIC,cAAc,EAAE;EAClB;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_default","exports","default","encryption","joseOptions","compact","contentAlg","protect","kmsInitialTimeout","kmsMaxTimeout","ecdhMaxTimeout","batcherWait","batcherMaxCalls","batcherMaxWait","caroots","undefined","carootsReportOnly"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nexport default {\n encryption: {\n joseOptions: {\n compact: true,\n contentAlg: 'A256GCM',\n protect: '*',\n },\n\n /**\n * Initial timeout before contacting KMS with a new request\n * @type {Number}\n */\n kmsInitialTimeout: 6000,\n\n /**\n * Maximum timeout before negotiating a new ECDH key\n * and contacting KMS with a new request\n * @type {Number}\n */\n kmsMaxTimeout: 32000,\n\n /**\n * Maximum timeout after negotiating several ECDH keys\n * @type {Number}\n */\n ecdhMaxTimeout: 32000 * 3,\n\n /**\n * Debounce wait before sending a kms request\n * @type {Number}\n */\n batcherWait: 50,\n\n /**\n * Maximum queue size before sending a kms request\n * @type {Number}\n */\n batcherMaxCalls: 50,\n\n /**\n * Debounce max wait before sending a kms metric\n * @type {Number}\n */\n batcherMaxWait: 150,\n\n /**\n * PEM encoded CA root bundle used to validate the KMS certificate chain.\n * When omitted, the KMS certificate chain signature is not verified.\n * @type {?string[]}\n */\n caroots: undefined,\n\n /**\n * An additional CA root bundle validated alongside `caroots`. Unlike\n * `caroots`, a validation failure against these roots is reported as a\n * metric instead of failing the ECDH negotiation. This allows a new CA\n * root bundle to be trialled in parallel with the enforced `caroots`\n * without risking total failure.\n * @type {?string[]}\n */\n carootsReportOnly: undefined,\n },\n};\n"],"mappings":";;;;;;;AAAA;AACA;AACA;AAFA,IAAAA,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAIe;EACbC,UAAU,EAAE;IACVC,WAAW,EAAE;MACXC,OAAO,EAAE,IAAI;MACbC,UAAU,EAAE,SAAS;MACrBC,OAAO,EAAE;IACX,CAAC;IAED;AACJ;AACA;AACA;IACIC,iBAAiB,EAAE,IAAI;IAEvB;AACJ;AACA;AACA;AACA;IACIC,aAAa,EAAE,KAAK;IAEpB;AACJ;AACA;AACA;IACIC,cAAc,EAAE,KAAK,GAAG,CAAC;IAEzB;AACJ;AACA;AACA;IACIC,WAAW,EAAE,EAAE;IAEf;AACJ;AACA;AACA;IACIC,eAAe,EAAE,EAAE;IAEnB;AACJ;AACA;AACA;IACIC,cAAc,EAAE,GAAG;IAEnB;AACJ;AACA;AACA;AACA;IACIC,OAAO,EAAEC,SAAS;IAElB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIC,iBAAiB,EAAED;EACrB;AACF,CAAC","ignoreList":[]}
package/dist/constants.js CHANGED
@@ -4,9 +4,10 @@ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/defi
4
4
  _Object$defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.KMS_KEY_REVOKE_FAILURE = exports.KMS_KEY_REVOKE_ERROR_STATUS = exports.KMS_KEY_REVOKE_ERROR_CODES = exports.KMS_KEY_REDIRECT_ERROR_CODE = void 0;
7
+ exports.KMS_KEY_REVOKE_FAILURE = exports.KMS_KEY_REVOKE_ERROR_STATUS = exports.KMS_KEY_REVOKE_ERROR_CODES = exports.KMS_KEY_REDIRECT_ERROR_CODE = exports.JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED = void 0;
8
8
  var KMS_KEY_REVOKE_FAILURE = exports.KMS_KEY_REVOKE_FAILURE = 'event:kms:key:revoke:encryption:failure';
9
9
  var KMS_KEY_REVOKE_ERROR_STATUS = exports.KMS_KEY_REVOKE_ERROR_STATUS = 405;
10
10
  var KMS_KEY_REVOKE_ERROR_CODES = exports.KMS_KEY_REVOKE_ERROR_CODES = [405005, 405006];
11
11
  var KMS_KEY_REDIRECT_ERROR_CODE = exports.KMS_KEY_REDIRECT_ERROR_CODE = 301002;
12
+ var JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED = exports.JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED = 'JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED';
12
13
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["KMS_KEY_REVOKE_FAILURE","exports","KMS_KEY_REVOKE_ERROR_STATUS","KMS_KEY_REVOKE_ERROR_CODES","KMS_KEY_REDIRECT_ERROR_CODE"],"sources":["constants.js"],"sourcesContent":["export const KMS_KEY_REVOKE_FAILURE = 'event:kms:key:revoke:encryption:failure';\nexport const KMS_KEY_REVOKE_ERROR_STATUS = 405;\nexport const KMS_KEY_REVOKE_ERROR_CODES = [405005, 405006];\nexport const KMS_KEY_REDIRECT_ERROR_CODE = 301002;\n"],"mappings":";;;;;;;AAAO,IAAMA,sBAAsB,GAAAC,OAAA,CAAAD,sBAAA,GAAG,yCAAyC;AACxE,IAAME,2BAA2B,GAAAD,OAAA,CAAAC,2BAAA,GAAG,GAAG;AACvC,IAAMC,0BAA0B,GAAAF,OAAA,CAAAE,0BAAA,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;AACnD,IAAMC,2BAA2B,GAAAH,OAAA,CAAAG,2BAAA,GAAG,MAAM","ignoreList":[]}
1
+ {"version":3,"names":["KMS_KEY_REVOKE_FAILURE","exports","KMS_KEY_REVOKE_ERROR_STATUS","KMS_KEY_REVOKE_ERROR_CODES","KMS_KEY_REDIRECT_ERROR_CODE","JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED"],"sources":["constants.js"],"sourcesContent":["export const KMS_KEY_REVOKE_FAILURE = 'event:kms:key:revoke:encryption:failure';\nexport const KMS_KEY_REVOKE_ERROR_STATUS = 405;\nexport const KMS_KEY_REVOKE_ERROR_CODES = [405005, 405006];\nexport const KMS_KEY_REDIRECT_ERROR_CODE = 301002;\nexport const JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED = 'JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED';\n"],"mappings":";;;;;;;AAAO,IAAMA,sBAAsB,GAAAC,OAAA,CAAAD,sBAAA,GAAG,yCAAyC;AACxE,IAAME,2BAA2B,GAAAD,OAAA,CAAAC,2BAAA,GAAG,GAAG;AACvC,IAAMC,0BAA0B,GAAAF,OAAA,CAAAE,0BAAA,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;AACnD,IAAMC,2BAA2B,GAAAH,OAAA,CAAAG,2BAAA,GAAG,MAAM;AAC1C,IAAMC,wCAAwC,GAAAJ,OAAA,CAAAI,wCAAA,GAAG,0CAA0C","ignoreList":[]}
@@ -278,7 +278,7 @@ var Encryption = _webexCore.WebexPlugin.extend({
278
278
  }));
279
279
  });
280
280
  },
281
- version: "3.12.0-next.5"
281
+ version: "3.12.0-next.50"
282
282
  });
283
283
 
284
284
  /**
package/dist/kms.js CHANGED
@@ -748,54 +748,91 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
748
748
  return rsaPublicKey;
749
749
  });
750
750
  },
751
+ /**
752
+ * Validates the KMS static public key against the configured CA roots. The
753
+ * enforced `caroots` bundle rejects on failure. When a `carootsReportOnly`
754
+ * bundle is also configured, it is validated in addition to `caroots`, but a
755
+ * failure against it is only reported as a metric so a new bundle can be
756
+ * trialled without risking failure.
757
+ * @private
758
+ * @param {Object} kmsStaticPubKey
759
+ * @returns {Promise<Object>} the KMS static public key
760
+ */
761
+ _validateKMSStaticPubKey: function _validateKMSStaticPubKey(kmsStaticPubKey) {
762
+ var _this17 = this;
763
+ var _this$config = this.config,
764
+ caroots = _this$config.caroots,
765
+ carootsReportOnly = _this$config.carootsReportOnly;
766
+ return (0, _kmsCertificateValidation.default)(caroots)(kmsStaticPubKey).then(function (jwt) {
767
+ if (!carootsReportOnly) {
768
+ return jwt;
769
+ }
770
+ return (0, _kmsCertificateValidation.default)(carootsReportOnly)(kmsStaticPubKey).catch(function (reason) {
771
+ _this17.logger.warn('kms: report-only certificate validation failed', reason);
772
+ _this17.webex.internal.metrics.submitClientMetrics(_constants.JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED, {
773
+ fields: {
774
+ success: false
775
+ },
776
+ tags: {
777
+ reason: reason.message,
778
+ kid: kmsStaticPubKey && kmsStaticPubKey.kid
779
+ }
780
+ });
781
+ }).then(function () {
782
+ return jwt;
783
+ });
784
+ });
785
+ },
751
786
  /**
752
787
  * @private
753
788
  * @returns {Promise<Object>}
754
789
  */
755
790
  _prepareContext: function _prepareContext() {
756
- var _this17 = this;
791
+ var _this18 = this;
757
792
  this.logger.info('kms: creating context');
758
793
  var context = new _nodeKms.Context();
759
- return _promise.default.all([this._getKMSStaticPubKey().then((0, _kmsCertificateValidation.default)(this.config.caroots)), this._getAuthorization()]).then(function (_ref18) {
794
+ return _promise.default.all([this._getKMSStaticPubKey().then(function (kmsStaticPubKey) {
795
+ return _this18._validateKMSStaticPubKey(kmsStaticPubKey);
796
+ }), this._getAuthorization()]).then(function (_ref18) {
760
797
  var _ref19 = (0, _slicedToArray2.default)(_ref18, 2),
761
798
  kmsStaticPubKey = _ref19[0],
762
799
  authorization = _ref19[1];
763
800
  context.clientInfo = {
764
- clientId: _this17.webex.internal.device.url,
801
+ clientId: _this18.webex.internal.device.url,
765
802
  credential: {
766
- userId: _this17.webex.internal.device.userId,
803
+ userId: _this18.webex.internal.device.userId,
767
804
  bearer: authorization
768
805
  }
769
806
  };
770
807
  context.serverInfo = {
771
808
  key: kmsStaticPubKey
772
809
  };
773
- _this17.logger.info('kms: creating local ephemeral key');
810
+ _this18.logger.info('kms: creating local ephemeral key');
774
811
  return context.createECDHKey();
775
812
  }).then(function (localECDHKey) {
776
813
  context.ephemeralKey = localECDHKey;
777
- partialContexts.set(_this17, context);
778
- return _promise.default.all([localECDHKey.asKey(), _this17._getKMSCluster()]);
814
+ partialContexts.set(_this18, context);
815
+ return _promise.default.all([localECDHKey.asKey(), _this18._getKMSCluster()]);
779
816
  }).then(function (_ref20) {
780
817
  var _ref21 = (0, _slicedToArray2.default)(_ref20, 2),
781
818
  localECDHKey = _ref21[0],
782
819
  cluster = _ref21[1];
783
- _this17.logger.info('kms: submitting ephemeral key request');
784
- return _this17.request({
820
+ _this18.logger.info('kms: submitting ephemeral key request');
821
+ return _this18.request({
785
822
  uri: "".concat(cluster, "/ecdhe"),
786
823
  method: 'create',
787
824
  jwk: localECDHKey.toJSON()
788
825
  });
789
826
  }).then(function (res) {
790
- _this17.logger.info('kms: deriving final ephemeral key');
827
+ _this18.logger.info('kms: deriving final ephemeral key');
791
828
  return context.deriveEphemeralKey(res.key);
792
829
  }).then(function (key) {
793
830
  context.ephemeralKey = key;
794
- partialContexts.delete(_this17);
795
- _this17.logger.info('kms: derived final ephemeral key');
831
+ partialContexts.delete(_this18);
832
+ _this18.logger.info('kms: derived final ephemeral key');
796
833
  return context;
797
834
  }).catch(function (reason) {
798
- _this17.logger.error('kms: failed to negotiate ephemeral key', reason);
835
+ _this18.logger.error('kms: failed to negotiate ephemeral key', reason);
799
836
  return _promise.default.reject(reason);
800
837
  });
801
838
  },
@@ -826,7 +863,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
826
863
  context.ephemeralKey = originalContext.ephemeralKey;
827
864
  return context;
828
865
  },
829
- version: "3.12.0-next.5"
866
+ version: "3.12.0-next.50"
830
867
  }, (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));
831
868
  var _default = exports.default = KMS;
832
869
  //# sourceMappingURL=kms.js.map
package/dist/kms.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":["_querystring","_interopRequireDefault","require","_util","_commonTimers","_common","_webexCore","_nodeKms","_nodeJose","_lodash","_uuid","_kmsBatcher","_interopRequireWildcard","_kmsCertificateValidation","_constants","_dec","_obj","e","t","_WeakMap2","r","n","__esModule","o","i","f","__proto__","default","_typeof","has","get","set","_t","hasOwnProperty","call","_Object$defineProperty","_Object$getOwnPropertyDescriptor2","contexts","_weakMap","kmsDetails","partialContexts","consoleDebug","KMS","WebexPlugin","extend","oneFlight","keyFactory","_ref","uri","onBehalfOf","concat","namespace","children","batcher","KMSBatcher","bindKey","_ref2","_this","kro","kroUri","key","keyUri","logger","info","_promise","reject","Error","request","method","resourceUri","then","res","createResource","_ref3","_this2","userIds","keyUris","keys","reduce","uris","k","push","length","resource","addAuthorization","_ref4","_this3","authIds","authorizations","listAuthorizations","_ref5","_this4","removeAuthorization","_ref6","_this5","authId","userId","querystring","stringify","createUnboundKeys","_ref7","_this6","count","all","map","asKey","fetchPublicKey","_ref8","_this7","assignedOrgId","publicKey","uploadCustomerMasterKey","_ref9","_this8","customerMasterKey","_ref9$awsKms","awsKms","_ref9$customerMasterK","customerMasterKeyBackup","undefined","_ref9$customerMasterK2","customerMasterKeyRole","requestId","uuid","v4","listAllCustomerMasterKey","_ref0","_this9","_ref0$awsKms","changeCustomerMasterKeyState","_ref1","_this0","keyId","keyState","deleteAllCustomerMasterKeys","_ref10","_this1","_ref10$awsKms","useGlobalMasterKey","_ref11","_this10","fetchKey","_ref12","_this11","errorCode","KMS_KEY_REDIRECT_ERROR_CODE","redirectUri","redirectRes","ping","jose","JWK","jwk","prepareRequest","payload","_this12","isECDHRequest","includes","resolve","_getContext","context","req","Request","requestContext","_contextOnBehalfOf","wrap","serverKey","process","env","NODE_ENV","util","inspect","omit","JSON","parse","_stringify","depth","processKmsMessageEvent","event","_this13","encryption","kmsMessages","kmsMessage","index","_isECDHEMessage","isECDHMessage","Response","unwrap","catch","reason","error","stack","decryptKmsMessage","body","_getKMSStaticPubKey","kmsStaticPubKey","fields","split","header","base64url","decode","kid","_this14","_ref13","arguments","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","_this15","promise","_prepareContext","expiresIn","ephemeralKey","expirationDate","_now","safeSetTimeout","_ref14","_ref15","_slicedToArray2","authorization","clientInfo","credential","bearer","_getKMSCluster","_getKMSDetails","_ref16","kmsCluster","_this16","details","service","device","rsaPublicKey","_ref17","_this17","Context","validateKMS","caroots","_ref18","_ref19","clientId","url","serverInfo","createECDHKey","localECDHKey","_ref20","_ref21","cluster","toJSON","deriveEphemeralKey","originalContext","version","_applyDecoratedDescriptor2","_getOwnPropertyDescriptor","_default","exports"],"sources":["kms.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2024 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';\nimport {KMS_KEY_REDIRECT_ERROR_CODE} from './constants';\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({kro, kroUri, key, keyUri}) {\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 }).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({userIds, keyUris, key, keys}) {\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 }).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({userIds, authIds, kro, kroUri}) {\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 }).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 }).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({authId, userId, kro, kroUri}) {\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 }).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 }).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 }).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 * @param {string} options.customerMasterKeyBackup the master key backup\n * @param {string} options.customerMasterKeyRole the optional role associated with customerMasterKey\n * @param {boolean} options.awsKms enable amazon aws keys\n * @returns {Promise.<UploadCmkResponse>} response of upload CMK api\n */\n uploadCustomerMasterKey({\n assignedOrgId,\n customerMasterKey,\n awsKms = false,\n customerMasterKeyBackup = undefined,\n customerMasterKeyRole = undefined,\n }) {\n this.logger.info('kms: upload customer master key for byok');\n\n return this.request({\n method: 'create',\n uri: awsKms ? '/awsKmsCmk' : '/cmk',\n assignedOrgId,\n customerMasterKey,\n requestId: uuid.v4(),\n customerMasterKeyBackup: awsKms ? customerMasterKeyBackup : undefined,\n customerMasterKeyRole: awsKms ? customerMasterKeyRole : undefined,\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 * @param {boolean} options.awsKms enable amazon aws keys\n * @returns {Promise.<ActivateCmkResponse>} response of list CMKs api\n */\n listAllCustomerMasterKey({assignedOrgId, awsKms = false}) {\n this.logger.info('kms: get all customer master keys for byok');\n\n return this.request({\n method: 'retrieve',\n uri: awsKms ? '/awsKmsCmk' : '/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 * @param {boolean} options.awsKms enable amazon aws keys\n * @returns {Promise.<{status, requestId}>}\n */\n deleteAllCustomerMasterKeys({assignedOrgId, awsKms = false}) {\n this.logger.info('kms: delete all customer master keys at the same time');\n\n return this.request({\n method: 'delete',\n uri: awsKms ? '/awsKmsCmk' : '/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 {\n method: 'retrieve',\n uri,\n },\n {onBehalfOf}\n ).then((res) => {\n // Handle redirect for migrated KRO, Key or Auth\n if (res.errorCode === KMS_KEY_REDIRECT_ERROR_CODE && res.redirectUri) {\n this.logger.info('kms: handling redirect for migrated resource', res.redirectUri);\n\n return this.request(\n {\n method: 'retrieve',\n uri: res.redirectUri,\n },\n {onBehalfOf}\n ).then((redirectRes) => {\n this.logger.info('kms: fetched key from redirect');\n\n return this.asKey(redirectRes.key);\n });\n }\n\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).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()).then(\n (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}).then(() => {\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info(\n 'kms: request payload',\n util.inspect(omit(JSON.parse(JSON.stringify(req)), 'wrapped'), {depth: null})\n );\n }\n\n return req;\n });\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(\n event.encryption.kmsMessages.map((kmsMessage, index) =>\n this._isECDHEMessage(kmsMessage).then((isECDHMessage) => {\n this.logger.info(`kms: received ${isECDHMessage ? 'ecdhe' : 'normal'} message`);\n const res = new Response(kmsMessage);\n\n return (\n 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(\n 'kms: response payload',\n util.inspect(omit(JSON.parse(JSON.stringify(res)), 'wrapped'), {depth: null})\n );\n }\n })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => {\n event.encryption.kmsMessages[index] = res;\n })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => res)\n );\n })\n )\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\n .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().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 (\n this.webex.internal.mercury\n .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 (\n process.env.NODE_ENV === 'test' &&\n (reason.status === 403 || reason.statusCode === 403) &&\n reason.message.match(\n /Failed to resolve authorization token in KmsMessage request for user/\n )\n ) {\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(\n 'kms: exceeded maximum KMS request retries; negotiating new ecdh key'\n );\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 /**\n * @private\n * @returns {Promise<string>}\n */\n _getAuthorization() {\n return this.webex.credentials.getUserToken('spark:kms').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([promise, this._getAuthorization()]).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().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\n .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().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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","ignoreList":[]}
1
+ {"version":3,"names":["_querystring","_interopRequireDefault","require","_util","_commonTimers","_common","_webexCore","_nodeKms","_nodeJose","_lodash","_uuid","_kmsBatcher","_interopRequireWildcard","_kmsCertificateValidation","_constants","_dec","_obj","e","t","_WeakMap2","r","n","__esModule","o","i","f","__proto__","default","_typeof","has","get","set","_t","hasOwnProperty","call","_Object$defineProperty","_Object$getOwnPropertyDescriptor2","contexts","_weakMap","kmsDetails","partialContexts","consoleDebug","KMS","WebexPlugin","extend","oneFlight","keyFactory","_ref","uri","onBehalfOf","concat","namespace","children","batcher","KMSBatcher","bindKey","_ref2","_this","kro","kroUri","key","keyUri","logger","info","_promise","reject","Error","request","method","resourceUri","then","res","createResource","_ref3","_this2","userIds","keyUris","keys","reduce","uris","k","push","length","resource","addAuthorization","_ref4","_this3","authIds","authorizations","listAuthorizations","_ref5","_this4","removeAuthorization","_ref6","_this5","authId","userId","querystring","stringify","createUnboundKeys","_ref7","_this6","count","all","map","asKey","fetchPublicKey","_ref8","_this7","assignedOrgId","publicKey","uploadCustomerMasterKey","_ref9","_this8","customerMasterKey","_ref9$awsKms","awsKms","_ref9$customerMasterK","customerMasterKeyBackup","undefined","_ref9$customerMasterK2","customerMasterKeyRole","requestId","uuid","v4","listAllCustomerMasterKey","_ref0","_this9","_ref0$awsKms","changeCustomerMasterKeyState","_ref1","_this0","keyId","keyState","deleteAllCustomerMasterKeys","_ref10","_this1","_ref10$awsKms","useGlobalMasterKey","_ref11","_this10","fetchKey","_ref12","_this11","errorCode","KMS_KEY_REDIRECT_ERROR_CODE","redirectUri","redirectRes","ping","jose","JWK","jwk","prepareRequest","payload","_this12","isECDHRequest","includes","resolve","_getContext","context","req","Request","requestContext","_contextOnBehalfOf","wrap","serverKey","process","env","NODE_ENV","util","inspect","omit","JSON","parse","_stringify","depth","processKmsMessageEvent","event","_this13","encryption","kmsMessages","kmsMessage","index","_isECDHEMessage","isECDHMessage","Response","unwrap","catch","reason","error","stack","decryptKmsMessage","body","_getKMSStaticPubKey","kmsStaticPubKey","fields","split","header","base64url","decode","kid","_this14","_ref13","arguments","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","_this15","promise","_prepareContext","expiresIn","ephemeralKey","expirationDate","_now","safeSetTimeout","_ref14","_ref15","_slicedToArray2","authorization","clientInfo","credential","bearer","_getKMSCluster","_getKMSDetails","_ref16","kmsCluster","_this16","details","service","device","rsaPublicKey","_ref17","_validateKMSStaticPubKey","_this17","_this$config","caroots","carootsReportOnly","validateKMS","jwt","metrics","submitClientMetrics","JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED","success","tags","_this18","Context","_ref18","_ref19","clientId","url","serverInfo","createECDHKey","localECDHKey","_ref20","_ref21","cluster","toJSON","deriveEphemeralKey","originalContext","version","_applyDecoratedDescriptor2","_getOwnPropertyDescriptor","_default","exports"],"sources":["kms.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2024 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';\nimport {\n JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED,\n KMS_KEY_REDIRECT_ERROR_CODE,\n} from './constants';\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({kro, kroUri, key, keyUri}) {\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 }).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({userIds, keyUris, key, keys}) {\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 }).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({userIds, authIds, kro, kroUri}) {\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 }).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 }).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({authId, userId, kro, kroUri}) {\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 }).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 }).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 }).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 * @param {string} options.customerMasterKeyBackup the master key backup\n * @param {string} options.customerMasterKeyRole the optional role associated with customerMasterKey\n * @param {boolean} options.awsKms enable amazon aws keys\n * @returns {Promise.<UploadCmkResponse>} response of upload CMK api\n */\n uploadCustomerMasterKey({\n assignedOrgId,\n customerMasterKey,\n awsKms = false,\n customerMasterKeyBackup = undefined,\n customerMasterKeyRole = undefined,\n }) {\n this.logger.info('kms: upload customer master key for byok');\n\n return this.request({\n method: 'create',\n uri: awsKms ? '/awsKmsCmk' : '/cmk',\n assignedOrgId,\n customerMasterKey,\n requestId: uuid.v4(),\n customerMasterKeyBackup: awsKms ? customerMasterKeyBackup : undefined,\n customerMasterKeyRole: awsKms ? customerMasterKeyRole : undefined,\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 * @param {boolean} options.awsKms enable amazon aws keys\n * @returns {Promise.<ActivateCmkResponse>} response of list CMKs api\n */\n listAllCustomerMasterKey({assignedOrgId, awsKms = false}) {\n this.logger.info('kms: get all customer master keys for byok');\n\n return this.request({\n method: 'retrieve',\n uri: awsKms ? '/awsKmsCmk' : '/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 * @param {boolean} options.awsKms enable amazon aws keys\n * @returns {Promise.<{status, requestId}>}\n */\n deleteAllCustomerMasterKeys({assignedOrgId, awsKms = false}) {\n this.logger.info('kms: delete all customer master keys at the same time');\n\n return this.request({\n method: 'delete',\n uri: awsKms ? '/awsKmsCmk' : '/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 {\n method: 'retrieve',\n uri,\n },\n {onBehalfOf}\n ).then((res) => {\n // Handle redirect for migrated KRO, Key or Auth\n if (res.errorCode === KMS_KEY_REDIRECT_ERROR_CODE && res.redirectUri) {\n this.logger.info('kms: handling redirect for migrated resource', res.redirectUri);\n\n return this.request(\n {\n method: 'retrieve',\n uri: res.redirectUri,\n },\n {onBehalfOf}\n ).then((redirectRes) => {\n this.logger.info('kms: fetched key from redirect');\n\n return this.asKey(redirectRes.key);\n });\n }\n\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).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()).then(\n (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}).then(() => {\n /* istanbul ignore else */\n if (process.env.NODE_ENV !== 'production') {\n this.logger.info(\n 'kms: request payload',\n util.inspect(omit(JSON.parse(JSON.stringify(req)), 'wrapped'), {depth: null})\n );\n }\n\n return req;\n });\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(\n event.encryption.kmsMessages.map((kmsMessage, index) =>\n this._isECDHEMessage(kmsMessage).then((isECDHMessage) => {\n this.logger.info(`kms: received ${isECDHMessage ? 'ecdhe' : 'normal'} message`);\n const res = new Response(kmsMessage);\n\n return (\n 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(\n 'kms: response payload',\n util.inspect(omit(JSON.parse(JSON.stringify(res)), 'wrapped'), {depth: null})\n );\n }\n })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => {\n event.encryption.kmsMessages[index] = res;\n })\n // eslint-disable-next-line max-nested-callbacks\n .then(() => res)\n );\n })\n )\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\n .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().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 (\n this.webex.internal.mercury\n .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 (\n process.env.NODE_ENV === 'test' &&\n (reason.status === 403 || reason.statusCode === 403) &&\n reason.message.match(\n /Failed to resolve authorization token in KmsMessage request for user/\n )\n ) {\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(\n 'kms: exceeded maximum KMS request retries; negotiating new ecdh key'\n );\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 /**\n * @private\n * @returns {Promise<string>}\n */\n _getAuthorization() {\n return this.webex.credentials.getUserToken('spark:kms').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([promise, this._getAuthorization()]).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().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\n .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().then(({rsaPublicKey}) => rsaPublicKey);\n },\n\n /**\n * Validates the KMS static public key against the configured CA roots. The\n * enforced `caroots` bundle rejects on failure. When a `carootsReportOnly`\n * bundle is also configured, it is validated in addition to `caroots`, but a\n * failure against it is only reported as a metric so a new bundle can be\n * trialled without risking failure.\n * @private\n * @param {Object} kmsStaticPubKey\n * @returns {Promise<Object>} the KMS static public key\n */\n _validateKMSStaticPubKey(kmsStaticPubKey) {\n const {caroots, carootsReportOnly} = this.config;\n\n return validateKMS(caroots)(kmsStaticPubKey).then((jwt) => {\n if (!carootsReportOnly) {\n return jwt;\n }\n\n return validateKMS(carootsReportOnly)(kmsStaticPubKey)\n .catch((reason) => {\n this.logger.warn('kms: report-only certificate validation failed', reason);\n\n this.webex.internal.metrics.submitClientMetrics(\n JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED,\n {\n fields: {success: false},\n tags: {reason: reason.message, kid: kmsStaticPubKey && kmsStaticPubKey.kid},\n }\n );\n })\n .then(() => jwt);\n });\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((kmsStaticPubKey) =>\n this._validateKMSStaticPubKey(kmsStaticPubKey)\n ),\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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","ignoreList":[]}
package/package.json CHANGED
@@ -28,23 +28,23 @@
28
28
  "@webex/eslint-config-legacy": "0.0.0",
29
29
  "@webex/jest-config-legacy": "0.0.0",
30
30
  "@webex/legacy-tools": "0.0.0",
31
- "@webex/test-helper-chai": "3.11.0-next.1",
32
- "@webex/test-helper-make-local-url": "3.11.0-next.1",
33
- "@webex/test-helper-mocha": "3.11.0-next.1",
34
- "@webex/test-helper-mock-webex": "3.11.0-next.1",
35
- "@webex/test-helper-test-users": "3.11.0-next.1",
31
+ "@webex/test-helper-chai": "3.12.0-next.6",
32
+ "@webex/test-helper-make-local-url": "3.12.0-next.6",
33
+ "@webex/test-helper-mocha": "3.12.0-next.6",
34
+ "@webex/test-helper-mock-webex": "3.12.0-next.6",
35
+ "@webex/test-helper-test-users": "3.12.0-next.6",
36
36
  "eslint": "^8.24.0",
37
37
  "prettier": "^2.7.1",
38
38
  "sinon": "^9.2.4"
39
39
  },
40
40
  "dependencies": {
41
- "@webex/common": "3.11.0-next.1",
42
- "@webex/common-timers": "3.11.0-next.1",
43
- "@webex/http-core": "3.11.0-next.1",
44
- "@webex/internal-plugin-device": "3.12.0-next.4",
45
- "@webex/internal-plugin-mercury": "3.12.0-next.5",
46
- "@webex/test-helper-file": "3.11.0-next.1",
47
- "@webex/webex-core": "3.12.0-next.4",
41
+ "@webex/common": "3.12.0-next.6",
42
+ "@webex/common-timers": "3.12.0-next.6",
43
+ "@webex/http-core": "3.12.0-next.6",
44
+ "@webex/internal-plugin-device": "3.12.0-next.45",
45
+ "@webex/internal-plugin-mercury": "3.12.0-next.49",
46
+ "@webex/test-helper-file": "3.12.0-next.6",
47
+ "@webex/webex-core": "3.12.0-next.45",
48
48
  "asn1js": "^2.0.26",
49
49
  "debug": "^4.3.4",
50
50
  "isomorphic-webcrypto": "^2.3.8",
@@ -67,5 +67,5 @@
67
67
  "test:style": "eslint ./src/**/*.*",
68
68
  "test:unit": "webex-legacy-tools test --unit --runner jest"
69
69
  },
70
- "version": "3.12.0-next.5"
70
+ "version": "3.12.0-next.50"
71
71
  }
package/src/config.js CHANGED
@@ -46,5 +46,22 @@ export default {
46
46
  * @type {Number}
47
47
  */
48
48
  batcherMaxWait: 150,
49
+
50
+ /**
51
+ * PEM encoded CA root bundle used to validate the KMS certificate chain.
52
+ * When omitted, the KMS certificate chain signature is not verified.
53
+ * @type {?string[]}
54
+ */
55
+ caroots: undefined,
56
+
57
+ /**
58
+ * An additional CA root bundle validated alongside `caroots`. Unlike
59
+ * `caroots`, a validation failure against these roots is reported as a
60
+ * metric instead of failing the ECDH negotiation. This allows a new CA
61
+ * root bundle to be trialled in parallel with the enforced `caroots`
62
+ * without risking total failure.
63
+ * @type {?string[]}
64
+ */
65
+ carootsReportOnly: undefined,
49
66
  },
50
67
  };
package/src/constants.js CHANGED
@@ -2,3 +2,4 @@ export const KMS_KEY_REVOKE_FAILURE = 'event:kms:key:revoke:encryption:failure';
2
2
  export const KMS_KEY_REVOKE_ERROR_STATUS = 405;
3
3
  export const KMS_KEY_REVOKE_ERROR_CODES = [405005, 405006];
4
4
  export const KMS_KEY_REDIRECT_ERROR_CODE = 301002;
5
+ export const JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED = 'JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED';
package/src/kms.js CHANGED
@@ -15,7 +15,10 @@ import uuid from 'uuid';
15
15
 
16
16
  import KMSBatcher, {TIMEOUT_SYMBOL} from './kms-batcher';
17
17
  import validateKMS, {KMSError} from './kms-certificate-validation';
18
- import {KMS_KEY_REDIRECT_ERROR_CODE} from './constants';
18
+ import {
19
+ JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED,
20
+ KMS_KEY_REDIRECT_ERROR_CODE,
21
+ } from './constants';
19
22
 
20
23
  const contexts = new WeakMap();
21
24
  const kmsDetails = new WeakMap();
@@ -780,6 +783,40 @@ const KMS = WebexPlugin.extend({
780
783
  return this._getKMSDetails().then(({rsaPublicKey}) => rsaPublicKey);
781
784
  },
782
785
 
786
+ /**
787
+ * Validates the KMS static public key against the configured CA roots. The
788
+ * enforced `caroots` bundle rejects on failure. When a `carootsReportOnly`
789
+ * bundle is also configured, it is validated in addition to `caroots`, but a
790
+ * failure against it is only reported as a metric so a new bundle can be
791
+ * trialled without risking failure.
792
+ * @private
793
+ * @param {Object} kmsStaticPubKey
794
+ * @returns {Promise<Object>} the KMS static public key
795
+ */
796
+ _validateKMSStaticPubKey(kmsStaticPubKey) {
797
+ const {caroots, carootsReportOnly} = this.config;
798
+
799
+ return validateKMS(caroots)(kmsStaticPubKey).then((jwt) => {
800
+ if (!carootsReportOnly) {
801
+ return jwt;
802
+ }
803
+
804
+ return validateKMS(carootsReportOnly)(kmsStaticPubKey)
805
+ .catch((reason) => {
806
+ this.logger.warn('kms: report-only certificate validation failed', reason);
807
+
808
+ this.webex.internal.metrics.submitClientMetrics(
809
+ JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED,
810
+ {
811
+ fields: {success: false},
812
+ tags: {reason: reason.message, kid: kmsStaticPubKey && kmsStaticPubKey.kid},
813
+ }
814
+ );
815
+ })
816
+ .then(() => jwt);
817
+ });
818
+ },
819
+
783
820
  /**
784
821
  * @private
785
822
  * @returns {Promise<Object>}
@@ -789,7 +826,9 @@ const KMS = WebexPlugin.extend({
789
826
  const context = new Context();
790
827
 
791
828
  return Promise.all([
792
- this._getKMSStaticPubKey().then(validateKMS(this.config.caroots)),
829
+ this._getKMSStaticPubKey().then((kmsStaticPubKey) =>
830
+ this._validateKMSStaticPubKey(kmsStaticPubKey)
831
+ ),
793
832
  this._getAuthorization(),
794
833
  ])
795
834
  .then(([kmsStaticPubKey, authorization]) => {
@@ -97,7 +97,7 @@ describe('Encryption', function () {
97
97
  describe('#decryptBinaryData()', () => {
98
98
  it('decrypts binary data', () =>
99
99
  webex.internal.encryption
100
- .encryptText(key, FILE.toString('base64'))
100
+ .encryptBinaryData(key, FILE)
101
101
  .then((ciphertext) => {
102
102
  assert.notEqual(ciphertext, FILE.toString('base64'));
103
103
 
@@ -112,7 +112,7 @@ describe('Encryption', function () {
112
112
  const binaryData = Buffer.from('test binary data', 'utf8');
113
113
 
114
114
  return webex.internal.encryption
115
- .encryptText(key, binaryData.toString('base64'))
115
+ .encryptBinaryData(key, binaryData)
116
116
  .then((ciphertext) => {
117
117
  assert.notEqual(ciphertext, binaryData.toString('base64'));
118
118
 
@@ -128,7 +128,7 @@ describe('Encryption', function () {
128
128
  const binaryData = Buffer.from('test binary data with options', 'utf8');
129
129
 
130
130
  return webex.internal.encryption
131
- .encryptText(key, binaryData.toString('base64'))
131
+ .encryptBinaryData(key, binaryData)
132
132
  .then((ciphertext) => {
133
133
  assert.notEqual(ciphertext, binaryData.toString('base64'));
134
134
 
@@ -163,7 +163,7 @@ describe('Encryption', function () {
163
163
  assert.equal(largeString.length, 3000);
164
164
 
165
165
  return webex.internal.encryption
166
- .encryptText(key, binaryData.toString('base64'))
166
+ .encryptBinaryData(key, binaryData)
167
167
  .then((ciphertext) => {
168
168
  assert.notEqual(ciphertext, binaryData.toString('base64'));
169
169
 
@@ -521,7 +521,7 @@ describe('Encryption', function () {
521
521
  const binaryData = Buffer.from('compliance test binary data', 'utf8');
522
522
 
523
523
  return webex.internal.encryption
524
- .encryptText(key, binaryData.toString('base64'))
524
+ .encryptBinaryData(key, binaryData)
525
525
  .then((ciphertext) => {
526
526
  assert.notEqual(ciphertext, binaryData.toString('base64'));
527
527
 
@@ -10,7 +10,7 @@ import sinon from 'sinon';
10
10
  import WebexCore from '@webex/webex-core';
11
11
  import testUsers from '@webex/test-helper-test-users';
12
12
  import uuid from 'uuid';
13
- import {skipInBrowser} from '@webex/test-helper-mocha';
13
+ import {browserOnly} from '@webex/test-helper-mocha';
14
14
 
15
15
  const debug = require('debug')('kms');
16
16
 
@@ -425,7 +425,7 @@ describe('Encryption', function () {
425
425
  describe('upload customer master key', () => {
426
426
  let uploadedkeyId;
427
427
 
428
- skipInBrowser(it)('upload customer master key', () =>
428
+ browserOnly(it)('upload customer master key', () =>
429
429
  webex.internal.encryption.kms
430
430
  .deleteAllCustomerMasterKeys({assignedOrgId: spock.orgId})
431
431
  .then(() => webex.internal.encryption.kms.fetchPublicKey({assignedOrgId: spock.orgId}))
@@ -26,6 +26,8 @@ describe('plugin-encryption', () => {
26
26
 
27
27
  before('register with wdm', () => webex.internal.device.register());
28
28
 
29
+ after(() => webex && webex.internal.mercury.disconnect());
30
+
29
31
  describe('when a DRY response has an error', () => {
30
32
  it('decrypts the error message', () =>
31
33
  assert
@@ -241,6 +241,74 @@ describe('internal-plugin-encryption', () => {
241
241
  });
242
242
  });
243
243
 
244
+ describe('_validateKMSStaticPubKey', () => {
245
+ // Real CA root that signed the `x5c` certificate below.
246
+ const caroots = [
247
+ 'MIID6TCCAtGgAwIBAgIURmBu688C9oUIJXlykr1J3fi5H4kwDQYJKoZIhvcNAQELBQAwgYMxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhDb2xvcmFkbzEPMA0GA1UEBwwGRGVudmVyMRAwDgYDVQQKDAdFeGFtcGxlMR8wHQYDVQQDDBZodHRwczovL2NhLmV4YW1wbGUuY29tMR0wGwYJKoZIhvcNAQkBFg5jYUBleGFtcGxlLmNvbTAeFw0yMDAyMDYyMDIyMDhaFw00MDAyMDEyMDIyMDhaMIGDMQswCQYDVQQGEwJVUzERMA8GA1UECAwIQ29sb3JhZG8xDzANBgNVBAcMBkRlbnZlcjEQMA4GA1UECgwHRXhhbXBsZTEfMB0GA1UEAwwWaHR0cHM6Ly9jYS5leGFtcGxlLmNvbTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7TaDWldwjU65y4fnNDIuNu4dZi3bZvaN9nJ3A8D9pwFcNx3DL5cPpafAkJuE/2ZBrsZxJWKwXLQFuNE9V3XVslv0OPgEZVfY5AKuPhVezRqEqsCdUgODMkJat6PE02r0NZRFpBiRCThh0wY5u/tiTiPgjHwEPhBEyLgcJ6FOWLn9wBsS4SvBzfppYGL5GW1G0eN9yORnKKgqkgyf0x8FvTMyVSjtkhcI/kA/8061sl4DFG6sefQmAOVvH7tp7YmN+jpQ7cOKQtjOpZS6Gp22u7LEI0/qb5n2QvjjcUQM81mN6CZ8nciWXRgjBhdAJJhmyMvcx8rnVb6vtU26fCaetAgMBAAGjUzBRMB0GA1UdDgQWBBRZiCyKaTYL94gwhxzktYg32qMOYjAfBgNVHSMEGDAWgBRZiCyKaTYL94gwhxzktYg32qMOYjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQATa2QkTGcj8IPjItnvg23ihlRjHdFHn6lB7uYPhcDurwRlBrlC2/OB44P3dHB9tEPbV4unoF9ftEKO3nNY3HUDcPrQwRqkPftlYYr4/6z/jnmNBRgiDICVaiTZNlX54fLiPsSAbIymPWLLLNtq17vjVEcfGUXhi/F+EkN/uXZ4yH6RK0YjBRwPV9cfziz1YsF2WVYVYtQErf+NTjnYR5S4Ba2kEqhI5j7mNhiafPNODaOchHcaRMvfWcBhlHt+atwNyPxNr4NP+cDjAWg0I8xAUdbZGQiRJecjkctolLHsfZXj+ulEv3eaKw7gSo3Aekexw8aZS7soy+VM1fzmLopw',
248
+ ];
249
+ // Unrelated self-signed CA that does NOT sign the `x5c` certificate.
250
+ const unrelatedCaroots = [
251
+ 'MIIFmTCCA4GgAwIBAgIUOxbqWoC/R0Lt2eWgqE3960xTLE4wDQYJKoZIhvcNAQELBQAwXDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNPMQ8wDQYDVQQHDAZEZW52ZXIxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEYMBYGA1UEAwwPa21zLmV4YW1wbGUuY29tMB4XDTIwMDIxMTIwMjk0NVoXDTQwMDIwNjIwMjk0NVowXDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNPMQ8wDQYDVQQHDAZEZW52ZXIxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEYMBYGA1UEAwwPa21zLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyRUvQFD9UboxW4xjOyo2Cu7RsAT0GDx66Brl3tEnxvCwnfSystwerbAZtGtrklDJWcqAWVbSNwxnPuGsxSUg4D8ziI4Biqc6rvoNO4YYzpHWYmS9aLMG8TOUzAZZORrnvuiu7VGleZKi+Yd08fXSjrUV4sldRiD+Y0IN80xa52B0053yFX4geCuFn0Ewo8NXhkCU6Pfwb9wVVuCmcu9mt3ubpWRa2H+h2ie3suAc4ADrb9Ng63stU3UrjUcYv5guo0gBOBrk7i0WL/2KJf2NmDJiTaaCxR0gEe0sHjio7PCXDNHS0eJj/2++Wq90fDbBFDP/LP0aBKJAvaTZNEKcX5Hr/Y32Bz1Szpi18/HSlEF6rIketLiAzgLfzRMktctWLGGubp6RarNWALBX5kJA43/Cernaf0sVRtCUqjKPRd8k8Bo3BXl5VwVn2b+nZO6EJQ6RslOfbumFPVhlyFv6I1tAOPmZOHjOpc4ogPyI7jMefXMMsSJOGgLb7JVPpbi0bjXmsW7I0sWcAdDzcASNUxxp1c0qXZu4nHI2VlPucA4LA5W4Z1qcNQsfQEN4gdPWBeSbDBv0FPxFcHZNqk87ywvLkurgASL+KxqB9FzIqhv7w0OYm1r7iClBJxsbItYeehEypv/PJpxBq1uxcd6pExY6kTP3x8YAqUgb3GoWlUsCAwEAAaNTMFEwHQYDVR0OBBYEFOJqvx/CUIV6mkiTURkyVYiugkqVMB8GA1UdIwQYMBaAFOJqvx/CUIV6mkiTURkyVYiugkqVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHTov7zZOMt7zAfy9N8X6yOsakUqAXVtrTDu9DMn9kw2vhudSfNfno7dSc3JeE+KtySkyfrMbNub19IzfVHMI2dRiO7PGzgv8XD69PC/PKaqNmViW27P0l4ORGKE4RHcjd0Y0Rj8nciwHDu4u7p9gI1yS7TiLtpQqyb0ba/ZVP88EVe7wI+BtoHiSMQeEjs13gTSARTYXay0WsL7xxwzKH68Y4RRjfqt+NpyMP7wrf5Kcha2cID8jG9i4LqSoj+o5jvwH969jEP+9DX7XFx0894O42xGreyl1E1HkKOgrGE+owkEpVNYLfcQP3tbx3maoG2g5TXMtMqei1ffNdUiONPbi9II1UP53JrTcnFUb3aVo2yLJ5ftkOSWpkyhk9G9TWoUiTB/k3Jb6gxzk6HvjhLgYTeT+UPW/ATiffL7SNmGTQBuVuNUHNxm4sAz9oQTmCo+8vCqMtqK4IHeKqNP+yqVGCAI71yEcxuYy17S57iarK7ON/RTMiblerUOowOSBzTmm+7kuR8Ke0BVCw6l0A7yUueAUnRaVXEAszvhHsLxZMlnMeYlL5qj6CAamdgpwdsMFa0QcAAcGl6j3vW9ks9nLlEAzJmUIQUx33W4SryYwflliWkH4f4OlRj7Lrq81/QvZ+tTUTiTBrvZjB1j9ezCv0Fjp9cEDi1hyV1ArKV3',
252
+ ];
253
+ const validKey = {
254
+ kty: 'RSA',
255
+ kid: 'kms://kms.example.com',
256
+ x5c: [
257
+ 'MIIDaDCCAlACFG2NkKF2WKCN/OnGN2E7mBamxhB2MA0GCSqGSIb3DQEBCwUAMIGDMQswCQYDVQQGEwJVUzERMA8GA1UECAwIQ29sb3JhZG8xDzANBgNVBAcMBkRlbnZlcjEQMA4GA1UECgwHRXhhbXBsZTEfMB0GA1UEAwwWaHR0cHM6Ly9jYS5leGFtcGxlLmNvbTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhcNMjAwMjA2MjAzMjU0WhcNNDAwMjAxMjAzMjU0WjBdMQswCQYDVQQGEwJVUzERMA8GA1UECAwIQ29sb3JhZG8xDzANBgNVBAcMBkRlbnZlcjEQMA4GA1UECgwHRXhhbXBsZTEYMBYGA1UEAwwPa21zLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2OObWUoNG0Wv4zYuhGUT7JNiUkefUsFZ384NS2l5VOB/lSNcElBtmX55yPcjvPnukfpETDUG82K8ncOwCuV8ZTpvzM3QHSIHGyO5JBFJ38U6Pq6kHje6An+eSHLCVkQfOlf4TCRb8SlcEoi8wkl3IIGewzC0/87b1OvyYTb8BHZJVeUV7AxcZChkAA/IJV5ADnmc/6ZCihXVuCWJgTFpLLv7HVqE924lNDTgRn64ioCpHK4pC1FFqQKLlsq0tV75gc5d7A6m5/9znEvg02JuqUFd9LdOcnf8QeTkyg6OTTvJUUa39KZDKONi8MXiECacGU6VbUvuKOXZU49UeqVKQQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCmlEodmn5LfgIWViRn8t4qjTZoM7VUGWXfCnaMqSnW6P0eYbZdCoCecja6WicBWPAlFFR/UscYv4rEGXtmzD+GQUQKfYFfsNdkfCpPvCFlpudHNuW0kCZ8lUfDWQRirrC+MyiAVpEG7mNHNZfK9hof05MHS6ItcpET5+F0DiC6l+vsBBRqP2SU8bo9gTrr8WO7bW8JQb59XNEoTQC1AzCn172+idJcgaasOfp/V+QqODIa96YNM7vT9pj09nGL0Wxulaq546pW32HYkOhZw1nr8prZn17UFLfoQnaNuTuT2ZCsFc7V2H0UqcMwjg1QZoObLI5tXPv0syP6WXo19OjW',
258
+ ],
259
+ e: 'AQAB',
260
+ n: '2OObWUoNG0Wv4zYuhGUT7JNiUkefUsFZ384NS2l5VOB_lSNcElBtmX55yPcjvPnukfpETDUG82K8ncOwCuV8ZTpvzM3QHSIHGyO5JBFJ38U6Pq6kHje6An-eSHLCVkQfOlf4TCRb8SlcEoi8wkl3IIGewzC0_87b1OvyYTb8BHZJVeUV7AxcZChkAA_IJV5ADnmc_6ZCihXVuCWJgTFpLLv7HVqE924lNDTgRn64ioCpHK4pC1FFqQKLlsq0tV75gc5d7A6m5_9znEvg02JuqUFd9LdOcnf8QeTkyg6OTTvJUUa39KZDKONi8MXiECacGU6VbUvuKOXZU49UeqVKQQ',
261
+ };
262
+ const invalidKey = {kty: 'NOT_RSA', kid: 'kms://kms.example.com'};
263
+
264
+ beforeEach(() => {
265
+ webex.internal.metrics = {submitClientMetrics: sinon.stub()};
266
+ webex.internal.encryption.config.caroots = caroots;
267
+ webex.internal.encryption.config.carootsReportOnly = undefined;
268
+ });
269
+
270
+ it('rejects and does not report when validation against caroots fails', async () => {
271
+ await assert.isRejected(
272
+ webex.internal.encryption.kms._validateKMSStaticPubKey(invalidKey),
273
+ /INVALID KMS/
274
+ );
275
+
276
+ assert.notCalled(webex.internal.metrics.submitClientMetrics);
277
+ });
278
+
279
+ it('resolves without a metric when no report-only bundle is configured', async () => {
280
+ const result = await webex.internal.encryption.kms._validateKMSStaticPubKey(validKey);
281
+
282
+ assert.equal(result, validKey);
283
+ assert.notCalled(webex.internal.metrics.submitClientMetrics);
284
+ });
285
+
286
+ it('resolves without a metric when the report-only bundle also validates', async () => {
287
+ webex.internal.encryption.config.carootsReportOnly = caroots;
288
+
289
+ const result = await webex.internal.encryption.kms._validateKMSStaticPubKey(validKey);
290
+
291
+ assert.equal(result, validKey);
292
+ assert.notCalled(webex.internal.metrics.submitClientMetrics);
293
+ });
294
+
295
+ it('resolves and submits a metric when only the report-only bundle fails', async () => {
296
+ webex.internal.encryption.config.carootsReportOnly = unrelatedCaroots;
297
+
298
+ const result = await webex.internal.encryption.kms._validateKMSStaticPubKey(validKey);
299
+
300
+ assert.equal(result, validKey);
301
+ assert.calledOnce(webex.internal.metrics.submitClientMetrics);
302
+
303
+ const [name, payload] = webex.internal.metrics.submitClientMetrics.args[0];
304
+
305
+ assert.equal(name, 'JS_SDK_KMS_CERTIFICATE_VALIDATION_FAILED');
306
+ assert.deepEqual(payload.fields, {success: false});
307
+ assert.equal(payload.tags.kid, 'kms://kms.example.com');
308
+ assert.match(payload.tags.reason, /INVALID KMS/);
309
+ });
310
+ });
311
+
244
312
  describe('KMS error', () => {
245
313
  it('KMSError', async () => {
246
314
  const error = new KmsError({