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