From f1cd2c9cf3ff1441a452042a4858267c5fdd65bc Mon Sep 17 00:00:00 2001 From: Curt Tudor Date: Mon, 26 Aug 2024 11:03:10 -0600 Subject: [PATCH] feat: Cert chain parsing support (#175) --- package.json | 2 +- src/context/context.js | 4 +++ src/enroll/enroller.js | 2 +- src/http/ziti-websocket-wrapper.js | 9 +++++-- src/utils/pki.js | 42 +++++++++++++++++++++++++++--- yarn.lock | 21 +++++++++++---- 6 files changed, 68 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index a494d19..21e183b 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "mime-types": "^2.1.35", "multistream": "^4.1.0", "pako": "^2.1.0", - "pkijs": "^3.1.0", + "pkijs": "^3.2.4", "process": "^0.11.10", "promise-controller": "^1.0.0", "promise.prototype.finally": "^3.1.8", diff --git a/src/context/context.js b/src/context/context.js index a4d9a86..24329d5 100644 --- a/src/context/context.js +++ b/src/context/context.js @@ -1326,6 +1326,10 @@ class ZitiContext extends EventEmitter { host: config['ziti-tunneler-client.v1'].hostname, port: config['ziti-tunneler-client.v1'].port, } + } else { + if (config['zrok.proxy.v1']) { + return undefined; + } } } } diff --git a/src/enroll/enroller.js b/src/enroll/enroller.js index 0410fb8..eb0008c 100644 --- a/src/enroll/enroller.js +++ b/src/enroll/enroller.js @@ -128,7 +128,7 @@ import { isUndefined, isNull } from 'lodash-es'; let certificate; try { - certificate = convertPemToCertificate( flatcert ); + certificate = await convertPemToCertificate( flatcert ); // printCertificate( certificate ); } catch (err) { this.logger.error(err); diff --git a/src/http/ziti-websocket-wrapper.js b/src/http/ziti-websocket-wrapper.js index cfaca74..cf0b2d6 100644 --- a/src/http/ziti-websocket-wrapper.js +++ b/src/http/ziti-websocket-wrapper.js @@ -543,8 +543,13 @@ async function initAsClient(websocket, address, protocols, options) { opts.createConnection = zitiConnect; // We're going over Ziti parsedUrl.protocol = websocket._zitiConfig.browzer.bootstrapper.target.scheme + ":"; - opts.href = parsedUrl.protocol + '//' + opts.configHostAndPort.host.toLowerCase() + parsedUrl.pathname + parsedUrl.search; - opts.origin = websocket._zitiConfig.browzer.bootstrapper.target.scheme + "://" + opts.configHostAndPort.host.toLowerCase() + ":" + opts.configHostAndPort.port; + if (opts.configHostAndPort) { + opts.href = parsedUrl.protocol + '//' + opts.configHostAndPort.host.toLowerCase() + parsedUrl.pathname + parsedUrl.search; + opts.origin = websocket._zitiConfig.browzer.bootstrapper.target.scheme + "://" + opts.configHostAndPort.host.toLowerCase() + ":" + opts.configHostAndPort.port; + } else { + opts.href = parsedUrl.protocol + '//' + websocket._zitiConfig.browzer.bootstrapper.target.service.toLowerCase() + parsedUrl.pathname + parsedUrl.search; + opts.origin = websocket._zitiConfig.browzer.bootstrapper.target.scheme + "://" + websocket._zitiConfig.browzer.bootstrapper.target.service.toLowerCase() + ":" + (websocket._zitiConfig.browzer.bootstrapper.target.scheme == 'https' ? '443' : '80'); + } opts.host = opts.serviceName; opts.defaultPort = opts.defaultPort || defaultPort; diff --git a/src/utils/pki.js b/src/utils/pki.js index 444b299..b154373 100644 --- a/src/utils/pki.js +++ b/src/utils/pki.js @@ -78,15 +78,51 @@ let convertBinaryToCertificate = (certificateBuffer) => { const certificate = new Certificate({ schema: asn1.result }); return certificate; } - + +// Function to parse a certificate +let parseCertificate = async function(pem) { + const der = convertPemToBinary(pem); + const asn1 = asn1js.fromBER(der); + const cert = new Certificate({ schema: asn1.result }); + return cert; +} + +// Function to split PEM chain into individual certificates +let splitPemChain = function(pemChain) { + // Regular expression to match individual certificates + const certRegex = /-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g; + const matches = pemChain.match(certRegex); + + if (!matches) { + throw new Error('No certificates found in the chain'); + } + + return matches; +} + +let parseCertificateChain = async function(certChain) { + const parsedCerts = []; + + let certificates = splitPemChain(certChain) + + for (const pem of certificates) { + const cert = await parseCertificate(pem); + parsedCerts.push(cert); + } + return parsedCerts; +} /** * Convert PEM to Certificate * * @param {string} pem */ -let convertPemToCertificate = (pem) => { - return convertBinaryToCertificate( convertPemToBinary(pem) ); +let convertPemToCertificate = async (pem) => { + + let parsedCerts = await parseCertificateChain(pem); + + return parsedCerts[0]; + } /** diff --git a/yarn.lock b/yarn.lock index 8260ca7..9925caa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1231,6 +1231,11 @@ dependencies: vary "^1.1.2" +"@noble/hashes@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -6400,16 +6405,17 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== -pkijs@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-3.1.0.tgz#ea7b84e2b3870582cc38d41473433bbe8b5c3c3c" - integrity sha512-N+OCWUp6xrg7OkG+4DIiZUOsp3qMztjq8RGCc1hSY92dsUG8cTlAo7pEkfRGjcdyBv2c1Y9bjAzqdTJAlctuNg== +pkijs@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-3.2.4.tgz#55ed72b363a20fbd42b139ee3b72e54483635171" + integrity sha512-Et9V5QpvBilPFgagJcaKBqXjKrrgF5JL2mSDELk1vvbOTt4fuBhSSsGn9Tcz0TQTfS5GCpXQ31Whrpqeqp0VRg== dependencies: + "@noble/hashes" "^1.4.0" asn1js "^3.0.5" bytestreamjs "^2.0.0" pvtsutils "^1.3.2" pvutils "^1.1.3" - tslib "^2.4.0" + tslib "^2.6.3" polyfills-loader@^1.7.4: version "1.7.6" @@ -7830,6 +7836,11 @@ tslib@^2.0.3, tslib@^2.4.0, tslib@^2.6.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.6.3: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + tsscmp@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"