certdata.awk revision 1.1 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.1 riastrad if ($3 == "CKT_NSS_TRUSTED" || $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.1 riastrad } else if ($3 == "CKT_NSS_MUST_VERIFY_TRUST" ||
177 1.1 riastrad $3 == "CKT_NSS_UNTRUSTED" ||
178 1.1 riastrad $3 == "CKT_NSS_NOT_TRUSTED") {
179 1.1 riastrad if (VERBOSE) {
180 1.1 riastrad printf "line %d: untrusted for %s\n", \
181 1.1 riastrad NR, desc
182 1.1 riastrad }
183 1.1 riastrad } else {
184 1.1 riastrad err(sprintf("%s: Unknown trust designation for %s: %s",
185 1.1 riastrad label, desc, $3))
186 1.1 riastrad }
187 1.1 riastrad }
188 1.1 riastrad
189 1.1 riastrad
190 1.1 riastrad BEGIN {
191 1.1 riastrad if (ARGV[0] == "awk")
192 1.1 riastrad ARGV[0] = "certdata"
193 1.1 riastrad if (!CERTDIR) {
194 1.1 riastrad printf "%s: specify -v CERTDIR=...", ARGV[0] >"/dev/stderr"
195 1.1 riastrad exit 1
196 1.1 riastrad }
197 1.1 riastrad if (!WORKDIR) {
198 1.1 riastrad printf "%s: specify -v WORKDIR=...", ARGV[0] >"/dev/stderr"
199 1.1 riastrad exit 1
200 1.1 riastrad }
201 1.1 riastrad if (!OPENSSL) {
202 1.1 riastrad printf "%s: specify -v OPENSSL=...", ARGV[0] >"/dev/stderr"
203 1.1 riastrad exit 1
204 1.1 riastrad }
205 1.1 riastrad if (!SERVERTRUST)
206 1.1 riastrad SERVERTRUST = "/dev/null"
207 1.1 riastrad if (!EMAILTRUST)
208 1.1 riastrad EMAILTRUST = "/dev/null"
209 1.1 riastrad if (!CODETRUST)
210 1.1 riastrad CODETRUST = "/dev/null"
211 1.1 riastrad printf "" >SERVERTRUST
212 1.1 riastrad printf "" >EMAILTRUST
213 1.1 riastrad printf "" >CODETRUST
214 1.1 riastrad errors = 0
215 1.1 riastrad reset()
216 1.1 riastrad
217 1.1 riastrad # Special cases. See
218 1.1 riastrad # https://wiki.mozilla.org/CA/Additional_Trust_Changes for
219 1.1 riastrad # details.
220 1.1 riastrad
221 1.1 riastrad # `The Turkish Government CA is name-constrained to *.tr.'
222 1.1 riastrad #
223 1.1 riastrad # Implemented in Firefox by
224 1.1 riastrad # https://phabricator.services.mozilla.com/D177242, but OpenSSL
225 1.1 riastrad # has no mechanism to implement this constraint, so we just
226 1.1 riastrad # exclude it altogether.
227 1.1 riastrad special_distrust["TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1"] = 1
228 1.1 riastrad }
229 1.1 riastrad
230 1.1 riastrad END {
231 1.1 riastrad # Make sure the special cases have been applied.
232 1.1 riastrad for (label in special_distrust)
233 1.1 riastrad err("special distrust not found: %s.pem", label)
234 1.1 riastrad
235 1.1 riastrad fflush() # flush all
236 1.1 riastrad close(SERVERTRUST)
237 1.1 riastrad close(EMAILTRUST)
238 1.1 riastrad close(CODETRUST)
239 1.1 riastrad if (errors) {
240 1.1 riastrad printf "%s: exiting with failure on %d error%s\n", ARGV[0], \
241 1.1 riastrad errors, (errors == 1 ? "" : "s") \
242 1.1 riastrad >"/dev/stderr"
243 1.1 riastrad exit 1
244 1.1 riastrad }
245 1.1 riastrad }
246 1.1 riastrad
247 1.1 riastrad /^ *#/ { # comment
248 1.1 riastrad next
249 1.1 riastrad }
250 1.1 riastrad
251 1.1 riastrad /^ *$/ {
252 1.1 riastrad next
253 1.1 riastrad }
254 1.1 riastrad
255 1.1 riastrad $1 == "BEGINDATA" {
256 1.1 riastrad next
257 1.1 riastrad }
258 1.1 riastrad
259 1.1 riastrad $1 == "CKA_CLASS" {
260 1.1 riastrad reset()
261 1.1 riastrad }
262 1.1 riastrad
263 1.1 riastrad skipping {
264 1.1 riastrad if (VERBOSE)
265 1.1 riastrad printf "line %d: skipping: %s\n", NR, $0
266 1.1 riastrad next
267 1.1 riastrad }
268 1.1 riastrad
269 1.1 riastrad $1 == "CKA_CLASS" && $2 != "CK_OBJECT_CLASS" {
270 1.1 riastrad err(sprintf("Invalid class: %s", $2))
271 1.1 riastrad skip()
272 1.1 riastrad next
273 1.1 riastrad }
274 1.1 riastrad
275 1.1 riastrad $1 == "CKA_CLASS" && $3 == "CKO_NSS_BUILTIN_ROOT_LIST" {
276 1.1 riastrad skip()
277 1.1 riastrad next
278 1.1 riastrad }
279 1.1 riastrad
280 1.1 riastrad $1 == "CKA_CLASS" {
281 1.1 riastrad cka_class = $3
282 1.1 riastrad next
283 1.1 riastrad }
284 1.1 riastrad
285 1.1 riastrad $1 == "CKA_TOKEN" ||
286 1.1 riastrad $1 == "CKA_NSS_MOZILLA_CA_POLICY" ||
287 1.1 riastrad 0 {
288 1.1 riastrad if ($2 != "CK_BBOOL") {
289 1.1 riastrad err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3))
290 1.1 riastrad next
291 1.1 riastrad }
292 1.1 riastrad if ($3 != "CK_TRUE")
293 1.1 riastrad err(sprintf("%s is false", $1))
294 1.1 riastrad next
295 1.1 riastrad }
296 1.1 riastrad
297 1.1 riastrad $1 == "CKA_MODIFIABLE" ||
298 1.1 riastrad $1 == "CKA_PRIVATE" ||
299 1.1 riastrad $1 == "CKA_TRUST_STEP_UP_APPROVED" ||
300 1.1 riastrad 0 {
301 1.1 riastrad if ($2 != "CK_BBOOL") {
302 1.1 riastrad err(sprintf("Invalid %s type: %s; value: %s", $1, $2, $3))
303 1.1 riastrad next
304 1.1 riastrad }
305 1.1 riastrad if ($3 != "CK_FALSE")
306 1.1 riastrad err(sprintf("%s is true", $1))
307 1.1 riastrad next
308 1.1 riastrad }
309 1.1 riastrad
310 1.1 riastrad $1 == "CKA_LABEL" {
311 1.1 riastrad if ($2 != "UTF8") {
312 1.1 riastrad err(sprintf("Non-UTF8 label type: %s; value: %s", $2, $3))
313 1.1 riastrad skip()
314 1.1 riastrad next
315 1.1 riastrad }
316 1.1 riastrad
317 1.1 riastrad # Clear the `CKA_LABEL UTF8' fields. (`shift 2', in sh, except
318 1.1 riastrad # that doesn't work here in awk.)
319 1.1 riastrad sub(/CKA_LABEL +UTF8 +/, "", $0)
320 1.1 riastrad
321 1.1 riastrad # Forbid embedded ", \, and /, as well as bunch of others.
322 1.1 riastrad #
323 1.1 riastrad # - We forbid embedded " because it's not clear what the escape
324 1.1 riastrad # sequence is.
325 1.1 riastrad #
326 1.1 riastrad # - We forbid \ in case there are escape sequences we don't
327 1.1 riastrad # know.
328 1.1 riastrad #
329 1.1 riastrad # - We forbid / so that we can always form a directory
330 1.1 riastrad # component
331 1.1 riastrad #
332 1.1 riastrad # We immediately forbid a bunch of others that might be
333 1.1 riastrad # metacharacters or otherwise problematic, so that the next
334 1.1 riastrad # person to update certdata will be forced to consciously think
335 1.1 riastrad # about how to handle them.
336 1.1 riastrad if ($0 !~ /^"[^[:cntrl:]!"#$%&\*\/:;?\[\\\]\^`\|~]*"$/) {
337 1.1 riastrad err(sprintf("Invalid characters in label: %s", $3))
338 1.1 riastrad skip()
339 1.1 riastrad next
340 1.1 riastrad }
341 1.1 riastrad
342 1.1 riastrad # Nix the "quotes".
343 1.1 riastrad label = substr($0, 2, length($0) - 2)
344 1.1 riastrad
345 1.1 riastrad # XXX The `renaming to' messages are inconsistent about whether
346 1.1 riastrad # they apply pre-substitution or post-substitution, so some
347 1.1 riastrad # have spaces and some have underscores. Oh well.
348 1.1 riastrad
349 1.1 riastrad # Special cases: Avoid parentheses in two CA names, and
350 1.1 riastrad # non-US-ASCII in one CA name. It is regrettable to limit
351 1.1 riastrad # ourselves to an anglocentric worldview like this, but this
352 1.1 riastrad # will avoid potential problems with file system pathname
353 1.1 riastrad # encoding and canonicalization downstream.
354 1.1 riastrad if (label ~ /^NetLock Arany \(Class Gold\) F.*$/) {
355 1.1 riastrad label = "NetLock Arany Class Gold"
356 1.1 riastrad if (cka_class == "CKO_CERTIFICATE") {
357 1.1 riastrad printf "line %s: special characters," \
358 1.1 riastrad " renaming to \"%s\"\n", \
359 1.1 riastrad NR, label
360 1.1 riastrad }
361 1.1 riastrad }
362 1.1 riastrad if (label == "LAWtrust Root CA2 (4096)") {
363 1.1 riastrad label = "LAWtrust Root CA2 4096"
364 1.1 riastrad if (cka_class == "CKO_CERTIFICATE") {
365 1.1 riastrad printf "line %s: special characters," \
366 1.1 riastrad " renaming to \"%s\"\n", \
367 1.1 riastrad NR, label
368 1.1 riastrad }
369 1.1 riastrad }
370 1.1 riastrad
371 1.1 riastrad # Avoid spaces in filenames, because Unix. Not that filenames
372 1.1 riastrad # can't have spaces in Unix, but a lot of downstream tools may
373 1.1 riastrad # get confused by them.
374 1.1 riastrad gsub(/ /, "_", label)
375 1.1 riastrad
376 1.1 riastrad # Make sure it uses onlypathname-safe characters.
377 1.1 riastrad if (label ~ /[^[:alnum:]._-]/ || label ~ /^\./) {
378 1.1 riastrad err(sprintf("Special CA label: %s", label))
379 1.1 riastrad skip()
380 1.1 riastrad next
381 1.1 riastrad }
382 1.1 riastrad
383 1.1 riastrad # Make sure it's not empty.
384 1.1 riastrad if (length(label) == 0) {
385 1.1 riastrad err("Empty label")
386 1.1 riastrad skip()
387 1.1 riastrad next
388 1.1 riastrad }
389 1.1 riastrad
390 1.1 riastrad # Make sure it fits within a reasonable limit as a filename.
391 1.1 riastrad if (length(label) > 100) {
392 1.1 riastrad err(sprintf("Label too long, %d bytes > max %d: %s",
393 1.1 riastrad length(label), 100, label))
394 1.1 riastrad skip()
395 1.1 riastrad next
396 1.1 riastrad }
397 1.1 riastrad
398 1.1 riastrad # If this defines the certificate, check for duplicates; if a
399 1.1 riastrad # duplicate is found, assign a counter suffix.
400 1.1 riastrad #
401 1.1 riastrad # XXX This collision numbering might not be stable across
402 1.1 riastrad # updates. What to do? Use the serial number?
403 1.1 riastrad #
404 1.1 riastrad # XXX This doesn't use Unicode case-folding. Let's hope we
405 1.1 riastrad # don't have anything that is a collision under casefold but
406 1.1 riastrad # not under US-ASCII-limited tolower.
407 1.1 riastrad lolab = tolower(label)
408 1.1 riastrad if (cka_class == "CKO_CERTIFICATE") {
409 1.1 riastrad if (VERBOSE)
410 1.1 riastrad printf "line %d: CA \"%s\"\n", NR, label
411 1.1 riastrad if (lolab in label_lineno) {
412 1.1 riastrad label = sprintf("%s.%d", label, ++label_counter[lolab])
413 1.1 riastrad lolab = tolower(label)
414 1.1 riastrad printf "line %s: duplicate, renaming to \"%s\"\n", \
415 1.1 riastrad NR, label
416 1.1 riastrad }
417 1.1 riastrad label_lineno[lolab] = NR
418 1.1 riastrad } else {
419 1.1 riastrad if (VERBOSE)
420 1.1 riastrad printf "line %d: trust \"%s\"\n", NR, label
421 1.1 riastrad # Hack: Take the highest-numbered counter for this label.
422 1.1 riastrad if (lolab in label_counter) {
423 1.1 riastrad label = sprintf("%s.%d", label, label_counter[lolab])
424 1.1 riastrad lolab = tolower(label)
425 1.1 riastrad printf "line %s: assuming duplicate is \"%s\"\n", \
426 1.1 riastrad NR, label
427 1.1 riastrad }
428 1.1 riastrad if (!(lolab in label_lineno)) {
429 1.1 riastrad err(snprintf("Missing label: %s", label))
430 1.1 riastrad skip()
431 1.1 riastrad next
432 1.1 riastrad }
433 1.1 riastrad }
434 1.1 riastrad
435 1.1 riastrad # Apply special cases.
436 1.1 riastrad if (cka_class == "CKO_CERTIFICATE") {
437 1.1 riastrad if (label in special_distrust) {
438 1.1 riastrad printf "line %s: specially distrusting \"%s\"\n", \
439 1.1 riastrad NR, label
440 1.1 riastrad distrusted[lolab] = 1
441 1.1 riastrad delete special_distrust[label]
442 1.1 riastrad }
443 1.1 riastrad }
444 1.1 riastrad
445 1.1 riastrad # Compute where this certificate will lives and a workspace.
446 1.1 riastrad certpem = CERTDIR"/"label".pem"
447 1.1 riastrad certworkdir = WORKDIR"/"label
448 1.1 riastrad
449 1.1 riastrad # If this defines the certificate, create the directory.
450 1.1 riastrad # Otherwise, make sure the directory is there already.
451 1.1 riastrad if (cka_class == "CKO_CERTIFICATE") {
452 1.1 riastrad if (system(sprintf("mkdir -- %s", quotify(certworkdir))) \
453 1.1 riastrad != 0) {
454 1.1 riastrad errors++
455 1.1 riastrad skip()
456 1.1 riastrad next
457 1.1 riastrad }
458 1.1 riastrad } else {
459 1.1 riastrad if (system(sprintf("test -f %s", quotify(certpem))) != 0) {
460 1.1 riastrad err("%s: Missing certificate for %s", label,
461 1.1 riastrad cka_class)
462 1.1 riastrad }
463 1.1 riastrad if (system(sprintf("test -d %s", quotify(certworkdir))) != 0)
464 1.1 riastrad err("%s: Missing directory for %s", label, cka_class)
465 1.1 riastrad }
466 1.1 riastrad
467 1.1 riastrad next
468 1.1 riastrad }
469 1.1 riastrad
470 1.1 riastrad # Remaining rules assume we are in the middle of an object block and we
471 1.1 riastrad # have a label.
472 1.1 riastrad
473 1.1 riastrad !label {
474 1.1 riastrad err(sprintf("%s: missing label", $1))
475 1.1 riastrad skip()
476 1.1 riastrad next
477 1.1 riastrad }
478 1.1 riastrad
479 1.1 riastrad $1 == "CKA_CERTIFICATE_TYPE" {
480 1.1 riastrad if ($2 != "CK_CERTIFICATE_TYPE") {
481 1.1 riastrad err(sprintf("%s: Invalid certificate type type: %s",
482 1.1 riastrad label, $2))
483 1.1 riastrad skip()
484 1.1 riastrad next
485 1.1 riastrad }
486 1.1 riastrad if ($3 != "CKC_X_509") {
487 1.1 riastrad err(sprintf("%s: Unknown certificate type: %s", label, $2))
488 1.1 riastrad skip()
489 1.1 riastrad next
490 1.1 riastrad }
491 1.1 riastrad next
492 1.1 riastrad }
493 1.1 riastrad
494 1.1 riastrad $1 == "CKA_SUBJECT" {
495 1.1 riastrad writeoctaldata(certworkdir"/subject", "subject")
496 1.1 riastrad next
497 1.1 riastrad }
498 1.1 riastrad
499 1.1 riastrad $1 == "CKA_ID" {
500 1.1 riastrad if ($0 != "CKA_ID UTF8 \"0\"") {
501 1.1 riastrad err(sprintf("%s: Invalid id: %s", label, $0))
502 1.1 riastrad skip()
503 1.1 riastrad next
504 1.1 riastrad }
505 1.1 riastrad next
506 1.1 riastrad }
507 1.1 riastrad
508 1.1 riastrad $1 == "CKA_ISSUER" {
509 1.1 riastrad writecheckoctaldata(certworkdir"/issuer", "issuer",
510 1.1 riastrad cka_class == "CKO_CERTIFICATE")
511 1.1 riastrad next
512 1.1 riastrad }
513 1.1 riastrad
514 1.1 riastrad $1 == "CKA_SERIAL_NUMBER" {
515 1.1 riastrad writecheckoctaldata(certworkdir"/serial", "serial number",
516 1.1 riastrad cka_class == "CKO_CERTIFICATE")
517 1.1 riastrad next
518 1.1 riastrad }
519 1.1 riastrad
520 1.1 riastrad $1 == "CKA_VALUE" {
521 1.1 riastrad if (writeoctaldata(certworkdir"/cert.der", "certificate data"))
522 1.1 riastrad next
523 1.1 riastrad if (system(sprintf("%s x509 -inform DER -outform PEM <%s >%s",
524 1.1 riastrad quotify(OPENSSL),
525 1.1 riastrad quotify(certworkdir"/cert.der"),
526 1.1 riastrad quotify(certpem))))
527 1.1 riastrad err(sprintf("%s: openssl x509 failed", label))
528 1.1 riastrad next
529 1.1 riastrad }
530 1.1 riastrad
531 1.1 riastrad $1 == "CKA_CERT_SHA1_HASH" {
532 1.1 riastrad writeoctaldata(certworkdir"/hash.sha1", "SHA-1 hash")
533 1.1 riastrad next
534 1.1 riastrad }
535 1.1 riastrad
536 1.1 riastrad $1 == "CKA_CERT_MD5_HASH" {
537 1.1 riastrad writeoctaldata(certworkdir"/hash.md5", "MD5 hash")
538 1.1 riastrad next
539 1.1 riastrad }
540 1.1 riastrad
541 1.1 riastrad $1 == "CKA_NSS_SERVER_DISTRUST_AFTER" {
542 1.1 riastrad distrust_after("server")
543 1.1 riastrad next
544 1.1 riastrad }
545 1.1 riastrad
546 1.1 riastrad $1 == "CKA_NSS_EMAIL_DISTRUST_AFTER" {
547 1.1 riastrad distrust_after("email")
548 1.1 riastrad next
549 1.1 riastrad }
550 1.1 riastrad
551 1.1 riastrad $1 !~ /^CKA_TRUST_/ {
552 1.1 riastrad err(sprintf("%s: Unknown line: %s", label, $0))
553 1.1 riastrad skip()
554 1.1 riastrad next
555 1.1 riastrad }
556 1.1 riastrad
557 1.1 riastrad $2 != "CK_TRUST" {
558 1.1 riastrad err(sprintf("%s: Invalid trust line: %s", label, $0))
559 1.1 riastrad skip()
560 1.1 riastrad next
561 1.1 riastrad }
562 1.1 riastrad
563 1.1 riastrad # Remaining rules assume we are on a valid CKA_TRUST_* attribute.
564 1.1 riastrad
565 1.1 riastrad $1 == "CKA_TRUST_SERVER_AUTH" {
566 1.1 riastrad addtrust(SERVERTRUST, "server authentication")
567 1.1 riastrad next
568 1.1 riastrad }
569 1.1 riastrad
570 1.1 riastrad $1 == "CKA_TRUST_EMAIL_PROTECTION" {
571 1.1 riastrad addtrust(EMAILTRUST, "email protection")
572 1.1 riastrad next
573 1.1 riastrad }
574 1.1 riastrad
575 1.1 riastrad $1 == "CKA_TRUST_CODE_SIGNING" {
576 1.1 riastrad addtrust(CODETRUST, "code signing")
577 1.1 riastrad next
578 1.1 riastrad }
579 1.1 riastrad
580 1.1 riastrad {
581 1.1 riastrad err(sprintf("%s: Unknown trust domain: %s", label, $1))
582 1.1 riastrad }
583