From nobody Wed Aug 13 22:36:45 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4c2NXG1XVmz64cmv; Wed, 13 Aug 2025 22:36:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4c2NXG0yMRz3dBy; Wed, 13 Aug 2025 22:36:46 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1755124606; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=9YiMPa2z05XFEGE+vyfbXaKTFNn1UIOHlKmgCqq1F/U=; b=T2x0JetsYQS0bTIa34MvXb4Vh5S7e1oaFup2X54nAKRpsM47Q8GCRJrBrqXCQKyvvRHcgM Y6mUFXAcQ1m/iXDWyOM4U417FPRpNDZBJHKAWK0HuVhfQIPs4VJHvlqoo2mAwlr5KbHUEt bE0BfznKkq77xdG7rWdbGCnBtB4yCjUUU/QN+XDnPBhsQqvInULZCsD7l5rAUSs2iLguoC BsXum+GVSOBJl2Ev7kjnIDukKVOx9vLYrZ931MKmwnY4K9pDacC+MUxIrqcn4vcdl7DDyu sYzSvh1BgrUnPqa+NUBSvYsQJdiB2vW7yrh09r29ZnBCdmfbBRDrfYOIhzc4ng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1755124606; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=9YiMPa2z05XFEGE+vyfbXaKTFNn1UIOHlKmgCqq1F/U=; b=i5FIY/qLATbxg5RTpWh6aNqTEX9i+4+TVOvN/1hyL7Uk8fDU0mHOHejOuSTIbalEXCSmTt UeK9kdfxbD1GuI10re6Pc7vIxT30xkOE/shUMxr/tt26tX8+CAs4hPBeAZROuJjgT/p2K0 BrbXKnntfK2Qeoq0m2QxcmX1PxggFFH500Y7of5cjrAvdJNwbScxqEyJ9OBojdkJLc1nVb HKpbff09Fud7XtPcGbB/LKX1+qjOzxd0Dyq0snp6dYxcb6l9pugMmjta8g1bO8mGy1LL+a F7hT/r576Uk1yyt5i+I144Q/1Fbqe+k9UMQYL9k6ac9yfd02ZqltsKq+hWgoKA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1755124606; a=rsa-sha256; cv=none; b=YCn7bCETi2vkOC4Azy1T8UyHmj/UxCNRSi2qzjCXPYjAsv5cBYpSOYp64kEm3nkZjqaxhd qzN3OIxp4yv99vM+/EUtyyYZfuRWQ+asocimfcDiJ3aifBnNE/93KrrgxY8Dc0aNsB9Obl lbOLFFvowoG6kMfiBALUzkmbZ+KSbSfc9+cZ+zHElmeQfVU23zVTJGVLXQaa9SDlg5C+wg Q36T4vljoSDwZgNagpRvOTaT68PTadhKe7W3/VTZZ5nCfqn79f/C8ggkAGvmJU1blbH9QU ViToguxcjX3FC7EsA//qyprNfPSy5H3tl3hE/untANlexlEs7+UtlVS7wnHlvg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4c2NXG07KKzBNn; Wed, 13 Aug 2025 22:36:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 57DMajxP002380; Wed, 13 Aug 2025 22:36:45 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 57DMajia002376; Wed, 13 Aug 2025 22:36:45 GMT (envelope-from git) Date: Wed, 13 Aug 2025 22:36:45 GMT Message-Id: <202508132236.57DMajia002376@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 42ac41983ee1 - main - certctl: Fix bootstrap build List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 42ac41983ee184e818f6e8da791a5c6c7530f87e Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=42ac41983ee184e818f6e8da791a5c6c7530f87e commit 42ac41983ee184e818f6e8da791a5c6c7530f87e Author: Dag-Erling Smørgrav AuthorDate: 2025-08-13 22:35:17 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2025-08-13 22:36:36 +0000 certctl: Fix bootstrap build Fixes: 81d8827ad875 ("certctl: Reimplement in C") --- usr.sbin/certctl/Makefile | 6 ++- usr.sbin/certctl/certctl.8 | 7 +++- usr.sbin/certctl/certctl.c | 94 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 77 insertions(+), 30 deletions(-) diff --git a/usr.sbin/certctl/Makefile b/usr.sbin/certctl/Makefile index 5430dbf24853..8f19bde8aaf6 100644 --- a/usr.sbin/certctl/Makefile +++ b/usr.sbin/certctl/Makefile @@ -3,8 +3,12 @@ PACKAGE= certctl PROG= certctl MAN= certctl.8 -LIBADD= crypto +LIBADD= crypto util HAS_TESTS= SUBDIR.${MK_TESTS}= tests +.ifdef BOOTSTRAPPING +CFLAGS+=-DBOOTSTRAPPING +.endif + .include diff --git a/usr.sbin/certctl/certctl.8 b/usr.sbin/certctl/certctl.8 index 97bdc840c359..c53ad9765544 100644 --- a/usr.sbin/certctl/certctl.8 +++ b/usr.sbin/certctl/certctl.8 @@ -38,7 +38,7 @@ .Op Fl lv .Ic untrusted .Nm -.Op Fl BnUv +.Op Fl BNnUv .Op Fl D Ar destdir .Op Fl M Ar metalog .Ic rehash @@ -75,6 +75,11 @@ default: This option is only valid in conjunction with the .Ic rehash command. +.It Fl N +Base the file name on the certificate's name instead of its hash. +This option is only valid in conjunction with the +.Ic rehash +command. .It Fl n Dry-run mode. Do not actually perform any actions except write the metalog. diff --git a/usr.sbin/certctl/certctl.c b/usr.sbin/certctl/certctl.c index 6687e56f23b4..f5876736d604 100644 --- a/usr.sbin/certctl/certctl.c +++ b/usr.sbin/certctl/certctl.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include @@ -13,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include +#include #include #define info(fmt, ...) \ @@ -58,6 +60,7 @@ static void usage(void); static bool dryrun; static bool longnames; static bool nobundle; +static bool nohash; static bool unprivileged; static bool verbose; @@ -381,14 +384,58 @@ write_certs(const char *dir, struct cert_tree *tree) if (file->c == INT_MAX) errx(1, "unable to disambiguate %08lx", cert->hash); free(cert->path); - cert->path = xasprintf("%08lx.%d", cert->hash, file->c); + if (nohash) { + X509_NAME *xn; + X509_NAME_ENTRY *xe; + ASN1_STRING *as; + unsigned char *us = NULL; + int xi, usl; + + xn = X509_get_subject_name(cert->x509); + xi = X509_NAME_get_index_by_NID(xn, NID_commonName, -1); + if (xi < 0) { + warnx("%08lx.%d: certificate has no CN", + cert->hash, file->c); + xi = X509_NAME_get_index_by_NID(xn, + NID_organizationalUnitName, -1); + } + if (xi < 0) { + warnx("%08lx.%d: certificate has no OU", + cert->hash, file->c); + xi = X509_NAME_get_index_by_NID(xn, + NID_organizationName, -1); + } + if (xi < 0) { + warnx("%08lx.%d: certificate has no O", + cert->hash, file->c); + cert->path = xasprintf("%08lx.%d", cert->hash, + file->c); + } + xe = X509_NAME_get_entry(xn, xi); + as = X509_NAME_ENTRY_get_data(xe); + usl = ASN1_STRING_to_UTF8(&us, as); + if (usl < 0) { + errx(1, "%08lx.%d: %s", cert->hash, file->c, + ERR_error_string(ERR_get_error(), NULL)); + } + cert->path = xasprintf("%s.pem", (char *)us); + OPENSSL_free(us); + } else { + cert->path = xasprintf("%08lx.%d", cert->hash, file->c); + } } /* * Open and scan the directory. */ if ((d = open(dir, O_DIRECTORY | O_RDONLY)) < 0 || - (ndents = fdscandir(d, &dents, NULL, lexisort)) < 0) +#ifdef BOOTSTRAPPING + (ndents = scandir(dir, &dents, NULL, lexisort)) +#else + (ndents = fdscandir(d, &dents, NULL, lexisort)) +#endif + < 0) err(1, "%s", dir); + /* * Iterate over the directory listing and the certificate listing * in parallel. If the directory listing gets ahead of the @@ -598,7 +645,7 @@ load_trusted(bool all, struct cert_tree *exclude) * Returns the number of certificates loaded. */ static unsigned int -load_untrusted(bool all) +load_untrusted(bool all, struct cert_tree *exclude) { char *path; unsigned int i, n; @@ -606,19 +653,19 @@ load_untrusted(bool all) /* load external untrusted certs */ for (i = n = 0; all && untrusted_paths[i] != NULL; i++) { - ret = read_certs(untrusted_paths[i], &untrusted, NULL); + ret = read_certs(untrusted_paths[i], &untrusted, exclude); if (ret > 0) n += ret; } /* load installed untrusted certs */ - ret = read_certs(untrusted_dest, &untrusted, NULL); + ret = read_certs(untrusted_dest, &untrusted, exclude); if (ret > 0) n += ret; /* load legacy untrusted certs */ path = expand_path(LEGACY_PATH); - ret = read_certs(path, &untrusted, NULL); + ret = read_certs(path, &untrusted, exclude); if (ret > 0) { warnx("certificates found in legacy directory %s", path); @@ -748,7 +795,7 @@ certctl_untrusted(int argc, char **argv __unused) if (argc > 1) usage(); /* load untrusted certificates */ - load_untrusted(false); + load_untrusted(false, NULL); /* list them */ list_certs(&untrusted); free_certs(&untrusted); @@ -775,7 +822,7 @@ certctl_rehash(int argc, char **argv __unused) } /* load untrusted certs first */ - load_untrusted(true); + load_untrusted(true, NULL); /* load trusted certs, excluding any that are already untrusted */ load_trusted(true, &untrusted); @@ -808,7 +855,7 @@ certctl_trust(int argc, char **argv) usage(); /* load untrusted certs first */ - load_untrusted(true); + load_untrusted(true, NULL); /* load trusted certs, excluding any that are already untrusted */ load_trusted(true, &untrusted); @@ -869,7 +916,7 @@ certctl_untrust(int argc, char **argv) usage(); /* load untrusted certs first */ - load_untrusted(true); + load_untrusted(true, NULL); /* now load the additional untrusted certificates */ n = 0; @@ -900,22 +947,10 @@ static void set_defaults(void) { const char *value; - char *str; - size_t len; if (localbase == NULL && - (localbase = getenv("LOCALBASE")) == NULL) { - if ((str = malloc((len = PATH_MAX) + 1)) == NULL) - err(1, NULL); - while (sysctlbyname("user.localbase", str, &len, NULL, 0) < 0) { - if (errno != ENOMEM) - err(1, "sysctl(user.localbase)"); - if ((str = realloc(str, len + 1)) == NULL) - err(1, NULL); - } - str[len] = '\0'; - localbase = str; - } + (localbase = getenv("LOCALBASE")) == NULL) + localbase = getlocalbase(); if (destdir == NULL && (destdir = getenv("DESTDIR")) == NULL) @@ -984,7 +1019,7 @@ usage(void) { fprintf(stderr, "usage: certctl [-lv] [-D destdir] list\n" " certctl [-lv] [-D destdir] untrusted\n" - " certctl [-BnUv] [-D destdir] [-M metalog] rehash\n" + " certctl [-BNnUv] [-D destdir] [-M metalog] rehash\n" " certctl [-nv] [-D destdir] untrust \n" " certctl [-nv] [-D destdir] trust \n"); exit(1); @@ -996,7 +1031,7 @@ main(int argc, char *argv[]) const char *command; int opt; - while ((opt = getopt(argc, argv, "BcD:g:lL:M:no:Uv")) != -1) + while ((opt = getopt(argc, argv, "BcD:g:lL:M:Nno:Uv")) != -1) switch (opt) { case 'B': nobundle = true; @@ -1019,6 +1054,9 @@ main(int argc, char *argv[]) case 'M': metalog = optarg; break; + case 'N': + nohash = true; + break; case 'n': dryrun = true; break; @@ -1043,7 +1081,7 @@ main(int argc, char *argv[]) command = *argv; - if ((nobundle || unprivileged || metalog != NULL) && + if ((nobundle || nohash || unprivileged || metalog != NULL) && strcmp(command, "rehash") != 0) usage(); if (!unprivileged && metalog != NULL) {