Skip to content

Commit 906f23d

Browse files
timjaaduh95
authored andcommittedMar 9, 2025
crypto: add support for intermediate certs in --use-system-ca
PR-URL: #57164 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent fd49144 commit 906f23d

20 files changed

+573
-81
lines changed
 

‎src/crypto/crypto_context.cc

+15
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,21 @@ void ReadWindowsCertificates(
630630
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY,
631631
L"ROOT");
632632

633+
// Grab the intermediate certs
634+
GatherCertsForLocation(
635+
system_root_certificates_X509, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"CA");
636+
GatherCertsForLocation(system_root_certificates_X509,
637+
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY,
638+
L"CA");
639+
GatherCertsForLocation(system_root_certificates_X509,
640+
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
641+
L"CA");
642+
GatherCertsForLocation(
643+
system_root_certificates_X509, CERT_SYSTEM_STORE_CURRENT_USER, L"CA");
644+
GatherCertsForLocation(system_root_certificates_X509,
645+
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY,
646+
L"CA");
647+
633648
// Grab the user-added trusted server certs. Trusted end-entity certs are
634649
// only allowed for server auth in the "local machine" store, but not in the
635650
// "current user" store.

‎test/fixtures/keys/Makefile

+104
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ all: \
4040
ec-cert.pem \
4141
ec.pfx \
4242
fake-cnnic-root-cert.pem \
43+
intermediate-ca-cert.pem \
44+
intermediate-ca-key.pem \
45+
leaf-from-intermediate-cert.pem \
46+
leaf-from-intermediate-key.pem \
47+
non-trusted-intermediate-ca-cert.pem \
48+
non-trusted-intermediate-ca-key.pem \
49+
non-trusted-leaf-from-intermediate-cert.pem \
50+
non-trusted-leaf-from-intermediate-key.pem \
4351
rsa_private.pem \
4452
rsa_private_encrypted.pem \
4553
rsa_private_pkcs8.pem \
@@ -236,6 +244,102 @@ fake-startcom-root-cert.pem: fake-startcom-root.cnf \
236244
echo '01' > fake-startcom-root-serial
237245
touch fake-startcom-root-database.txt
238246

247+
248+
intermediate-ca-key.pem:
249+
openssl genrsa -out intermediate.key 2048
250+
251+
intermediate-ca-cert.pem: intermediate-ca-key.pem
252+
openssl req -new \
253+
-sha256 \
254+
-nodes \
255+
-key intermediate.key \
256+
-subj "/C=US/ST=CA/L=SF/O=NODEJS/CN=NodeJS-Test-Intermediate-CA" \
257+
-out test-intermediate-ca.csr
258+
259+
openssl x509 -req \
260+
-extensions v3_ca \
261+
-extfile fake-startcom-root.cnf \
262+
-in test-intermediate-ca.csr \
263+
-CA fake-startcom-root-cert.pem \
264+
-CAkey fake-startcom-root-key.pem \
265+
-CAcreateserial \
266+
-out intermediate-ca.pem \
267+
-days 99999 \
268+
-sha256
269+
rm -f test-intermediate-ca.csr
270+
271+
leaf-from-intermediate-key.pem:
272+
openssl genrsa -out leaf-from-intermediate-key.pem 2048
273+
274+
leaf-from-intermediate-cert.pem: leaf-from-intermediate-key.pem
275+
openssl genrsa -out leaf-from-intermediate-key.pem 2048
276+
openssl req -new \
277+
-sha256 \
278+
-nodes \
279+
-key leaf-from-intermediate-key.pem \
280+
-addext "subjectAltName = DNS:localhost" \
281+
-subj "/C=US/ST=CA/L=SF/O=NODEJS/CN=localhost" \
282+
-out leaf-from-intermediate-cert.csr
283+
openssl x509 -req \
284+
-in leaf-from-intermediate-cert.csr \
285+
-CA intermediate-ca.pem \
286+
-CAkey intermediate.key \
287+
-CAcreateserial \
288+
-out leaf-from-intermediate-cert.pem \
289+
-days 99999 \
290+
-copy_extensions copy \
291+
-sha256
292+
293+
rm -f leaf-from-intermediate-cert.csr
294+
295+
non-trusted-intermediate-ca-key.pem:
296+
openssl genrsa -out non-trusted-intermediate.key 2048
297+
298+
non-trusted-intermediate-ca-cert.pem: non-trusted-intermediate-ca-key.pem
299+
openssl req -new \
300+
-sha256 \
301+
-nodes \
302+
-key non-trusted-intermediate.key \
303+
-subj "/C=US/ST=CA/L=SF/O=NODEJS/CN=NodeJS-Non-Trusted-Test-Intermediate-CA" \
304+
-out non-trusted-test-intermediate-ca.csr
305+
306+
openssl x509 -req \
307+
-extensions v3_ca \
308+
-extfile fake-startcom-root.cnf \
309+
-in non-trusted-test-intermediate-ca.csr \
310+
-passin "pass:password" \
311+
-CA ca1-cert.pem \
312+
-CAkey ca1-key.pem \
313+
-CAcreateserial \
314+
-out non-trusted-intermediate-ca.pem \
315+
-days 99999 \
316+
-sha256
317+
rm -f non-trusted-test-intermediate-ca.csr
318+
319+
non-trusted-leaf-from-intermediate-key.pem:
320+
openssl genrsa -out non-trusted-leaf-from-intermediate-key.pem 2048
321+
322+
non-trusted-leaf-from-intermediate-cert.pem: non-trusted-leaf-from-intermediate-key.pem
323+
openssl genrsa -out non-trusted-leaf-from-intermediate-key.pem 2048
324+
openssl req -new \
325+
-sha256 \
326+
-nodes \
327+
-key non-trusted-leaf-from-intermediate-key.pem \
328+
-addext "subjectAltName = DNS:localhost" \
329+
-subj "/C=US/ST=CA/L=SF/O=NODEJS/CN=localhost" \
330+
-out non-trusted-leaf-from-intermediate-cert.csr
331+
openssl x509 -req \
332+
-in non-trusted-leaf-from-intermediate-cert.csr \
333+
-CA non-trusted-intermediate-ca.pem \
334+
-CAkey non-trusted-intermediate.key \
335+
-CAcreateserial \
336+
-out non-trusted-leaf-from-intermediate-cert.pem \
337+
-days 99999 \
338+
-copy_extensions copy \
339+
-sha256
340+
341+
rm -f non-trusted-leaf-from-intermediate-cert.csr
342+
239343
#
240344
# agent1 is signed by ca1.
241345
#

