mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
fix(runtime): cover Windows policy root stores
This commit is contained in:
+1
-1
@@ -2378,7 +2378,7 @@ declare module "tls" {
|
||||
/** The CA-store introspection surface (scr_tls_ca.c): per-type cached
|
||||
* PEM string arrays. The host bundle stands in for Node's compiled-in
|
||||
* Mozilla roots ('bundled', and rootCertificates) AND the platform
|
||||
* store ('system') — the Windows ROOT store or POSIX bundle probe;
|
||||
* store ('system') — the Windows ROOT stores or POSIX bundle probe;
|
||||
* 'extra' reads NODE_EXTRA_CA_CERTS. An unknown type string throws
|
||||
* Node's ERR_INVALID_ARG_VALUE TypeError. */
|
||||
export function getCACertificates(type?: string): string[];
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { execFile, execFileSync } from "node:child_process";
|
||||
import { chmod, mkdir, mkdtemp, readFile, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { EOL, tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import { describe, expect, test } from "vitest";
|
||||
@@ -414,7 +414,7 @@ describe.skipIf(!zigOnPath())("zig cc builds (zig on PATH)", () => {
|
||||
"../../../tests/fixtures/server/certs/ca.pem",
|
||||
);
|
||||
const { stdout } = await execFileAsync(outPath, [caPath]);
|
||||
expect(stdout).toBe("windows EKU policy ok\n");
|
||||
expect(stdout).toBe(`windows EKU policy ok${EOL}`);
|
||||
},
|
||||
600_000,
|
||||
);
|
||||
|
||||
@@ -5495,7 +5495,7 @@ long scr_secure_ctx_live_count(void);
|
||||
/* ── node:tls, the CA-store introspection slice (scr_tls_ca.c — its own
|
||||
* unit and link gate; NO mbedTLS, so a getCACertificates-only binary never
|
||||
* builds the archive; cc.ts also compiles it whenever scr_tls.c does). The
|
||||
* HOST roots (Windows' logical ROOT store, the established bundle probe on
|
||||
* HOST roots (Windows' system ROOT stores, the established bundle probe on
|
||||
* POSIX) stand in for both Node's compiled-in Mozilla roots ('bundled',
|
||||
* rootCertificates) and the platform store ('system') — the established
|
||||
* SEMANTICS divergence, extended to introspection; 'extra' uses the
|
||||
@@ -5505,9 +5505,9 @@ long scr_secure_ctx_live_count(void);
|
||||
void scr_tls_ca_install(void); /* snapshots NODE_EXTRA_CA_CERTS + file bytes */
|
||||
bool scr_tls_ca_extra_pem(const char **pem, size_t *len); /* borrowed launch snapshot */
|
||||
#ifdef _WIN32
|
||||
/* Enumerates the current user's logical ROOT store (including inherited
|
||||
* machine roots), yielding only certificates whose effective Windows EKU
|
||||
* policy permits TLS server authentication. DER is borrowed for the call. */
|
||||
/* Enumerates the machine, enterprise, current-user, and policy ROOT-store
|
||||
* locations, yielding only certificates whose effective Windows EKU policy
|
||||
* permits TLS server authentication. DER is borrowed for the call. */
|
||||
typedef void (*ScrTlsCaWindowsRootFn)(void *ctx, const unsigned char *der, size_t len);
|
||||
bool scr_tls_ca_windows_cert_server_auth(const void *cert_context);
|
||||
void scr_tls_ca_windows_roots(ScrTlsCaWindowsRootFn fn, void *ctx);
|
||||
|
||||
@@ -338,9 +338,9 @@ typedef struct ScrTlsCli {
|
||||
|
||||
/* The default trust anchors when no `ca` option is given: the host trust
|
||||
* store, standing in for Node's compiled-in Mozilla roots, plus
|
||||
* NODE_EXTRA_CA_CERTS. Windows certificates live as DER entries in the
|
||||
* current user's logical ROOT store, which includes the inherited machine
|
||||
* roots; mbedTLS copies each successfully parsed entry into its own chain.
|
||||
* NODE_EXTRA_CA_CERTS. Windows certificates live as DER entries across the
|
||||
* machine, enterprise, current-user, and policy ROOT-store locations;
|
||||
* mbedTLS copies each successfully parsed entry into its own chain.
|
||||
* POSIX hosts probe the established bundle spellings — /etc/ssl/cert.pem
|
||||
* first (macOS ships it; Alpine links it), then Debian/Ubuntu's
|
||||
* ca-certificates.crt, Fedora/RHEL's ca-bundle.crt, and openSUSE's
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
* Divergences, documented: the host bundle stands in for Node's
|
||||
* compiled-in Mozilla roots ('bundled' and rootCertificates) AND for the
|
||||
* platform store ('system') — Windows' logical ROOT store and the POSIX
|
||||
* platform store ('system') — Windows' system ROOT stores and the POSIX
|
||||
* bundle probe are the same sources scr_tls.c's anchors use; and set-time
|
||||
* validation is PEM-BLOCK shaped (a well-formed block with corrupt DER
|
||||
* inside is kept here where Node's X509 parse would drop it — such a cert
|
||||
@@ -191,11 +191,11 @@ bool scr_tls_ca_windows_cert_server_auth(const void *cert_context) {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
void scr_tls_ca_windows_roots(ScrTlsCaWindowsRootFn fn, void *ctx) {
|
||||
static void scr_tls_ca_windows_roots_at(
|
||||
DWORD location, ScrTlsCaWindowsRootFn fn, void *ctx) {
|
||||
HCERTSTORE store = CertOpenStore(
|
||||
CERT_STORE_PROV_SYSTEM_A, 0, 0,
|
||||
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG |
|
||||
CERT_STORE_READONLY_FLAG,
|
||||
location | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG,
|
||||
"ROOT");
|
||||
if (store == NULL) return;
|
||||
PCCERT_CONTEXT cert = NULL;
|
||||
@@ -209,6 +209,24 @@ void scr_tls_ca_windows_roots(ScrTlsCaWindowsRootFn fn, void *ctx) {
|
||||
(void)CertCloseStore(store, 0);
|
||||
}
|
||||
|
||||
void scr_tls_ca_windows_roots(ScrTlsCaWindowsRootFn fn, void *ctx) {
|
||||
/* Windows keeps policy and enterprise roots in distinct store locations;
|
||||
* the ordinary current-user ROOT collection does not include the
|
||||
* current-user Group Policy store. Match Node's ROOT-location coverage so
|
||||
* organization-managed roots reach both TLS verification and CA-store
|
||||
* introspection. Duplicate entries are harmless and match Node's gather. */
|
||||
static const DWORD locations[] = {
|
||||
CERT_SYSTEM_STORE_LOCAL_MACHINE,
|
||||
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY,
|
||||
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
|
||||
CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY,
|
||||
};
|
||||
for (size_t i = 0; i < sizeof locations / sizeof locations[0]; i++) {
|
||||
scr_tls_ca_windows_roots_at(locations[i], fn, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void scr_ca_push_windows_root(void *ctx, const unsigned char *der, size_t len) {
|
||||
if (len > UINT32_MAX) return;
|
||||
DWORD pem_cap = 0;
|
||||
|
||||
Reference in New Issue
Block a user