pkg.c (21816B)
1 #include <kit/cas.h> 2 #include <kit/core.h> 3 #include <kit/package.h> 4 #include <stddef.h> 5 #include <stdint.h> 6 #include <stdio.h> 7 #include <string.h> 8 9 #include "dist_host.h" 10 #include "driver.h" 11 #include "env.h" 12 13 #define PKG_TOOL "pkg" 14 #define PKG_PATH_BUF 1024u 15 #define PKG_TRUST_LINE_MAX 1024u 16 #define PKG_KEYID_HEX (2u * KIT_PKG_KEYID_LEN + 1u) 17 18 void driver_help_pkg(void) { 19 driver_printf( 20 "kit pkg - signed code distribution\n" 21 "\n" 22 "USAGE\n" 23 " kit pkg keygen -o BASE\n" 24 " kit pkg create --name N --version V [--desc D] -s SECKEY\n" 25 " [--format kpkg|tar.gz] [--compression " 26 "none|lz4-block-v1]\n" 27 " [--native-shape fat|metadata|thin] [--external DIR]\n" 28 " (--cas DIR --tree TREE_ID | --root DIR) -o OUT\n" 29 " kit pkg verify [-p PUBKEY | --tofu] [--format kpkg|tar.gz]\n" 30 " [--external DIR] FILE\n" 31 " kit pkg unpack [--verify] [-p PUBKEY | --tofu] [--format " 32 "kpkg|tar.gz]\n" 33 " [--external DIR] FILE -C DIR\n" 34 " kit pkg inspect [--manifest | --encoding] FILE\n" 35 " kit pkg trust {path | list | add PUBKEY [label] | remove KEYID}\n"); 36 } 37 38 /* ---------------------------------------------------------------------- */ 39 /* small driver-side helpers */ 40 /* ---------------------------------------------------------------------- */ 41 42 static int pkg_read(const KitContext* ctx, const char* path, KitFileData* out) { 43 out->data = NULL; 44 out->size = 0; 45 out->token = NULL; 46 return ctx->file_io->read_all(ctx->file_io->user, path, out) == KIT_OK; 47 } 48 49 static void pkg_release(const KitContext* ctx, KitFileData* fd) { 50 if ((fd->token || fd->data) && ctx->file_io->release) 51 ctx->file_io->release(ctx->file_io->user, fd); 52 } 53 54 static void pkg_parent_dir(const char* path, char* buf, size_t cap) { 55 const char* slash = NULL; 56 const char* p; 57 size_t n; 58 for (p = path; *p; ++p) 59 if (*p == '/') slash = p; 60 if (!slash) { 61 buf[0] = '\0'; 62 return; 63 } 64 n = (size_t)(slash - path); 65 if (n >= cap) n = cap - 1u; 66 memcpy(buf, path, n); 67 buf[n] = '\0'; 68 } 69 70 static int pkg_trust_path(char* buf, size_t cap) { 71 const char* env = driver_getenv("KIT_TRUSTED_KEYS"); 72 const char* home; 73 if (env) { 74 snprintf(buf, cap, "%s", env); 75 return 0; 76 } 77 home = driver_getenv("HOME"); 78 if (!home) return 1; 79 snprintf(buf, cap, "%s/.config/kit/trusted_keys", home); 80 return 0; 81 } 82 83 static KitPkgFormat pkg_parse_format(const char* s) { 84 if (driver_streq(s, "kpkg") || driver_streq(s, "native")) 85 return KIT_PKG_FORMAT_KPKG; 86 if (driver_streq(s, "tar.gz") || driver_streq(s, "portable")) 87 return KIT_PKG_FORMAT_TARGZ; 88 return KIT_PKG_FORMAT_AUTO; 89 } 90 91 static KitPkgFormat pkg_infer_format(const char* path) { 92 if (driver_has_suffix(path, ".tar.gz")) return KIT_PKG_FORMAT_TARGZ; 93 if (driver_has_suffix(path, ".kpkg")) return KIT_PKG_FORMAT_KPKG; 94 return KIT_PKG_FORMAT_AUTO; 95 } 96 97 static int pkg_parse_native_shape(const char* s, KitPkgShape* out) { 98 if (driver_streq(s, "fat")) { 99 *out = KIT_PKG_SHAPE_FAT; 100 return 0; 101 } 102 if (driver_streq(s, "metadata") || driver_streq(s, "metadata-rich")) { 103 *out = KIT_PKG_SHAPE_METADATA; 104 return 0; 105 } 106 if (driver_streq(s, "thin")) { 107 *out = KIT_PKG_SHAPE_THIN; 108 return 0; 109 } 110 return 1; 111 } 112 113 static int pkg_parse_compression(const char* s, KitPkgCompression* out) { 114 if (driver_streq(s, "none")) { 115 *out = KIT_PKG_COMPRESSION_NONE; 116 return 0; 117 } 118 if (driver_streq(s, "lz4-block-v1") || driver_streq(s, "lz4")) { 119 *out = KIT_PKG_COMPRESSION_LZ4_BLOCK_V1; 120 return 0; 121 } 122 return 1; 123 } 124 125 /* ---------------------------------------------------------------------- */ 126 /* keygen */ 127 /* ---------------------------------------------------------------------- */ 128 129 static int pkg_keygen(DriverEnv* env, const KitContext* ctx, int argc, 130 char** argv) { 131 const char* base = NULL; 132 KitWriter *pubw = NULL, *seckw = NULL; 133 uint8_t keyid[KIT_PKG_KEYID_LEN]; 134 char path[PKG_PATH_BUF], hex[PKG_KEYID_HEX]; 135 int i, rc = 1; 136 (void)env; 137 for (i = 0; i < argc; ++i) { 138 if (driver_streq(argv[i], "-o") && i + 1 < argc) 139 base = argv[++i]; 140 else { 141 driver_errf(PKG_TOOL, "keygen: unexpected argument: %s", argv[i]); 142 return 2; 143 } 144 } 145 if (!base) { 146 driver_errf(PKG_TOOL, "keygen: -o BASE is required"); 147 return 2; 148 } 149 snprintf(path, sizeof path, "%s.pub", base); 150 if (ctx->file_io->open_writer(ctx->file_io->user, path, &pubw) != KIT_OK) { 151 driver_errf(PKG_TOOL, "keygen: failed to open output: %s", path); 152 return 1; 153 } 154 snprintf(path, sizeof path, "%s.key", base); 155 if (ctx->file_io->open_writer(ctx->file_io->user, path, &seckw) != KIT_OK) { 156 driver_errf(PKG_TOOL, "keygen: failed to open output: %s", path); 157 kit_writer_close(pubw); 158 return 1; 159 } 160 if (kit_pkg_keygen(ctx, driver_dist_random, NULL, pubw, seckw, keyid) == 161 KIT_OK) 162 rc = 0; 163 kit_writer_close(seckw); 164 kit_writer_close(pubw); 165 if (rc == 0) { 166 kit_hex_encode(hex, keyid, KIT_PKG_KEYID_LEN); 167 driver_printf("wrote %s.pub and %s.key (key id %s)\n", base, base, hex); 168 } 169 return rc; 170 } 171 172 /* ---------------------------------------------------------------------- */ 173 /* create */ 174 /* ---------------------------------------------------------------------- */ 175 176 static int pkg_create(DriverEnv* env, const KitContext* ctx, int argc, 177 char** argv) { 178 KitPkgCreateOptions opts; 179 KitPkgCreateResult result; 180 KitCasHost host; 181 KitFileData skfd; 182 uint8_t sk[KIT_PKG_SK_LEN], keyid[KIT_PKG_KEYID_LEN]; 183 const char* seckey = NULL; 184 char pkgid_hex[2 * KIT_CAS_HASH_LEN + 1]; 185 int i, rc = 1, sk_loaded = 0; 186 187 memset(&opts, 0, sizeof opts); 188 opts.format = KIT_PKG_FORMAT_AUTO; 189 opts.native_shape = KIT_PKG_SHAPE_FAT; 190 opts.compression = KIT_PKG_COMPRESSION_NONE; 191 for (i = 0; i < argc; ++i) { 192 const char* a = argv[i]; 193 if (driver_streq(a, "--name") && i + 1 < argc) 194 opts.name = argv[++i]; 195 else if (driver_streq(a, "--version") && i + 1 < argc) 196 opts.version = argv[++i]; 197 else if (driver_streq(a, "--desc") && i + 1 < argc) 198 opts.description = argv[++i]; 199 else if (driver_streq(a, "-o") && i + 1 < argc) 200 opts.out_path = argv[++i]; 201 else if (driver_streq(a, "-s") && i + 1 < argc) 202 seckey = argv[++i]; 203 else if (driver_streq(a, "--cas") && i + 1 < argc) 204 opts.cas_dir = argv[++i]; 205 else if (driver_streq(a, "--tree") && i + 1 < argc) 206 opts.tree_id = argv[++i]; 207 else if (driver_streq(a, "--root") && i + 1 < argc) 208 opts.root_dir = argv[++i]; 209 else if (driver_streq(a, "--external") && i + 1 < argc) 210 opts.external_dir = argv[++i]; 211 else if (driver_streq(a, "--native-shape") && i + 1 < argc) { 212 if (pkg_parse_native_shape(argv[++i], &opts.native_shape) != 0) { 213 driver_errf(PKG_TOOL, "create: unknown native shape"); 214 return 2; 215 } 216 } else if (driver_streq(a, "--format") && i + 1 < argc) { 217 opts.format = pkg_parse_format(argv[++i]); 218 if (opts.format == KIT_PKG_FORMAT_AUTO) { 219 driver_errf(PKG_TOOL, "create: unknown format"); 220 return 2; 221 } 222 } else if (driver_streq(a, "--compression") && i + 1 < argc) { 223 if (pkg_parse_compression(argv[++i], &opts.compression) != 0) { 224 driver_errf(PKG_TOOL, "create: unknown compression"); 225 return 2; 226 } 227 } else if (a[0] == '-' && a[1] != '\0') { 228 driver_errf(PKG_TOOL, "create: unknown option: %s", a); 229 return 2; 230 } else { 231 driver_errf( 232 PKG_TOOL, 233 "create: positional file inputs were removed; use --root DIR"); 234 return 2; 235 } 236 } 237 if (!opts.name || !opts.version || !opts.out_path || !seckey) { 238 driver_errf(PKG_TOOL, 239 "create: --name, --version, -s SECKEY and -o OUT are required"); 240 return 2; 241 } 242 if ((opts.root_dir != NULL) == 243 (opts.cas_dir != NULL || opts.tree_id != NULL) || 244 (opts.cas_dir && !opts.tree_id) || (opts.tree_id && !opts.cas_dir)) { 245 driver_errf( 246 PKG_TOOL, 247 "create: pass exactly one of --root DIR or --cas DIR --tree TREE_ID"); 248 return 2; 249 } 250 if (opts.format == KIT_PKG_FORMAT_AUTO) 251 opts.format = pkg_infer_format(opts.out_path); 252 if (opts.format == KIT_PKG_FORMAT_AUTO) { 253 driver_errf(PKG_TOOL, "create: cannot infer format; pass --format"); 254 return 2; 255 } 256 if (opts.format != KIT_PKG_FORMAT_KPKG && 257 opts.native_shape != KIT_PKG_SHAPE_FAT) { 258 driver_errf(PKG_TOOL, "create: --native-shape only applies to kpkg"); 259 return 2; 260 } 261 if (opts.format != KIT_PKG_FORMAT_KPKG && opts.external_dir) { 262 driver_errf(PKG_TOOL, "create: --external only applies to kpkg"); 263 return 2; 264 } 265 266 if (!pkg_read(ctx, seckey, &skfd)) { 267 driver_errf(PKG_TOOL, "create: cannot read secret key: %s", seckey); 268 return 1; 269 } 270 sk_loaded = 1; 271 { 272 KitStatus kr = kit_minisig_parse_seckey(skfd.data, skfd.size, sk, keyid); 273 if (kr == KIT_UNSUPPORTED) 274 driver_errf(PKG_TOOL, "create: encrypted secret keys need scrypt"); 275 else if (kr != KIT_OK) 276 driver_errf(PKG_TOOL, "create: malformed secret key: %s", seckey); 277 if (kr != KIT_OK) goto done; 278 } 279 opts.sk = sk; 280 opts.keyid = keyid; 281 282 host = driver_cas_host(env); 283 if (kit_pkg_create(ctx, &host, &opts, &result) == KIT_OK) { 284 kit_hex_encode(pkgid_hex, result.package_id, KIT_CAS_HASH_LEN); 285 driver_printf("wrote %s (%llu file(s), id %s)\n", opts.out_path, 286 (unsigned long long)result.n_files, pkgid_hex); 287 rc = 0; 288 } 289 290 done: 291 if (sk_loaded) pkg_release(ctx, &skfd); 292 return rc; 293 } 294 295 /* ---------------------------------------------------------------------- */ 296 /* verify / unpack */ 297 /* ---------------------------------------------------------------------- */ 298 299 /* Persist a trust-on-first-use pin. Returns 0 on success; nonzero if it could 300 * not be written (no trust path, or I/O failure) — the original tool failed 301 * verification when the pin could not be persisted, so the caller treats a 302 * nonzero return as a verify failure. */ 303 static int pkg_pin_tofu(DriverEnv* env, const KitContext* ctx, 304 const char* tpath, const KitPkgVerifyResult* r) { 305 char line[PKG_TRUST_LINE_MAX], parent[PKG_PATH_BUF], hex[PKG_KEYID_HEX]; 306 KitFileData old; 307 KitWriter* w = NULL; 308 int had_old, ok = 1, wrote = 0; 309 if (!tpath[0]) return 1; 310 kit_hex_encode(hex, r->keyid, KIT_PKG_KEYID_LEN); 311 if (kit_trust_format_entry(line, sizeof line, r->keyid, r->tofu_pk, 312 "tofu-pinned") != KIT_OK) 313 return 1; 314 had_old = pkg_read(ctx, tpath, &old); 315 pkg_parent_dir(tpath, parent, sizeof parent); 316 if (parent[0]) driver_mkdir_p(env, parent); 317 if (ctx->file_io->open_writer(ctx->file_io->user, tpath, &w) == KIT_OK) { 318 if (had_old && old.size) 319 ok = kit_writer_write(w, old.data, old.size) == KIT_OK; 320 if (ok) ok = kit_writer_write(w, line, strlen(line)) == KIT_OK; 321 if (ok && kit_writer_status(w) == KIT_OK) wrote = 1; 322 kit_writer_close(w); 323 } 324 if (had_old) pkg_release(ctx, &old); 325 if (wrote) driver_printf("pkg: tofu-pinned key id %s to %s\n", hex, tpath); 326 return wrote ? 0 : 1; 327 } 328 329 static int pkg_verify_or_unpack(DriverEnv* env, const KitContext* ctx, int argc, 330 char** argv, int unpack) { 331 const char *file = NULL, *pubkey = NULL, *dir = ".", *external_dir = NULL; 332 int tofu = 0, explicit_verify = 0, i, rc = 1; 333 KitPkgFormat fmt = KIT_PKG_FORMAT_AUTO; 334 KitPkgVerifyOptions opts; 335 KitPkgVerifyResult result; 336 KitCasHost host; 337 KitFileData pkgfd, pubfd, trustfd; 338 char tpath[PKG_PATH_BUF]; 339 int pub_loaded = 0, trust_loaded = 0, have_tpath; 340 for (i = 0; i < argc; ++i) { 341 if (driver_streq(argv[i], "-p") && i + 1 < argc) 342 pubkey = argv[++i]; 343 else if (driver_streq(argv[i], "--tofu")) 344 tofu = 1; 345 else if (unpack && driver_streq(argv[i], "--verify")) 346 explicit_verify = 1; 347 else if (driver_streq(argv[i], "--external") && i + 1 < argc) 348 external_dir = argv[++i]; 349 else if (driver_streq(argv[i], "--format") && i + 1 < argc) { 350 fmt = pkg_parse_format(argv[++i]); 351 if (fmt == KIT_PKG_FORMAT_AUTO) { 352 driver_errf(PKG_TOOL, "%s: unknown format", 353 unpack ? "unpack" : "verify"); 354 return 2; 355 } 356 } else if (unpack && driver_streq(argv[i], "-C") && i + 1 < argc) 357 dir = argv[++i]; 358 else if (argv[i][0] != '-') 359 file = argv[i]; 360 else { 361 driver_errf(PKG_TOOL, "%s: unknown option: %s", 362 unpack ? "unpack" : "verify", argv[i]); 363 return 2; 364 } 365 } 366 if (!file) { 367 driver_errf(PKG_TOOL, "%s: FILE is required", unpack ? "unpack" : "verify"); 368 return 2; 369 } 370 if (fmt == KIT_PKG_FORMAT_AUTO) fmt = pkg_infer_format(file); 371 372 if (!pkg_read(ctx, file, &pkgfd)) { 373 driver_errf(PKG_TOOL, "cannot read package: %s", file); 374 return 1; 375 } 376 memset(&opts, 0, sizeof opts); 377 opts.pkg_data = pkgfd.data; 378 opts.pkg_len = pkgfd.size; 379 opts.format = fmt; 380 opts.external_dir = external_dir; 381 opts.unpack_dir = unpack ? dir : NULL; 382 opts.tofu = tofu; 383 if (pubkey) { 384 if (!pkg_read(ctx, pubkey, &pubfd)) { 385 driver_errf(PKG_TOOL, "cannot read public key: %s", pubkey); 386 pkg_release(ctx, &pkgfd); 387 return 1; 388 } 389 pub_loaded = 1; 390 opts.pubkey_bytes = pubfd.data; 391 opts.pubkey_len = pubfd.size; 392 } 393 have_tpath = (pkg_trust_path(tpath, sizeof tpath) == 0); 394 if (!have_tpath) tpath[0] = '\0'; 395 if (have_tpath && !pubkey && pkg_read(ctx, tpath, &trustfd)) { 396 trust_loaded = 1; 397 opts.trusted_keys = trustfd.data; 398 opts.trusted_keys_len = trustfd.size; 399 } 400 401 host = driver_cas_host(env); 402 if (kit_pkg_verify(ctx, &host, &opts, &result) == KIT_OK) { 403 /* A trust-on-first-use acceptance must persist its pin, like the original 404 * tool — a pin that can't be written fails verification (exit 1). */ 405 if (result.tofu_pin && pkg_pin_tofu(env, ctx, tpath, &result) != 0) { 406 driver_errf(PKG_TOOL, 407 "tofu: could not persist key id to trusted-keys " 408 "(set KIT_TRUSTED_KEYS or HOME)"); 409 } else { 410 int quiet = unpack && !explicit_verify; 411 if (!quiet) { 412 char idhex[PKG_KEYID_HEX]; 413 kit_hex_encode(idhex, result.keyid, KIT_PKG_KEYID_LEN); 414 driver_printf("ok: %s %s signer %s [%s]\n", result.name, 415 result.version, idhex, result.trusted); 416 } 417 if (opts.unpack_dir) 418 driver_printf("unpacked %s %s to %s\n", result.name, result.version, 419 opts.unpack_dir); 420 rc = 0; 421 } 422 } 423 424 if (trust_loaded) pkg_release(ctx, &trustfd); 425 if (pub_loaded) pkg_release(ctx, &pubfd); 426 pkg_release(ctx, &pkgfd); 427 return rc; 428 } 429 430 /* ---------------------------------------------------------------------- */ 431 /* inspect */ 432 /* ---------------------------------------------------------------------- */ 433 434 static int pkg_inspect(DriverEnv* env, const KitContext* ctx, int argc, 435 char** argv) { 436 const char* file = NULL; 437 KitPkgFormat fmt = KIT_PKG_FORMAT_AUTO; 438 int show_encoding = 0, i, rc = 1; 439 KitFileData fd; 440 KitWriter* out; 441 for (i = 0; i < argc; ++i) { 442 if (driver_streq(argv[i], "--format") && i + 1 < argc) { 443 fmt = pkg_parse_format(argv[++i]); 444 if (fmt == KIT_PKG_FORMAT_AUTO) { 445 driver_errf(PKG_TOOL, "inspect: unknown format"); 446 return 2; 447 } 448 } else if (driver_streq(argv[i], "--manifest")) { 449 show_encoding = 0; 450 } else if (driver_streq(argv[i], "--encoding")) { 451 show_encoding = 1; 452 } else if (argv[i][0] != '-') 453 file = argv[i]; 454 else { 455 driver_errf(PKG_TOOL, "inspect: unknown option: %s", argv[i]); 456 return 2; 457 } 458 } 459 if (!file) { 460 driver_errf(PKG_TOOL, "inspect: FILE is required"); 461 return 2; 462 } 463 if (fmt == KIT_PKG_FORMAT_AUTO) fmt = pkg_infer_format(file); 464 if (fmt == KIT_PKG_FORMAT_TARGZ && show_encoding) { 465 driver_errf(PKG_TOOL, 466 "inspect: portable packages have no encoding descriptor"); 467 return 2; 468 } 469 if (!pkg_read(ctx, file, &fd)) { 470 driver_errf(PKG_TOOL, "cannot read package: %s", file); 471 return 1; 472 } 473 out = driver_stdout_writer(env); 474 if (out) { 475 if (kit_pkg_inspect(ctx, fd.data, fd.size, fmt, show_encoding, out) == 476 KIT_OK) 477 rc = 0; 478 kit_writer_close(out); 479 } 480 pkg_release(ctx, &fd); 481 return rc; 482 } 483 484 /* ---------------------------------------------------------------------- */ 485 /* trust */ 486 /* ---------------------------------------------------------------------- */ 487 488 static int pkg_trust(DriverEnv* env, const KitContext* ctx, int argc, 489 char** argv) { 490 char tpath[PKG_PATH_BUF]; 491 const char* sub = (argc > 0) ? argv[0] : "list"; 492 if (pkg_trust_path(tpath, sizeof tpath) != 0) { 493 driver_errf(PKG_TOOL, 494 "no trusted-keys path (set KIT_TRUSTED_KEYS or HOME)"); 495 return 1; 496 } 497 if (driver_streq(sub, "path")) { 498 if (argc > 1) { 499 driver_errf(PKG_TOOL, "trust path: unexpected argument: %s", argv[1]); 500 return 2; 501 } 502 driver_printf("%s\n", tpath); 503 return 0; 504 } 505 if (driver_streq(sub, "list")) { 506 KitFileData fd; 507 if (!pkg_read(ctx, tpath, &fd)) { 508 driver_printf("(no trusted keys at %s)\n", tpath); 509 return 0; 510 } 511 driver_printf("%.*s", (int)fd.size, (const char*)fd.data); 512 pkg_release(ctx, &fd); 513 return 0; 514 } 515 if (driver_streq(sub, "add")) { 516 const char* pubkey = (argc > 1) ? argv[1] : NULL; 517 const char* label = (argc > 2) ? argv[2] : ""; 518 KitFileData kf, old; 519 uint8_t pk[KIT_PKG_PK_LEN], keyid[KIT_PKG_KEYID_LEN], dummy[KIT_PKG_PK_LEN]; 520 char line[PKG_TRUST_LINE_MAX], parent[PKG_PATH_BUF]; 521 int had_old, ok = 1, rc = 1; 522 KitWriter* w = NULL; 523 if (!pubkey) { 524 driver_errf(PKG_TOOL, "trust add: PUBKEY is required"); 525 return 2; 526 } 527 if (!pkg_read(ctx, pubkey, &kf)) { 528 driver_errf(PKG_TOOL, "cannot read public key: %s", pubkey); 529 return 1; 530 } 531 ok = kit_minisig_parse_pubkey(kf.data, kf.size, pk, keyid) == KIT_OK; 532 pkg_release(ctx, &kf); 533 if (!ok) return 1; 534 had_old = pkg_read(ctx, tpath, &old); 535 if (had_old && 536 kit_trust_lookup(old.data, old.size, keyid, dummy) == KIT_OK) { 537 pkg_release(ctx, &old); 538 return 0; 539 } 540 if (kit_trust_format_entry(line, sizeof line, keyid, pk, label) != KIT_OK) { 541 if (had_old) pkg_release(ctx, &old); 542 return 1; 543 } 544 pkg_parent_dir(tpath, parent, sizeof parent); 545 if (parent[0]) driver_mkdir_p(env, parent); 546 if (ctx->file_io->open_writer(ctx->file_io->user, tpath, &w) == KIT_OK) { 547 if (had_old && old.size) 548 ok = kit_writer_write(w, old.data, old.size) == KIT_OK; 549 if (ok) ok = kit_writer_write(w, line, strlen(line)) == KIT_OK; 550 if (ok && kit_writer_status(w) == KIT_OK) rc = 0; 551 kit_writer_close(w); 552 } 553 if (had_old) pkg_release(ctx, &old); 554 return rc; 555 } 556 if (driver_streq(sub, "remove")) { 557 const char* idhex = (argc > 1) ? argv[1] : NULL; 558 KitFileData old; 559 uint8_t want[KIT_PKG_KEYID_LEN]; 560 KitWriter* w = NULL; 561 size_t pos = 0; 562 int rc = 1; 563 if (!idhex || strlen(idhex) != 2 * KIT_PKG_KEYID_LEN || 564 kit_hex_decode(want, idhex, KIT_PKG_KEYID_LEN) != KIT_OK) 565 return 2; 566 if (!pkg_read(ctx, tpath, &old)) return 0; 567 if (ctx->file_io->open_writer(ctx->file_io->user, tpath, &w) != KIT_OK) { 568 pkg_release(ctx, &old); 569 return 1; 570 } 571 rc = 0; 572 while (pos < old.size) { 573 size_t start = pos, end = pos; 574 uint8_t got[KIT_PKG_KEYID_LEN]; 575 char idbuf[2 * KIT_PKG_KEYID_LEN + 1]; 576 int keep = 1; 577 while (end < old.size && old.data[end] != '\n') ++end; 578 if (end - start >= 2 * KIT_PKG_KEYID_LEN) { 579 memcpy(idbuf, old.data + start, 2 * KIT_PKG_KEYID_LEN); 580 idbuf[2 * KIT_PKG_KEYID_LEN] = '\0'; 581 if (kit_hex_decode(got, idbuf, KIT_PKG_KEYID_LEN) == KIT_OK && 582 memcmp(got, want, KIT_PKG_KEYID_LEN) == 0) 583 keep = 0; 584 } 585 if (keep) { 586 size_t n = (end < old.size ? end + 1 : end) - start; 587 if (kit_writer_write(w, old.data + start, n) != KIT_OK) rc = 1; 588 } 589 pos = (end < old.size) ? end + 1 : end; 590 } 591 if (kit_writer_status(w) != KIT_OK) rc = 1; 592 kit_writer_close(w); 593 pkg_release(ctx, &old); 594 return rc; 595 } 596 driver_errf(PKG_TOOL, "trust: unknown subcommand: %s", sub); 597 return 2; 598 } 599 600 int driver_pkg(int argc, char** argv) { 601 DriverEnv env; 602 KitContext ctx; 603 const char* sub; 604 int rc; 605 if (driver_argv_wants_help(argc, argv, 1) || argc < 2) { 606 driver_help_pkg(); 607 return argc < 2 ? 2 : 0; 608 } 609 sub = argv[1]; 610 driver_env_init(&env); 611 ctx = driver_env_to_context(&env); 612 if (driver_streq(sub, "keygen")) 613 rc = pkg_keygen(&env, &ctx, argc - 2, argv + 2); 614 else if (driver_streq(sub, "create")) 615 rc = pkg_create(&env, &ctx, argc - 2, argv + 2); 616 else if (driver_streq(sub, "verify")) 617 rc = pkg_verify_or_unpack(&env, &ctx, argc - 2, argv + 2, 0); 618 else if (driver_streq(sub, "unpack")) 619 rc = pkg_verify_or_unpack(&env, &ctx, argc - 2, argv + 2, 1); 620 else if (driver_streq(sub, "inspect")) 621 rc = pkg_inspect(&env, &ctx, argc - 2, argv + 2); 622 else if (driver_streq(sub, "trust")) 623 rc = pkg_trust(&env, &ctx, argc - 2, argv + 2); 624 else { 625 driver_errf(PKG_TOOL, "unknown subcommand: %s", sub); 626 rc = 2; 627 } 628 driver_env_fini(&env); 629 return rc; 630 }