@webex/internal-plugin-encryption 3.0.0-beta.16 → 3.0.0-beta.161

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.
@@ -225,7 +225,7 @@ var Encryption = _webexCore.WebexPlugin.extend({
225
225
  }));
226
226
  });
227
227
  },
228
- version: "3.0.0-beta.16"
228
+ version: "3.0.0-beta.161"
229
229
  });
230
230
 
231
231
  /**
@@ -10,7 +10,7 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
10
10
  _Object$defineProperty(exports, "__esModule", {
11
11
  value: true
12
12
  });
13
- exports.default = exports.KMSError = void 0;
13
+ exports.validateCommonName = exports.default = exports.X509_SUBJECT_ALT_NAME_KEY = exports.KMSError = void 0;
14
14
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
15
15
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
16
16
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
@@ -46,6 +46,7 @@ var X509_SUBJECT_ALT_NAME_KEY = '2.5.29.17';
46
46
  * Customize Error so the SDK knows to quit retrying and notify
47
47
  * the user
48
48
  */
49
+ exports.X509_SUBJECT_ALT_NAME_KEY = X509_SUBJECT_ALT_NAME_KEY;
49
50
  var KMSError = /*#__PURE__*/function (_Error) {
50
51
  (0, _inherits2.default)(KMSError, _Error);
51
52
  var _super = _createSuper(KMSError);
@@ -137,7 +138,7 @@ var validateCommonName = function validateCommonName(_ref3, _ref4) {
137
138
  try {
138
139
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
139
140
  var entry = _step2.value;
140
- var san = entry.value;
141
+ var san = entry.value.toLowerCase();
141
142
  validationSuccessful = san === kidHostname;
142
143
  if (validationSuccessful) {
143
144
  break;
@@ -196,6 +197,7 @@ var validateCommonName = function validateCommonName(_ref3, _ref4) {
196
197
  * @throws {KMSError} if e or n doesn't match the first certificate
197
198
  * @returns {void}
198
199
  */
200
+ exports.validateCommonName = validateCommonName;
199
201
  var validatePublicCertificate = function validatePublicCertificate(_ref6, _ref7) {
200
202
  var _ref8 = (0, _slicedToArray2.default)(_ref6, 1),
201
203
  certificate = _ref8[0];
@@ -1 +1 @@
1
- {"version":3,"names":["setEngine","crypto","CryptoEngine","name","subtle","VALID_KTY","VALID_KID_PROTOCOL","X509_COMMON_NAME_KEY","X509_SUBJECT_ALT_NAME_KEY","KMSError","message","kmsError","Error","throwError","err","decodeCert","pem","der","Buffer","from","ber","Uint8Array","buffer","asn1","fromBER","Certificate","schema","result","validateKtyHeader","kty","validateKidHeader","kid","isUri","parseUrl","protocol","validateCommonName","certificate","kidHostname","hostname","validationSuccessful","extensions","extension","extnID","altNames","parsedValue","entry","san","value","subjectAttributes","subject","typesAndValues","attribute","type","commonName","valueBlock","validatePublicCertificate","publicExponent","e","modulus","n","encode","jose","util","base64url","publicKey","subjectPublicKeyInfo","subjectPublicKey","asn1PublicCert","valueHex","publicCert","RSAPublicKey","publicExponentHex","modulusHex","validateCertificatesSignature","certificates","caroots","certificateEngine","CertificateChainValidationEngine","trustedCerts","map","certs","verify","then","resultCode","resultMessage","validateKMS","jwt","resolve","x5c","length","promise"],"sources":["kms-certificate-validation.js"],"sourcesContent":["import {parse as parseUrl} from 'url';\n\nimport {isUri} from 'valid-url';\nimport {fromBER} from 'asn1js';\nimport {\n Certificate,\n RSAPublicKey,\n CertificateChainValidationEngine,\n CryptoEngine,\n setEngine,\n} from 'pkijs';\nimport {isArray} from 'lodash';\nimport jose from 'node-jose';\nimport crypto from 'isomorphic-webcrypto';\nimport {Buffer} from 'safe-buffer';\n\nsetEngine(\n 'newEngine',\n crypto,\n new CryptoEngine({\n name: '',\n crypto,\n subtle: crypto.subtle,\n })\n);\n\nconst VALID_KTY = 'RSA';\nconst VALID_KID_PROTOCOL = 'kms:';\n\nconst X509_COMMON_NAME_KEY = '2.5.4.3';\n\nconst X509_SUBJECT_ALT_NAME_KEY = '2.5.29.17';\n\n/**\n * Customize Error so the SDK knows to quit retrying and notify\n * the user\n */\nexport class KMSError extends Error {\n /**\n * add kmsError field to notify\n * @param {string} message\n */\n constructor(message) {\n super(message);\n this.kmsError = true;\n }\n}\n\nconst throwError = (err) => {\n throw new KMSError(`INVALID KMS: ${err}`);\n};\n\n/**\n * Converts the PEM string to a pkijs certificate object\n * @param {string} pem PEM representation of a certificate\n * @returns {Certificate} pkijs object of the certificate\n */\nconst decodeCert = (pem) => {\n if (typeof pem !== 'string') {\n throwError('certificate needs to be a string');\n }\n\n const der = Buffer.from(pem, 'base64');\n const ber = new Uint8Array(der).buffer;\n\n const asn1 = fromBER(ber);\n\n return new Certificate({schema: asn1.result});\n};\n\n/**\n * Validate the 'kty' property of the KMS credentials\n * @param {Object} JWT KMS credentials\n * @param {string} JWT.kty type of certificate\n * @throws {KMSError} if kty is not a valid type\n * @returns {void}\n */\nconst validateKtyHeader = ({kty}) => {\n if (kty !== VALID_KTY) {\n throwError(`'kty' header must be '${VALID_KTY}'`);\n }\n};\n\nconst validateKidHeader = ({kid}) => {\n if (!isUri(kid)) {\n throwError(\"'kid' is not a valid URI\");\n }\n\n if (parseUrl(kid).protocol !== VALID_KID_PROTOCOL) {\n throwError(`'kid' protocol must be '${VALID_KID_PROTOCOL}'`);\n }\n};\n\n/**\n * Checks the first certificate matches the 'kid' in the JWT.\n * It first checks the Subject Alternative Name then it checks\n * the Common Name\n * @param {Certificate} certificate represents the KMS\n * @param {Object} JWT KMS credentials\n * @param {string} JWT.kid the uri of the KMS\n * @throws {KMSError} if unable to validate certificate against KMS credentials\n * @returns {void}\n */\nconst validateCommonName = ([certificate], {kid}) => {\n const kidHostname = parseUrl(kid).hostname;\n let validationSuccessful = false;\n\n if (certificate.extensions) {\n // Subject Alt Names are in here\n for (const extension of certificate.extensions) {\n if (extension.extnID === X509_SUBJECT_ALT_NAME_KEY) {\n const {altNames} = extension.parsedValue;\n\n for (const entry of altNames) {\n const san = entry.value;\n\n validationSuccessful = san === kidHostname;\n if (validationSuccessful) {\n break;\n }\n }\n\n if (validationSuccessful) {\n break;\n }\n }\n }\n }\n\n if (!validationSuccessful) {\n // Didn't match kid in the Subject Alt Names, checking the Common Name\n const subjectAttributes = certificate.subject.typesAndValues;\n\n for (const attribute of subjectAttributes) {\n if (attribute.type === X509_COMMON_NAME_KEY) {\n const commonName = attribute.value.valueBlock.value;\n\n validationSuccessful = commonName === kidHostname;\n if (validationSuccessful) {\n break;\n }\n }\n }\n }\n\n if (!validationSuccessful) {\n throwError(\"hostname of the 1st certificate does not match 'kid'\");\n }\n};\n\n/**\n * Validate the first KMS certificate against the information\n * provided in the JWT\n * @param {Certificate} certificate first certificate the identifies the KMS\n * @param {Object} JWT credentials of the KMS\n * @param {string} JWT.e Public exponent of the first certificate\n * @param {string} KWT.n Modulus of the first certificate\n * @throws {KMSError} if e or n doesn't match the first certificate\n * @returns {void}\n */\nconst validatePublicCertificate = ([certificate], {e: publicExponent, n: modulus}) => {\n const {encode} = jose.util.base64url;\n\n const publicKey = certificate.subjectPublicKeyInfo.subjectPublicKey;\n const asn1PublicCert = fromBER(publicKey.valueBlock.valueHex);\n const publicCert = new RSAPublicKey({schema: asn1PublicCert.result});\n const publicExponentHex = publicCert.publicExponent.valueBlock.valueHex;\n const modulusHex = publicCert.modulus.valueBlock.valueHex;\n\n if (publicExponent !== encode(publicExponentHex)) {\n throwError('Public exponent is invalid');\n }\n if (modulus !== encode(modulusHex)) {\n throwError('Modulus is invalid');\n }\n};\n\n/**\n * Validates the list of certificates against the CAs provided\n * @param {certificate[]} certificates list of certificates provided\n * by the KMS to certify itself\n * @param {string[]} [caroots=[]] list of Certificate Authorities used to\n * validate the KMS's certificates\n * @returns {Promise} rejects if unable to validate the certificates\n */\nconst validateCertificatesSignature = (certificates, caroots = []) => {\n const certificateEngine = new CertificateChainValidationEngine({\n trustedCerts: caroots.map(decodeCert),\n certs: certificates,\n });\n\n return certificateEngine.verify().then(({result, resultCode, resultMessage}) => {\n if (!result) {\n throwError(`Certificate Validation failed [${resultCode}]: ${resultMessage}`);\n }\n });\n};\n\n/**\n * Validates the information provided by the KMS. This is a curried function.\n * The first function takes the caroots param and returns a second function.\n * The second function takes the credentials of the KMS and validates it\n * @param {string[]} caroots PEM encoded certificates that will be used\n * as Certificate Authorities\n * @param {Object} jwt Object containing the fields necessary to\n * validate the KMS\n * @returns {Promise} when resolved will return the jwt\n */\nconst validateKMS =\n (caroots) =>\n (jwt = {}) =>\n Promise.resolve().then(() => {\n validateKtyHeader(jwt);\n validateKidHeader(jwt);\n\n if (!(isArray(jwt.x5c) && jwt.x5c.length > 0)) {\n throwError('JWK does not contain a list of certificates');\n }\n const certificates = jwt.x5c.map(decodeCert);\n\n validateCommonName(certificates, jwt);\n validatePublicCertificate(certificates, jwt);\n\n // Skip validating signatures if no CA roots were provided\n const promise = caroots\n ? validateCertificatesSignature(certificates, caroots)\n : Promise.resolve();\n\n return promise.then(() => jwt);\n });\n\nexport default validateKMS;\n"],"mappings":"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"}
1
+ {"version":3,"names":["setEngine","crypto","CryptoEngine","name","subtle","VALID_KTY","VALID_KID_PROTOCOL","X509_COMMON_NAME_KEY","X509_SUBJECT_ALT_NAME_KEY","KMSError","message","kmsError","Error","throwError","err","decodeCert","pem","der","Buffer","from","ber","Uint8Array","buffer","asn1","fromBER","Certificate","schema","result","validateKtyHeader","kty","validateKidHeader","kid","isUri","parseUrl","protocol","validateCommonName","certificate","kidHostname","hostname","validationSuccessful","extensions","extension","extnID","altNames","parsedValue","entry","san","value","toLowerCase","subjectAttributes","subject","typesAndValues","attribute","type","commonName","valueBlock","validatePublicCertificate","publicExponent","e","modulus","n","encode","jose","util","base64url","publicKey","subjectPublicKeyInfo","subjectPublicKey","asn1PublicCert","valueHex","publicCert","RSAPublicKey","publicExponentHex","modulusHex","validateCertificatesSignature","certificates","caroots","certificateEngine","CertificateChainValidationEngine","trustedCerts","map","certs","verify","then","resultCode","resultMessage","validateKMS","jwt","resolve","x5c","length","promise"],"sources":["kms-certificate-validation.js"],"sourcesContent":["import {parse as parseUrl} from 'url';\n\nimport {isUri} from 'valid-url';\nimport {fromBER} from 'asn1js';\nimport {\n Certificate,\n RSAPublicKey,\n CertificateChainValidationEngine,\n CryptoEngine,\n setEngine,\n} from 'pkijs';\nimport {isArray} from 'lodash';\nimport jose from 'node-jose';\nimport crypto from 'isomorphic-webcrypto';\nimport {Buffer} from 'safe-buffer';\n\nsetEngine(\n 'newEngine',\n crypto,\n new CryptoEngine({\n name: '',\n crypto,\n subtle: crypto.subtle,\n })\n);\n\nconst VALID_KTY = 'RSA';\nconst VALID_KID_PROTOCOL = 'kms:';\n\nconst X509_COMMON_NAME_KEY = '2.5.4.3';\n\nexport const X509_SUBJECT_ALT_NAME_KEY = '2.5.29.17';\n\n/**\n * Customize Error so the SDK knows to quit retrying and notify\n * the user\n */\nexport class KMSError extends Error {\n /**\n * add kmsError field to notify\n * @param {string} message\n */\n constructor(message) {\n super(message);\n this.kmsError = true;\n }\n}\n\nconst throwError = (err) => {\n throw new KMSError(`INVALID KMS: ${err}`);\n};\n\n/**\n * Converts the PEM string to a pkijs certificate object\n * @param {string} pem PEM representation of a certificate\n * @returns {Certificate} pkijs object of the certificate\n */\nconst decodeCert = (pem) => {\n if (typeof pem !== 'string') {\n throwError('certificate needs to be a string');\n }\n\n const der = Buffer.from(pem, 'base64');\n const ber = new Uint8Array(der).buffer;\n\n const asn1 = fromBER(ber);\n\n return new Certificate({schema: asn1.result});\n};\n\n/**\n * Validate the 'kty' property of the KMS credentials\n * @param {Object} JWT KMS credentials\n * @param {string} JWT.kty type of certificate\n * @throws {KMSError} if kty is not a valid type\n * @returns {void}\n */\nconst validateKtyHeader = ({kty}) => {\n if (kty !== VALID_KTY) {\n throwError(`'kty' header must be '${VALID_KTY}'`);\n }\n};\n\nconst validateKidHeader = ({kid}) => {\n if (!isUri(kid)) {\n throwError(\"'kid' is not a valid URI\");\n }\n\n if (parseUrl(kid).protocol !== VALID_KID_PROTOCOL) {\n throwError(`'kid' protocol must be '${VALID_KID_PROTOCOL}'`);\n }\n};\n\n/**\n * Checks the first certificate matches the 'kid' in the JWT.\n * It first checks the Subject Alternative Name then it checks\n * the Common Name\n * @param {Certificate} certificate represents the KMS\n * @param {Object} JWT KMS credentials\n * @param {string} JWT.kid the uri of the KMS\n * @throws {KMSError} if unable to validate certificate against KMS credentials\n * @returns {void}\n */\nexport const validateCommonName = ([certificate], {kid}) => {\n const kidHostname = parseUrl(kid).hostname;\n let validationSuccessful = false;\n\n if (certificate.extensions) {\n // Subject Alt Names are in here\n for (const extension of certificate.extensions) {\n if (extension.extnID === X509_SUBJECT_ALT_NAME_KEY) {\n const {altNames} = extension.parsedValue;\n\n for (const entry of altNames) {\n const san = entry.value.toLowerCase();\n\n validationSuccessful = san === kidHostname;\n if (validationSuccessful) {\n break;\n }\n }\n\n if (validationSuccessful) {\n break;\n }\n }\n }\n }\n\n if (!validationSuccessful) {\n // Didn't match kid in the Subject Alt Names, checking the Common Name\n const subjectAttributes = certificate.subject.typesAndValues;\n\n for (const attribute of subjectAttributes) {\n if (attribute.type === X509_COMMON_NAME_KEY) {\n const commonName = attribute.value.valueBlock.value;\n\n validationSuccessful = commonName === kidHostname;\n if (validationSuccessful) {\n break;\n }\n }\n }\n }\n\n if (!validationSuccessful) {\n throwError(\"hostname of the 1st certificate does not match 'kid'\");\n }\n};\n\n/**\n * Validate the first KMS certificate against the information\n * provided in the JWT\n * @param {Certificate} certificate first certificate the identifies the KMS\n * @param {Object} JWT credentials of the KMS\n * @param {string} JWT.e Public exponent of the first certificate\n * @param {string} KWT.n Modulus of the first certificate\n * @throws {KMSError} if e or n doesn't match the first certificate\n * @returns {void}\n */\nconst validatePublicCertificate = ([certificate], {e: publicExponent, n: modulus}) => {\n const {encode} = jose.util.base64url;\n\n const publicKey = certificate.subjectPublicKeyInfo.subjectPublicKey;\n const asn1PublicCert = fromBER(publicKey.valueBlock.valueHex);\n const publicCert = new RSAPublicKey({schema: asn1PublicCert.result});\n const publicExponentHex = publicCert.publicExponent.valueBlock.valueHex;\n const modulusHex = publicCert.modulus.valueBlock.valueHex;\n\n if (publicExponent !== encode(publicExponentHex)) {\n throwError('Public exponent is invalid');\n }\n if (modulus !== encode(modulusHex)) {\n throwError('Modulus is invalid');\n }\n};\n\n/**\n * Validates the list of certificates against the CAs provided\n * @param {certificate[]} certificates list of certificates provided\n * by the KMS to certify itself\n * @param {string[]} [caroots=[]] list of Certificate Authorities used to\n * validate the KMS's certificates\n * @returns {Promise} rejects if unable to validate the certificates\n */\nconst validateCertificatesSignature = (certificates, caroots = []) => {\n const certificateEngine = new CertificateChainValidationEngine({\n trustedCerts: caroots.map(decodeCert),\n certs: certificates,\n });\n\n return certificateEngine.verify().then(({result, resultCode, resultMessage}) => {\n if (!result) {\n throwError(`Certificate Validation failed [${resultCode}]: ${resultMessage}`);\n }\n });\n};\n\n/**\n * Validates the information provided by the KMS. This is a curried function.\n * The first function takes the caroots param and returns a second function.\n * The second function takes the credentials of the KMS and validates it\n * @param {string[]} caroots PEM encoded certificates that will be used\n * as Certificate Authorities\n * @param {Object} jwt Object containing the fields necessary to\n * validate the KMS\n * @returns {Promise} when resolved will return the jwt\n */\nconst validateKMS =\n (caroots) =>\n (jwt = {}) =>\n Promise.resolve().then(() => {\n validateKtyHeader(jwt);\n validateKidHeader(jwt);\n\n if (!(isArray(jwt.x5c) && jwt.x5c.length > 0)) {\n throwError('JWK does not contain a list of certificates');\n }\n const certificates = jwt.x5c.map(decodeCert);\n\n validateCommonName(certificates, jwt);\n validatePublicCertificate(certificates, jwt);\n\n // Skip validating signatures if no CA roots were provided\n const promise = caroots\n ? validateCertificatesSignature(certificates, caroots)\n : Promise.resolve();\n\n return promise.then(() => jwt);\n });\n\nexport default validateKMS;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAEA;AACA;AACA;AAQA;AACA;AACA;AAAmC;AAAA;AAAA;AAAA;AAAA;AAEnC,IAAAA,gBAAS,EACP,WAAW,EACXC,4BAAM,EACN,IAAIC,mBAAY,CAAC;EACfC,IAAI,EAAE,EAAE;EACRF,MAAM,EAANA,4BAAM;EACNG,MAAM,EAAEH,4BAAM,CAACG;AACjB,CAAC,CAAC,CACH;AAED,IAAMC,SAAS,GAAG,KAAK;AACvB,IAAMC,kBAAkB,GAAG,MAAM;AAEjC,IAAMC,oBAAoB,GAAG,SAAS;AAE/B,IAAMC,yBAAyB,GAAG,WAAW;;AAEpD;AACA;AACA;AACA;AAHA;AAAA,IAIaC,QAAQ;EAAA;EAAA;EACnB;AACF;AACA;AACA;EACE,kBAAYC,OAAO,EAAE;IAAA;IAAA;IACnB,0BAAMA,OAAO;IACb,MAAKC,QAAQ,GAAG,IAAI;IAAC;EACvB;EAAC;AAAA,+CAR2BC,KAAK;AAAA;AAWnC,IAAMC,UAAU,GAAG,SAAbA,UAAU,CAAIC,GAAG,EAAK;EAC1B,MAAM,IAAIL,QAAQ,wBAAiBK,GAAG,EAAG;AAC3C,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,IAAMC,UAAU,GAAG,SAAbA,UAAU,CAAIC,GAAG,EAAK;EAC1B,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE;IAC3BH,UAAU,CAAC,kCAAkC,CAAC;EAChD;EAEA,IAAMI,GAAG,GAAGC,kBAAM,CAACC,IAAI,CAACH,GAAG,EAAE,QAAQ,CAAC;EACtC,IAAMI,GAAG,GAAG,IAAIC,UAAU,CAACJ,GAAG,CAAC,CAACK,MAAM;EAEtC,IAAMC,IAAI,GAAG,IAAAC,eAAO,EAACJ,GAAG,CAAC;EAEzB,OAAO,IAAIK,kBAAW,CAAC;IAACC,MAAM,EAAEH,IAAI,CAACI;EAAM,CAAC,CAAC;AAC/C,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMC,iBAAiB,GAAG,SAApBA,iBAAiB,OAAc;EAAA,IAATC,GAAG,QAAHA,GAAG;EAC7B,IAAIA,GAAG,KAAKxB,SAAS,EAAE;IACrBQ,UAAU,iCAA0BR,SAAS,OAAI;EACnD;AACF,CAAC;AAED,IAAMyB,iBAAiB,GAAG,SAApBA,iBAAiB,QAAc;EAAA,IAATC,GAAG,SAAHA,GAAG;EAC7B,IAAI,CAAC,IAAAC,eAAK,EAACD,GAAG,CAAC,EAAE;IACflB,UAAU,CAAC,0BAA0B,CAAC;EACxC;EAEA,IAAI,IAAAoB,UAAQ,EAACF,GAAG,CAAC,CAACG,QAAQ,KAAK5B,kBAAkB,EAAE;IACjDO,UAAU,mCAA4BP,kBAAkB,OAAI;EAC9D;AACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,IAAM6B,kBAAkB,GAAG,SAArBA,kBAAkB,eAA6B;EAAA;IAAxBC,WAAW;EAAA,IAAIL,GAAG,SAAHA,GAAG;EACpD,IAAMM,WAAW,GAAG,IAAAJ,UAAQ,EAACF,GAAG,CAAC,CAACO,QAAQ;EAC1C,IAAIC,oBAAoB,GAAG,KAAK;EAEhC,IAAIH,WAAW,CAACI,UAAU,EAAE;IAC1B;IAAA,2CACwBJ,WAAW,CAACI,UAAU;MAAA;IAAA;MAA9C,oDAAgD;QAAA,IAArCC,SAAS;QAClB,IAAIA,SAAS,CAACC,MAAM,KAAKlC,yBAAyB,EAAE;UAClD,IAAOmC,QAAQ,GAAIF,SAAS,CAACG,WAAW,CAAjCD,QAAQ;UAA0B,4CAErBA,QAAQ;YAAA;UAAA;YAA5B,uDAA8B;cAAA,IAAnBE,KAAK;cACd,IAAMC,GAAG,GAAGD,KAAK,CAACE,KAAK,CAACC,WAAW,EAAE;cAErCT,oBAAoB,GAAGO,GAAG,KAAKT,WAAW;cAC1C,IAAIE,oBAAoB,EAAE;gBACxB;cACF;YACF;UAAC;YAAA;UAAA;YAAA;UAAA;UAED,IAAIA,oBAAoB,EAAE;YACxB;UACF;QACF;MACF;IAAC;MAAA;IAAA;MAAA;IAAA;EACH;EAEA,IAAI,CAACA,oBAAoB,EAAE;IACzB;IACA,IAAMU,iBAAiB,GAAGb,WAAW,CAACc,OAAO,CAACC,cAAc;IAAC,4CAErCF,iBAAiB;MAAA;IAAA;MAAzC,uDAA2C;QAAA,IAAhCG,SAAS;QAClB,IAAIA,SAAS,CAACC,IAAI,KAAK9C,oBAAoB,EAAE;UAC3C,IAAM+C,UAAU,GAAGF,SAAS,CAACL,KAAK,CAACQ,UAAU,CAACR,KAAK;UAEnDR,oBAAoB,GAAGe,UAAU,KAAKjB,WAAW;UACjD,IAAIE,oBAAoB,EAAE;YACxB;UACF;QACF;MACF;IAAC;MAAA;IAAA;MAAA;IAAA;EACH;EAEA,IAAI,CAACA,oBAAoB,EAAE;IACzB1B,UAAU,CAAC,sDAAsD,CAAC;EACpE;AACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AATA;AAUA,IAAM2C,yBAAyB,GAAG,SAA5BA,yBAAyB,eAAuD;EAAA;IAAlDpB,WAAW;EAAA,IAAOqB,cAAc,SAAjBC,CAAC;IAAqBC,OAAO,SAAVC,CAAC;EACrE,IAAOC,MAAM,GAAIC,iBAAI,CAACC,IAAI,CAACC,SAAS,CAA7BH,MAAM;EAEb,IAAMI,SAAS,GAAG7B,WAAW,CAAC8B,oBAAoB,CAACC,gBAAgB;EACnE,IAAMC,cAAc,GAAG,IAAA5C,eAAO,EAACyC,SAAS,CAACV,UAAU,CAACc,QAAQ,CAAC;EAC7D,IAAMC,UAAU,GAAG,IAAIC,mBAAY,CAAC;IAAC7C,MAAM,EAAE0C,cAAc,CAACzC;EAAM,CAAC,CAAC;EACpE,IAAM6C,iBAAiB,GAAGF,UAAU,CAACb,cAAc,CAACF,UAAU,CAACc,QAAQ;EACvE,IAAMI,UAAU,GAAGH,UAAU,CAACX,OAAO,CAACJ,UAAU,CAACc,QAAQ;EAEzD,IAAIZ,cAAc,KAAKI,MAAM,CAACW,iBAAiB,CAAC,EAAE;IAChD3D,UAAU,CAAC,4BAA4B,CAAC;EAC1C;EACA,IAAI8C,OAAO,KAAKE,MAAM,CAACY,UAAU,CAAC,EAAE;IAClC5D,UAAU,CAAC,oBAAoB,CAAC;EAClC;AACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAM6D,6BAA6B,GAAG,SAAhCA,6BAA6B,CAAIC,YAAY,EAAmB;EAAA,IAAjBC,OAAO,uEAAG,EAAE;EAC/D,IAAMC,iBAAiB,GAAG,IAAIC,uCAAgC,CAAC;IAC7DC,YAAY,EAAEH,OAAO,CAACI,GAAG,CAACjE,UAAU,CAAC;IACrCkE,KAAK,EAAEN;EACT,CAAC,CAAC;EAEF,OAAOE,iBAAiB,CAACK,MAAM,EAAE,CAACC,IAAI,CAAC,iBAAyC;IAAA,IAAvCxD,MAAM,SAANA,MAAM;MAAEyD,UAAU,SAAVA,UAAU;MAAEC,aAAa,SAAbA,aAAa;IACxE,IAAI,CAAC1D,MAAM,EAAE;MACXd,UAAU,0CAAmCuE,UAAU,gBAAMC,aAAa,EAAG;IAC/E;EACF,CAAC,CAAC;AACJ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMC,WAAW,GACf,SADIA,WAAW,CACdV,OAAO;EAAA,OACR;IAAA,IAACW,GAAG,uEAAG,CAAC,CAAC;IAAA,OACP,iBAAQC,OAAO,EAAE,CAACL,IAAI,CAAC,YAAM;MAC3BvD,iBAAiB,CAAC2D,GAAG,CAAC;MACtBzD,iBAAiB,CAACyD,GAAG,CAAC;MAEtB,IAAI,EAAE,uBAAQA,GAAG,CAACE,GAAG,CAAC,IAAIF,GAAG,CAACE,GAAG,CAACC,MAAM,GAAG,CAAC,CAAC,EAAE;QAC7C7E,UAAU,CAAC,6CAA6C,CAAC;MAC3D;MACA,IAAM8D,YAAY,GAAGY,GAAG,CAACE,GAAG,CAACT,GAAG,CAACjE,UAAU,CAAC;MAE5CoB,kBAAkB,CAACwC,YAAY,EAAEY,GAAG,CAAC;MACrC/B,yBAAyB,CAACmB,YAAY,EAAEY,GAAG,CAAC;;MAE5C;MACA,IAAMI,OAAO,GAAGf,OAAO,GACnBF,6BAA6B,CAACC,YAAY,EAAEC,OAAO,CAAC,GACpD,iBAAQY,OAAO,EAAE;MAErB,OAAOG,OAAO,CAACR,IAAI,CAAC;QAAA,OAAMI,GAAG;MAAA,EAAC;IAChC,CAAC,CAAC;EAAA;AAAA;AAAC,eAEQD,WAAW;AAAA"}
package/dist/kms.js CHANGED
@@ -793,7 +793,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
793
793
  context.ephemeralKey = originalContext.ephemeralKey;
794
794
  return context;
795
795
  },
796
- version: "3.0.0-beta.16"
796
+ version: "3.0.0-beta.161"
797
797
  }, ((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)));
798
798
  var _default = KMS;
799
799
  exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-encryption",
3
- "version": "3.0.0-beta.16",
3
+ "version": "3.0.0-beta.161",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -24,27 +24,27 @@
24
24
  ]
25
25
  },
26
26
  "devDependencies": {
27
- "@webex/test-helper-chai": "3.0.0-beta.16",
28
- "@webex/test-helper-make-local-url": "3.0.0-beta.16",
29
- "@webex/test-helper-mocha": "3.0.0-beta.16",
30
- "@webex/test-helper-mock-webex": "3.0.0-beta.16",
31
- "@webex/test-helper-test-users": "3.0.0-beta.16",
27
+ "@webex/test-helper-chai": "3.0.0-beta.161",
28
+ "@webex/test-helper-make-local-url": "3.0.0-beta.161",
29
+ "@webex/test-helper-mocha": "3.0.0-beta.161",
30
+ "@webex/test-helper-mock-webex": "3.0.0-beta.161",
31
+ "@webex/test-helper-test-users": "3.0.0-beta.161",
32
32
  "sinon": "^9.2.4"
33
33
  },
34
34
  "dependencies": {
35
- "@webex/common": "3.0.0-beta.16",
36
- "@webex/common-timers": "3.0.0-beta.16",
37
- "@webex/http-core": "3.0.0-beta.16",
38
- "@webex/internal-plugin-device": "3.0.0-beta.16",
39
- "@webex/internal-plugin-encryption": "3.0.0-beta.16",
40
- "@webex/internal-plugin-mercury": "3.0.0-beta.16",
41
- "@webex/test-helper-file": "3.0.0-beta.16",
42
- "@webex/webex-core": "3.0.0-beta.16",
35
+ "@webex/common": "3.0.0-beta.161",
36
+ "@webex/common-timers": "3.0.0-beta.161",
37
+ "@webex/http-core": "3.0.0-beta.161",
38
+ "@webex/internal-plugin-device": "3.0.0-beta.161",
39
+ "@webex/internal-plugin-encryption": "3.0.0-beta.161",
40
+ "@webex/internal-plugin-mercury": "3.0.0-beta.161",
41
+ "@webex/test-helper-file": "3.0.0-beta.161",
42
+ "@webex/webex-core": "3.0.0-beta.161",
43
43
  "asn1js": "^2.0.26",
44
44
  "debug": "^4.3.4",
45
45
  "isomorphic-webcrypto": "^2.3.8",
46
46
  "lodash": "^4.17.21",
47
- "node-jose": "^2.0.0",
47
+ "node-jose": "^2.2.0",
48
48
  "node-kms": "^0.4.0",
49
49
  "node-scr": "^0.3.0",
50
50
  "pkijs": "^2.1.84",
@@ -29,7 +29,7 @@ const VALID_KID_PROTOCOL = 'kms:';
29
29
 
30
30
  const X509_COMMON_NAME_KEY = '2.5.4.3';
31
31
 
32
- const X509_SUBJECT_ALT_NAME_KEY = '2.5.29.17';
32
+ export const X509_SUBJECT_ALT_NAME_KEY = '2.5.29.17';
33
33
 
34
34
  /**
35
35
  * Customize Error so the SDK knows to quit retrying and notify
@@ -101,7 +101,7 @@ const validateKidHeader = ({kid}) => {
101
101
  * @throws {KMSError} if unable to validate certificate against KMS credentials
102
102
  * @returns {void}
103
103
  */
104
- const validateCommonName = ([certificate], {kid}) => {
104
+ export const validateCommonName = ([certificate], {kid}) => {
105
105
  const kidHostname = parseUrl(kid).hostname;
106
106
  let validationSuccessful = false;
107
107
 
@@ -112,7 +112,7 @@ const validateCommonName = ([certificate], {kid}) => {
112
112
  const {altNames} = extension.parsedValue;
113
113
 
114
114
  for (const entry of altNames) {
115
- const san = entry.value;
115
+ const san = entry.value.toLowerCase();
116
116
 
117
117
  validationSuccessful = san === kidHostname;
118
118
  if (validationSuccessful) {
@@ -158,7 +158,8 @@ describe('Encryption', function () {
158
158
  }));
159
159
  });
160
160
 
161
- describe('#download()', () => {
161
+ // SPARK-413317
162
+ describe.skip('#download()', () => {
162
163
  it('downloads and decrypts an encrypted file', () =>
163
164
  webex.internal.encryption
164
165
  .encryptBinary(FILE)
@@ -425,7 +425,6 @@ describe('Encryption', function () {
425
425
  describe('upload customer master key', () => {
426
426
  let uploadedkeyId;
427
427
 
428
- /* eslint-disable no-unused-expressions */
429
428
  skipInBrowser(it)('upload customer master key', () =>
430
429
  webex.internal.encryption.kms
431
430
  .deleteAllCustomerMasterKeys({assignedOrgId: spock.orgId})
@@ -1,6 +1,6 @@
1
1
  import {assert} from '@webex/test-helper-chai';
2
2
 
3
- import validateCert, {KMSError} from '../../../src/kms-certificate-validation';
3
+ import validateCert, {KMSError, validateCommonName, X509_SUBJECT_ALT_NAME_KEY} from '../../../src/kms-certificate-validation';
4
4
 
5
5
  const caroots = [
6
6
  'MIID6TCCAtGgAwIBAgIURmBu688C9oUIJXlykr1J3fi5H4kwDQYJKoZIhvcNAQELBQAwgYMxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhDb2xvcmFkbzEPMA0GA1UEBwwGRGVudmVyMRAwDgYDVQQKDAdFeGFtcGxlMR8wHQYDVQQDDBZodHRwczovL2NhLmV4YW1wbGUuY29tMR0wGwYJKoZIhvcNAQkBFg5jYUBleGFtcGxlLmNvbTAeFw0yMDAyMDYyMDIyMDhaFw00MDAyMDEyMDIyMDhaMIGDMQswCQYDVQQGEwJVUzERMA8GA1UECAwIQ29sb3JhZG8xDzANBgNVBAcMBkRlbnZlcjEQMA4GA1UECgwHRXhhbXBsZTEfMB0GA1UEAwwWaHR0cHM6Ly9jYS5leGFtcGxlLmNvbTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7TaDWldwjU65y4fnNDIuNu4dZi3bZvaN9nJ3A8D9pwFcNx3DL5cPpafAkJuE/2ZBrsZxJWKwXLQFuNE9V3XVslv0OPgEZVfY5AKuPhVezRqEqsCdUgODMkJat6PE02r0NZRFpBiRCThh0wY5u/tiTiPgjHwEPhBEyLgcJ6FOWLn9wBsS4SvBzfppYGL5GW1G0eN9yORnKKgqkgyf0x8FvTMyVSjtkhcI/kA/8061sl4DFG6sefQmAOVvH7tp7YmN+jpQ7cOKQtjOpZS6Gp22u7LEI0/qb5n2QvjjcUQM81mN6CZ8nciWXRgjBhdAJJhmyMvcx8rnVb6vtU26fCaetAgMBAAGjUzBRMB0GA1UdDgQWBBRZiCyKaTYL94gwhxzktYg32qMOYjAfBgNVHSMEGDAWgBRZiCyKaTYL94gwhxzktYg32qMOYjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQATa2QkTGcj8IPjItnvg23ihlRjHdFHn6lB7uYPhcDurwRlBrlC2/OB44P3dHB9tEPbV4unoF9ftEKO3nNY3HUDcPrQwRqkPftlYYr4/6z/jnmNBRgiDICVaiTZNlX54fLiPsSAbIymPWLLLNtq17vjVEcfGUXhi/F+EkN/uXZ4yH6RK0YjBRwPV9cfziz1YsF2WVYVYtQErf+NTjnYR5S4Ba2kEqhI5j7mNhiafPNODaOchHcaRMvfWcBhlHt+atwNyPxNr4NP+cDjAWg0I8xAUdbZGQiRJecjkctolLHsfZXj+ulEv3eaKw7gSo3Aekexw8aZS7soy+VM1fzmLopw',
@@ -163,3 +163,36 @@ describe('internal-plugin-encryption', () => {
163
163
  });
164
164
  });
165
165
  });
166
+
167
+ describe('validateCommonName', () => {
168
+
169
+ const checkValidate = (SAN, kidHostname) => {
170
+ validateCommonName(
171
+ [
172
+ {
173
+ extensions: [
174
+ {
175
+ extnID: X509_SUBJECT_ALT_NAME_KEY,
176
+ parsedValue: {
177
+ altNames: [{value: 'Example.com'}],
178
+ },
179
+ },
180
+ ],
181
+ },
182
+ ],
183
+ {kid: 'https://Example.com'}
184
+ );
185
+ }
186
+
187
+ it('handles mixed case SAN', () => {
188
+ checkValidate('Example.com', 'https://Example.com');
189
+ });
190
+
191
+ it('handles different case SAN', () => {
192
+ checkValidate('ExAmpLe.cOm', 'https://example.com');
193
+ });
194
+
195
+ it('handles different case kid hostname', () => {
196
+ checkValidate('example.com', 'https://ExAmpLe.cOm');
197
+ });
198
+ });