Sun Mar 3 04:35:58 2024 UTC (104d)
mozilla-certdata: Fix typo: sprintf, not snprintf, in awk.

Only used during import, and only in case something is wrong anyway
requiring manual intervention, so no change to builds.


(riastradh)
diff -r1.2 -r1.3 src/external/mpl/mozilla-certdata/share/certdata.awk

cvs diff -r1.2 -r1.3 src/external/mpl/mozilla-certdata/share/certdata.awk (switch to unified diff)

--- src/external/mpl/mozilla-certdata/share/certdata.awk 2023/10/11 19:57:25 1.2
+++ src/external/mpl/mozilla-certdata/share/certdata.awk 2024/03/03 04:35:58 1.3
@@ -1,583 +1,583 @@ @@ -1,583 +1,583 @@
1#!/usr/bin/awk -f 1#!/usr/bin/awk -f
2# 2#
3# Copyright (c) 2023 The NetBSD Foundation, Inc. 3# Copyright (c) 2023 The NetBSD Foundation, Inc.
4# All rights reserved. 4# All rights reserved.
5# 5#
6# Redistribution and use in source and binary forms, with or without 6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions 7# modification, are permitted provided that the following conditions
8# are met: 8# are met:
9# 1. Redistributions of source code must retain the above copyright 9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer. 10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright 11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the 12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution. 13# documentation and/or other materials provided with the distribution.
14# 14#
15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE. 25# POSSIBILITY OF SUCH DAMAGE.
26# 26#
27 27
28function quotify(x) { 28function quotify(x) {
29 gsub(/'/, "'\\''", x) 29 gsub(/'/, "'\\''", x)
30 return "'"x"'" 30 return "'"x"'"
31} 31}
32 32
33function err(s) { 33function err(s) {
34 printf "%s: line %s: error: %s\n", ARGV[0], NR, s >"/dev/stderr" 34 printf "%s: line %s: error: %s\n", ARGV[0], NR, s >"/dev/stderr"
35 printf "# %s\n", $0 >"/dev/stderr" 35 printf "# %s\n", $0 >"/dev/stderr"
36 errors++ 36 errors++
37} 37}
38 38
39function symlink(target, link, cmd, status) { 39function symlink(target, link, cmd, status) {
40 cmd = sprintf("ln -sfn %s %s", quotify(target), quotify(link)) 40 cmd = sprintf("ln -sfn %s %s", quotify(target), quotify(link))
41 status = system(cmd) 41 status = system(cmd)
42 if (status != 0) 42 if (status != 0)
43 err(sprintf("ln failed with status %d", status)) 43 err(sprintf("ln failed with status %d", status))
44} 44}
45 45
46function reset() { 46function reset() {
47 cka_class = "" 47 cka_class = ""
48 label = "" 48 label = ""
49 lolab = "" 49 lolab = ""
50 certpem = "" 50 certpem = ""
51 certworkdir = "" 51 certworkdir = ""
52 skipping = 0 52 skipping = 0
53} 53}
54 54
55function skip() { 55function skip() {
56 if (VERBOSE) 56 if (VERBOSE)
57 printf "line %d: skip from: %s\n", NR, $0 57 printf "line %d: skip from: %s\n", NR, $0
58 skipping = 1 58 skipping = 1
59} 59}
60 60
61function parseoctal(s, i, n, x) { 61function parseoctal(s, i, n, x) {
62 x = 0 62 x = 0
63 n += i 63 n += i
64 for (; i < n; i++) { 64 for (; i < n; i++) {
65 x *= 8 65 x *= 8
66 x += int(substr(s, i, 1)) 66 x += int(substr(s, i, 1))
67 } 67 }
68 return x 68 return x
69} 69}
70 70
71function writeoctaldata(f, desc, warned, status) { 71function writeoctaldata(f, desc, warned, status) {
72 if ($2 != "MULTILINE_OCTAL") { 72 if ($2 != "MULTILINE_OCTAL") {
73 err(sprintf("%s: Invalid %s type: %s", label, desc, $2)) 73 err(sprintf("%s: Invalid %s type: %s", label, desc, $2))
74 skip() 74 skip()
75 return -1 75 return -1
76 } 76 }
77 warned = 0 77 warned = 0
78 while (getline) { 78 while (getline) {
79 if ($0 == "END") 79 if ($0 == "END")
80 break 80 break
81 for (i = 0; i < length($0); i += 4) { 81 for (i = 0; i < length($0); i += 4) {
82 if (substr($0, i + 1, 4) !~ /\\[0-7][0-7][0-7]/) { 82 if (substr($0, i + 1, 4) !~ /\\[0-7][0-7][0-7]/) {
83 if (!warned) 83 if (!warned)
84 err(sprintf("%s: Invalid %s data", 84 err(sprintf("%s: Invalid %s data",
85 label, desc)) 85 label, desc))
86 warned = 1 86 warned = 1
87 break 87 break
88 } 88 }
89 printf "%c", parseoctal($0, i + 2, 3) >f 89 printf "%c", parseoctal($0, i + 2, 3) >f
90 } 90 }
91 } 91 }
92 status = close(f) 92 status = close(f)
93 if ($0 != "END") { 93 if ($0 != "END") {
94 err(sprintf("%s: Invalid octal data", label)) 94 err(sprintf("%s: Invalid octal data", label))
95 warned = 1 95 warned = 1
96 } 96 }
97 if (warned) 97 if (warned)
98 return -1 98 return -1
99 return status 99 return status
100} 100}
101 101
102function checkoctaldata(f, desc, fcheck) { 102function checkoctaldata(f, desc, fcheck) {
103 fcheck = f".tmp" 103 fcheck = f".tmp"
104 if (writeoctaldata(fcheck, desc) != 0) 104 if (writeoctaldata(fcheck, desc) != 0)
105 return 105 return
106 cmd = sprintf("cmp -- %s %s >/dev/null && rm -- %s", 106 cmd = sprintf("cmp -- %s %s >/dev/null && rm -- %s",
107 quotify(f), quotify(fcheck), quotify(fcheck)) 107 quotify(f), quotify(fcheck), quotify(fcheck))
108 if (system(cmd) != 0) { 108 if (system(cmd) != 0) {
109 err(sprintf("%s: %s mismatch", label, desc)) 109 err(sprintf("%s: %s mismatch", label, desc))
110 skip() 110 skip()
111 } 111 }
112} 112}
113 113
114function writecheckoctaldata(f, desc, dowrite) { 114function writecheckoctaldata(f, desc, dowrite) {
115 if (dowrite) 115 if (dowrite)
116 writeoctaldata(f, desc) 116 writeoctaldata(f, desc)
117 else 117 else
118 checkoctaldata(f, desc) 118 checkoctaldata(f, desc)
119} 119}
120 120
121function skipoctaldata(desc, warned) { 121function skipoctaldata(desc, warned) {
122 if ($2 != "MULTILINE_OCTAL") { 122 if ($2 != "MULTILINE_OCTAL") {
123 err(sprintf("%s: Invalid %s type: %s", label, desc, $2)) 123 err(sprintf("%s: Invalid %s type: %s", label, desc, $2))
124 skip() 124 skip()
125 return -1 125 return -1
126 } 126 }
127 warned = 0 127 warned = 0
128 while (getline) { 128 while (getline) {
129 if ($0 == "END") 129 if ($0 == "END")
130 return 0 130 return 0
131 if ($0 !~ /(\\[0-7][0-7][0-7])*/ && !warned) { 131 if ($0 !~ /(\\[0-7][0-7][0-7])*/ && !warned) {
132 err(sprintf("%s: Invalid %s data", label, desc)) 132 err(sprintf("%s: Invalid %s data", label, desc))
133 warned = 1 133 warned = 1
134 } 134 }
135 } 135 }
136 err(sprintf("%s: Invalid octal data", label)) 136 err(sprintf("%s: Invalid octal data", label))
137 skip() 137 skip()
138 return 1 138 return 1
139} 139}
140 140
141function distrust_after(desc) { 141function distrust_after(desc) {
142 if ($2 == "CK_BBOOL" && $3 == "CK_FALSE") 142 if ($2 == "CK_BBOOL" && $3 == "CK_FALSE")
143 return 143 return
144 if ($2 == "MULTILINE_OCTAL") { 144 if ($2 == "MULTILINE_OCTAL") {
145 skipoctaldata(sprintf("%s distrust deadline", $2)) 145 skipoctaldata(sprintf("%s distrust deadline", $2))
146 } else { 146 } else {
147 err(sprintf("%s: Unknown %s distrust type %d, value: %s", 147 err(sprintf("%s: Unknown %s distrust type %d, value: %s",
148 label, desc, $2, $3)) 148 label, desc, $2, $3))
149 } 149 }
150 if (VERBOSE) 150 if (VERBOSE)
151 printf "line %d: distrust for %s: %s\n", NR, desc, label 151 printf "line %d: distrust for %s: %s\n", NR, desc, label
152 distrusted[lolab] = 1 152 distrusted[lolab] = 1
153} 153}
154 154
155function addtrust(trustfile, desc) { 155function addtrust(trustfile, desc) {
156 if (desc":"lolab in trust_lineno) { 156 if (desc":"lolab in trust_lineno) {
157 err(sprintf("%s: Multiple trust lines for %s, first at %d", 157 err(sprintf("%s: Multiple trust lines for %s, first at %d",
158 label, desc, trust_lineno[desc":"lolab])) 158 label, desc, trust_lineno[desc":"lolab]))
159 skip() 159 skip()
160 return 160 return
161 } 161 }
162 trust_lineno[desc":"lolab] = NR 162 trust_lineno[desc":"lolab] = NR
163 if ($3 == "CKT_NSS_TRUSTED_DELEGATOR") { 163 if ($3 == "CKT_NSS_TRUSTED_DELEGATOR") {
164 if (distrusted[lolab]) { 164 if (distrusted[lolab]) {
165 if (VERBOSE) { 165 if (VERBOSE) {
166 printf "line %d: distrusted for %s\n", \ 166 printf "line %d: distrusted for %s\n", \
167 NR, desc 167 NR, desc
168 } 168 }
169 } else { 169 } else {
170 if (VERBOSE) { 170 if (VERBOSE) {
171 printf "line %d: trusted for %s\n", \ 171 printf "line %d: trusted for %s\n", \
172 NR, desc 172 NR, desc
173 } 173 }
174 printf "%s\n", label >trustfile 174 printf "%s\n", label >trustfile
175 } 175 }
176 } else if ($3 == "CKT_NSS_TRUSTED" || 176 } else if ($3 == "CKT_NSS_TRUSTED" ||
177 $3 == "CKT_NSS_MUST_VERIFY_TRUST" || 177 $3 == "CKT_NSS_MUST_VERIFY_TRUST" ||
178 $3 == "CKT_NSS_UNTRUSTED" || 178 $3 == "CKT_NSS_UNTRUSTED" ||
179 $3 == "CKT_NSS_NOT_TRUSTED") { 179 $3 == "CKT_NSS_NOT_TRUSTED") {
180 if (VERBOSE) { 180 if (VERBOSE) {
181 printf "line %d: untrusted as CA for %s\n", \ 181 printf "line %d: untrusted as CA for %s\n", \
182 NR, desc 182 NR, desc
183 } 183 }
184 } else { 184 } else {
185 err(sprintf("%s: Unknown trust designation for %s: %s", 185 err(sprintf("%s: Unknown trust designation for %s: %s",
186 label, desc, $3)) 186 label, desc, $3))
187 } 187 }
188} 188}
189 189
190 190
191BEGIN { 191BEGIN {
192 if (ARGV[0] == "awk") 192 if (ARGV[0] == "awk")
193 ARGV[0] = "certdata" 193 ARGV[0] = "certdata"
194 if (!CERTDIR) { 194 if (!CERTDIR) {
195 printf "%s: specify -v CERTDIR=...", ARGV[0] >"/dev/stderr" 195 printf "%s: specify -v CERTDIR=...", ARGV[0] >"/dev/stderr"
196 exit 1 196 exit 1
197 } 197 }
198 if (!WORKDIR) { 198 if (!WORKDIR) {
199 printf "%s: specify -v WORKDIR=...", ARGV[0] >"/dev/stderr" 199 printf "%s: specify -v WORKDIR=...", ARGV[0] >"/dev/stderr"
200 exit 1 200 exit 1
201 } 201 }
202 if (!OPENSSL) { 202 if (!OPENSSL) {
203 printf "%s: specify -v OPENSSL=...", ARGV[0] >"/dev/stderr" 203 printf "%s: specify -v OPENSSL=...", ARGV[0] >"/dev/stderr"
204 exit 1 204 exit 1
205 } 205 }
206 if (!SERVERTRUST) 206 if (!SERVERTRUST)
207 SERVERTRUST = "/dev/null" 207 SERVERTRUST = "/dev/null"
208 if (!EMAILTRUST) 208 if (!EMAILTRUST)
209 EMAILTRUST = "/dev/null" 209 EMAILTRUST = "/dev/null"
210 if (!CODETRUST) 210 if (!CODETRUST)
211 CODETRUST = "/dev/null" 211 CODETRUST = "/dev/null"
212 printf "" >SERVERTRUST 212 printf "" >SERVERTRUST
213 printf "" >EMAILTRUST 213 printf "" >EMAILTRUST
214 printf "" >CODETRUST 214 printf "" >CODETRUST
215 errors = 0 215 errors = 0
216 reset() 216 reset()
217 217
218 # Special cases. See 218 # Special cases. See
219 # https://wiki.mozilla.org/CA/Additional_Trust_Changes for 219 # https://wiki.mozilla.org/CA/Additional_Trust_Changes for
220 # details. 220 # details.
221 221
222 # `The Turkish Government CA is name-constrained to *.tr.' 222 # `The Turkish Government CA is name-constrained to *.tr.'
223 # 223 #
224 # Implemented in Firefox by 224 # Implemented in Firefox by
225 # https://phabricator.services.mozilla.com/D177242, but OpenSSL 225 # https://phabricator.services.mozilla.com/D177242, but OpenSSL
226 # has no mechanism to implement this constraint, so we just 226 # has no mechanism to implement this constraint, so we just
227 # exclude it altogether. 227 # exclude it altogether.
228 special_distrust["TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1"] = 1 228 special_distrust["TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1"] = 1
229} 229}
230 230
231END { 231END {
232 # Make sure the special cases have been applied. 232 # Make sure the special cases have been applied.
233 for (label in special_distrust) 233 for (label in special_distrust)
234 err("special distrust not found: %s.pem", label) 234 err("special distrust not found: %s.pem", label)
235 235
236 fflush() # flush all 236 fflush() # flush all
237 close(SERVERTRUST) 237 close(SERVERTRUST)
238 close(EMAILTRUST) 238 close(EMAILTRUST)
239 close(CODETRUST) 239 close(CODETRUST)
240 if (errors) { 240 if (errors) {
241 printf "%s: exiting with failure on %d error%s\n", ARGV[0], \ 241 printf "%s: exiting with failure on %d error%s\n", ARGV[0], \
242 errors, (errors == 1 ? "" : "s") \ 242 errors, (errors == 1 ? "" : "s") \
243 >"/dev/stderr" 243 >"/dev/stderr"
244 exit 1 244 exit 1
245 } 245 }
246} 246}
247 247
248/^ *#/ { # comment 248/^ *#/ { # comment
249 next 249 next
250} 250}
251 251
252/^ *$/ { 252/^ *$/ {
253 next 253 next
254} 254}
255 255
256$1 == "BEGINDATA" { 256$1 == "BEGINDATA" {
257 next 257 next
258} 258}
259 259
260$1 == "CKA_CLASS" { 260$1 == "CKA_CLASS" {
261 reset() 261 reset()
262} 262}
263 263
264skipping { 264skipping {
265 if (VERBOSE) 265 if (VERBOSE)
266 printf "line %d: skipping: %s\n", NR, $0 266 printf "line %d: skipping: %s\n", NR, $0
267 next 267 next
268} 268}
269 269
270$1 == "CKA_CLASS" && $2 != "CK_OBJECT_CLASS" { 270$1 == "CKA_CLASS" && $2 != "CK_OBJECT_CLASS" {
271 err(sprintf("Invalid class: %s", $2)) 271 err(sprintf("Invalid class: %s", $2))
272 skip() 272 skip()
273 next 273 next
274} 274}
275 275
276$1 == "CKA_CLASS" && $3 == "CKO_NSS_BUILTIN_ROOT_LIST" { 276$1 == "CKA_CLASS" && $3 == "CKO_NSS_BUILTIN_ROOT_LIST" {
277 skip() 277 skip()
278 next 278 next
279} 279}
280 280
281$1 == "CKA_CLASS" { 281$1 == "CKA_CLASS" {
282 cka_class = $3 282 cka_class = $3
283 next 283 next
284} 284}
285 285
286$1 == "CKA_TOKEN" || 286$1 == "CKA_TOKEN" ||
287$1 == "CKA_NSS_MOZILLA_CA_POLICY" || 287$1 == "CKA_NSS_MOZILLA_CA_POLICY" ||
2880 { 2880 {
289 if ($2 != "CK_BBOOL") { 289 if ($2 != "CK_BBOOL") {
290 err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3)) 290 err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3))
291 next 291 next
292 } 292 }
293 if ($3 != "CK_TRUE") 293 if ($3 != "CK_TRUE")
294 err(sprintf("%s is false", $1)) 294 err(sprintf("%s is false", $1))
295 next 295 next
296} 296}
297 297
298$1 == "CKA_MODIFIABLE" || 298$1 == "CKA_MODIFIABLE" ||
299$1 == "CKA_PRIVATE" || 299$1 == "CKA_PRIVATE" ||
300$1 == "CKA_TRUST_STEP_UP_APPROVED" || 300$1 == "CKA_TRUST_STEP_UP_APPROVED" ||
3010 { 3010 {
302 if ($2 != "CK_BBOOL") { 302 if ($2 != "CK_BBOOL") {
303 err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3)) 303 err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3))
304 next 304 next
305 } 305 }
306 if ($3 != "CK_FALSE") 306 if ($3 != "CK_FALSE")
307 err(sprintf("%s is true", $1)) 307 err(sprintf("%s is true", $1))
308 next 308 next
309} 309}
310 310
311$1 == "CKA_LABEL" { 311$1 == "CKA_LABEL" {
312 if ($2 != "UTF8") { 312 if ($2 != "UTF8") {
313 err(sprintf("Non-UTF8 label type: %s; value: %s", $2, $3)) 313 err(sprintf("Non-UTF8 label type: %s; value: %s", $2, $3))
314 skip() 314 skip()
315 next 315 next
316 } 316 }
317 317
318 # Clear the `CKA_LABEL UTF8' fields. (`shift 2', in sh, except 318 # Clear the `CKA_LABEL UTF8' fields. (`shift 2', in sh, except
319 # that doesn't work here in awk.) 319 # that doesn't work here in awk.)
320 sub(/CKA_LABEL +UTF8 +/, "", $0) 320 sub(/CKA_LABEL +UTF8 +/, "", $0)
321 321
322 # Forbid embedded ", \, and /, as well as bunch of others. 322 # Forbid embedded ", \, and /, as well as bunch of others.
323 # 323 #
324 # - We forbid embedded " because it's not clear what the escape 324 # - We forbid embedded " because it's not clear what the escape
325 # sequence is. 325 # sequence is.
326 # 326 #
327 # - We forbid \ in case there are escape sequences we don't 327 # - We forbid \ in case there are escape sequences we don't
328 # know. 328 # know.
329 # 329 #
330 # - We forbid / so that we can always form a directory 330 # - We forbid / so that we can always form a directory
331 # component 331 # component
332 # 332 #
333 # We immediately forbid a bunch of others that might be 333 # We immediately forbid a bunch of others that might be
334 # metacharacters or otherwise problematic, so that the next 334 # metacharacters or otherwise problematic, so that the next
335 # person to update certdata will be forced to consciously think 335 # person to update certdata will be forced to consciously think
336 # about how to handle them. 336 # about how to handle them.
337 if ($0 !~ /^"[^[:cntrl:]!"#$%&\*\/:;?\[\\\]\^`\|~]*"$/) { 337 if ($0 !~ /^"[^[:cntrl:]!"#$%&\*\/:;?\[\\\]\^`\|~]*"$/) {
338 err(sprintf("Invalid characters in label: %s", $3)) 338 err(sprintf("Invalid characters in label: %s", $3))
339 skip() 339 skip()
340 next 340 next
341 } 341 }
342 342
343 # Nix the "quotes". 343 # Nix the "quotes".
344 label = substr($0, 2, length($0) - 2) 344 label = substr($0, 2, length($0) - 2)
345 345
346 # XXX The `renaming to' messages are inconsistent about whether 346 # XXX The `renaming to' messages are inconsistent about whether
347 # they apply pre-substitution or post-substitution, so some 347 # they apply pre-substitution or post-substitution, so some
348 # have spaces and some have underscores. Oh well. 348 # have spaces and some have underscores. Oh well.
349 349
350 # Special cases: Avoid parentheses in two CA names, and 350 # Special cases: Avoid parentheses in two CA names, and
351 # non-US-ASCII in one CA name. It is regrettable to limit 351 # non-US-ASCII in one CA name. It is regrettable to limit
352 # ourselves to an anglocentric worldview like this, but this 352 # ourselves to an anglocentric worldview like this, but this
353 # will avoid potential problems with file system pathname 353 # will avoid potential problems with file system pathname
354 # encoding and canonicalization downstream. 354 # encoding and canonicalization downstream.
355 if (label ~ /^NetLock Arany \(Class Gold\) F.*$/) { 355 if (label ~ /^NetLock Arany \(Class Gold\) F.*$/) {
356 label = "NetLock Arany Class Gold" 356 label = "NetLock Arany Class Gold"
357 if (cka_class == "CKO_CERTIFICATE") { 357 if (cka_class == "CKO_CERTIFICATE") {
358 printf "line %s: special characters," \ 358 printf "line %s: special characters," \
359 " renaming to \"%s\"\n", \ 359 " renaming to \"%s\"\n", \
360 NR, label 360 NR, label
361 } 361 }
362 } 362 }
363 if (label == "LAWtrust Root CA2 (4096)") { 363 if (label == "LAWtrust Root CA2 (4096)") {
364 label = "LAWtrust Root CA2 4096" 364 label = "LAWtrust Root CA2 4096"
365 if (cka_class == "CKO_CERTIFICATE") { 365 if (cka_class == "CKO_CERTIFICATE") {
366 printf "line %s: special characters," \ 366 printf "line %s: special characters," \
367 " renaming to \"%s\"\n", \ 367 " renaming to \"%s\"\n", \
368 NR, label 368 NR, label
369 } 369 }
370 } 370 }
371 371
372 # Avoid spaces in filenames, because Unix. Not that filenames 372 # Avoid spaces in filenames, because Unix. Not that filenames
373 # can't have spaces in Unix, but a lot of downstream tools may 373 # can't have spaces in Unix, but a lot of downstream tools may
374 # get confused by them. 374 # get confused by them.
375 gsub(/ /, "_", label) 375 gsub(/ /, "_", label)
376 376
377 # Make sure it uses onlypathname-safe characters. 377 # Make sure it uses onlypathname-safe characters.
378 if (label ~ /[^[:alnum:]._-]/ || label ~ /^\./) { 378 if (label ~ /[^[:alnum:]._-]/ || label ~ /^\./) {
379 err(sprintf("Special CA label: %s", label)) 379 err(sprintf("Special CA label: %s", label))
380 skip() 380 skip()
381 next 381 next
382 } 382 }
383 383
384 # Make sure it's not empty. 384 # Make sure it's not empty.
385 if (length(label) == 0) { 385 if (length(label) == 0) {
386 err("Empty label") 386 err("Empty label")
387 skip() 387 skip()
388 next 388 next
389 } 389 }
390 390
391 # Make sure it fits within a reasonable limit as a filename. 391 # Make sure it fits within a reasonable limit as a filename.
392 if (length(label) > 100) { 392 if (length(label) > 100) {
393 err(sprintf("Label too long, %d bytes > max %d: %s", 393 err(sprintf("Label too long, %d bytes > max %d: %s",
394 length(label), 100, label)) 394 length(label), 100, label))
395 skip() 395 skip()
396 next 396 next
397 } 397 }
398 398
399 # If this defines the certificate, check for duplicates; if a 399 # If this defines the certificate, check for duplicates; if a
400 # duplicate is found, assign a counter suffix. 400 # duplicate is found, assign a counter suffix.
401 # 401 #
402 # XXX This collision numbering might not be stable across 402 # XXX This collision numbering might not be stable across
403 # updates. What to do? Use the serial number? 403 # updates. What to do? Use the serial number?
404 # 404 #
405 # XXX This doesn't use Unicode case-folding. Let's hope we 405 # XXX This doesn't use Unicode case-folding. Let's hope we
406 # don't have anything that is a collision under casefold but 406 # don't have anything that is a collision under casefold but
407 # not under US-ASCII-limited tolower. 407 # not under US-ASCII-limited tolower.
408 lolab = tolower(label) 408 lolab = tolower(label)
409 if (cka_class == "CKO_CERTIFICATE") { 409 if (cka_class == "CKO_CERTIFICATE") {
410 if (VERBOSE) 410 if (VERBOSE)
411 printf "line %d: CA \"%s\"\n", NR, label 411 printf "line %d: CA \"%s\"\n", NR, label
412 if (lolab in label_lineno) { 412 if (lolab in label_lineno) {
413 label = sprintf("%s.%d", label, ++label_counter[lolab]) 413 label = sprintf("%s.%d", label, ++label_counter[lolab])
414 lolab = tolower(label) 414 lolab = tolower(label)
415 printf "line %s: duplicate, renaming to \"%s\"\n", \ 415 printf "line %s: duplicate, renaming to \"%s\"\n", \
416 NR, label 416 NR, label
417 } 417 }
418 label_lineno[lolab] = NR 418 label_lineno[lolab] = NR
419 } else { 419 } else {
420 if (VERBOSE) 420 if (VERBOSE)
421 printf "line %d: trust \"%s\"\n", NR, label 421 printf "line %d: trust \"%s\"\n", NR, label
422 # Hack: Take the highest-numbered counter for this label. 422 # Hack: Take the highest-numbered counter for this label.
423 if (lolab in label_counter) { 423 if (lolab in label_counter) {
424 label = sprintf("%s.%d", label, label_counter[lolab]) 424 label = sprintf("%s.%d", label, label_counter[lolab])
425 lolab = tolower(label) 425 lolab = tolower(label)
426 printf "line %s: assuming duplicate is \"%s\"\n", \ 426 printf "line %s: assuming duplicate is \"%s\"\n", \
427 NR, label 427 NR, label
428 } 428 }
429 if (!(lolab in label_lineno)) { 429 if (!(lolab in label_lineno)) {
430 err(snprintf("Missing label: %s", label)) 430 err(sprintf("Missing label: %s", label))
431 skip() 431 skip()
432 next 432 next
433 } 433 }
434 } 434 }
435 435
436 # Apply special cases. 436 # Apply special cases.
437 if (cka_class == "CKO_CERTIFICATE") { 437 if (cka_class == "CKO_CERTIFICATE") {
438 if (label in special_distrust) { 438 if (label in special_distrust) {
439 printf "line %s: specially distrusting \"%s\"\n", \ 439 printf "line %s: specially distrusting \"%s\"\n", \
440 NR, label 440 NR, label
441 distrusted[lolab] = 1 441 distrusted[lolab] = 1
442 delete special_distrust[label] 442 delete special_distrust[label]
443 } 443 }
444 } 444 }
445 445
446 # Compute where this certificate will lives and a workspace. 446 # Compute where this certificate will lives and a workspace.
447 certpem = CERTDIR"/"label".pem" 447 certpem = CERTDIR"/"label".pem"
448 certworkdir = WORKDIR"/"label 448 certworkdir = WORKDIR"/"label
449 449
450 # If this defines the certificate, create the directory. 450 # If this defines the certificate, create the directory.
451 # Otherwise, make sure the directory is there already. 451 # Otherwise, make sure the directory is there already.
452 if (cka_class == "CKO_CERTIFICATE") { 452 if (cka_class == "CKO_CERTIFICATE") {
453 if (system(sprintf("mkdir -- %s", quotify(certworkdir))) \ 453 if (system(sprintf("mkdir -- %s", quotify(certworkdir))) \
454 != 0) { 454 != 0) {
455 errors++ 455 errors++
456 skip() 456 skip()
457 next 457 next
458 } 458 }
459 } else { 459 } else {
460 if (system(sprintf("test -f %s", quotify(certpem))) != 0) { 460 if (system(sprintf("test -f %s", quotify(certpem))) != 0) {
461 err("%s: Missing certificate for %s", label, 461 err("%s: Missing certificate for %s", label,
462 cka_class) 462 cka_class)
463 } 463 }
464 if (system(sprintf("test -d %s", quotify(certworkdir))) != 0) 464 if (system(sprintf("test -d %s", quotify(certworkdir))) != 0)
465 err("%s: Missing directory for %s", label, cka_class) 465 err("%s: Missing directory for %s", label, cka_class)
466 } 466 }
467 467
468 next 468 next
469} 469}
470 470
471# Remaining rules assume we are in the middle of an object block and we 471# Remaining rules assume we are in the middle of an object block and we
472# have a label. 472# have a label.
473 473
474!label { 474!label {
475 err(sprintf("%s: missing label", $1)) 475 err(sprintf("%s: missing label", $1))
476 skip() 476 skip()
477 next 477 next
478} 478}
479 479
480$1 == "CKA_CERTIFICATE_TYPE" { 480$1 == "CKA_CERTIFICATE_TYPE" {
481 if ($2 != "CK_CERTIFICATE_TYPE") { 481 if ($2 != "CK_CERTIFICATE_TYPE") {
482 err(sprintf("%s: Invalid certificate type type: %s", 482 err(sprintf("%s: Invalid certificate type type: %s",
483 label, $2)) 483 label, $2))
484 skip() 484 skip()
485 next 485 next
486 } 486 }
487 if ($3 != "CKC_X_509") { 487 if ($3 != "CKC_X_509") {
488 err(sprintf("%s: Unknown certificate type: %s", label, $2)) 488 err(sprintf("%s: Unknown certificate type: %s", label, $2))
489 skip() 489 skip()
490 next 490 next
491 } 491 }
492 next 492 next
493} 493}
494 494
495$1 == "CKA_SUBJECT" { 495$1 == "CKA_SUBJECT" {
496 writeoctaldata(certworkdir"/subject", "subject") 496 writeoctaldata(certworkdir"/subject", "subject")
497 next 497 next
498} 498}
499 499
500$1 == "CKA_ID" { 500$1 == "CKA_ID" {
501 if ($0 != "CKA_ID UTF8 \"0\"") { 501 if ($0 != "CKA_ID UTF8 \"0\"") {
502 err(sprintf("%s: Invalid id: %s", label, $0)) 502 err(sprintf("%s: Invalid id: %s", label, $0))
503 skip() 503 skip()
504 next 504 next
505 } 505 }
506 next 506 next
507} 507}
508 508
509$1 == "CKA_ISSUER" { 509$1 == "CKA_ISSUER" {
510 writecheckoctaldata(certworkdir"/issuer", "issuer", 510 writecheckoctaldata(certworkdir"/issuer", "issuer",
511 cka_class == "CKO_CERTIFICATE") 511 cka_class == "CKO_CERTIFICATE")
512 next 512 next
513} 513}
514 514
515$1 == "CKA_SERIAL_NUMBER" { 515$1 == "CKA_SERIAL_NUMBER" {
516 writecheckoctaldata(certworkdir"/serial", "serial number", 516 writecheckoctaldata(certworkdir"/serial", "serial number",
517 cka_class == "CKO_CERTIFICATE") 517 cka_class == "CKO_CERTIFICATE")
518 next 518 next
519} 519}
520 520
521$1 == "CKA_VALUE" { 521$1 == "CKA_VALUE" {
522 if (writeoctaldata(certworkdir"/cert.der", "certificate data")) 522 if (writeoctaldata(certworkdir"/cert.der", "certificate data"))
523 next 523 next
524 if (system(sprintf("%s x509 -inform DER -outform PEM <%s >%s", 524 if (system(sprintf("%s x509 -inform DER -outform PEM <%s >%s",
525 quotify(OPENSSL), 525 quotify(OPENSSL),
526 quotify(certworkdir"/cert.der"), 526 quotify(certworkdir"/cert.der"),
527 quotify(certpem)))) 527 quotify(certpem))))
528 err(sprintf("%s: openssl x509 failed", label)) 528 err(sprintf("%s: openssl x509 failed", label))
529 next 529 next
530} 530}
531 531
532$1 == "CKA_CERT_SHA1_HASH" { 532$1 == "CKA_CERT_SHA1_HASH" {
533 writeoctaldata(certworkdir"/hash.sha1", "SHA-1 hash") 533 writeoctaldata(certworkdir"/hash.sha1", "SHA-1 hash")
534 next 534 next
535} 535}
536 536
537$1 == "CKA_CERT_MD5_HASH" { 537$1 == "CKA_CERT_MD5_HASH" {
538 writeoctaldata(certworkdir"/hash.md5", "MD5 hash") 538 writeoctaldata(certworkdir"/hash.md5", "MD5 hash")
539 next 539 next
540} 540}
541 541
542$1 == "CKA_NSS_SERVER_DISTRUST_AFTER" { 542$1 == "CKA_NSS_SERVER_DISTRUST_AFTER" {
543 distrust_after("server") 543 distrust_after("server")
544 next 544 next
545} 545}
546 546
547$1 == "CKA_NSS_EMAIL_DISTRUST_AFTER" { 547$1 == "CKA_NSS_EMAIL_DISTRUST_AFTER" {
548 distrust_after("email") 548 distrust_after("email")
549 next 549 next
550} 550}
551 551
552$1 !~ /^CKA_TRUST_/ { 552$1 !~ /^CKA_TRUST_/ {
553 err(sprintf("%s: Unknown line: %s", label, $0)) 553 err(sprintf("%s: Unknown line: %s", label, $0))
554 skip() 554 skip()
555 next 555 next
556} 556}
557 557
558$2 != "CK_TRUST" { 558$2 != "CK_TRUST" {
559 err(sprintf("%s: Invalid trust line: %s", label, $0)) 559 err(sprintf("%s: Invalid trust line: %s", label, $0))
560 skip() 560 skip()
561 next 561 next
562} 562}
563 563
564# Remaining rules assume we are on a valid CKA_TRUST_* attribute. 564# Remaining rules assume we are on a valid CKA_TRUST_* attribute.
565 565
566$1 == "CKA_TRUST_SERVER_AUTH" { 566$1 == "CKA_TRUST_SERVER_AUTH" {
567 addtrust(SERVERTRUST, "server authentication") 567 addtrust(SERVERTRUST, "server authentication")
568 next 568 next
569} 569}
570 570
571$1 == "CKA_TRUST_EMAIL_PROTECTION" { 571$1 == "CKA_TRUST_EMAIL_PROTECTION" {
572 addtrust(EMAILTRUST, "email protection") 572 addtrust(EMAILTRUST, "email protection")
573 next 573 next
574} 574}
575 575
576$1 == "CKA_TRUST_CODE_SIGNING" { 576$1 == "CKA_TRUST_CODE_SIGNING" {
577 addtrust(CODETRUST, "code signing") 577 addtrust(CODETRUST, "code signing")
578 next 578 next
579} 579}
580 580
581{ 581{
582 err(sprintf("%s: Unknown trust domain: %s", label, $1)) 582 err(sprintf("%s: Unknown trust domain: %s", label, $1))
583} 583}