From 55d177e9eecbd28dcb156c22a5f628330f2ccf03 Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Sun, 19 Jul 2026 07:00:48 +0200 Subject: [PATCH] fix(control-plane): accept escaped-PEM client cert on /renew nginx has no njs deployed, so the mTLS terminator forwards the verified client cert via $ssl_client_escaped_cert (URL-encoded PEM). headerPresentedCert now normalizes base64-DER, PEM, and escaped-PEM alike to raw DER. 281 tests pass. --- control-plane/src/api/renew.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/control-plane/src/api/renew.ts b/control-plane/src/api/renew.ts index 7851967..8d2c5a1 100644 --- a/control-plane/src/api/renew.ts +++ b/control-plane/src/api/renew.ts @@ -171,7 +171,15 @@ export function headerPresentedCert(headerName: string = DEFAULT_CLIENT_CERT_HEA const value = Array.isArray(raw) ? raw[0] : raw if (typeof value !== 'string' || value.length === 0) return null try { - return new Uint8Array(Buffer.from(value, 'base64')) + // The terminator may forward the verified cert as base64 DER, OR as PEM — including nginx's + // header-safe `$ssl_client_escaped_cert` (URL-encoded PEM). Normalize all three to raw DER: + // URL-decode if escaped, then strip PEM armor + whitespace to recover the base64 DER body. + let s = value.includes('%') ? safeDecodeUri(value) : value + if (s.includes('BEGIN CERTIFICATE')) { + s = s.replace(/-----[^-]+-----/g, '').replace(/\s+/g, '') + } + const der = Buffer.from(s, 'base64') + return der.length > 0 ? new Uint8Array(der) : null } catch { return null } @@ -179,6 +187,15 @@ export function headerPresentedCert(headerName: string = DEFAULT_CLIENT_CERT_HEA } } +/** URL-decode `value`, returning it unchanged if it is not valid percent-encoding. */ +function safeDecodeUri(value: string): string { + try { + return decodeURIComponent(value) + } catch { + return value + } +} + /** * Trust-anchor verification of the presented current cert (defense in depth: the mTLS terminator has * already verified it, but this route must not trust a cert the terminator would never have accepted).