‎test/fixtures/keys/ca1-cert.srl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
147D36C1C2F74206DE9FAB5F2226D78ADB00A426
1+
147D36C1C2F74206DE9FAB5F2226D78ADB00A428
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEOTCCAyGgAwIBAgIULe6EHUBNm9nZz+fYRZx1P8uqmGwwDQYJKoZIhvcNAQEL
3+
BQAwfTELMAkGA1UEBhMCSUwxFjAUBgNVBAoMDVN0YXJ0Q29tIEx0ZC4xKzApBgNV
4+
BAsMIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMM
5+
IFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MCAXDTI1MDIyMTIyMTYx
6+
N1oYDzIyOTgxMjA2MjIxNjE3WjBeMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0Ex
7+
CzAJBgNVBAcMAlNGMQ8wDQYDVQQKDAZOT0RFSlMxJDAiBgNVBAMMG05vZGVKUy1U
8+
ZXN0LUludGVybWVkaWF0ZS1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
9+
ggEBAKfGhM1vXISvBuEJv4yapacu1CFnH9hQ6Z7e8p1kjMjaSg+NSvofPeb6byel
10+
Jk7GI9wRN4ZQISpKNxvQAjyc9RqkAwUDPY9KEp38PSQFU4osqvJDP4zf2dn0Hl55
11+
4DW22JzaWdwGgvq0admVwUBMnly4fVGBuxvy1m/j5wM6DHoSbC0Kgs13P2TpaqRT
12+
jz7jzN5YaT16M3kTDKVcTQGzZOCro0JF+V4xIDiOV9v9Cy4F6FRuksHx/e7gWXSF
13+
qaHqzblr9k/c8/3md5aBwHeUGJHe1+U/hhfE4D8IgG3ZdwNFI9KH5Zc8KfGTgr6s
14+
fgbpnNg7p9d5VJNOOM4So8ybig8CAwEAAaOBzTCByjAMBgNVHRMEBTADAQH/MB0G
15+
A1UdDgQWBBR6olPWoViHQBOxuAyYPRUSGaoEYDCBmgYDVR0jBIGSMIGPoYGBpH8w
16+
fTELMAkGA1UEBhMCSUwxFjAUBgNVBAoMDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsM
17+
IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxKTAnBgNVBAMMIFN0
18+
YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggkAgg9vTE81yAowDQYJKoZI
19+
hvcNAQELBQADggEBAC7nBG4JxrSFT/mJlCJxeHfFQj3xqduYePWK5H/h+buuX6OW
20+
pjMA8se2SjQUfVn81GAtNxb1kX8o9HjmaTvkx8bq6iuF9oyJh96N22Hl3kfWXX6H
21+
jy74Ur/pq73gpC90Xx8/DALpAYr9vKOKJM7DHWW9iuksRRvM1yh8kZagO0ewI8xU
22+
I9DLzl6+Zu6ZChosMlIn7yGdXB3Wi5mO+1fN+ryFlOVfTurzeinDbLm4xHb6pLnP
23+
x3VL1kKzQurUcvQvaIT3x3vd/FP+O7B+pWNyUE7HXZ9J4E2maUC+q81cpgAiCFoN
24+
ks7RFmz1z2myhB8opEpgRFYu6lxjCtHsr+meLjo=
25+
-----END CERTIFICATE-----

