Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 6 additions & 11 deletions src/crypto/crypto_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -450,23 +450,18 @@ bool IsCertificateTrustValid(SecCertificateRef ref) {
CFArrayCreateMutable(nullptr, 1, &kCFTypeArrayCallBacks);
CFArraySetValueAtIndex(subj_certs, 0, ref);

// SecTrustEvaluateWithError is used to check whether an individual
// certificate is trusted by the system — not to validate it for a
// specific role (server, intermediate, etc.). We just need a minimal
// policy that guarantees the certificate can be chained to a known
// trust anchor while filtering out irrelevant certificates.
//
// Refs
// https://github.com/apple-oss-distributions/Security/blob/db15acbe6a7f257a859ad9a3bb86097bfe0679d9/OSX/sec/Security/SecPolicy.c#L1855-L1890
// SecPolicyCreateSSL (both mark EKU optional):
// server=true -> BasicX509 + serverAuth + anyExtendedKeyUsage + SGC
// server=false -> BasicX509 + clientAuth + anyExtendedKeyUsage
// Use the SSL client policy to preserve the existing certificate filtering,
// but disable network access to avoid AIA and revocation requests during
// certificate enumeration.
SecPolicyRef policy = SecPolicyCreateSSL(false, nullptr);
OSStatus ortn =
SecTrustCreateWithCertificates(subj_certs, policy, &sec_trust);
bool result = false;
if (ortn) {
/* should never happen */
} else if (SecTrustSetNetworkFetchAllowed(sec_trust, false) !=
errSecSuccess) {
/* should never happen */
} else {
result = SecTrustEvaluateWithError(sec_trust, nullptr);
}
Expand Down
54 changes: 54 additions & 0 deletions test/fixtures/keys/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ all: \
non-trusted-intermediate-ca-key.pem \
non-trusted-leaf-from-intermediate-cert.pem \
non-trusted-leaf-from-intermediate-key.pem \
system-ca-network-intermediate-cert.pem \
system-ca-network-intermediate-key.pem \
system-ca-network-leaf-cert.pem \
system-ca-network-leaf-key.pem \
rsa_private.pem \
rsa_private_encrypted.pem \
rsa_private_pkcs8.pem \
Expand Down Expand Up @@ -415,6 +419,56 @@ non-trusted-leaf-from-intermediate-cert.pem: non-trusted-leaf-from-intermediate-

rm -f non-trusted-leaf-from-intermediate-cert.csr

system-ca-network-intermediate-key.pem:
openssl genrsa -out system-ca-network-intermediate-key.pem 2048

system-ca-network-intermediate-cert.pem: \
system-ca-network-intermediate-key.pem \
system-ca-network.cnf \
fake-startcom-root-cert.pem \
fake-startcom-root-key.pem
openssl req -new \
-sha256 \
-key system-ca-network-intermediate-key.pem \
-subj "/CN=NodeJS-System-CA-Network-Intermediate" \
-out system-ca-network-intermediate-cert.csr
openssl x509 -req \
-in system-ca-network-intermediate-cert.csr \
-CA fake-startcom-root-cert.pem \
-CAkey fake-startcom-root-key.pem \
-set_serial 0x4e6f64654e657403 \
-out system-ca-network-intermediate-cert.pem \
-days 99999 \
-extfile system-ca-network.cnf \
-extensions v3_ca \
-sha256
rm -f system-ca-network-intermediate-cert.csr

system-ca-network-leaf-key.pem:
openssl genrsa -out system-ca-network-leaf-key.pem 2048

system-ca-network-leaf-cert.pem: \
system-ca-network-leaf-key.pem \
system-ca-network-intermediate-cert.pem \
system-ca-network-intermediate-key.pem \
system-ca-network.cnf
openssl req -new \
-sha256 \
-key system-ca-network-leaf-key.pem \
-subj "/CN=NodeJS-System-CA-Network-Leaf" \
-out system-ca-network-leaf-cert.csr
openssl x509 -req \
-in system-ca-network-leaf-cert.csr \
-CA system-ca-network-intermediate-cert.pem \
-CAkey system-ca-network-intermediate-key.pem \
-set_serial 0x4e6f64654e657405 \
-out system-ca-network-leaf-cert.pem \
-days 99999 \
-extfile system-ca-network.cnf \
-extensions v3_leaf \
-sha256
rm -f system-ca-network-leaf-cert.csr

#
# agent1 is signed by ca1.
#
Expand Down
24 changes: 24 additions & 0 deletions test/fixtures/keys/system-ca-network-intermediate-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIITm9kZU5ldAMwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE
BhMCSUwxFjAUBgNVBAoMDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsMIlNlY3VyZSBE
aWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMMIFN0YXJ0Q29tIENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MCAXDTI2MDkwNDA3MTI1MloYDzIzMDAwNjE5
MDcxMjUyWjAwMS4wLAYDVQQDDCVOb2RlSlMtU3lzdGVtLUNBLU5ldHdvcmstSW50
ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtvTTze+
GOXD+rl3wxwLgGR0J5e/0qV4k9CupE5Agp4jw7clbM7KVXQrEsgGP3bR2SAlBsOH
VTkQy+YQnbYEpDUkKKwQZVlVSwpW/7zm72+HMAt89ZlKYZeRi1NZ3YqeLWtPOAGW
diX7IkQGw1Q8FcGjQC/06UqEA5s6lrOY1YdxRGWY0DlF9EQqJK1Xrgl6KtvdV/oU
sui0LARvvm+EpWUeebm4iZSA7Jar9M/6KysoeY1Y8kjqFSqZU9QP0sFSpctKL37c
L5Go8KCI9tvUUFwjfseOTSDyKH/s8671m+RO9lJtlJ26vDG8kY1jNG6OZHdsljIR
m5fCJG9QlF+3rQIDAQABo4HjMIHgMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0P
AQH/BAQDAgEGMB0GA1UdDgQWBBT/bdAcwGLQOOUrDT28Nv51jdnBrzCBmgYDVR0j
BIGSMIGPoYGBpH8wfTELMAkGA1UEBhMCSUwxFjAUBgNVBAoMDVN0YXJ0Q29tIEx0
ZC4xKzApBgNVBAsMIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcx
KTAnBgNVBAMMIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggkAgg9v
TE81yAowDQYJKoZIhvcNAQELBQADggEBAHzyyAD0a2lVNkJOk09iwlllCO8kNv7D
BAbZt2byd9CAFZ5j9XMJMibSjOlgA0jK7wMO26rSoVvNjNZNdT+KzLsa6WxPcaXm
37gG7Oj29JvB0uMsAczIyoRvuDzLIYSgZNHFm+SRsHkaQdrjLNXlfc/SmckET6EF
KdmnGILQL1PA/ZC7MEvn9O+u+QsrkVVfziTzPrAJQmUaXhZZW+yoOvHof55mhbNV
wO2bFIvn+OI6HDkQJjcrTdQmM7em++sPSkEO4rUSlQVfgsP/6zpX2WmTyOQZURjq
USuBhVTqEU2QaVMdxRNwRPtgPHoXeBKXnKTRwU9svShFD9SMDyPC4mY=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions test/fixtures/keys/system-ca-network-intermediate-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+29NPN74Y5cP6
uXfDHAuAZHQnl7/SpXiT0K6kTkCCniPDtyVszspVdCsSyAY/dtHZICUGw4dVORDL
5hCdtgSkNSQorBBlWVVLClb/vObvb4cwC3z1mUphl5GLU1ndip4ta084AZZ2Jfsi
RAbDVDwVwaNAL/TpSoQDmzqWs5jVh3FEZZjQOUX0RCokrVeuCXoq291X+hSy6LQs
BG++b4SlZR55ubiJlIDslqv0z/orKyh5jVjySOoVKplT1A/SwVKly0ovftwvkajw
oIj229RQXCN+x45NIPIof+zzrvWb5E72Um2Unbq8MbyRjWM0bo5kd2yWMhGbl8Ik
b1CUX7etAgMBAAECggEAHOZ1DiEK9kKuhSP59E+mFzQ+2XLzTz6SrlFSbJtTzeOL
11o/fsUmYr+zOQYUWh5QIuBo8uf/MWKxfiqReAwkkkfguI7rcalQDsubRmDQmE+L
STVoH9ltJ693kMEXkcIodwixh3HIGo5gQ31JB+FUsteuNG0+mOfZayFhgwnhee2j
li4pxdX87xP56gs5jSLx+5XAFkzJFCjxhovhenDIzC7/8NzCHWXouvZou08h69mn
CBUfZrjZfr1TJTjJo4bthxDHlZF6YUGUv9dLquhH/6+sCXsq9QZoh7gZs7/wfb/p
58gzJ1S9Us+ngcVDt9lkba/0B/13dXNhYgfAkF/mYQKBgQD+pez5+zRtNHU9pDv2
yMzUXm2lDBMghanXbOJFfaqYYoaBttjhdMUl5EPKebx+EAEQzX/ws/MH1X63q1KK
ZdhJ81Gu0QTg710OjUPFSnBX6t6gdSbmG00iVPzZYyTzYcacsKhqzpDs6iDBMfHE
VtqzQJlZbvOZMQUlx2+FWknZ4QKBgQC/3zU/QwWw5emPIvITZjhyN59qjbnJc84v
GK0cpLY2bxpuguW3YSrnnxN5U9Epd4IdJddP21I/TtnZA9+FgfIelFLbPTkSZA61
JC269JgKDAXeEflVssGeBbwdbeP2RzxvgvyRgYfA5s0OtcSwb8VkM85zA+peNYAI
9pbZtwUPTQKBgDYTTDCFnMt38VGmt6kfWQfcCZKb7s/gMoHxuFcjaX+0pHWVO5cc
8eSrBY5QratjgKZtzTZzMC/AsYkVU5DaMcT6a6Ug89VEX1GAxBx4Q0UYNjCC0EDb
GVUqEQuk1yrr335UsV8FAJee3FfKYFneS9D27dmlCwvD8iDkqhT6aGZhAoGBAKey
rxdbvN2gFULFiE7sSOmLNAotVPR+Avem2abvT1LESJXOUni0tIs8vgiM+YMEsPRI
3qctSfWLNVw3xmUp7jRL7x8vo3IvgatQs6dzoG8nkvlFPGdqlU9IM+KE6XmXSXst
QRLr43r2PsNcm0yaZCvwG8Dq6yzsFbu/ypj/Ha0BAoGBAIYajJc1dPYP167VjV1b
AgUD+/JpbsLj+GknOv4zrBZdipSpGzPbanHwRGRtWA2x67iA1jv+F5iL4wykUzZB
4FB0wB4occkOraXEeEwqm5/BdBiKTqEGNf5wGv67ciNOWkdamWj1DE7PQ2RpgjiT
7ChZGDlBcpH46Ttp+ndJPKzX
-----END PRIVATE KEY-----
23 changes: 23 additions & 0 deletions test/fixtures/keys/system-ca-network-leaf-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID6TCCAtGgAwIBAgIITm9kZU5ldAUwDQYJKoZIhvcNAQELBQAwMDEuMCwGA1UE
AwwlTm9kZUpTLVN5c3RlbS1DQS1OZXR3b3JrLUludGVybWVkaWF0ZTAgFw0yNjA5
MDQwNzEyNTJaGA8yMzAwMDYxOTA3MTI1MlowKDEmMCQGA1UEAwwdTm9kZUpTLVN5
c3RlbS1DQS1OZXR3b3JrLUxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCWJUja7Z1+Q98Id7vyqBuT7/qCRY4CeoD65mC0CtfHEM4fcPZQ/+6+48iQ
V4GRcDjLReuJKf8FsPpfiSCccnfOqpmer9dduWn6mibKCZ9NoV/YFYg3hf9FuNXj
1p9AhMhGNXCiElVWhjUgn7gO39g3jhGKq7IzlnIfS0nvEeJC2prxjr1hJ7x1gTIo
xlBNJuK2OLWz80tcFUrEl6TB14RvEwXU8XOkbdwkK0iWpWpuaAUl647X8UGPqwgW
rb1je3A+DIPtS370IXEyZtdXzHuWbwI93X77HmN8nYTzzCDo7DMlNHLARHfDTX0M
YctPsCqmrZLdZbvqeJ8FsbhKfWVBAgMBAAGjggELMIIBBzAMBgNVHRMBAf8EAjAA
MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
GgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMGwGCCsGAQUFBwEBBGAwXjAzBggr
BgEFBQcwAoYnaHR0cDovLzEyNy4wLjAuMToxMjM0Ny9pbnRlcm1lZGlhdGUuZGVy
MCcGCCsGAQUFBzABhhtodHRwOi8vMTI3LjAuMC4xOjEyMzQ3L29jc3AwHQYDVR0O
BBYEFEaI/ENl5rvz8Bly69p3n1Gany4hMB8GA1UdIwQYMBaAFP9t0BzAYtA45SsN
Pbw2/nWN2cGvMA0GCSqGSIb3DQEBCwUAA4IBAQAe7BCQEuqEl3gnWfM47UmTyb1y
mvJYZmEpChwZaGYrJKfKunt5X0dATzdKPwi8ouXZI+4chLY45/tul7B1BpkqdlY+
XzaHOYi8oJPyvQKf/r+6V7nWomnfTHuAkrT6RmjgTFYJwblv+N26hOnnewkTLQQI
y8yBvm1BH5GppQpfVG2DhhDImJzur2+4s59Oh4v1aMZHelZyN6wnjAz+CSU9HJxO
G4z4AWiGRdxQKL07d6in8ugvl8cyVuIhFtMbS1SAh4rQXqiFMsBbX3Exbqhlgm+F
p51htAhfXe3QagafY8G+ffVbPxoLO+D4+HPTiGVv5SWyrT4Fh0CbpxuggE+z
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions test/fixtures/keys/system-ca-network-leaf-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCWJUja7Z1+Q98I
d7vyqBuT7/qCRY4CeoD65mC0CtfHEM4fcPZQ/+6+48iQV4GRcDjLReuJKf8FsPpf
iSCccnfOqpmer9dduWn6mibKCZ9NoV/YFYg3hf9FuNXj1p9AhMhGNXCiElVWhjUg
n7gO39g3jhGKq7IzlnIfS0nvEeJC2prxjr1hJ7x1gTIoxlBNJuK2OLWz80tcFUrE
l6TB14RvEwXU8XOkbdwkK0iWpWpuaAUl647X8UGPqwgWrb1je3A+DIPtS370IXEy
ZtdXzHuWbwI93X77HmN8nYTzzCDo7DMlNHLARHfDTX0MYctPsCqmrZLdZbvqeJ8F
sbhKfWVBAgMBAAECggEAAtw9+ZG6RNwFJTOmvHYwZE6XjqDFlk2AJId8AyILv0qW
KqorvxpJEZDkUr+gA8XIBzNTS98lcRXQhz5lBSX3G1RLrea6qxnrp28FWyb4xnFT
EppCaJBgbxMY3AjMKt38tL2y4huITagr3e29A2eHRnOp6OLhd7MfhHIaO/gyv8RD
369o6sxt6RS0N/oGWioeNpIO6XFVZLCfzvDXUbVPPO4KLrqi9cicfKUgT+xBDAx8
D/a4vXqGIdEMuczVCZMubI0omqSbMf3OO0P/lMIhnNAtXRG4DTnvTssl9nDTfZgI
QUwISjq3w3t5+hk7gqBxvNrRK7WzQHA0IUhWozURgQKBgQDR0v0Rh3PcGKTvoh5x
os9Wbn4jo5cgU0rbxIG0p3OZY1hbLOUB+GYUvnH/ob+keB+0z3XgGvxBYHg1YDmX
rEtrTHeDDL0lXYslj1GVGMrkraHgQbZ5D0nKtuenHKDDjcwot2TEPseiK4qz8LMP
l1Cyx8PRvpUeYVFwzzJiPTfMMQKBgQC3MCUUEtblfJ56xiuLYLyO6DllKJuPmseq
c0p6mgFNUPpPdVY4yb9XmD6S3Zx5ua9ToQnJWmDVDgvbDEDrS+dUqKvVjPTn+QJP
G7Scaet4ku4b4rW13KjqOzX3wrVFsIWsCk4TITeHvJ60sM+Esbfe8pYXIbZGXN9M
QUTP1v62EQKBgQCa74pRTE0AQ+5eyL5kOM2TTAm2tVCd3QNU3njMdi3FIPeYc8Ey
wEJYpPw2wDBr+QuojtzCvApzGBILj99XITGbrJ4/VcPBeJ6MAJVEXEdNruzuVHey
UtixaHgMDPalD+qmUi2FP7pYBIDqOB1wsNI1AY+WLH2eLkxd2ZGhuwSdsQKBgFPa
Tu6sXP/5FlYexinrowRLWpJqjyKh+AmW8p3CRxxMF/gtPsWJ2/NNtj7mAE1b6NyA
F4m6vB5qapTfPAw413BSMS30ctqIij0J8peyiF3N6/6JvSG9Gvj1F5QM5Ys77UQ+
B1UMXG3esksFsEgOTZtZMcju3o/AzVoLemMlB7zxAoGBAMnu67XJ2wjix6A+q/tB
RGGcmqFiOhERhkHj1uh0K0Mdlx2vRcrfVb7PLfbeUSQy0VrZWsUjP5FuExmNunbg
M2jg2NHQ4dEWyV6/UBZ/lcA048aLZPoKglAVU7s75SRFkYYGdo+elz+cXjsdyURr
cwAPnlqqpcReBDRTGtgSreNI
-----END PRIVATE KEY-----
13 changes: 13 additions & 0 deletions test/fixtures/keys/system-ca-network.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[v3_ca]
basicConstraints = critical,CA:TRUE,pathlen:0
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

[v3_leaf]
basicConstraints = critical,CA:FALSE
keyUsage = critical,digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth,clientAuth
subjectAltName = DNS:localhost,IP:127.0.0.1
authorityInfoAccess = caIssuers;URI:http://127.0.0.1:12347/intermediate.der,\
OCSP;URI:http://127.0.0.1:12347/ocsp
162 changes: 162 additions & 0 deletions test/system-ca/test-macos-cert-network-fetch.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import * as common from '../common/index.mjs';
import * as fixtures from '../common/fixtures.mjs';
import assert from 'node:assert/strict';
import { X509Certificate } from 'node:crypto';
import { execFile, execFileSync } from 'node:child_process';
import http from 'node:http';
import { once } from 'node:events';
import { promisify } from 'node:util';
import { test } from 'node:test';

if (!common.hasCrypto) {
common.skip('requires crypto');
}

if (process.platform !== 'darwin') {
common.skip('macOS-specific test');
}

function isCertInKeychain(cn) {
try {
execFileSync('security', ['find-certificate', '-c', cn], { stdio: 'pipe' });
return true;
} catch {
return false;
}
}

if (!isCertInKeychain('StartCom Certification Authority')) {
common.skip(
'fake-startcom-root-cert.pem not found in system CA store. ' +
'Please follow setup instructions in test/system-ca/README.md',
);
}

const execFileAsync = promisify(execFile);
const responderPort = 12347;

async function run(file, args) {
return execFileAsync(file, args, { encoding: 'utf8' });
}

async function runToCompletion(file, args) {
await new Promise((resolve) => execFile(file, args, resolve));
}

function parseKeychainSearchList(stdout) {
return stdout.trim().split(/\r?\n/)
.map((line) => line.trim().replace(/^"|"$/g, ''))
.filter(Boolean);
}

test('system CA enumeration does not fetch AIA or OCSP', {
timeout: 30_000,
}, async (t) => {
const requests = [];
const leafCert = fixtures.path('keys', 'system-ca-network-leaf-cert.pem');
const rootCert = fixtures.path('keys', 'fake-startcom-root-cert.pem');
const infoAccess = new X509Certificate(
fixtures.readKey('system-ca-network-leaf-cert.pem'),
).infoAccess;
assert.match(
infoAccess,
/CA Issuers - URI:http:\/\/127\.0\.0\.1:12347\/intermediate\.der/,
);
assert.match(infoAccess, /OCSP - URI:http:\/\/127\.0\.0\.1:12347\/ocsp/);

const server = http.createServer((req, res) => {
requests.push({ method: req.method, url: req.url });
if (req.url === '/intermediate.der') {
res.writeHead(404, { 'Cache-Control': 'no-store' });
res.end();
} else if (req.url?.startsWith('/ocsp')) {
res.writeHead(500, { 'Cache-Control': 'no-store' });
res.end();
} else {
res.writeHead(404);
res.end();
}
});
server.listen(responderPort, '127.0.0.1');
await once(server, 'listening');
t.after(() => new Promise((resolve) => server.close(resolve)));

const keychain = '/tmp/node-system-ca-network-test.keychain-db';
const password = 'node-test';
const { stdout } = await run('/usr/bin/security', [
'list-keychains', '-d', 'user',
]);
const originalKeychains = parseKeychainSearchList(stdout);

await run('/usr/bin/security', [
'create-keychain', '-p', password, keychain,
]);
t.after(async () => {
await run('/usr/bin/security', [
'list-keychains', '-d', 'user', '-s', ...originalKeychains,
]);
await run('/usr/bin/security', ['delete-keychain', keychain]);
});
await run('/usr/bin/security', [
'unlock-keychain', '-p', password, keychain,
]);
await run('/usr/bin/security', [
'set-keychain-settings', '-lut', '3600', keychain,
]);
await run('/usr/bin/security', [
'add-certificates', '-k', keychain, leafCert,
]);
await run('/usr/bin/security', [
'list-keychains', '-d', 'user', '-s', ...originalKeychains, keychain,
]);

await run(process.execPath, [
'-e', 'require("node:tls").getCACertificates("system")',
]);
const enumerationRequests = [...requests];
requests.length = 0;

// Node's TLS validation uses OpenSSL and does not fetch AIA or OCSP itself.
// Use macOS trust evaluation as a control to show that the generated
// certificate can trigger both types of network request.
await runToCompletion('/usr/bin/security', [
'verify-cert',
'-c', leafCert,
'-r', rootCert,
'-p', 'basic',
'-R', 'ocsp',
'-R', 'online',
'-R', 'require',
]);
const validationFetchedAia = requests.some(
({ url }) => url === '/intermediate.der',
);

requests.length = 0;
await runToCompletion('/usr/bin/security', [
'verify-cert',
'-c', leafCert,
'-c', fixtures.path(
'keys',
'system-ca-network-intermediate-cert.pem',
),
'-r', rootCert,
'-p', 'basic',
'-R', 'ocsp',
'-R', 'online',
'-R', 'require',
]);
const validationRequestedOcsp = requests.some(
({ url }) => url?.startsWith('/ocsp'),
);

assert.deepStrictEqual({
enumerationRequests,
validationFetchedAia,
validationRequestedOcsp,
}, {
enumerationRequests: [],
validationFetchedAia: true,
validationRequestedOcsp: true,
});
});