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