Module Name: src
Committed By: riastradh
Date: Sat Aug 26 05:47:53 UTC 2023
Added Files:
src/external/mpl/mozilla-certdata: Makefile
src/external/mpl/mozilla-certdata/share: Makefile certdata.awk
Log Message:
mozilla-certdata: Makefile infrastructure.
To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/external/mpl/mozilla-certdata/Makefile
cvs rdiff -u -r0 -r1.1 src/external/mpl/mozilla-certdata/share/Makefile \
src/external/mpl/mozilla-certdata/share/certdata.awk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Added files:
Index: src/external/mpl/mozilla-certdata/Makefile
diff -u /dev/null src/external/mpl/mozilla-certdata/Makefile:1.1
--- /dev/null Sat Aug 26 05:47:53 2023
+++ src/external/mpl/mozilla-certdata/Makefile Sat Aug 26 05:47:53 2023
@@ -0,0 +1,9 @@
+# $NetBSD: Makefile,v 1.1 2023/08/26 05:47:53 riastradh Exp $
+#
+
+.include <bsd.own.mk>
+
+.if ${MKSHARE} != "no"
+SUBDIR= share
+.include <bsd.subdir.mk>
+.endif
Index: src/external/mpl/mozilla-certdata/share/Makefile
diff -u /dev/null src/external/mpl/mozilla-certdata/share/Makefile:1.1
--- /dev/null Sat Aug 26 05:47:53 2023
+++ src/external/mpl/mozilla-certdata/share/Makefile Sat Aug 26 05:47:53 2023
@@ -0,0 +1,80 @@
+# $NetBSD: Makefile,v 1.1 2023/08/26 05:47:53 riastradh Exp $
+#
+
+MOZCERTS= /usr/share/certs/mozilla
+FILESDIR= ${MOZCERTS}/all
+
+TRUSTDOMAINS= server email code
+
+# Normally it is a bad idea to use file system globs to list sources in
+# a makefile, but we replace the directory wholesale on regen using the
+# same pattern below. So in this case, maintaining an explicit list of
+# files would be more error-prone.
+CERTS!= cd ${.CURDIR:Q} && echo certs/*.pem
+FILES+= ${CERTS}
+
+.for D in ${TRUSTDOMAINS}
+$D_CERTS!= cat ${.CURDIR:Q}/$D.trust
+. for C in ${$D_CERTS}
+SYMLINKS+= ${MOZCERTS}/all/$C.pem ${MOZCERTS}/$D/$C.pem
+. endfor
+.endfor
+
+# The upstream Mozilla certdata.txt lives in the Mozilla nss repository
+# at https://hg.mozilla.org/projects/nss, under
+# lib/ckfw/builtins/certdata.txt.
+#
+# Updates:
+#
+# 1. Go to:
+# https://hg.mozilla.org/projects/nss/log/tip/lib/ckfw/builtins/certdata.txt
+#
+# 2. Find the top revision and follow the link to `diff'.
+#
+# 3. For the file lib/ckfw/builtins/certdata.txt, follow the link to
+# `file'.
+#
+# 4. Follow the link to `raw'.
+#
+# 5. Record the date of the latest revision and the URL to the
+# raw file in the comment below (includes hg revision).
+#
+# 6. Verify that the file matches when downloaded from at least
+# three different networks. (Suggestions: Your home
+# residential network, a TNF server, and Tor.)
+#
+# 7. Once you have verified this, commit certdata.txt.
+#
+# 8. Review https://wiki.mozilla.org/CA/Additional_Trust_Changes
+# for new special cases and apply to certdata.awk if
+# appropriate.
+#
+# 9. After committing certdata.txt and updating certdata.awk, run
+# `make regen' and verify that it builds and installs and
+# generally looks sensible.
+#
+# 10. Once you have verified that it builds and installs, cvs add
+# any new files and cvs rm any deleted files under certs/,
+# and commit certs/ and *.trust.
+#
+# Latest revision, from 2023-07-19:
+#
+# https://hg.mozilla.org/projects/nss/raw-file/f479bdba756c78ef9355a48c88744c69fdb4768e/lib/ckfw/builtins/certdata.txt
+#
+regen: .PHONY
+ rm -f certs/*.pem
+ rm -f ${TRUSTDOMAINS:=.trust}
+ mkdir tmp
+ awk -f certdata.awk \
+ -v CERTDIR=certs \
+ -v CODETRUST=code.trust \
+ -v EMAILTRUST=email.trust \
+ -v OPENSSL=openssl \
+ -v SERVERTRUST=server.trust \
+ -v WORKDIR=tmp \
+ <${.CURDIR:Q}/../dist/certdata.txt
+ rm -rf tmp
+
+.include <bsd.files.mk>
+.include <bsd.inc.mk> # XXX
+.include <bsd.links.mk>
Index: src/external/mpl/mozilla-certdata/share/certdata.awk
diff -u /dev/null src/external/mpl/mozilla-certdata/share/certdata.awk:1.1
--- /dev/null Sat Aug 26 05:47:53 2023
+++ src/external/mpl/mozilla-certdata/share/certdata.awk Sat Aug 26 05:47:53 2023
@@ -0,0 +1,582 @@
+#!/usr/bin/awk -f
+#
+# 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.
+#
+
+function quotify(x) {
+ gsub(/'/, "'\\''", x)
+ return "'"x"'"
+}
+
+function err(s) {
+ printf "%s: line %s: error: %s\n", ARGV[0], NR, s >"/dev/stderr"
+ printf "# %s\n", $0 >"/dev/stderr"
+ errors++
+}
+
+function symlink(target, link, cmd, status) {
+ cmd = sprintf("ln -sfn %s %s", quotify(target), quotify(link))
+ status = system(cmd)
+ if (status != 0)
+ err(sprintf("ln failed with status %d", status))
+}
+
+function reset() {
+ cka_class = ""
+ label = ""
+ lolab = ""
+ certpem = ""
+ certworkdir = ""
+ skipping = 0
+}
+
+function skip() {
+ if (VERBOSE)
+ printf "line %d: skip from: %s\n", NR, $0
+ skipping = 1
+}
+
+function parseoctal(s, i, n, x) {
+ x = 0
+ n += i
+ for (; i < n; i++) {
+ x *= 8
+ x += int(substr(s, i, 1))
+ }
+ return x
+}
+
+function writeoctaldata(f, desc, warned, status) {
+ if ($2 != "MULTILINE_OCTAL") {
+ err(sprintf("%s: Invalid %s type: %s", label, desc, $2))
+ skip()
+ return -1
+ }
+ warned = 0
+ while (getline) {
+ if ($0 == "END")
+ break
+ for (i = 0; i < length($0); i += 4) {
+ if (substr($0, i + 1, 4) !~ /\\[0-7][0-7][0-7]/) {
+ if (!warned)
+ err(sprintf("%s: Invalid %s data",
+ label, desc))
+ warned = 1
+ break
+ }
+ printf "%c", parseoctal($0, i + 2, 3) >f
+ }
+ }
+ status = close(f)
+ if ($0 != "END") {
+ err(sprintf("%s: Invalid octal data", label))
+ warned = 1
+ }
+ if (warned)
+ return -1
+ return status
+}
+
+function checkoctaldata(f, desc, fcheck) {
+ fcheck = f".tmp"
+ if (writeoctaldata(fcheck, desc) != 0)
+ return
+ cmd = sprintf("cmp -- %s %s >/dev/null && rm -- %s",
+ quotify(f), quotify(fcheck), quotify(fcheck))
+ if (system(cmd) != 0) {
+ err(sprintf("%s: %s mismatch", label, desc))
+ skip()
+ }
+}
+
+function writecheckoctaldata(f, desc, dowrite) {
+ if (dowrite)
+ writeoctaldata(f, desc)
+ else
+ checkoctaldata(f, desc)
+}
+
+function skipoctaldata(desc, warned) {
+ if ($2 != "MULTILINE_OCTAL") {
+ err(sprintf("%s: Invalid %s type: %s", label, desc, $2))
+ skip()
+ return -1
+ }
+ warned = 0
+ while (getline) {
+ if ($0 == "END")
+ return 0
+ if ($0 !~ /(\\[0-7][0-7][0-7])*/ && !warned) {
+ err(sprintf("%s: Invalid %s data", label, desc))
+ warned = 1
+ }
+ }
+ err(sprintf("%s: Invalid octal data", label))
+ skip()
+ return 1
+}
+
+function distrust_after(desc) {
+ if ($2 == "CK_BBOOL" && $3 == "CK_FALSE")
+ return
+ if ($2 == "MULTILINE_OCTAL") {
+ skipoctaldata(sprintf("%s distrust deadline", $2))
+ } else {
+ err(sprintf("%s: Unknown %s distrust type %d, value: %s",
+ label, desc, $2, $3))
+ }
+ if (VERBOSE)
+ printf "line %d: distrust for %s: %s\n", NR, desc, label
+ distrusted[lolab] = 1
+}
+
+function addtrust(trustfile, desc) {
+ if (desc":"lolab in trust_lineno) {
+ err(sprintf("%s: Multiple trust lines for %s, first at %d",
+ label, desc, trust_lineno[desc":"lolab]))
+ skip()
+ return
+ }
+ trust_lineno[desc":"lolab] = NR
+ if ($3 == "CKT_NSS_TRUSTED" || $3 == "CKT_NSS_TRUSTED_DELEGATOR") {
+ if (distrusted[lolab]) {
+ if (VERBOSE) {
+ printf "line %d: distrusted for %s\n", \
+ NR, desc
+ }
+ } else {
+ if (VERBOSE) {
+ printf "line %d: trusted for %s\n", \
+ NR, desc
+ }
+ printf "%s\n", label >trustfile
+ }
+ } else if ($3 == "CKT_NSS_MUST_VERIFY_TRUST" ||
+ $3 == "CKT_NSS_UNTRUSTED" ||
+ $3 == "CKT_NSS_NOT_TRUSTED") {
+ if (VERBOSE) {
+ printf "line %d: untrusted for %s\n", \
+ NR, desc
+ }
+ } else {
+ err(sprintf("%s: Unknown trust designation for %s: %s",
+ label, desc, $3))
+ }
+}
+
+
+BEGIN {
+ if (ARGV[0] == "awk")
+ ARGV[0] = "certdata"
+ if (!CERTDIR) {
+ printf "%s: specify -v CERTDIR=...", ARGV[0] >"/dev/stderr"
+ exit 1
+ }
+ if (!WORKDIR) {
+ printf "%s: specify -v WORKDIR=...", ARGV[0] >"/dev/stderr"
+ exit 1
+ }
+ if (!OPENSSL) {
+ printf "%s: specify -v OPENSSL=...", ARGV[0] >"/dev/stderr"
+ exit 1
+ }
+ if (!SERVERTRUST)
+ SERVERTRUST = "/dev/null"
+ if (!EMAILTRUST)
+ EMAILTRUST = "/dev/null"
+ if (!CODETRUST)
+ CODETRUST = "/dev/null"
+ printf "" >SERVERTRUST
+ printf "" >EMAILTRUST
+ printf "" >CODETRUST
+ errors = 0
+ reset()
+
+ # Special cases. See
+ # https://wiki.mozilla.org/CA/Additional_Trust_Changes for
+ # details.
+
+ # `The Turkish Government CA is name-constrained to *.tr.'
+ #
+ # Implemented in Firefox by
+ # https://phabricator.services.mozilla.com/D177242, but OpenSSL
+ # has no mechanism to implement this constraint, so we just
+ # exclude it altogether.
+ special_distrust["TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1"] = 1
+}
+
+END {
+ # Make sure the special cases have been applied.
+ for (label in special_distrust)
+ err("special distrust not found: %s.pem", label)
+
+ fflush() # flush all
+ close(SERVERTRUST)
+ close(EMAILTRUST)
+ close(CODETRUST)
+ if (errors) {
+ printf "%s: exiting with failure on %d error%s\n", ARGV[0], \
+ errors, (errors == 1 ? "" : "s") \
+ >"/dev/stderr"
+ exit 1
+ }
+}
+
+/^ *#/ { # comment
+ next
+}
+
+/^ *$/ {
+ next
+}
+
+$1 == "BEGINDATA" {
+ next
+}
+
+$1 == "CKA_CLASS" {
+ reset()
+}
+
+skipping {
+ if (VERBOSE)
+ printf "line %d: skipping: %s\n", NR, $0
+ next
+}
+
+$1 == "CKA_CLASS" && $2 != "CK_OBJECT_CLASS" {
+ err(sprintf("Invalid class: %s", $2))
+ skip()
+ next
+}
+
+$1 == "CKA_CLASS" && $3 == "CKO_NSS_BUILTIN_ROOT_LIST" {
+ skip()
+ next
+}
+
+$1 == "CKA_CLASS" {
+ cka_class = $3
+ next
+}
+
+$1 == "CKA_TOKEN" ||
+$1 == "CKA_NSS_MOZILLA_CA_POLICY" ||
+0 {
+ if ($2 != "CK_BBOOL") {
+ err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3))
+ next
+ }
+ if ($3 != "CK_TRUE")
+ err(sprintf("%s is false", $1))
+ next
+}
+
+$1 == "CKA_MODIFIABLE" ||
+$1 == "CKA_PRIVATE" ||
+$1 == "CKA_TRUST_STEP_UP_APPROVED" ||
+0 {
+ if ($2 != "CK_BBOOL") {
+ err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3))
+ next
+ }
+ if ($3 != "CK_FALSE")
+ err(sprintf("%s is true", $1))
+ next
+}
+
+$1 == "CKA_LABEL" {
+ if ($2 != "UTF8") {
+ err(sprintf("Non-UTF8 label type: %s; value: %s", $2, $3))
+ skip()
+ next
+ }
+
+ # Clear the `CKA_LABEL UTF8' fields. (`shift 2', in sh, except
+ # that doesn't work here in awk.)
+ sub(/CKA_LABEL +UTF8 +/, "", $0)
+
+ # Forbid embedded ", \, and /, as well as bunch of others.
+ #
+ # - We forbid embedded " because it's not clear what the escape
+ # sequence is.
+ #
+ # - We forbid \ in case there are escape sequences we don't
+ # know.
+ #
+ # - We forbid / so that we can always form a directory
+ # component
+ #
+ # We immediately forbid a bunch of others that might be
+ # metacharacters or otherwise problematic, so that the next
+ # person to update certdata will be forced to consciously think
+ # about how to handle them.
+ if ($0 !~ /^"[^[:cntrl:]!"#$%&\*\/:;?\[\\\]\^`\|~]*"$/) {
+ err(sprintf("Invalid characters in label: %s", $3))
+ skip()
+ next
+ }
+
+ # Nix the "quotes".
+ label = substr($0, 2, length($0) - 2)
+
+ # XXX The `renaming to' messages are inconsistent about whether
+ # they apply pre-substitution or post-substitution, so some
+ # have spaces and some have underscores. Oh well.
+
+ # Special cases: Avoid parentheses in two CA names, and
+ # non-US-ASCII in one CA name. It is regrettable to limit
+ # ourselves to an anglocentric worldview like this, but this
+ # will avoid potential problems with file system pathname
+ # encoding and canonicalization downstream.
+ if (label ~ /^NetLock Arany \(Class Gold\) F.*$/) {
+ label = "NetLock Arany Class Gold"
+ if (cka_class == "CKO_CERTIFICATE") {
+ printf "line %s: special characters," \
+ " renaming to \"%s\"\n", \
+ NR, label
+ }
+ }
+ if (label == "LAWtrust Root CA2 (4096)") {
+ label = "LAWtrust Root CA2 4096"
+ if (cka_class == "CKO_CERTIFICATE") {
+ printf "line %s: special characters," \
+ " renaming to \"%s\"\n", \
+ NR, label
+ }
+ }
+
+ # Avoid spaces in filenames, because Unix. Not that filenames
+ # can't have spaces in Unix, but a lot of downstream tools may
+ # get confused by them.
+ gsub(/ /, "_", label)
+
+ # Make sure it uses onlypathname-safe characters.
+ if (label ~ /[^[:alnum:]._-]/ || label ~ /^\./) {
+ err(sprintf("Special CA label: %s", label))
+ skip()
+ next
+ }
+
+ # Make sure it's not empty.
+ if (length(label) == 0) {
+ err("Empty label")
+ skip()
+ next
+ }
+
+ # Make sure it fits within a reasonable limit as a filename.
+ if (length(label) > 100) {
+ err(sprintf("Label too long, %d bytes > max %d: %s",
+ length(label), 100, label))
+ skip()
+ next
+ }
+
+ # If this defines the certificate, check for duplicates; if a
+ # duplicate is found, assign a counter suffix.
+ #
+ # XXX This collision numbering might not be stable across
+ # updates. What to do? Use the serial number?
+ #
+ # XXX This doesn't use Unicode case-folding. Let's hope we
+ # don't have anything that is a collision under casefold but
+ # not under US-ASCII-limited tolower.
+ lolab = tolower(label)
+ if (cka_class == "CKO_CERTIFICATE") {
+ if (VERBOSE)
+ printf "line %d: CA \"%s\"\n", NR, label
+ if (lolab in label_lineno) {
+ label = sprintf("%s.%d", label, ++label_counter[lolab])
+ lolab = tolower(label)
+ printf "line %s: duplicate, renaming to \"%s\"\n", \
+ NR, label
+ }
+ label_lineno[lolab] = NR
+ } else {
+ if (VERBOSE)
+ printf "line %d: trust \"%s\"\n", NR, label
+ # Hack: Take the highest-numbered counter for this label.
+ if (lolab in label_counter) {
+ label = sprintf("%s.%d", label, label_counter[lolab])
+ lolab = tolower(label)
+ printf "line %s: assuming duplicate is \"%s\"\n", \
+ NR, label
+ }
+ if (!(lolab in label_lineno)) {
+ err(snprintf("Missing label: %s", label))
+ skip()
+ next
+ }
+ }
+
+ # Apply special cases.
+ if (cka_class == "CKO_CERTIFICATE") {
+ if (label in special_distrust) {
+ printf "line %s: specially distrusting \"%s\"\n", \
+ NR, label
+ distrusted[lolab] = 1
+ delete special_distrust[label]
+ }
+ }
+
+ # Compute where this certificate will lives and a workspace.
+ certpem = CERTDIR"/"label".pem"
+ certworkdir = WORKDIR"/"label
+
+ # If this defines the certificate, create the directory.
+ # Otherwise, make sure the directory is there already.
+ if (cka_class == "CKO_CERTIFICATE") {
+ if (system(sprintf("mkdir -- %s", quotify(certworkdir))) \
+ != 0) {
+ errors++
+ skip()
+ next
+ }
+ } else {
+ if (system(sprintf("test -f %s", quotify(certpem))) != 0) {
+ err("%s: Missing certificate for %s", label,
+ cka_class)
+ }
+ if (system(sprintf("test -d %s", quotify(certworkdir))) != 0)
+ err("%s: Missing directory for %s", label, cka_class)
+ }
+
+ next
+}
+
+# Remaining rules assume we are in the middle of an object block and we
+# have a label.
+
+!label {
+ err(sprintf("%s: missing label", $1))
+ skip()
+ next
+}
+
+$1 == "CKA_CERTIFICATE_TYPE" {
+ if ($2 != "CK_CERTIFICATE_TYPE") {
+ err(sprintf("%s: Invalid certificate type type: %s",
+ label, $2))
+ skip()
+ next
+ }
+ if ($3 != "CKC_X_509") {
+ err(sprintf("%s: Unknown certificate type: %s", label, $2))
+ skip()
+ next
+ }
+ next
+}
+
+$1 == "CKA_SUBJECT" {
+ writeoctaldata(certworkdir"/subject", "subject")
+ next
+}
+
+$1 == "CKA_ID" {
+ if ($0 != "CKA_ID UTF8 \"0\"") {
+ err(sprintf("%s: Invalid id: %s", label, $0))
+ skip()
+ next
+ }
+ next
+}
+
+$1 == "CKA_ISSUER" {
+ writecheckoctaldata(certworkdir"/issuer", "issuer",
+ cka_class == "CKO_CERTIFICATE")
+ next
+}
+
+$1 == "CKA_SERIAL_NUMBER" {
+ writecheckoctaldata(certworkdir"/serial", "serial number",
+ cka_class == "CKO_CERTIFICATE")
+ next
+}
+
+$1 == "CKA_VALUE" {
+ if (writeoctaldata(certworkdir"/cert.der", "certificate data"))
+ next
+ if (system(sprintf("%s x509 -inform DER -outform PEM <%s >%s",
+ quotify(OPENSSL),
+ quotify(certworkdir"/cert.der"),
+ quotify(certpem))))
+ err(sprintf("%s: openssl x509 failed", label))
+ next
+}
+
+$1 == "CKA_CERT_SHA1_HASH" {
+ writeoctaldata(certworkdir"/hash.sha1", "SHA-1 hash")
+ next
+}
+
+$1 == "CKA_CERT_MD5_HASH" {
+ writeoctaldata(certworkdir"/hash.md5", "MD5 hash")
+ next
+}
+
+$1 == "CKA_NSS_SERVER_DISTRUST_AFTER" {
+ distrust_after("server")
+ next
+}
+
+$1 == "CKA_NSS_EMAIL_DISTRUST_AFTER" {
+ distrust_after("email")
+ next
+}
+
+$1 !~ /^CKA_TRUST_/ {
+ err(sprintf("%s: Unknown line: %s", label, $0))
+ skip()
+ next
+}
+
+$2 != "CK_TRUST" {
+ err(sprintf("%s: Invalid trust line: %s", label, $0))
+ skip()
+ next
+}
+
+# Remaining rules assume we are on a valid CKA_TRUST_* attribute.
+
+$1 == "CKA_TRUST_SERVER_AUTH" {
+ addtrust(SERVERTRUST, "server authentication")
+ next
+}
+
+$1 == "CKA_TRUST_EMAIL_PROTECTION" {
+ addtrust(EMAILTRUST, "email protection")
+ next
+}
+
+$1 == "CKA_TRUST_CODE_SIGNING" {
+ addtrust(CODETRUST, "code signing")
+ next
+}
+
+{
+ err(sprintf("%s: Unknown trust domain: %s", label, $1))
+}