aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/certctl/Makefile10
-rw-r--r--usr.sbin/certctl/Makefile.inc6
-rw-r--r--usr.sbin/certctl/certs1/DigiCert_Global_Root_CA.pem22
-rw-r--r--usr.sbin/certctl/certs1/Explicitly_Distrust_DigiNotar_Root_CA.pem32
-rw-r--r--usr.sbin/certctl/certs1/Makefile10
-rw-r--r--usr.sbin/certctl/certs2/GTS_Root_R1.pem31
-rw-r--r--usr.sbin/certctl/certs2/GlobalSign_Root_CA_-_R3.pem21
-rw-r--r--usr.sbin/certctl/certs2/Makefile10
-rw-r--r--usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.1.pem35
-rw-r--r--usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem35
-rw-r--r--usr.sbin/certctl/certs3/Makefile10
-rw-r--r--usr.sbin/certctl/certs4/AC_RAIZ_FNMT-RCM.pem32
-rw-r--r--usr.sbin/certctl/certs4/DigiCert_Global_Root_CA.pem22
-rw-r--r--usr.sbin/certctl/certs4/Makefile10
-rw-r--r--usr.sbin/certctl/t_certctl.sh486
-rw-r--r--usr.sbin/makefs/Makefile8
-rw-r--r--usr.sbin/makefs/t_makefs.sh65
17 files changed, 845 insertions, 0 deletions
diff --git a/usr.sbin/certctl/Makefile b/usr.sbin/certctl/Makefile
new file mode 100644
index 000000000000..962a472cb281
--- /dev/null
+++ b/usr.sbin/certctl/Makefile
@@ -0,0 +1,10 @@
+# $NetBSD: Makefile,v 1.1 2023/08/26 05:27:14 riastradh Exp $
+#
+
+.include "Makefile.inc" # TESTSDIR
+
+SUBDIR= certs1 certs2 certs3 certs4
+
+TESTS_SH= t_certctl
+
+.include <bsd.test.mk>
diff --git a/usr.sbin/certctl/Makefile.inc b/usr.sbin/certctl/Makefile.inc
new file mode 100644
index 000000000000..b3c142bf5aba
--- /dev/null
+++ b/usr.sbin/certctl/Makefile.inc
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile.inc,v 1.1 2023/08/26 05:27:14 riastradh Exp $
+#
+
+TESTSDIR= ${TESTSBASE}/usr.sbin/certctl
+
+.include <bsd.own.mk>
diff --git a/usr.sbin/certctl/certs1/DigiCert_Global_Root_CA.pem b/usr.sbin/certctl/certs1/DigiCert_Global_Root_CA.pem
new file mode 100644
index 000000000000..fd4341df2663
--- /dev/null
+++ b/usr.sbin/certctl/certs1/DigiCert_Global_Root_CA.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs1/Explicitly_Distrust_DigiNotar_Root_CA.pem b/usr.sbin/certctl/certs1/Explicitly_Distrust_DigiNotar_Root_CA.pem
new file mode 100644
index 000000000000..ab60ad25fe99
--- /dev/null
+++ b/usr.sbin/certctl/certs1/Explicitly_Distrust_DigiNotar_Root_CA.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFijCCA3KgAwIBAgIQD////////////////////zANBgkqhkiG9w0BAQUFADBf
+MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp
+Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww
+HhcNMDcwNzI3MTcxOTM3WhcNMjUwMzMxMTgxOTIyWjBfMQswCQYDVQQGEwJOTDES
+MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg
+MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B
+8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY
+tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl
+HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj
+zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU
+JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM
+ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv
+a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p
+K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi
+puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT
+yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO
+owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC
+jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy
+fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo
+Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo
+M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM
+Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed
+2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH
+/M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl
+nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE
+O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU
+9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9
+j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs1/Makefile b/usr.sbin/certctl/certs1/Makefile
new file mode 100644
index 000000000000..b75066c9a7b9
--- /dev/null
+++ b/usr.sbin/certctl/certs1/Makefile
@@ -0,0 +1,10 @@
+# $NetBSD: Makefile,v 1.1 2023/08/26 05:27:14 riastradh Exp $
+#
+
+FILESDIR= ${TESTSDIR}/certs1
+
+FILES+= DigiCert_Global_Root_CA.pem
+FILES+= Explicitly_Distrust_DigiNotar_Root_CA.pem
+
+.include <bsd.files.mk>
+.include <bsd.inc.mk>
diff --git a/usr.sbin/certctl/certs2/GTS_Root_R1.pem b/usr.sbin/certctl/certs2/GTS_Root_R1.pem
new file mode 100644
index 000000000000..a13aa0564117
--- /dev/null
+++ b/usr.sbin/certctl/certs2/GTS_Root_R1.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
+27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
+Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
+TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
+qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
+szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
+Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
+MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
+wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
+aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
+VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
+C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
+QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
+h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
+7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
+ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
+MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
+Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
+6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
+0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
+2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
+bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs2/GlobalSign_Root_CA_-_R3.pem b/usr.sbin/certctl/certs2/GlobalSign_Root_CA_-_R3.pem
new file mode 100644
index 000000000000..8afb219058fb
--- /dev/null
+++ b/usr.sbin/certctl/certs2/GlobalSign_Root_CA_-_R3.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs2/Makefile b/usr.sbin/certctl/certs2/Makefile
new file mode 100644
index 000000000000..8b046afd6ad5
--- /dev/null
+++ b/usr.sbin/certctl/certs2/Makefile
@@ -0,0 +1,10 @@
+# $NetBSD: Makefile,v 1.1 2023/08/26 05:27:14 riastradh Exp $
+#
+
+FILESDIR= ${TESTSDIR}/certs2
+
+FILES+= GTS_Root_R1.pem
+FILES+= GlobalSign_Root_CA_-_R3.pem
+
+.include <bsd.files.mk>
+.include <bsd.inc.mk>
diff --git a/usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.1.pem b/usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.1.pem
new file mode 100644
index 000000000000..842652306722
--- /dev/null
+++ b/usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.1.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
+MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc
+tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd
+IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j
+b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC
+AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw
+ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m
+iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF
+Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ
+hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P
+Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE
+EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV
+1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t
+CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
+5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw
+f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
+ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
+GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem b/usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem
new file mode 100644
index 000000000000..de97f841cbfa
--- /dev/null
+++ b/usr.sbin/certctl/certs3/Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
+MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
+VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
+cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
+ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
+AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
+661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
+am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
+ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
+PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
+3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
+SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
+3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
+ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
+StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
+Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
+jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs3/Makefile b/usr.sbin/certctl/certs3/Makefile
new file mode 100644
index 000000000000..c9721ef7aa2a
--- /dev/null
+++ b/usr.sbin/certctl/certs3/Makefile
@@ -0,0 +1,10 @@
+# $NetBSD: Makefile,v 1.1 2023/08/26 05:27:14 riastradh Exp $
+#
+
+FILESDIR= ${TESTSDIR}/certs3
+
+FILES+= Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.1.pem
+FILES+= Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068.pem
+
+.include <bsd.files.mk>
+.include <bsd.inc.mk>
diff --git a/usr.sbin/certctl/certs4/AC_RAIZ_FNMT-RCM.pem b/usr.sbin/certctl/certs4/AC_RAIZ_FNMT-RCM.pem
new file mode 100644
index 000000000000..666cf67c32be
--- /dev/null
+++ b/usr.sbin/certctl/certs4/AC_RAIZ_FNMT-RCM.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
+CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
+WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
+BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG
+Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/
+yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf
+BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz
+WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF
+tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z
+374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC
+IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL
+mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7
+wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS
+MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2
+ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet
+UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H
+YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3
+LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
+nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1
+RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM
+LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf
+77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N
+JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm
+fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
+6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp
+1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B
+9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
+RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
+uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs4/DigiCert_Global_Root_CA.pem b/usr.sbin/certctl/certs4/DigiCert_Global_Root_CA.pem
new file mode 100644
index 000000000000..fd4341df2663
--- /dev/null
+++ b/usr.sbin/certctl/certs4/DigiCert_Global_Root_CA.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
diff --git a/usr.sbin/certctl/certs4/Makefile b/usr.sbin/certctl/certs4/Makefile
new file mode 100644
index 000000000000..6fe3a4d5f118
--- /dev/null
+++ b/usr.sbin/certctl/certs4/Makefile
@@ -0,0 +1,10 @@
+# $NetBSD: Makefile,v 1.1 2023/08/26 05:27:15 riastradh Exp $
+#
+
+FILESDIR= ${TESTSDIR}/certs4
+
+FILES+= AC_RAIZ_FNMT-RCM.pem
+FILES+= DigiCert_Global_Root_CA.pem
+
+.include <bsd.files.mk>
+.include <bsd.inc.mk>
diff --git a/usr.sbin/certctl/t_certctl.sh b/usr.sbin/certctl/t_certctl.sh
new file mode 100644
index 000000000000..d14a57283404
--- /dev/null
+++ b/usr.sbin/certctl/t_certctl.sh
@@ -0,0 +1,486 @@
+#!/bin/sh
+
+# $NetBSD: t_certctl.sh,v 1.10 2023/09/05 12:32:30 riastradh Exp $
+#
+# Copyright (c) 2023 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+CERTCTL="certctl -C certs.conf -c certs -u untrusted"
+
+# setupconf <subdir>...
+#
+# Create certs/ and set up certs.conf to search the specified
+# subdirectories of the source directory.
+#
+setupconf()
+{
+ local sep subdir dir
+
+ mkdir certs
+ cat <<EOF >certs.conf
+netbsd-certctl 20230816
+
+# comment at line start
+ # comment not at line start, plus some intentional whitespace
+
+# THE WHITESPACE ABOVE IS INTENTIONAL, DO NOT DELETE
+EOF
+ # Start with a continuation line separator; then switch to
+ # non-continuation lines.
+ sep=$(printf ' \\\n\t')
+ for subdir; do
+ dir=$(atf_get_srcdir)/$subdir
+ cat <<EOF >>certs.conf
+path$sep$(printf '%s' "$dir" | vis -M)
+EOF
+ sep=' '
+ done
+}
+
+# check_empty
+#
+# Verify the certs directory is empty after dry runs or after
+# clearing the directory.
+#
+check_empty()
+{
+ local why
+
+ why=${1:-dry run}
+ for x in certs/*; do
+ if [ -e "$x" -o -h "$x" ]; then
+ atf_fail "certs/ should be empty after $why"
+ fi
+ done
+}
+
+# check_nonempty
+#
+# Verify the certs directory is nonempty.
+#
+check_nonempty()
+{
+ for x in certs/*.0; do
+ test -e "$x" && test -h "$x" && return
+ done
+ atf_fail "certs/ should be nonempty"
+}
+
+# checks <certsN>...
+#
+# Run various checks with certctl.
+#
+checks()
+{
+ local certs1 diginotar_base diginotar diginotar_hash subdir srcdir
+
+ certs1=$(atf_get_srcdir)/certs1
+ diginotar_base=Explicitly_Distrust_DigiNotar_Root_CA.pem
+ diginotar=$certs1/$diginotar_base
+ diginotar_hash=$(openssl x509 -hash -noout <$diginotar)
+
+ # Do a dry run of rehash and make sure the directory is still
+ # empty.
+ atf_check -s exit:0 $CERTCTL -n rehash
+ check_empty
+
+ # Distrust and trust one CA, as a dry run. The trust should
+ # fail because it's not currently distrusted.
+ atf_check -s exit:0 $CERTCTL -n untrust "$diginotar"
+ check_empty
+ atf_check -s not-exit:0 -e match:currently \
+ $CERTCTL -n trust "$diginotar"
+ check_empty
+
+ # Do a real rehash, not a dry run.
+ atf_check -s exit:0 $CERTCTL rehash
+
+ # Make sure all the certificates are trusted.
+ for subdir; do
+ case $subdir in
+ /*) srcdir=$subdir;;
+ *) srcdir=$(atf_get_srcdir)/$subdir;;
+ esac
+ for cert in "$srcdir"/*.pem; do
+ # Verify the certificate is linked by its base name.
+ certbase=$(basename "$cert")
+ atf_check -s exit:0 -o inline:"$cert" \
+ readlink -n "certs/$certbase"
+
+ # Verify the certificate is linked by a hash.
+ hash=$(openssl x509 -hash -noout <$cert)
+ counter=0
+ found=false
+ while [ $counter -lt 10 ]; do
+ if cmp -s "certs/$hash.$counter" "$cert"; then
+ found=true
+ break
+ fi
+ counter=$((counter + 1))
+ done
+ if ! $found; then
+ atf_fail "missing $cert"
+ fi
+
+ # Delete both links.
+ rm "certs/$certbase"
+ rm "certs/$hash.$counter"
+ done
+ done
+
+ # Verify the certificate bundle is there with the right
+ # permissions (0644) and delete it.
+ #
+ # XXX Verify its content.
+ atf_check -s exit:0 test -f certs/ca-certificates.crt
+ atf_check -s exit:0 test ! -h certs/ca-certificates.crt
+ atf_check -s exit:0 -o inline:'100644\n' \
+ stat -f %p certs/ca-certificates.crt
+ rm certs/ca-certificates.crt
+
+ # Make sure after deleting everything there's nothing left.
+ check_empty "removing all expected certificates"
+
+ # Distrust, trust, and re-distrust one CA, and verify that it
+ # ceases to appear, reappears, and again ceases to appear.
+ # (This one has no subject hash collisions to worry about, so
+ # we hard-code the `.0' suffix.)
+ atf_check -s exit:0 $CERTCTL untrust "$diginotar"
+ atf_check -s exit:0 test -e "untrusted/$diginotar_base"
+ atf_check -s exit:0 test -h "untrusted/$diginotar_base"
+ atf_check -s exit:0 test ! -e "certs/$diginotar_base"
+ atf_check -s exit:0 test ! -h "certs/$diginotar_base"
+ atf_check -s exit:0 test ! -e "certs/$diginotar_hash.0"
+ atf_check -s exit:0 test ! -h "certs/$diginotar_hash.0"
+ check_nonempty
+
+ atf_check -s exit:0 $CERTCTL trust "$diginotar"
+ atf_check -s exit:0 test ! -e "untrusted/$diginotar_base"
+ atf_check -s exit:0 test ! -h "untrusted/$diginotar_base"
+ atf_check -s exit:0 test -e "certs/$diginotar_base"
+ atf_check -s exit:0 test -h "certs/$diginotar_base"
+ atf_check -s exit:0 test -e "certs/$diginotar_hash.0"
+ atf_check -s exit:0 test -h "certs/$diginotar_hash.0"
+ rm "certs/$diginotar_base"
+ rm "certs/$diginotar_hash.0"
+ check_nonempty
+
+ atf_check -s exit:0 $CERTCTL untrust "$diginotar"
+ atf_check -s exit:0 test -e "untrusted/$diginotar_base"
+ atf_check -s exit:0 test -h "untrusted/$diginotar_base"
+ atf_check -s exit:0 test ! -e "certs/$diginotar_base"
+ atf_check -s exit:0 test ! -h "certs/$diginotar_base"
+ atf_check -s exit:0 test ! -e "certs/$diginotar_hash.0"
+ atf_check -s exit:0 test ! -h "certs/$diginotar_hash.0"
+ check_nonempty
+}
+
+atf_test_case empty
+empty_head()
+{
+ atf_set "descr" "Test empty certificates store"
+}
+empty_body()
+{
+ setupconf # no directories
+ check_empty "empty cert path"
+ atf_check -s exit:0 $CERTCTL -n rehash
+ check_empty
+ atf_check -s exit:0 $CERTCTL rehash
+ atf_check -s exit:0 test -f certs/ca-certificates.crt
+ atf_check -s exit:0 test \! -h certs/ca-certificates.crt
+ atf_check -s exit:0 test \! -s certs/ca-certificates.crt
+ atf_check -s exit:0 rm certs/ca-certificates.crt
+ check_empty "empty cert path"
+}
+
+atf_test_case onedir
+onedir_head()
+{
+ atf_set "descr" "Test one certificates directory"
+}
+onedir_body()
+{
+ setupconf certs1
+ checks certs1
+}
+
+atf_test_case twodir
+twodir_head()
+{
+ atf_set "descr" "Test two certificates directories"
+}
+twodir_body()
+{
+ setupconf certs1 certs2
+ checks certs1 certs2
+}
+
+atf_test_case collidehash
+collidehash_head()
+{
+ atf_set "descr" "Test colliding hashes"
+}
+collidehash_body()
+{
+ # certs3 has two certificates with the same subject hash
+ setupconf certs1 certs3
+ checks certs1 certs3
+}
+
+atf_test_case collidebase
+collidebase_head()
+{
+ atf_set "descr" "Test colliding base names"
+}
+collidebase_body()
+{
+ # certs1 and certs4 both have DigiCert_Global_Root_CA.pem,
+ # which should cause list and rehash to fail and mention
+ # duplicates.
+ setupconf certs1 certs4
+ atf_check -s not-exit:0 -o ignore -e match:duplicate $CERTCTL list
+ atf_check -s not-exit:0 -o ignore -e match:duplicate $CERTCTL rehash
+}
+
+atf_test_case manual
+manual_head()
+{
+ atf_set "descr" "Test manual operation"
+}
+manual_body()
+{
+ local certs1 diginotar_base diginotar diginotar_hash
+
+ certs1=$(atf_get_srcdir)/certs1
+ diginotar_base=Explicitly_Distrust_DigiNotar_Root_CA.pem
+ diginotar=$certs1/$diginotar_base
+ diginotar_hash=$(openssl x509 -hash -noout <$diginotar)
+
+ setupconf certs1 certs2
+ cat <<EOF >>certs.conf
+manual
+EOF
+ touch certs/bogus.pem
+ ln -s bogus.pem certs/0123abcd.0
+
+ # Listing shouldn't mention anything in the certs/ cache.
+ atf_check -s exit:0 -o not-match:bogus $CERTCTL list
+ atf_check -s exit:0 -o not-match:bogus $CERTCTL untrusted
+
+ # Rehashing and changing the configuration should succeed, but
+ # mention `manual' in a warning message and should not touch
+ # the cache.
+ atf_check -s exit:0 -e match:manual $CERTCTL rehash
+ atf_check -s exit:0 -e match:manual $CERTCTL untrust "$diginotar"
+ atf_check -s exit:0 -e match:manual $CERTCTL trust "$diginotar"
+
+ # The files we created should still be there.
+ atf_check -s exit:0 test -f certs/bogus.pem
+ atf_check -s exit:0 test -h certs/0123abcd.0
+}
+
+atf_test_case evilcertsdir
+evilcertsdir_head()
+{
+ atf_set "descr" "Test certificate directory with evil characters"
+}
+evilcertsdir_body()
+{
+ local certs1 diginotar_base diginotar evilcertsdir evildistrustdir
+
+ certs1=$(atf_get_srcdir)/certs1
+ diginotar_base=Explicitly_Distrust_DigiNotar_Root_CA.pem
+ diginotar=$certs1/$diginotar_base
+
+ evilcertsdir=$(printf '-evil certs\n.')
+ evilcertsdir=${evilcertsdir%.}
+ evildistrustdir=$(printf '-evil untrusted\n.')
+ evildistrustdir=${evildistrustdir%.}
+
+ setupconf certs1
+
+ # initial (re)hash, nonexistent certs directory
+ atf_check -s exit:0 $CERTCTL rehash
+ atf_check -s exit:0 certctl -C certs.conf \
+ -c "$evilcertsdir" -u "$evildistrustdir" \
+ rehash
+ atf_check -s exit:0 diff -ruN -- certs "$evilcertsdir"
+ atf_check -s exit:0 test ! -e untrusted
+ atf_check -s exit:0 test ! -h untrusted
+ atf_check -s exit:0 test ! -e "$evildistrustdir"
+ atf_check -s exit:0 test ! -h "$evildistrustdir"
+
+ # initial (re)hash, empty certs directory
+ atf_check -s exit:0 rm -rf -- certs
+ atf_check -s exit:0 rm -rf -- "$evilcertsdir"
+ atf_check -s exit:0 mkdir -- certs
+ atf_check -s exit:0 mkdir -- "$evilcertsdir"
+ atf_check -s exit:0 $CERTCTL rehash
+ atf_check -s exit:0 certctl -C certs.conf \
+ -c "$evilcertsdir" -u "$evildistrustdir" \
+ rehash
+ atf_check -s exit:0 diff -ruN -- certs "$evilcertsdir"
+ atf_check -s exit:0 test ! -e untrusted
+ atf_check -s exit:0 test ! -h untrusted
+ atf_check -s exit:0 test ! -e "$evildistrustdir"
+ atf_check -s exit:0 test ! -h "$evildistrustdir"
+
+ # test distrusting a CA
+ atf_check -s exit:0 $CERTCTL untrust "$diginotar"
+ atf_check -s exit:0 certctl -C certs.conf \
+ -c "$evilcertsdir" -u "$evildistrustdir" \
+ untrust "$diginotar"
+ atf_check -s exit:0 diff -ruN -- certs "$evilcertsdir"
+ atf_check -s exit:0 diff -ruN -- untrusted "$evildistrustdir"
+
+ # second rehash
+ atf_check -s exit:0 $CERTCTL rehash
+ atf_check -s exit:0 certctl -C certs.conf \
+ -c "$evilcertsdir" -u "$evildistrustdir" \
+ rehash
+ atf_check -s exit:0 diff -ruN -- certs "$evilcertsdir"
+ atf_check -s exit:0 diff -ruN -- untrusted "$evildistrustdir"
+}
+
+atf_test_case evilpath
+evilpath_head()
+{
+ atf_set "descr" "Test certificate paths with evil characters"
+}
+evilpath_body()
+{
+ local evildir
+
+ evildir=$(printf 'evil\n.')
+ evildir=${evildir%.}
+ mkdir "$evildir"
+
+ cp -p "$(atf_get_srcdir)/certs2"/*.pem "$evildir"/
+
+ setupconf certs1
+ cat <<EOF >>certs.conf
+path $(printf '%s' "$(pwd)/$evildir" | vis -M)
+EOF
+ checks certs1 "$(pwd)/$evildir"
+}
+
+atf_test_case missingconf
+missingconf_head()
+{
+ atf_set "descr" "Test certctl with missing certs.conf"
+}
+missingconf_body()
+{
+ mkdir certs
+ atf_check -s exit:0 test ! -e certs.conf
+ atf_check -s not-exit:0 -e match:'certs\.conf' \
+ $CERTCTL rehash
+}
+
+atf_test_case nonexistentcertsdir
+nonexistentcertsdir_head()
+{
+ atf_set "descr" "Test certctl succeeds when certsdir is nonexistent"
+}
+nonexistentcertsdir_body()
+{
+ setupconf certs1
+ rmdir certs
+ checks certs1
+}
+
+atf_test_case symlinkcertsdir
+symlinkcertsdir_head()
+{
+ atf_set "descr" "Test certctl fails when certsdir is a symlink"
+}
+symlinkcertsdir_body()
+{
+ setupconf certs1
+ rmdir certs
+ mkdir empty
+ ln -sfn empty certs
+
+ atf_check -s not-exit:0 -e match:symlink $CERTCTL -n rehash
+ atf_check -s not-exit:0 -e match:symlink $CERTCTL rehash
+ atf_check -s exit:0 rmdir empty
+}
+
+atf_test_case regularfilecertsdir
+regularfilecertsdir_head()
+{
+ atf_set "descr" "Test certctl fails when certsdir is a regular file"
+}
+regularfilecertsdir_body()
+{
+ setupconf certs1
+ rmdir certs
+ echo 'hello world' >certs
+
+ atf_check -s not-exit:0 -e match:directory $CERTCTL -n rehash
+ atf_check -s not-exit:0 -e match:directory $CERTCTL rehash
+ atf_check -s exit:0 rm certs
+}
+
+atf_test_case prepopulatedcerts
+prepopulatedcerts_head()
+{
+ atf_set "descr" "Test certctl fails when directory is prepopulated"
+}
+prepopulatedcerts_body()
+{
+ local cert certbase target
+
+ setupconf certs1
+ ln -sfn "$(atf_get_srcdir)/certs2"/*.pem certs/
+
+ atf_check -s not-exit:0 -e match:manual $CERTCTL -n rehash
+ atf_check -s not-exit:0 -e match:manual $CERTCTL rehash
+ for cert in "$(atf_get_srcdir)/certs2"/*.pem; do
+ certbase=$(basename "$cert")
+ atf_check -s exit:0 -o inline:"$cert" \
+ readlink -n "certs/$certbase"
+ rm "certs/$certbase"
+ done
+ check_empty
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case collidebase
+ atf_add_test_case collidehash
+ atf_add_test_case empty
+ atf_add_test_case evilcertsdir
+ atf_add_test_case evilpath
+ atf_add_test_case manual
+ atf_add_test_case missingconf
+ atf_add_test_case nonexistentcertsdir
+ atf_add_test_case onedir
+ atf_add_test_case prepopulatedcerts
+ atf_add_test_case regularfilecertsdir
+ atf_add_test_case symlinkcertsdir
+ atf_add_test_case twodir
+}
diff --git a/usr.sbin/makefs/Makefile b/usr.sbin/makefs/Makefile
new file mode 100644
index 000000000000..c614c26b6208
--- /dev/null
+++ b/usr.sbin/makefs/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2024/10/18 23:22:52 christos Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/usr.sbin/makefs
+TESTS_SH= t_makefs
+
+.include <bsd.test.mk>
diff --git a/usr.sbin/makefs/t_makefs.sh b/usr.sbin/makefs/t_makefs.sh
new file mode 100644
index 000000000000..cf5d6fda54e3
--- /dev/null
+++ b/usr.sbin/makefs/t_makefs.sh
@@ -0,0 +1,65 @@
+# $NetBSD: t_makefs.sh,v 1.1 2024/10/18 23:22:52 christos Exp $
+#
+# Copyright (c) 2024 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Christos Zoulas
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+
+# replace
+#
+atf_test_case replace replace_cleanup
+
+replace_head() {
+ atf_require_prog makefs
+ atf_set "descr" "Test replacing a single file (PR/58759)"
+}
+
+replace_body() {
+ export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+ mkdir -p 1 2/1
+ echo foo > 1/foo
+ echo bar > 2/1/foo
+ makefs -r -d 0xf0 -s 1m -t ffs foo.img 1 2/1
+ dump 0f foo.dump -F foo.img
+ restore -rf foo.dump
+ if [ ! -f foo ]; then
+ atf_fail "file foo does not exist"
+ fi
+ x=$(cat foo)
+ if [ "$x" != "bar" ]; then
+ atf_fail "file foo does not contain bar, but $x"
+ fi
+ atf_pass
+}
+
+replace_cleanup() {
+ rm -fr 1 2 foo foo.dump foo.img
+}
+
+atf_init_test_cases() {
+ atf_add_test_case replace
+}