@webex/internal-plugin-encryption 3.11.0-next.1 → 3.11.0-next.10
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 +28 -5
- package/dist/encryption.js.map +1 -1
- package/dist/kms.js +1 -1
- package/package.json +13 -13
- package/src/encryption.js +23 -0
- package/test/integration/spec/encryption.js +101 -0
- package/test/unit/spec/encryption.js +78 -0
package/dist/encryption.js
CHANGED
|
@@ -223,6 +223,29 @@ var Encryption = _webexCore.WebexPlugin.extend({
|
|
|
223
223
|
}).final(plaintext, 'utf8');
|
|
224
224
|
});
|
|
225
225
|
},
|
|
226
|
+
/**
|
|
227
|
+
* Encrypt binary data using the supplied key uri.
|
|
228
|
+
*
|
|
229
|
+
* @param {string} kmsKeyUri - The uri of a key stored in KMS
|
|
230
|
+
* @param {Buffer|ArrayBuffer|Blob|File} data - Binary data to encrypt
|
|
231
|
+
* @param {Object} options
|
|
232
|
+
* @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role
|
|
233
|
+
* @returns {string} Encrypted binary data as JWE
|
|
234
|
+
*/
|
|
235
|
+
encryptBinaryData: function encryptBinaryData(kmsKeyUri, data, options) {
|
|
236
|
+
var _this4 = this;
|
|
237
|
+
return this.getKey(kmsKeyUri, options).then(function (k) {
|
|
238
|
+
return (0, _ensureBuffer.default)(data).then(function (buffer) {
|
|
239
|
+
return _nodeJose.default.JWE.createEncrypt(_this4.config.joseOptions, {
|
|
240
|
+
key: k.jwk,
|
|
241
|
+
header: {
|
|
242
|
+
alg: 'dir'
|
|
243
|
+
},
|
|
244
|
+
reference: null
|
|
245
|
+
}).final(buffer);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
},
|
|
226
249
|
/**
|
|
227
250
|
* Fetch the key associated with the supplied KMS uri.
|
|
228
251
|
*
|
|
@@ -232,7 +255,7 @@ var Encryption = _webexCore.WebexPlugin.extend({
|
|
|
232
255
|
* @returns {string} Key
|
|
233
256
|
*/
|
|
234
257
|
getKey: function getKey(uri) {
|
|
235
|
-
var
|
|
258
|
+
var _this5 = this;
|
|
236
259
|
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
237
260
|
onBehalfOf = _ref.onBehalfOf;
|
|
238
261
|
if (uri.jwk) {
|
|
@@ -245,17 +268,17 @@ var Encryption = _webexCore.WebexPlugin.extend({
|
|
|
245
268
|
return this.unboundedStorage.get(storageKey).then(function (keyString) {
|
|
246
269
|
return JSON.parse(keyString);
|
|
247
270
|
}).then(function (keyObject) {
|
|
248
|
-
return
|
|
271
|
+
return _this5.kms.asKey(keyObject);
|
|
249
272
|
}).catch(function () {
|
|
250
|
-
return
|
|
273
|
+
return _this5.kms.fetchKey({
|
|
251
274
|
uri: uri,
|
|
252
275
|
onBehalfOf: onBehalfOf
|
|
253
276
|
}).then((0, _common.tap)(function (key) {
|
|
254
|
-
return
|
|
277
|
+
return _this5.unboundedStorage.put(storageKey, (0, _stringify.default)(key, replacer));
|
|
255
278
|
}));
|
|
256
279
|
});
|
|
257
280
|
},
|
|
258
|
-
version: "3.11.0-next.
|
|
281
|
+
version: "3.11.0-next.10"
|
|
259
282
|
});
|
|
260
283
|
|
|
261
284
|
/**
|
package/dist/encryption.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_events","require","_url","_interopRequireDefault","_webexCore","_common","_nodeJose","_nodeScr","_ensureBuffer","_kms","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","Encryption","WebexPlugin","extend","children","kms","KMS","namespace","processKmsMessageEvent","event","decryptBinary","scr","buffer","ensureBuffer","then","b","byteLength","_promise","reject","Error","decrypt","decryptScr","key","cipherScr","options","getKey","k","SCR","fromJWE","jwk","decryptText","ciphertext","jose","JWE","createDecrypt","result","plaintext","toString","decryptBinaryData","kmsKeyUri","payload","download","fileUrl","_this","shunt","EventEmitter","promise","_fetchDownloadUrl","useFileService","uri","method","responseType","ret","request","transferEvents","res","body","proxyEvents","_this2","logger","info","process","env","NODE_ENV","includes","resolve","startsWith","error","inputBody","endpoints","endpointUrl","url","parse","protocol","pathname","format","params","_keys","indexOf","allow","warn","catch","err","concat","encryptBinary","file","create","encrypt","cdata","encryptScr","loc","toJWE","encryptText","_this3","createEncrypt","config","joseOptions","header","alg","reference","final","_this4","_ref","undefined","onBehalfOf","asKey","storageKey","unboundedStorage","get","keyString","JSON","keyObject","fetchKey","tap","put","_stringify","replacer","version","v","json","toJSON","_default","exports"],"sources":["encryption.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {EventEmitter} from 'events';\nimport url from 'url';\n\nimport {WebexPlugin} from '@webex/webex-core';\nimport {proxyEvents, tap, transferEvents} from '@webex/common';\nimport jose from 'node-jose';\nimport SCR from 'node-scr';\n\nimport ensureBuffer from './ensure-buffer';\nimport KMS from './kms';\n\nconst Encryption = WebexPlugin.extend({\n children: {\n kms: KMS,\n },\n\n namespace: 'Encryption',\n\n processKmsMessageEvent(event) {\n return this.kms.processKmsMessageEvent(event);\n },\n\n decryptBinary(scr, buffer) {\n return ensureBuffer(buffer).then((b) => {\n /* istanbul ignore if */\n if (buffer.length === 0 || buffer.byteLength === 0) {\n return Promise.reject(new Error('Attempted to decrypt zero-length buffer'));\n }\n\n return scr.decrypt(b);\n });\n },\n\n /**\n * Decrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} cipherScr - An encrypted SCR\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {Object} Decrypted SCR\n */\n decryptScr(key, cipherScr, options) {\n return this.getKey(key, options).then((k) => SCR.fromJWE(k.jwk, cipherScr));\n },\n\n /**\n * Decrypt text using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} ciphertext - Encrypted text\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Decrypted plaintext\n */\n decryptText(key, ciphertext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createDecrypt(k.jwk)\n .decrypt(ciphertext)\n .then((result) => result.plaintext.toString())\n );\n },\n\n /**\n * Decrypt binary data using the supplied key uri.\n *\n * @param {string} kmsKeyUri - The uri of a key stored in KMS\n * @param {string} JWE - Encrypted binary data as JWE\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {Buffer} Decrypted binary data as Buffer\n */\n decryptBinaryData(kmsKeyUri, JWE, options) {\n return this.getKey(kmsKeyUri, options).then((k) =>\n jose.JWE.createDecrypt(k.jwk)\n .decrypt(JWE)\n .then((result) => result.payload)\n );\n },\n\n /**\n * Validate and initiate a Download request for requested file\n * @param {Object} fileUrl - Plaintext\n * @param {Object} scr - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise}\n */\n download(fileUrl, scr, options) {\n /* istanbul ignore if */\n if (!fileUrl || !scr) {\n return Promise.reject(new Error('`scr` and `fileUrl` are required'));\n }\n\n const shunt = new EventEmitter();\n const promise = this._fetchDownloadUrl(fileUrl, {useFileService: true, ...options})\n .then((uri) => {\n // eslint-disable-next-line no-shadow\n const options = {\n method: 'GET',\n uri,\n responseType: 'buffer',\n };\n\n const ret = this.request(options);\n\n transferEvents('progress', options.download, shunt);\n\n return ret;\n })\n .then((res) => this.decryptBinary(scr, res.body));\n\n proxyEvents(shunt, promise);\n\n return promise;\n },\n\n /**\n * Fetch Download URL for the requested file\n * @param {Object} fileUrl - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise} url of the downloadable file\n */\n _fetchDownloadUrl(fileUrl, options) {\n this.logger.info('encryption: retrieving download url for encrypted file');\n\n if (process.env.NODE_ENV !== 'production' && fileUrl.includes('localhost')) {\n this.logger.info(\n 'encryption: bypassing webex files because this looks to be a test file on localhost'\n );\n\n return Promise.resolve(fileUrl);\n }\n\n if (options?.useFileService === false) {\n if (!fileUrl.startsWith('https://')) {\n this.logger.error('encryption: direct file URLs must use HTTPS');\n\n return Promise.reject(new Error('Direct file URLs must use HTTPS'));\n }\n\n return Promise.resolve(fileUrl);\n }\n\n const inputBody = {\n endpoints: [fileUrl],\n };\n const endpointUrl = url.parse(fileUrl);\n\n // hardcode the url to use 'https' and the file service '/v1/download/endpoints' api\n endpointUrl.protocol = 'https';\n endpointUrl.pathname = '/v1/download/endpoints';\n\n return this.request({\n method: 'POST',\n uri: url.format(endpointUrl),\n body:\n options?.params && Object.keys(options.params).indexOf('allow') > -1\n ? {\n ...inputBody,\n allow: options.params.allow,\n }\n : inputBody,\n })\n .then((res) => {\n // eslint-disable-next-line no-shadow\n const url = res.body.endpoints[fileUrl];\n\n if (!url) {\n this.logger.warn(\n 'encryption: could not determine download url for `fileUrl`; attempting to download `fileUrl` directly'\n );\n\n return fileUrl;\n }\n this.logger.info('encryption: retrieved download url for encrypted file');\n\n return url;\n })\n .catch((err) => {\n this.logger.warn(\n `encryption: ${err} could not determine download url for ${fileUrl}; attempting to download ${fileUrl} directly`\n );\n\n return fileUrl;\n });\n },\n\n encryptBinary(file) {\n return ensureBuffer(file).then((buffer) =>\n SCR.create().then((scr) =>\n scr\n .encrypt(buffer)\n .then(ensureBuffer)\n // eslint-disable-next-line max-nested-callbacks\n .then((cdata) => ({scr, cdata}))\n )\n );\n },\n\n /**\n * Encrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} scr - SCRObject\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted SCR\n */\n encryptScr(key, scr, options) {\n /* istanbul ignore if */\n if (!scr.loc) {\n return Promise.reject(new Error('Cannot encrypt `scr` without first setting `loc`'));\n }\n\n return this.getKey(key, options).then((k) => scr.toJWE(k.jwk));\n },\n\n /**\n * Encrypt plaintext using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} plaintext\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted text\n */\n encryptText(key, plaintext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createEncrypt(this.config.joseOptions, {\n key: k.jwk,\n header: {\n alg: 'dir',\n },\n reference: null,\n }).final(plaintext, 'utf8')\n );\n },\n\n /**\n * Fetch the key associated with the supplied KMS uri.\n *\n * @param {string} uri - The uri of a key stored in KMS\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Key\n */\n getKey(uri, {onBehalfOf} = {}) {\n if (uri.jwk) {\n return this.kms.asKey(uri);\n }\n\n let storageKey = uri;\n\n if (onBehalfOf) {\n storageKey += `/onBehalfOf/${onBehalfOf}`;\n }\n\n return this.unboundedStorage\n .get(storageKey)\n .then((keyString) => JSON.parse(keyString))\n .then((keyObject) => this.kms.asKey(keyObject))\n .catch(() =>\n this.kms\n .fetchKey({uri, onBehalfOf})\n .then(tap((key) => this.unboundedStorage.put(storageKey, JSON.stringify(key, replacer))))\n );\n },\n});\n\n/**\n * JSON.stringify replacer that ensures private key data is serialized.\n * @param {string} k\n * @param {mixed} v\n * @returns {mixed}\n */\nfunction replacer(k, v) {\n if (k === 'jwk') {\n // note: this[k] and v may be different representations of the same value\n // eslint-disable-next-line no-invalid-this\n const json = this[k].toJSON(true);\n\n return json;\n }\n\n return v;\n}\n\nexport default Encryption;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_events","require","_url","_interopRequireDefault","_webexCore","_common","_nodeJose","_nodeScr","_ensureBuffer","_kms","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","Encryption","WebexPlugin","extend","children","kms","KMS","namespace","processKmsMessageEvent","event","decryptBinary","scr","buffer","ensureBuffer","then","b","byteLength","_promise","reject","Error","decrypt","decryptScr","key","cipherScr","options","getKey","k","SCR","fromJWE","jwk","decryptText","ciphertext","jose","JWE","createDecrypt","result","plaintext","toString","decryptBinaryData","kmsKeyUri","payload","download","fileUrl","_this","shunt","EventEmitter","promise","_fetchDownloadUrl","useFileService","uri","method","responseType","ret","request","transferEvents","res","body","proxyEvents","_this2","logger","info","process","env","NODE_ENV","includes","resolve","startsWith","error","inputBody","endpoints","endpointUrl","url","parse","protocol","pathname","format","params","_keys","indexOf","allow","warn","catch","err","concat","encryptBinary","file","create","encrypt","cdata","encryptScr","loc","toJWE","encryptText","_this3","createEncrypt","config","joseOptions","header","alg","reference","final","encryptBinaryData","data","_this4","_this5","_ref","undefined","onBehalfOf","asKey","storageKey","unboundedStorage","get","keyString","JSON","keyObject","fetchKey","tap","put","_stringify","replacer","version","v","json","toJSON","_default","exports"],"sources":["encryption.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {EventEmitter} from 'events';\nimport url from 'url';\n\nimport {WebexPlugin} from '@webex/webex-core';\nimport {proxyEvents, tap, transferEvents} from '@webex/common';\nimport jose from 'node-jose';\nimport SCR from 'node-scr';\n\nimport ensureBuffer from './ensure-buffer';\nimport KMS from './kms';\n\nconst Encryption = WebexPlugin.extend({\n children: {\n kms: KMS,\n },\n\n namespace: 'Encryption',\n\n processKmsMessageEvent(event) {\n return this.kms.processKmsMessageEvent(event);\n },\n\n decryptBinary(scr, buffer) {\n return ensureBuffer(buffer).then((b) => {\n /* istanbul ignore if */\n if (buffer.length === 0 || buffer.byteLength === 0) {\n return Promise.reject(new Error('Attempted to decrypt zero-length buffer'));\n }\n\n return scr.decrypt(b);\n });\n },\n\n /**\n * Decrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} cipherScr - An encrypted SCR\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {Object} Decrypted SCR\n */\n decryptScr(key, cipherScr, options) {\n return this.getKey(key, options).then((k) => SCR.fromJWE(k.jwk, cipherScr));\n },\n\n /**\n * Decrypt text using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} ciphertext - Encrypted text\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Decrypted plaintext\n */\n decryptText(key, ciphertext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createDecrypt(k.jwk)\n .decrypt(ciphertext)\n .then((result) => result.plaintext.toString())\n );\n },\n\n /**\n * Decrypt binary data using the supplied key uri.\n *\n * @param {string} kmsKeyUri - The uri of a key stored in KMS\n * @param {string} JWE - Encrypted binary data as JWE\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {Buffer} Decrypted binary data as Buffer\n */\n decryptBinaryData(kmsKeyUri, JWE, options) {\n return this.getKey(kmsKeyUri, options).then((k) =>\n jose.JWE.createDecrypt(k.jwk)\n .decrypt(JWE)\n .then((result) => result.payload)\n );\n },\n\n /**\n * Validate and initiate a Download request for requested file\n * @param {Object} fileUrl - Plaintext\n * @param {Object} scr - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise}\n */\n download(fileUrl, scr, options) {\n /* istanbul ignore if */\n if (!fileUrl || !scr) {\n return Promise.reject(new Error('`scr` and `fileUrl` are required'));\n }\n\n const shunt = new EventEmitter();\n const promise = this._fetchDownloadUrl(fileUrl, {useFileService: true, ...options})\n .then((uri) => {\n // eslint-disable-next-line no-shadow\n const options = {\n method: 'GET',\n uri,\n responseType: 'buffer',\n };\n\n const ret = this.request(options);\n\n transferEvents('progress', options.download, shunt);\n\n return ret;\n })\n .then((res) => this.decryptBinary(scr, res.body));\n\n proxyEvents(shunt, promise);\n\n return promise;\n },\n\n /**\n * Fetch Download URL for the requested file\n * @param {Object} fileUrl - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise} url of the downloadable file\n */\n _fetchDownloadUrl(fileUrl, options) {\n this.logger.info('encryption: retrieving download url for encrypted file');\n\n if (process.env.NODE_ENV !== 'production' && fileUrl.includes('localhost')) {\n this.logger.info(\n 'encryption: bypassing webex files because this looks to be a test file on localhost'\n );\n\n return Promise.resolve(fileUrl);\n }\n\n if (options?.useFileService === false) {\n if (!fileUrl.startsWith('https://')) {\n this.logger.error('encryption: direct file URLs must use HTTPS');\n\n return Promise.reject(new Error('Direct file URLs must use HTTPS'));\n }\n\n return Promise.resolve(fileUrl);\n }\n\n const inputBody = {\n endpoints: [fileUrl],\n };\n const endpointUrl = url.parse(fileUrl);\n\n // hardcode the url to use 'https' and the file service '/v1/download/endpoints' api\n endpointUrl.protocol = 'https';\n endpointUrl.pathname = '/v1/download/endpoints';\n\n return this.request({\n method: 'POST',\n uri: url.format(endpointUrl),\n body:\n options?.params && Object.keys(options.params).indexOf('allow') > -1\n ? {\n ...inputBody,\n allow: options.params.allow,\n }\n : inputBody,\n })\n .then((res) => {\n // eslint-disable-next-line no-shadow\n const url = res.body.endpoints[fileUrl];\n\n if (!url) {\n this.logger.warn(\n 'encryption: could not determine download url for `fileUrl`; attempting to download `fileUrl` directly'\n );\n\n return fileUrl;\n }\n this.logger.info('encryption: retrieved download url for encrypted file');\n\n return url;\n })\n .catch((err) => {\n this.logger.warn(\n `encryption: ${err} could not determine download url for ${fileUrl}; attempting to download ${fileUrl} directly`\n );\n\n return fileUrl;\n });\n },\n\n encryptBinary(file) {\n return ensureBuffer(file).then((buffer) =>\n SCR.create().then((scr) =>\n scr\n .encrypt(buffer)\n .then(ensureBuffer)\n // eslint-disable-next-line max-nested-callbacks\n .then((cdata) => ({scr, cdata}))\n )\n );\n },\n\n /**\n * Encrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} scr - SCRObject\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted SCR\n */\n encryptScr(key, scr, options) {\n /* istanbul ignore if */\n if (!scr.loc) {\n return Promise.reject(new Error('Cannot encrypt `scr` without first setting `loc`'));\n }\n\n return this.getKey(key, options).then((k) => scr.toJWE(k.jwk));\n },\n\n /**\n * Encrypt plaintext using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} plaintext\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted text\n */\n encryptText(key, plaintext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createEncrypt(this.config.joseOptions, {\n key: k.jwk,\n header: {\n alg: 'dir',\n },\n reference: null,\n }).final(plaintext, 'utf8')\n );\n },\n\n /**\n * Encrypt binary data using the supplied key uri.\n *\n * @param {string} kmsKeyUri - The uri of a key stored in KMS\n * @param {Buffer|ArrayBuffer|Blob|File} data - Binary data to encrypt\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted binary data as JWE\n */\n encryptBinaryData(kmsKeyUri, data, options) {\n return this.getKey(kmsKeyUri, options).then((k) =>\n ensureBuffer(data).then((buffer) =>\n jose.JWE.createEncrypt(this.config.joseOptions, {\n key: k.jwk,\n header: {\n alg: 'dir',\n },\n reference: null,\n }).final(buffer)\n )\n );\n },\n\n /**\n * Fetch the key associated with the supplied KMS uri.\n *\n * @param {string} uri - The uri of a key stored in KMS\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Key\n */\n getKey(uri, {onBehalfOf} = {}) {\n if (uri.jwk) {\n return this.kms.asKey(uri);\n }\n\n let storageKey = uri;\n\n if (onBehalfOf) {\n storageKey += `/onBehalfOf/${onBehalfOf}`;\n }\n\n return this.unboundedStorage\n .get(storageKey)\n .then((keyString) => JSON.parse(keyString))\n .then((keyObject) => this.kms.asKey(keyObject))\n .catch(() =>\n this.kms\n .fetchKey({uri, onBehalfOf})\n .then(tap((key) => this.unboundedStorage.put(storageKey, JSON.stringify(key, replacer))))\n );\n },\n});\n\n/**\n * JSON.stringify replacer that ensures private key data is serialized.\n * @param {string} k\n * @param {mixed} v\n * @returns {mixed}\n */\nfunction replacer(k, v) {\n if (k === 'jwk') {\n // note: this[k] and v may be different representations of the same value\n // eslint-disable-next-line no-invalid-this\n const json = this[k].toJSON(true);\n\n return json;\n }\n\n return v;\n}\n\nexport default Encryption;\n"],"mappings":"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","ignoreList":[]}
|
package/dist/kms.js
CHANGED
|
@@ -826,7 +826,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
826
826
|
context.ephemeralKey = originalContext.ephemeralKey;
|
|
827
827
|
return context;
|
|
828
828
|
},
|
|
829
|
-
version: "3.11.0-next.
|
|
829
|
+
version: "3.11.0-next.10"
|
|
830
830
|
}, (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
831
|
var _default = exports.default = KMS;
|
|
832
832
|
//# sourceMappingURL=kms.js.map
|
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.
|
|
32
|
-
"@webex/test-helper-make-local-url": "3.
|
|
33
|
-
"@webex/test-helper-mocha": "3.
|
|
34
|
-
"@webex/test-helper-mock-webex": "3.
|
|
35
|
-
"@webex/test-helper-test-users": "3.
|
|
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",
|
|
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.
|
|
42
|
-
"@webex/common-timers": "3.
|
|
43
|
-
"@webex/http-core": "3.
|
|
44
|
-
"@webex/internal-plugin-device": "3.11.0-next.
|
|
45
|
-
"@webex/internal-plugin-mercury": "3.11.0-next.
|
|
46
|
-
"@webex/test-helper-file": "3.
|
|
47
|
-
"@webex/webex-core": "3.11.0-next.
|
|
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.11.0-next.7",
|
|
45
|
+
"@webex/internal-plugin-mercury": "3.11.0-next.9",
|
|
46
|
+
"@webex/test-helper-file": "3.11.0-next.1",
|
|
47
|
+
"@webex/webex-core": "3.11.0-next.7",
|
|
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.11.0-next.
|
|
70
|
+
"version": "3.11.0-next.10"
|
|
71
71
|
}
|
package/src/encryption.js
CHANGED
|
@@ -240,6 +240,29 @@ const Encryption = WebexPlugin.extend({
|
|
|
240
240
|
);
|
|
241
241
|
},
|
|
242
242
|
|
|
243
|
+
/**
|
|
244
|
+
* Encrypt binary data using the supplied key uri.
|
|
245
|
+
*
|
|
246
|
+
* @param {string} kmsKeyUri - The uri of a key stored in KMS
|
|
247
|
+
* @param {Buffer|ArrayBuffer|Blob|File} data - Binary data to encrypt
|
|
248
|
+
* @param {Object} options
|
|
249
|
+
* @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role
|
|
250
|
+
* @returns {string} Encrypted binary data as JWE
|
|
251
|
+
*/
|
|
252
|
+
encryptBinaryData(kmsKeyUri, data, options) {
|
|
253
|
+
return this.getKey(kmsKeyUri, options).then((k) =>
|
|
254
|
+
ensureBuffer(data).then((buffer) =>
|
|
255
|
+
jose.JWE.createEncrypt(this.config.joseOptions, {
|
|
256
|
+
key: k.jwk,
|
|
257
|
+
header: {
|
|
258
|
+
alg: 'dir',
|
|
259
|
+
},
|
|
260
|
+
reference: null,
|
|
261
|
+
}).final(buffer)
|
|
262
|
+
)
|
|
263
|
+
);
|
|
264
|
+
},
|
|
265
|
+
|
|
243
266
|
/**
|
|
244
267
|
* Fetch the key associated with the supplied KMS uri.
|
|
245
268
|
*
|
|
@@ -390,6 +390,78 @@ describe('Encryption', function () {
|
|
|
390
390
|
// browserOnly(it)(`accepts a Blob`);
|
|
391
391
|
});
|
|
392
392
|
|
|
393
|
+
describe('#encryptBinaryData()', () => {
|
|
394
|
+
it('encrypts binary data', () =>
|
|
395
|
+
webex.internal.encryption
|
|
396
|
+
.encryptBinaryData(key, FILE)
|
|
397
|
+
.then((jwe) => {
|
|
398
|
+
assert.isString(jwe);
|
|
399
|
+
assert.notEqual(jwe, FILE.toString('base64'));
|
|
400
|
+
// JWE format starts with eyJ (base64 encoded header)
|
|
401
|
+
assert.match(jwe, /^eyJ/);
|
|
402
|
+
}));
|
|
403
|
+
|
|
404
|
+
it('encrypts binary data with Buffer input', () => {
|
|
405
|
+
const binaryData = Buffer.from('test binary data', 'utf8');
|
|
406
|
+
|
|
407
|
+
return webex.internal.encryption
|
|
408
|
+
.encryptBinaryData(key, binaryData)
|
|
409
|
+
.then((jwe) => {
|
|
410
|
+
assert.isString(jwe);
|
|
411
|
+
assert.notEqual(jwe, binaryData.toString());
|
|
412
|
+
assert.match(jwe, /^eyJ/);
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it('encrypts binary data with options parameter', () => {
|
|
417
|
+
const binaryData = Buffer.from('test binary data with options', 'utf8');
|
|
418
|
+
|
|
419
|
+
return webex.internal.encryption
|
|
420
|
+
.encryptBinaryData(key, binaryData, {})
|
|
421
|
+
.then((jwe) => {
|
|
422
|
+
assert.isString(jwe);
|
|
423
|
+
assert.match(jwe, /^eyJ/);
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
it('encrypts binary data with dynamically generated 3000 character string', () => {
|
|
428
|
+
// Generate a 3000-character string dynamically using different character sets
|
|
429
|
+
const generateLargeString = (length) => {
|
|
430
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';
|
|
431
|
+
let result = '';
|
|
432
|
+
const charsLength = chars.length;
|
|
433
|
+
|
|
434
|
+
for (let i = 0; i < length; i++) {
|
|
435
|
+
// Use modulo to cycle through different patterns for variety
|
|
436
|
+
const index = (i * 7 + Math.floor(i / 100) * 3) % charsLength;
|
|
437
|
+
result += chars.charAt(index);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return result;
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
const largeString = generateLargeString(3000);
|
|
444
|
+
const binaryData = Buffer.from(largeString, 'utf8');
|
|
445
|
+
|
|
446
|
+
// Verify the string is exactly 3000 characters
|
|
447
|
+
assert.equal(largeString.length, 3000);
|
|
448
|
+
|
|
449
|
+
return webex.internal.encryption
|
|
450
|
+
.encryptBinaryData(key, binaryData)
|
|
451
|
+
.then((jwe) => {
|
|
452
|
+
assert.isString(jwe);
|
|
453
|
+
assert.notEqual(jwe, binaryData.toString('base64'));
|
|
454
|
+
|
|
455
|
+
return webex.internal.encryption.decryptBinaryData(key, jwe);
|
|
456
|
+
})
|
|
457
|
+
.then((decryptedData) => {
|
|
458
|
+
assert.isTrue(isBuffer(decryptedData));
|
|
459
|
+
assert.equal(decryptedData.toString('utf8'), largeString);
|
|
460
|
+
assert.equal(decryptedData.toString('utf8').length, 3000);
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
|
|
393
465
|
describe('#encryptScr()', () => {
|
|
394
466
|
it('encrypts an scr', () =>
|
|
395
467
|
webex.internal.encryption
|
|
@@ -463,6 +535,35 @@ describe('Encryption', function () {
|
|
|
463
535
|
});
|
|
464
536
|
});
|
|
465
537
|
|
|
538
|
+
it('encrypt binary data', () => {
|
|
539
|
+
const binaryData = Buffer.from('compliance encrypt binary data', 'utf8');
|
|
540
|
+
|
|
541
|
+
return complianceUser.webex.internal.encryption
|
|
542
|
+
.encryptBinaryData(key, binaryData, {onBehalfOf: user.id})
|
|
543
|
+
.then((jwe) => {
|
|
544
|
+
assert.isString(jwe);
|
|
545
|
+
assert.match(jwe, /^eyJ/);
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
it('encrypt and decrypt binary data', () => {
|
|
550
|
+
const binaryData = Buffer.from('compliance round-trip binary data', 'utf8');
|
|
551
|
+
|
|
552
|
+
return complianceUser.webex.internal.encryption
|
|
553
|
+
.encryptBinaryData(key, binaryData, {onBehalfOf: user.id})
|
|
554
|
+
.then((jwe) => {
|
|
555
|
+
assert.isString(jwe);
|
|
556
|
+
|
|
557
|
+
return complianceUser.webex.internal.encryption.decryptBinaryData(key, jwe, {
|
|
558
|
+
onBehalfOf: user.id,
|
|
559
|
+
});
|
|
560
|
+
})
|
|
561
|
+
.then((decryptedData) => {
|
|
562
|
+
assert.isTrue(isBuffer(decryptedData));
|
|
563
|
+
assert.equal(decryptedData.toString('utf8'), 'compliance round-trip binary data');
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
|
|
466
567
|
it('encrypt and decrypt text', () =>
|
|
467
568
|
complianceUser.webex.internal.encryption
|
|
468
569
|
.encryptText(key, PLAINTEXT, {onBehalfOf: user.id})
|
|
@@ -154,4 +154,82 @@ describe('internal-plugin-encryption', () => {
|
|
|
154
154
|
});
|
|
155
155
|
});
|
|
156
156
|
});
|
|
157
|
+
|
|
158
|
+
describe('encryptBinaryData', () => {
|
|
159
|
+
let webex;
|
|
160
|
+
|
|
161
|
+
beforeEach(() => {
|
|
162
|
+
webex = new MockWebex({
|
|
163
|
+
children: {
|
|
164
|
+
encryption: Encryption,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('check encryptBinaryData()', () => {
|
|
170
|
+
const testKey = 'https://kms.example.com/keys/test-key-id';
|
|
171
|
+
const testData = Buffer.from('binary data to encrypt');
|
|
172
|
+
const testOptions = {onBehalfOf: 'test-user-uuid'};
|
|
173
|
+
const mockJwk = {kty: 'oct', k: 'test-key-material'};
|
|
174
|
+
const mockKey = {jwk: mockJwk};
|
|
175
|
+
const mockEncryptedJWE = 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..encrypted.data.here';
|
|
176
|
+
let getKeyStub;
|
|
177
|
+
let joseEncryptStub;
|
|
178
|
+
let mockEncryptor;
|
|
179
|
+
|
|
180
|
+
beforeEach(() => {
|
|
181
|
+
getKeyStub = sinon.stub(webex.internal.encryption, 'getKey').resolves(mockKey);
|
|
182
|
+
|
|
183
|
+
// Mock the jose.JWE.createEncrypt chain
|
|
184
|
+
mockEncryptor = {
|
|
185
|
+
final: sinon.stub().resolves(mockEncryptedJWE)
|
|
186
|
+
};
|
|
187
|
+
joseEncryptStub = sinon.stub(require('node-jose').JWE, 'createEncrypt').returns(mockEncryptor);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should call getKey and jose.JWE.createEncrypt with correct parameters', async () => {
|
|
191
|
+
await webex.internal.encryption.encryptBinaryData(testKey, testData, testOptions);
|
|
192
|
+
|
|
193
|
+
assert.equal(getKeyStub.calledOnce, true);
|
|
194
|
+
assert.equal(getKeyStub.args[0][0], testKey);
|
|
195
|
+
assert.deepEqual(getKeyStub.args[0][1], testOptions);
|
|
196
|
+
|
|
197
|
+
assert.equal(joseEncryptStub.calledOnce, true);
|
|
198
|
+
assert.deepEqual(joseEncryptStub.args[0][1], {
|
|
199
|
+
key: mockJwk,
|
|
200
|
+
header: {
|
|
201
|
+
alg: 'dir',
|
|
202
|
+
},
|
|
203
|
+
reference: null,
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should call final with buffer', async () => {
|
|
208
|
+
await webex.internal.encryption.encryptBinaryData(testKey, testData, testOptions);
|
|
209
|
+
|
|
210
|
+
assert.equal(mockEncryptor.final.calledOnce, true);
|
|
211
|
+
assert.equal(Buffer.isBuffer(mockEncryptor.final.args[0][0]), true);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should return the encrypted JWE string', async () => {
|
|
215
|
+
const result = await webex.internal.encryption.encryptBinaryData(testKey, testData, testOptions);
|
|
216
|
+
|
|
217
|
+
assert.equal(result, mockEncryptedJWE);
|
|
218
|
+
assert.equal(typeof result, 'string');
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('should work without options parameter', async () => {
|
|
222
|
+
await webex.internal.encryption.encryptBinaryData(testKey, testData);
|
|
223
|
+
|
|
224
|
+
assert.equal(getKeyStub.calledOnce, true);
|
|
225
|
+
assert.equal(getKeyStub.args[0][0], testKey);
|
|
226
|
+
assert.equal(getKeyStub.args[0][1], undefined);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
afterEach(() => {
|
|
230
|
+
getKeyStub.restore();
|
|
231
|
+
joseEncryptStub.restore();
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|
|
157
235
|
});
|