‎test/fixtures/keys/intermediate.key

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCnxoTNb1yErwbh
3+
Cb+MmqWnLtQhZx/YUOme3vKdZIzI2koPjUr6Hz3m+m8npSZOxiPcETeGUCEqSjcb
4+
0AI8nPUapAMFAz2PShKd/D0kBVOKLKryQz+M39nZ9B5eeeA1ttic2lncBoL6tGnZ
5+
lcFATJ5cuH1Rgbsb8tZv4+cDOgx6EmwtCoLNdz9k6WqkU48+48zeWGk9ejN5Ewyl
6+
XE0Bs2Tgq6NCRfleMSA4jlfb/QsuBehUbpLB8f3u4Fl0hamh6s25a/ZP3PP95neW
7+
gcB3lBiR3tflP4YXxOA/CIBt2XcDRSPSh+WXPCnxk4K+rH4G6ZzYO6fXeVSTTjjO
8+
EqPMm4oPAgMBAAECggEAAMP0GSfX6TcPNfmgaRjPhqq9BwX8bDU6S6JCwxsRVV1B
9+
lz6Sx/9affJIjYrAWP2objmZ4j/9Vr8N70+MoxAoQh3bcatpHX0+BoB/Gun3TpsT
10+
kJVj9dWTnd3yQYYW0sfpxxVr8YgKEvC9xuNbBVsUIeIpmDSaUO9TsSD+DdK2+duX
11+
wKPjCe097669ZG994GP9ilG6FdfIlVNWHWPExmFgbx0ydXr97nDuurt72HnqCVRR
12+
95g9SNAbkadUVj7iTSVovuaIQpQY4BMFICsGGRo10mMFGTzpAUwsl6OVZTUZXaST
13+
dg/Wl8ZD98CucVFmk546pJrfPDvk+qLqt0hlkXA5mQKBgQDrqPCNzz/VhsIlTmuO
14+
Dgmf4q9/hglR8JKjMQTuEXLGAhA09ZZrhKsGYSkciXEzmlL5mGZX+83Ss+ns8nI7
15+
21e6ZYm5hokltVbZ2Of2xGyeZ0SZ22QwIm4Eg2MmEpmyXAMTKAfvuvfQW1dC0UXG
16+
JEiRBYq3Chxv82ExmlkU5gZNIwKBgQC2QaCnPVV/VkwF0912lto8IRpwgZ0Jrj4b
17+
xqKTCc7oFNzd4Ua/I0W9qPqR1ORyVpq0li7cjHDmFWCZZMbCgy7+g5eclaZ3qWZZ
18+
Faj4rpv7y7ODKz2W2cmug9fWrrtsr96ohW1rfVn5racbHKAsT4f+RB+Gi1NK6aWp
19+
tOmh4MRMJQKBgQDLSk5RluJTOc/LTO39emCVG4EXejIaDHUC8Ct3j3e6FleSx/S9
20+
xZGfjDth0bLkuBEyHWTUK3UveWKns7IVrq7sLeF0OPmgnOFSRgo81s94ik8khpzT
21+
5S+RFyJ12n/Z3AQPB25pQJm8lL8e9dbCCdTLvcMfCUrkzEgg+Sw1mgT/jwKBgQCM
22+
7xbB/CW/AAZtgzV/3IsJcDe3xCKhN8IDTIiu1yjOQkPAt9EzQJ1PWfnZBx1YZSvg
23+
dTnrhhZPdTxroYgpJbQTT8LPbNF7Ot1QCfXNx4gLH6vCxI8ttV/FuWIQOrHoC99L
24+
xVGlixsmfWf5CRu66A0rS5ZtPhO8nAxkvOblLJ/emQKBgQCQkhBrZTDwgD4W6yxe
25+
juo/H/y6PMD4vp68zk/GmuV7mzHpYg18+gGAI57dQoxWjjMxxhkB8WKpnEkXXiva
26+
5YHq4ARUhXnPuNckvnOBj9jjy8HMeDKTPfZ6frv+B9i1y0N3ArerhPx44zCFpllH
27+
BlVhzBa52wYAtbjg291+/G1ndw==
28+
-----END PRIVATE KEY-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDkjCCAnqgAwIBAgIUPgpDrWcCOmjk4xOAkLpxa7UTx/4wDQYJKoZIhvcNAQEL
3+
BQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQswCQYDVQQHDAJTRjEPMA0G
4+
A1UECgwGTk9ERUpTMSQwIgYDVQQDDBtOb2RlSlMtVGVzdC1JbnRlcm1lZGlhdGUt
5+
Q0EwIBcNMjUwMjIxMjIxNjUyWhgPMjI5ODEyMDYyMjE2NTJaMEwxCzAJBgNVBAYT
6+
AlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzANBgNVBAoMBk5PREVKUzES
7+
MBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
8+
AQEAnnWYLNbVnE2veKzF28rarJh0En4Rd5+1ZwHp7+iP2gjEVmjBaSGK/F80MV9l
9+
S/wtZskUoZH0aKwiq9ly6Jp9IETte9Tk1Td6jTUeG8Vs9N6zoZcXM2Q359xbA+0X
10+
YzvHwD6TM5LQ6l3RKhJT2BRNz0oOCVQGHGepbcLbX99E3yXW0yXvZKAIcZY0NEk2
11+
AZ1eDz7QAhdPQ6W8QuYjlqOa+wmxqzVb3RReMg3zrL9jfd4AgCT9IN7HMB0FkQys
12+
y78EUHa12wlJkzHzz9N8+Qjt0537LjDpBuUBgnPn7Ukvz1kzD6q8a/dbB2RIbfVK
13+
7o0I/P9hJuXPhRpZQeDRQmDt+QIDAQABo1gwVjAUBgNVHREEDTALgglsb2NhbGhv
14+
c3QwHQYDVR0OBBYEFJHfQLpEP+M7+PYoxk/bY1vuDv/4MB8GA1UdIwQYMBaAFHqi
15+
U9ahWIdAE7G4DJg9FRIZqgRgMA0GCSqGSIb3DQEBCwUAA4IBAQCXckUku5JZiXSb
16+
qvlFH1JS7/SVeugquYZyI+boIzS2ykrLBkCVCbg6dD75Nu5VlcEGq4UNlY7vdfhk
17+
wG/jHNe6Hm36Lm2vbwH3z21IIGZlkw4cbNzdeT5WQuQNoembtbaZSsE7s1Hs052l
18+
kVJnq0ZJ7YgO54/0C9mE7dqhWHHWm9wPUC4emucqCKYcu1M9/onZgjjmAh39G473
19+
1qlWuTacywQHHCg8B0w+iZlV1rJ93dTyxJvg+fgmQj2FqBNqOXu6ojhOWHt62D3Y
20+
55zXFoUqToY6kgF+e9Rkn2vbZsSQO+cXSKVyRjnfIOCC4zO37yl31q02ouVv1Uct
21+
ubqxlcPA
22+
-----END CERTIFICATE-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCedZgs1tWcTa94
3+
rMXbytqsmHQSfhF3n7VnAenv6I/aCMRWaMFpIYr8XzQxX2VL/C1myRShkfRorCKr
4+
2XLomn0gRO171OTVN3qNNR4bxWz03rOhlxczZDfn3FsD7RdjO8fAPpMzktDqXdEq
5+
ElPYFE3PSg4JVAYcZ6ltwttf30TfJdbTJe9koAhxljQ0STYBnV4PPtACF09DpbxC
6+
5iOWo5r7CbGrNVvdFF4yDfOsv2N93gCAJP0g3scwHQWRDKzLvwRQdrXbCUmTMfPP
7+
03z5CO3TnfsuMOkG5QGCc+ftSS/PWTMPqrxr91sHZEht9UrujQj8/2Em5c+FGllB
8+
4NFCYO35AgMBAAECggEACIfP4A0WPZaEjWhus+cLJ+rCp+qzxcb6KPAWUBkq4lvh
9+
tv2neOGKhgzZhlVqgoFST+PgGZUeDWMD8FCx4hIMDahMSSP0SEK29SJgizHxDEsv
10+
bDHyOKzq4g9vsmnJfij+F0w/GDINj2pqy9sl+p5YNII5+HhWpmGRwlQQw4vlXSZq
11+
hcubO1DyL/3FL0gVMHUZex86QJ9cYXkf++omaFNPaOsiKbZu7Whtg4rxJOBw38FD
12+
/fX4U6SQwSxI6ffxFbmGvSBAQW4333Qvbs0xZnusKrcaKNQ3kCoQ7+cgyDogwSAE
13+
TQN1mqPynGlMmTW4KyyR1/W0jpQEW+pll2DNCqHb8QKBgQDONX8QXu2mp/5qjXJK
14+
Sa1orgqneadbWiUfq+6vWEIwAWbcUYGqgzUNa9OeK8jV5hEsCJOrfPvhKYdyVrfr
15+
cu8mLtQFQLZzTlaEyX4a8Euk2xlHIYG7/giEnBugdHcHu9MV7TLRFzunc5Y4cA4W
16+
3crScf/gl+LDO3TZ5E3ZHu4u8QKBgQDEuIagHlhcuyEfHUPRJk6ZXexlkQ383f3/
17+
g1aqWQxxPnlZuo/wFyxVl7YP5VNELOsiCQHm2efk+8dx0Fc8jzuafp8iSnSOJnNM
18+
7C9K5JcbkxsJxArx1Z2ZMPfFM40Nw5kFYNCPhsuzZ/w+/eOe2EyFEZMkWdH5lMpw
19+
Y6GvxiS/iQKBgB6WLs/F1OhoeMNjUbWVMiSZ1Di9Qca6G1GUViYqKD8ophI+AMbD
20+
CYaBHPWUNwkLRDbM2uKP+miOmWmrVUKWXMTEI2zYCXgXAZxWqt7iD8ZXPWugm7a/
21+
2pGY+jwVqmY6RPg2o9gB4zZWXcznSh+4LFKE2Fh/DwK4ef+r7qQrA1dxAoGAdIEI
22+
EfoGwNx+cCvnxw0VzZSndTtj+lcKn3GMORTF3qduPOrVZg6DTimsRFu/ZYfotV56
23+
RtrUkHNgmhIWKCJ33TaSTj+kKa+x52OVWphouYb0o2L8TF8Dl/89LggqyHUHwfyl
24+
Z+sf5p9172RzktZs8v4Gk6eySEqLXeZTkoMZrmkCgYEAg8QV0rE1GprYoL02DiMT
25+
/KlRyOUGawz559Rr5Ufdrm/SA37Yhyp/eADq1jrkpoL0uBd4YsqOFAtkCofxnI9i
26+
BonK/T1JV1+wDnXYCU9Tis/d043/vCR4RVXQGfucmrPxjuObXCu5c8Q0DzpzLG3u
27+
HmotaQ9Z3Wdd9PaX4le87R8=
28+
-----END PRIVATE KEY-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIESTCCAzGgAwIBAgIUFH02wcL3Qgben6tfIibXitsApCgwDQYJKoZIhvcNAQEL
3+
BQAwejELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQswCQYDVQQHDAJTRjEPMA0G
4+
A1UECgwGSm95ZW50MRAwDgYDVQQLDAdOb2RlLmpzMQwwCgYDVQQDDANjYTExIDAe
5+
BgkqhkiG9w0BCQEWEXJ5QHRpbnljbG91ZHMub3JnMCAXDTI1MDIyNzA4MTczM1oY
6+
DzIyOTgxMjEyMDgxNzMzWjBqMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJ
7+
BgNVBAcMAlNGMQ8wDQYDVQQKDAZOT0RFSlMxMDAuBgNVBAMMJ05vZGVKUy1Ob24t
8+
VHJ1c3RlZC1UZXN0LUludGVybWVkaWF0ZS1DQTCCASIwDQYJKoZIhvcNAQEBBQAD
9+
ggEPADCCAQoCggEBAMH8MfKXtkBMn58gJVCwe2w/XOl9rNK0M348KFcYTStC2ta0
10+
pwaB4ax7NeXs/xCDqtbuweZ0SLcS/nAOP9KQHN+fNSiXQ0gnHh23rZRri9VCvLWE
11+
5mGle2yjBApz7JERLW7gZX1Xtw/X5Qt9CtIYVKf7rGTgkq0kSvJQf6DhJ8e68HwG
12+
EQCp8ZmPQTFhIgzB35wYTgeKTU3uvQAYsAIw9fC5Vta8U9uU0VyN7mFxsoMXm4/u
13+
prk9L4AYSOFIV+njTd8xL+puSfZSKQA8yLcZ1LeRkAZo3RjUcEUPRDdLxB1UAZvh
14+
LYcJggWmx7799MZOsF1u9d2wR9HJ1Nzg3+IJiW0CAwEAAaOB1DCB0TAMBgNVHRME
15+
BTADAQH/MB0GA1UdDgQWBBR9aYwxOpYpUe2jMoN0MAqeG4A8GzCBoQYDVR0jBIGZ
16+
MIGWoX6kfDB6MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNG
17+
MQ8wDQYDVQQKDAZKb3llbnQxEDAOBgNVBAsMB05vZGUuanMxDDAKBgNVBAMMA2Nh
18+
MTEgMB4GCSqGSIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmeCFEqxbI39an0NLfyr
19+
35xLDpLGrQIpMA0GCSqGSIb3DQEBCwUAA4IBAQDADBpifaPV4jRtSefetMnhxxwj
20+
tPlLXRWqEJpJy+nHYJJdwQHxFHVoZSPinGpYpECCV73Gkh/rMKa+cvR4dBBIK6DP
21+
Bl1IQNP4Jr90z9c0T/zzUxVXE4iwcv2/Vg5OvVHU3z5gW4Mk3R4Rb+69UWHB1z8D
22+
41sm9w4u30vKGJrkdQ5ZLtfRLonncwLQexTlj1k/8VRytP4S9uIAmXwQpEPZxsto
23+
pRcMO2aWW0PvDzk7WPU+ZKnf1RC+pQx+PPH1/ZfyXHy7njJKZ04plIdTA/ah9pPw
24+
Bl++VCO7LSwDz+FlmuHnxc2LMR2EIRiNV03ooSc5XGGhIOKLl6+nMPQ0dlta
25+
-----END CERTIFICATE-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
78A88418149F0BFCEC38DC14D085BA43D36090F0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDB/DHyl7ZATJ+f
3+
ICVQsHtsP1zpfazStDN+PChXGE0rQtrWtKcGgeGsezXl7P8Qg6rW7sHmdEi3Ev5w
4+
Dj/SkBzfnzUol0NIJx4dt62Ua4vVQry1hOZhpXtsowQKc+yRES1u4GV9V7cP1+UL
5+
fQrSGFSn+6xk4JKtJEryUH+g4SfHuvB8BhEAqfGZj0ExYSIMwd+cGE4Hik1N7r0A
6+
GLACMPXwuVbWvFPblNFcje5hcbKDF5uP7qa5PS+AGEjhSFfp403fMS/qbkn2UikA
7+
PMi3GdS3kZAGaN0Y1HBFD0Q3S8QdVAGb4S2HCYIFpse+/fTGTrBdbvXdsEfRydTc
8+
4N/iCYltAgMBAAECggEALR4V1OVd1Xss1gMRQsDlV/Itzz20dEZGwrnFrSohCqqQ
9+
QQc/4MbVIPuAN/PFCEeDdN2PuiS6I+B2TsQ1qmjr2kQKhmAWHUJB4ioOJHrWCVou
10+
D27zcWsed5A7uJ2pPD1ZSpRE7p/32ya85kzlNyPDDtX9jPHhk4UhLFY2NQohKTYF
11+
CM2+YL6V8x2Kq9OOjGxPrX3t5H0cgVW7f+mMwhCSevJQAoLWO7cNbbN/fWHEK0jn
12+
ovHkpmK7dWejWN8MYMQOhmIuUV54aLIKoNLEAhnFj70/36I/GMUSQf+rCjjQtLXb
13+
lmNiKF33+3L6ti9HdcznhJujtMjiAXloRkESKcYPoQKBgQDoKO9wj7ZUvapt7ZnD
14+
9ALwkVpxPPCA7rDdu9DmEmXt8Zf3pVCaw1K2qPWM1iAoL6/AZDPs2E1nJGsmDNYv
15+
wMPt09TsZTURKvQYfdFs0uZPcTCJAXg36+dgxXq1OUNirB7Z+F1QPE3EHZT5AaPc
16+
vxRfA4RyJ+DcfMFzUcjePd2MTQKBgQDV57bQKf5wHkWCLVl/ZJB+hy1futN9In6u
17+
n0UeqSK+8m7Go8rPvNFlTeY6/lz/bm58u0mJFKd7vNQs+l7Y1DitC7BLItNwtcuW
18+
OEnhltbhry6i/9lieF607kwq9sNTVpp+iROF1BRmeDh3d3ByBa9Y9HSjfMPUgy6r
19+
Tb6lgMgBoQKBgDmL9BYtuV92CCnpjITzFkt1bDrHhUIgaHz+EkEFbHi3uxiqxLko
20+
E3etl/hKF3x+nY0OCYT69OzNLTYoVmtN2AM6z/us9qODxy/O+DuGZ4pnn0VGtPr/
21+
ocHuEYWcZSSvT5JuKws5d3lWb9ftXSXZw33tzEXTtrxQvE8OhcD5CtK9AoGBAMk0
22+
kqOwPKOd9egDXGIWaEx8PtQDWpgkcGE1c8Dpe8N9K3Ix874AcD8ITX5EcZnbeJZf
23+
XUZSZVBhSHuebsUqqr0rd4LVmWo1tvDwtZ47UpkrPYUZgJO9gehTFtZ7EzQ7DEvm
24+
CLUjzqSshQDrGpxGeLAGEgkOfO5TDv0XvjLTtk7BAoGBAM9ObVMPg+RhnVUY5oNT
25+
2A+Qq/3sitcbaJ2JKCjJEhttF0fF+0VYXf8c1YNE1AOfA/YnEazfCvPEOVmXGAeq
26+
iKf0FohQ1+dh9ShOK5tcR3jmMzrCwBJFlqjX942m/8FFg6B1za8nrrkSnWNCbJi5
27+
rmSv7B4llshgzTeEKqgM6GX1
28+
-----END PRIVATE KEY-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDnjCCAoagAwIBAgIUeKiEGBSfC/zsONwU0IW6Q9NgkPAwDQYJKoZIhvcNAQEL
3+
BQAwajELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQswCQYDVQQHDAJTRjEPMA0G
4+
A1UECgwGTk9ERUpTMTAwLgYDVQQDDCdOb2RlSlMtTm9uLVRydXN0ZWQtVGVzdC1J
5+
bnRlcm1lZGlhdGUtQ0EwIBcNMjUwMjI3MDgxNzUwWhgPMjI5ODEyMTIwODE3NTBa
6+
MEwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzANBgNV
7+
BAoMBk5PREVKUzESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
8+
AAOCAQ8AMIIBCgKCAQEAshskMqfwX4J5IA0poqWfm2jF23rBDBFw5FTdZP/dbYrS
9+
UCBOYqg5Jxgq4BxCnGq8ArGAQajOAAiwISK3h/WQ+XqaeEh5PmL4/dW3UZCvcR8I
10+
NN7LCXPnQcvJu1G4VbBDm8WbkkmGJvy6553kA+8SXyeoEs3nXTqQWVINo/8alt6m
11+
bRe2KA8FWgPrEUJgb+Vvl/z7a1V7PQSvWSuL0pBcj04tJQ5WrXAl72GI6eArJrM4
12+
Yl7Z08ZeGsSKAN+9aFnFyBfRmUeHgDTI9OQjw6FcwArCXZRmaX3CyGZJYgL6DAyf
13+
ukyyRXUT8Ii37W306Vp6d1prqZ4A2fih2sfbcpeLrwIDAQABo1gwVjAUBgNVHREE
14+
DTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFAa6wwZ2tpzJdeCtsG0sUw7MpG39MB8G
15+
A1UdIwQYMBaAFH1pjDE6lilR7aMyg3QwCp4bgDwbMA0GCSqGSIb3DQEBCwUAA4IB
16+
AQBWyVgyhKnRomPa23axktq8/8RC7h6mSJEOW+uTlwam/TqnWQFJspwosStOQFu4
17+
pg7Ww9MtKJSr9/vxxsyvNaKH5ZNTtgqqlzfYzVLbfwOirNSx4Mp1izQ0G5mfx3Yj
18+
+WEXarNaY8R0benqWMeArTFb9CdDcxvMcSdtkGrMXMuKXFN67zou8NQVkvGzc/tb
19+
imS/Ur9goJYUPlg2xor+P09tiIT+pEG+bpjYZ0U/1D5lIjQYCmZiy9ECL3WBc4df
20+
NKsJnlA2GZ4TXh2jFzQw3yZPSLCqNdy+9RdOB058wRYooaFYrOkRiUe9ZV5w1MW5
21+
mVuwUmrRSI79K26jdTav44PZ
22+
-----END CERTIFICATE-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyGyQyp/Bfgnkg
3+
DSmipZ+baMXbesEMEXDkVN1k/91titJQIE5iqDknGCrgHEKcarwCsYBBqM4ACLAh
4+
IreH9ZD5epp4SHk+Yvj91bdRkK9xHwg03ssJc+dBy8m7UbhVsEObxZuSSYYm/Lrn
5+
neQD7xJfJ6gSzeddOpBZUg2j/xqW3qZtF7YoDwVaA+sRQmBv5W+X/PtrVXs9BK9Z
6+
K4vSkFyPTi0lDlatcCXvYYjp4CsmszhiXtnTxl4axIoA371oWcXIF9GZR4eANMj0
7+
5CPDoVzACsJdlGZpfcLIZkliAvoMDJ+6TLJFdRPwiLftbfTpWnp3WmupngDZ+KHa
8+
x9tyl4uvAgMBAAECggEAMKa1VpkFUjGjwJuX2fQAC0Wtdmyruw4wlk6QQ3yZEckv
9+
9e89OjnVktZJL/rIP03wmZO/AzCHRP8ajZKcK6lqtptFAsJZTC9g8IWmk8NACVh+
10+
t2J8d9KPQyvVqTODdPS3Ix/xhR5MZO34aDh7BpARpqiAgtJ39sF+mMePLlMLAlbO
11+
U7/u1cttplvgiBRWTIiisyl9O+G2OCre1CXacEqkZ8jYWTP7sLofGCXCpgjBVKgl
12+
8q4ktgPlREMVD/QW78CIdrKuOdmzV42zSeFfPoZjUC3nLCdIALquPJyBSSZvDEeA
13+
T+eWSaIm5JcSTBjxG0f9riLQdup2Gz5NjPALHUTxMQKBgQDq2jyr1g0BUMFAJTQR
14+
6LraWcCOz+7l/oH6WuFGm7gUBf5yrdykeWvd8cSfwZRm2tzoxVu44+M05X3ORMHR
15+
wPyckITG9kWndzcOXpEOSiaObfqmEuz5gkpyzaUs5c9AE4pMhzIKNnruavPbD9Hy
16+
4AiLIT3ssjAL14/cjFuZTXl/dQKBgQDCJMxq0jf2rtVfrPrpEh8CyNu4sUQs8O5t
17+
9u4cvjGmHCfFpcdvCjS7gLuAZeFww3qjiv4pM0K5b7rjY3CelB+jlF2TG+4Jxf6h
18+
y/9iPSN98i2FT4Jxc02GYxsPa3mYAxykmqqvIkak+2omaJake2tCyjE49QrfGx0r
19+
TivZnwn+EwKBgQDe0a4MjqqKG/cuB94uO7PEZLE4DfooRl9Fi6H+3tE4VjOC1Ifp
20+
mLYJvk+CDyTgrTg4tL8AXV59GltRL5UAkGxbkxYWuyN87rPSs1BG0X1hVuEfXgdt
21+
9vrxj0Dupx8KOT/WudJ1NBlQSTMSHSFhoMMaVbCt+KVzJtL8OkLR4Vqr3QKBgAy8
22+
MziSn58r6s1C4JanXKdnG5qq7ijwiQNnnkj+ZO1bjXRWopVzGvBtyl7qz/YArKvL
23+
s05qkWbuoFjILhwI5WZqlhTPUTcM6N4eLpt4HTrmxvumsozUnnJBUAYb67cABUH6
24+
71VbrzylTVpFpBQYEHoqHz54PIVUFv6/OvskhphHAoGAJukr8k+rvxXIXOjvgE2O
25+
9sf2h7YZoW2AKK3tHPlG7XCuIFZJKKhkh+cVRorg/Ws5LLF/5egf234sfeZzdrvP
26+
O2TA/0Hf4mhaJhn53E/PLSLEDVTzORs1L+PfLrFptrP2Eq7iAnbTwaWnjMfAcsy2
27+
4ukRw65bBMLqv62KLTEZ5uk=
28+
-----END PRIVATE KEY-----

