client-certificate-auth 1.3.7 → 1.3.8
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/lib/parsers.js +35 -25
- package/package.json +3 -2
package/lib/parsers.js
CHANGED
|
@@ -103,8 +103,9 @@ function splitPemBlocks(pem) {
|
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
105
|
* Parse a multi-block PEM blob into a chained PeerCertificate. Splits the
|
|
106
|
-
* input into individual blocks
|
|
107
|
-
*
|
|
106
|
+
* input into individual blocks and links them via issuerCertificate. The
|
|
107
|
+
* first block is the leaf and must parse; later blocks that fail to parse
|
|
108
|
+
* are dropped and the chain links past them.
|
|
108
109
|
*
|
|
109
110
|
* Used by parsers whose proxies forward the full chain in a single field
|
|
110
111
|
* (parseUrlPemAws, parseXfcc Chain). Without explicit chain linking, calling
|
|
@@ -117,22 +118,33 @@ function splitPemBlocks(pem) {
|
|
|
117
118
|
*/
|
|
118
119
|
function chainFromMultiBlockPem(pem) {
|
|
119
120
|
const pemBlocks = splitPemBlocks(pem);
|
|
120
|
-
// Stryker disable next-line BlockStatement,ConditionalExpression: short-circuit; falling through
|
|
121
|
+
// Stryker disable next-line BlockStatement,ConditionalExpression: short-circuit; falling through hands undefined to pemToCertificate, which throws for the same null result
|
|
121
122
|
if (pemBlocks.length === 0) {
|
|
122
123
|
return null;
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
// Junk ahead of the leaf block means the leaf was damaged past recognition;
|
|
127
|
+
// the next block must not slide into its place. Leading whitespace is fine.
|
|
128
|
+
if (pem.slice(0, pem.indexOf(pemBlocks[0])).trim() !== '') {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// An unparseable leaf rejects the whole blob. Promoting the next block
|
|
133
|
+
// would authenticate the request as whichever certificate parsed first.
|
|
134
|
+
let leaf;
|
|
135
|
+
try {
|
|
136
|
+
leaf = pemToCertificate(pemBlocks[0]);
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const certs = [leaf];
|
|
142
|
+
for (const block of pemBlocks.slice(1)) {
|
|
126
143
|
try {
|
|
127
|
-
|
|
144
|
+
certs.push(pemToCertificate(block));
|
|
128
145
|
} catch {
|
|
129
|
-
//
|
|
130
|
-
return null;
|
|
146
|
+
// Dropped; the chain links past it.
|
|
131
147
|
}
|
|
132
|
-
}).filter(Boolean);
|
|
133
|
-
|
|
134
|
-
if (certs.length === 0) {
|
|
135
|
-
return null;
|
|
136
148
|
}
|
|
137
149
|
|
|
138
150
|
// Stryker disable next-line EqualityOperator: setting issuerCertificate = undefined on last cert is same as not setting it
|
|
@@ -271,27 +283,25 @@ export function parseBase64Der(headerValue) {
|
|
|
271
283
|
}
|
|
272
284
|
|
|
273
285
|
// Handle comma-separated cert chains (Traefik format)
|
|
274
|
-
// Stryker disable next-line MethodExpression: .trim() no-op (base64 ignores whitespace)
|
|
275
|
-
const certParts = headerValue.split(',').map(s => s.trim())
|
|
286
|
+
// Stryker disable next-line MethodExpression: .trim() no-op (base64 ignores whitespace)
|
|
287
|
+
const certParts = headerValue.split(',').map(s => s.trim());
|
|
276
288
|
|
|
277
|
-
//
|
|
278
|
-
|
|
289
|
+
// An empty or unparseable leaf rejects the whole header. Promoting the next
|
|
290
|
+
// entry would authenticate the request as whichever certificate parsed first.
|
|
291
|
+
let leaf;
|
|
292
|
+
try {
|
|
293
|
+
leaf = derToCertificate(Buffer.from(certParts[0], 'base64'));
|
|
294
|
+
} catch {
|
|
279
295
|
return null;
|
|
280
296
|
}
|
|
281
297
|
|
|
282
|
-
|
|
283
|
-
const
|
|
298
|
+
const certs = [leaf];
|
|
299
|
+
for (const base64 of certParts.slice(1)) {
|
|
284
300
|
try {
|
|
285
|
-
|
|
286
|
-
return derToCertificate(derBuffer);
|
|
301
|
+
certs.push(derToCertificate(Buffer.from(base64, 'base64')));
|
|
287
302
|
} catch {
|
|
288
|
-
//
|
|
289
|
-
return null;
|
|
303
|
+
// Dropped; the chain links past it.
|
|
290
304
|
}
|
|
291
|
-
}).filter(Boolean);
|
|
292
|
-
|
|
293
|
-
if (certs.length === 0) {
|
|
294
|
-
return null;
|
|
295
305
|
}
|
|
296
306
|
|
|
297
307
|
// Link the cert chain via issuerCertificate
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "client-certificate-auth",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"description": "Express/Connect middleware for mTLS client certificate authentication with reverse proxy support (AWS ALB, Envoy, Cloudflare, Traefik)",
|
|
5
5
|
"homepage": "https://github.com/tgies/client-certificate-auth",
|
|
6
6
|
"bugs": {
|
|
@@ -145,6 +145,7 @@
|
|
|
145
145
|
"lib/**/*.d.cts"
|
|
146
146
|
],
|
|
147
147
|
"overrides": {
|
|
148
|
-
"fflate": "0.8.2"
|
|
148
|
+
"fflate": "0.8.2",
|
|
149
|
+
"qs": "^6.15.2"
|
|
149
150
|
}
|
|
150
151
|
}
|