‎test/parallel/parallel.status

-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ test-fs-read-stream-concurrent-reads: PASS, FLAKY
1919
# https://github.com/nodejs/build/issues/3043
2020
test-snapshot-incompatible: SKIP
2121

22-
# Requires manual setup for certificates to be trusted by the system
23-
test-native-certs: SKIP
24-
2522
[$system==win32]
2623
# https://github.com/nodejs/node/issues/54807
2724
test-runner-watch-mode-complex: PASS, FLAKY

‎test/parallel/test-native-certs.mjs

-77
This file was deleted.

‎test/system-ca/README.md

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# system-ca
2+
3+
Tests for [--use-system-ca](../../doc/api/cli.md#--use-system-ca).
4+
5+
On both macOS and Windows interactive dialogs need confirming to add certificates to the OS trust store.
6+
7+
## macOS
8+
9+
**Adding the certificate**
10+
11+
```bash
12+
security add-trusted-cert \
13+
-k /Users/$USER/Library/Keychains/login.keychain-db \
14+
test/fixtures/keys/fake-startcom-root-cert.pem
15+
security add-certificates \
16+
-k /Users/$USER/Library/Keychains/login.keychain-db \
17+
test/fixtures/keys/intermediate-ca.pem
18+
security add-certificates \
19+
-k /Users/$USER/Library/Keychains/login.keychain-db \
20+
test/fixtures/keys/non-trusted-intermediate-ca.pem
21+
```
22+
23+
**Removing the certificate**
24+
25+
```bash
26+
security delete-certificate -c 'StartCom Certification Authority' \
27+
-t /Users/$USER/Library/Keychains/login.keychain-db
28+
security delete-certificate -c 'NodeJS-Test-Intermediate-CA' \
29+
-t /Users/$USER/Library/Keychains/login.keychain-db
30+
security delete-certificate -c 'NodeJS-Non-Trusted-Test-Intermediate-CA' \
31+
-t /Users/$USER/Library/Keychains/login.keychain-db
32+
```
33+
34+
## Windows
35+
36+
**Adding the certificate**
37+
38+
Powershell:
39+
40+
```powershell
41+
Import-Certificate -FilePath .\test\fixtures\keys\fake-startcom-root-cert.cer \
42+
-CertStoreLocation Cert:\CurrentUser\Root
43+
Import-Certificate -FilePath .\test\fixtures\keys\intermediate-ca.pem \
44+
-CertStoreLocation Cert:\CurrentUser\CA
45+
Import-Certificate -FilePath .\test\fixtures\keys\non-trusted-intermediate-ca.pem \
46+
-CertStoreLocation Cert:\CurrentUser\CA
47+
```
48+
49+
**Removing the certificate**
50+
51+
```powershell
52+
$thumbprint = (Get-ChildItem -Path Cert:\CurrentUser\Root | \
53+
Where-Object { $_.Subject -match "StartCom Certification Authority" }).Thumbprint
54+
Remove-Item -Path "Cert:\CurrentUser\Root\$thumbprint"
55+
56+
$thumbprint = (Get-ChildItem -Path Cert:\CurrentUser\CA | \
57+
Where-Object { $_.Subject -match "NodeJS-Test-Intermediate-CA" }).Thumbprint
58+
Remove-Item -Path "Cert:\CurrentUser\CA\$thumbprint"
59+
60+
$thumbprint = (Get-ChildItem -Path Cert:\CurrentUser\CA | \
61+
Where-Object { $_.Subject -match "NodeJS-Non-Trusted-Test-Intermediate-CA" }).Thumbprint
62+
Remove-Item -Path "Cert:\CurrentUser\CA\$thumbprint"
63+
```
64+
65+
## Debian/Ubuntu
66+
67+
**Adding the certificate**
68+
69+
```bash
70+
sudo cp test/fixtures/keys/fake-startcom-root-cert.pem \
71+
/usr/local/share/ca-certificates/fake-startcom-root-cert.crt
72+
sudo cp test/fixtures/keys/intermediate-ca.pem \
73+
/usr/local/share/ca-certificates/intermediate-ca.crt
74+
sudo cp test/fixtures/keys/non-trusted-intermediate-ca.pem \
75+
/usr/local/share/ca-certificates/non-trusted-intermediate-ca.crt
76+
sudo update-ca-certificates
77+
```
78+
79+
**Removing the certificate**
80+
81+
```bash
82+
sudo rm /usr/local/share/ca-certificates/fake-startcom-root-cert.crt \
83+
/usr/local/share/ca-certificates/intermediate-ca.crt \
84+
/usr/local/share/ca-certificates/non-trusted-intermediate-ca.crt
85+
sudo update-ca-certificates --fresh
86+
```
87+
88+
## Other Unix-like systems
89+
90+
For other Unix-like systems, consult their manuals, there are usually
91+
file-based processes similar to the Debian/Ubuntu one but with different
92+
file locations and update commands.

‎test/system-ca/system-ca.status

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
prefix system-ca
2+
3+
# To mark a test as flaky, list the test name in the appropriate section
4+
# below, without ".js", followed by ": PASS,FLAKY". Example:
5+
# sample-test : PASS,FLAKY
6+
7+
[true] # This section applies to all platforms
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Flags: --use-system-ca
2+
3+
import * as common from '../common/index.mjs';
4+
import assert from 'node:assert/strict';
5+
import https from 'node:https';
6+
import fixtures from '../common/fixtures.js';
7+
import { it, beforeEach, afterEach, describe } from 'node:test';
8+
import { once } from 'events';
9+
10+
if (!common.hasCrypto) {
11+
common.skip('requires crypto');
12+
}
13+
14+
// To run this test, the system needs to be configured to trust
15+
// the CA certificate first (which needs an interactive GUI approval, e.g. TouchID):
16+
// see the README.md in this folder for instructions on how to do this.
17+
const handleRequest = (req, res) => {
18+
const path = req.url;
19+
switch (path) {
20+
case '/hello-world':
21+
res.writeHead(200);
22+
res.end('hello world\n');
23+
break;
24+
default:
25+
assert(false, `Unexpected path: ${path}`);
26+
}
27+
};
28+
29+
describe('use-system-ca', function() {
30+
31+
async function setupServer(key, cert) {
32+
const theServer = https.createServer({
33+
key: fixtures.readKey(key),
34+
cert: fixtures.readKey(cert),
35+
}, handleRequest);
36+
theServer.listen(0);
37+
await once(theServer, 'listening');
38+
39+
return theServer;
40+
}
41+
42+
describe('signed with an intermediate CA certificate', () => {
43+
let server;
44+
45+
beforeEach(async function() {
46+
server = await setupServer('leaf-from-intermediate-key.pem', 'leaf-from-intermediate-cert.pem');
47+
});
48+
49+
it('can connect successfully', async function() {
50+
await fetch(`https://localhost:${server.address().port}/hello-world`);
51+
});
52+
53+
afterEach(async function() {
54+
server?.close();
55+
});
56+
});
57+
58+
describe('signed with a trusted intermediate but not trusted root CA certificate', () => {
59+
let server;
60+
61+
beforeEach(async function() {
62+
server = await setupServer(
63+
'non-trusted-leaf-from-intermediate-key.pem',
64+
'non-trusted-leaf-from-intermediate-cert.pem',
65+
);
66+
});
67+
68+
it('can connect successfully', async function() {
69+
try {
70+
await fetch(`https://localhost:${server.address().port}/hello-world`);
71+
} catch (err) {
72+
if (common.isWindows) {
73+
assert.strictEqual(err.cause.code, 'UNABLE_TO_GET_ISSUER_CERT');
74+
} else {
75+
assert.strictEqual(err.cause.code, 'UNABLE_TO_VERIFY_LEAF_SIGNATURE');
76+
}
77+
}
78+
});
79+
80+
afterEach(async function() {
81+
server?.close();
82+
});
83+
});
84+
85+
});
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Flags: --use-system-ca
2+
3+
import * as common from '../common/index.mjs';
4+
import assert from 'node:assert/strict';
5+
import https from 'node:https';
6+
import fixtures from '../common/fixtures.js';
7+
import { it, beforeEach, afterEach, describe } from 'node:test';
8+
import { once } from 'events';
9+
10+
if (!common.hasCrypto) {
11+
common.skip('requires crypto');
12+
}
13+
14+
// To run this test, the system needs to be configured to trust
15+
// the CA certificate first (which needs an interactive GUI approval, e.g. TouchID):
16+
// see the README.md in this folder for instructions on how to do this.
17+
const handleRequest = (req, res) => {
18+
const path = req.url;
19+
switch (path) {
20+
case '/hello-world':
21+
res.writeHead(200);
22+
res.end('hello world\n');
23+
break;
24+
default:
25+
assert(false, `Unexpected path: ${path}`);
26+
}
27+
};
28+
29+
describe('use-system-ca', function() {
30+
31+
async function setupServer(key, cert) {
32+
const theServer = https.createServer({
33+
key: fixtures.readKey(key),
34+
cert: fixtures.readKey(cert),
35+
}, handleRequest);
36+
theServer.listen(0);
37+
await once(theServer, 'listening');
38+
39+
return theServer;
40+
}
41+
42+
let server;
43+
44+
beforeEach(async function() {
45+
server = await setupServer('agent8-key.pem', 'agent8-cert.pem');
46+
});
47+
48+
it('trusts a valid root certificate', async function() {
49+
await fetch(`https://localhost:${server.address().port}/hello-world`);
50+
});
51+
52+
afterEach(async function() {
53+
server?.close();
54+
});
55+
});

‎test/system-ca/test.cfg.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import sys, os
2+
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
3+
import testpy
4+
5+
def GetConfiguration(context, root):
6+
return testpy.ParallelTestConfiguration(context, root, 'system-ca')

‎tools/test.py

+1
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,7 @@ def PrintCrashed(code):
15861586
'node-api',
15871587
'pummel',
15881588
'sqlite',
1589+
'system-ca',
15891590
'tick-processor',
15901591
'v8-updates'
15911592
]

0 commit comments

Comments
 (0)
Please sign in to comment.