Milestone 6: BLOCK_MAP.md signature-status column
--manifest mode's file scan is a completely separate code path from build mode (only ever walks .4th files, never the embedded PKI cert or font capsule) -- extended it to accept the same optional --sign-key <path> prefix build mode already has, factoring the key-loading code into a shared load_sign_key(), so the manifest can report real per-capsule signing status without touching or requiring a rebuild of capsule_generated.c. New "Signed" column on the capsule summary table: yes/no when --sign-key was given, n/a (with an explanatory footnote) when it wasn't -- never a bare blank that could be misread as "unsigned". Makefile.starkernel's manifest-generation call site now passes the same SIGN_KEY_ARGS the real build uses, so capsules/BLOCK_MAP.md reflects this machine's actual signed state by default. Verified: clean compile, BLOCK_MAP.md correctly shows "yes" for all 31 tracked capsules on a real signed build; a quick amd64 boot (no kernel code touched, host tooling only) confirmed no regression. This closes every open Milestone 6 item except magic-number content-type detection (shared with Milestone 4, not started) and the hard-refuse flip (deliberately deferred). Documented in FABRIC-3.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U14ET9CWAtbQMbYqomKgXd
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2fc55f47e1
commit
c640f99211
+21
@@ -802,6 +802,27 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
|
|||||||
clean for a while, not bundled into this pass) and the `BLOCK_MAP.md` signature-status
|
clean for a while, not bundled into this pass) and the `BLOCK_MAP.md` signature-status
|
||||||
column.
|
column.
|
||||||
|
|
||||||
|
**`BLOCK_MAP.md` signature-status column, done 2026-08-26.** `--manifest` mode's file scan
|
||||||
|
(`manifest_file()`) is a completely separate code path from build mode's `process_file()` —
|
||||||
|
confirmed it only ever walks `.4th` files (never the embedded PKI cert or font capsule), and
|
||||||
|
the Makefile invokes `mkcapsule` twice per build for two different purposes (once to emit
|
||||||
|
`capsule_generated.c`, once for the manifest). Extended `--manifest` to accept the same
|
||||||
|
optional `--sign-key <path>` prefix as build mode (factored the key-loading code, previously
|
||||||
|
inline in build mode's arg parsing, into a shared `load_sign_key()` used by both) so the
|
||||||
|
manifest can report real per-capsule signing status without touching or requiring a rebuild
|
||||||
|
of `capsule_generated.c`. New `Signed` column on the capsule summary table: `yes`/`no` when
|
||||||
|
`--sign-key` was given, `n/a` (with an explanatory footnote) when it wasn't — never a bare
|
||||||
|
blank that could be misread as "unsigned." `Makefile.starkernel`'s manifest-generation call
|
||||||
|
site updated to pass the same `$(SIGN_KEY_ARGS)` the real build already uses, so
|
||||||
|
`capsules/BLOCK_MAP.md` reflects this machine's actual signed state by default. Verified:
|
||||||
|
clean compile, `capsules/BLOCK_MAP.md` correctly shows `yes` for all 31 tracked `.4th`
|
||||||
|
capsules on a real signed build; a quick amd64 boot (no kernel code touched by this step,
|
||||||
|
only host tooling) confirmed no regression, zero signature warnings, conservation intact.
|
||||||
|
|
||||||
|
**This closes every open item from FABRIC-2.md's original Milestone 6 punch list except
|
||||||
|
magic-number content-type detection (Section U item 14, shared with Milestone 4, not
|
||||||
|
started) and the hard-refuse flip (deliberately deferred).**
|
||||||
|
|
||||||
### From FABRIC-2.md §X, Milestone 7 — Contributor capsules / trust tiers
|
### From FABRIC-2.md §X, Milestone 7 — Contributor capsules / trust tiers
|
||||||
|
|
||||||
- [ ] Create the `capsules/contrib/` directory (mechanically trivial, matches existing
|
- [ ] Create the `capsules/contrib/` directory (mechanically trivial, matches existing
|
||||||
|
|||||||
+2
-2
@@ -588,12 +588,12 @@ $(CAPSULE_GENERATED): $(MKCAPSULE_BIN) $(CAPSULE_SRCS)
|
|||||||
@echo " MKCAP $(CAPSULES_DIR) -> $@"
|
@echo " MKCAP $(CAPSULES_DIR) -> $@"
|
||||||
@$(MKCAPSULE_BIN) $(SIGN_KEY_ARGS) $(CAPSULES_DIR) $@
|
@$(MKCAPSULE_BIN) $(SIGN_KEY_ARGS) $(CAPSULES_DIR) $@
|
||||||
@echo " MKCAP $(CAPSULES_DIR) -> $(CAPSULES_DIR)/BLOCK_MAP.md"
|
@echo " MKCAP $(CAPSULES_DIR) -> $(CAPSULES_DIR)/BLOCK_MAP.md"
|
||||||
@$(MKCAPSULE_BIN) --manifest $(CAPSULES_DIR) $(CAPSULES_DIR)/BLOCK_MAP.md
|
@$(MKCAPSULE_BIN) --manifest $(SIGN_KEY_ARGS) $(CAPSULES_DIR) $(CAPSULES_DIR)/BLOCK_MAP.md
|
||||||
|
|
||||||
# manifest — regenerate capsules/BLOCK_MAP.md without a full kernel build
|
# manifest — regenerate capsules/BLOCK_MAP.md without a full kernel build
|
||||||
.PHONY: manifest
|
.PHONY: manifest
|
||||||
manifest: $(MKCAPSULE_BIN)
|
manifest: $(MKCAPSULE_BIN)
|
||||||
@$(MKCAPSULE_BIN) --manifest $(CAPSULES_DIR) $(CAPSULES_DIR)/BLOCK_MAP.md
|
@$(MKCAPSULE_BIN) --manifest $(SIGN_KEY_ARGS) $(CAPSULES_DIR) $(CAPSULES_DIR)/BLOCK_MAP.md
|
||||||
@echo " Wrote $(CAPSULES_DIR)/BLOCK_MAP.md"
|
@echo " Wrote $(CAPSULES_DIR)/BLOCK_MAP.md"
|
||||||
|
|
||||||
$(CAPSULE_GENERATED_OBJ): $(CAPSULE_GENERATED)
|
$(CAPSULE_GENERATED_OBJ): $(CAPSULE_GENERATED)
|
||||||
|
|||||||
+34
-34
@@ -1,44 +1,44 @@
|
|||||||
# Capsule Block Manifest — Auto-generated
|
# Capsule Block Manifest — Auto-generated
|
||||||
<!-- Generated by mkcapsule --manifest 2026-08-27T01:28:54Z -->
|
<!-- Generated by mkcapsule --manifest 2026-08-27T01:40:17Z -->
|
||||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||||
<!-- Hand-written justifications and immutability notes live -->
|
<!-- Hand-written justifications and immutability notes live -->
|
||||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||||
|
|
||||||
## Capsule Summary
|
## Capsule Summary
|
||||||
|
|
||||||
| Capsule | Blocks claimed | xxHash64 |
|
| Capsule | Blocks claimed | xxHash64 | Signed |
|
||||||
|---------|----------------|----------|
|
|---------|----------------|----------|--------|
|
||||||
| `ACL.4th` | 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4015 | `0xd781d22148ff171d` |
|
| `ACL.4th` | 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4015 | `0xd781d22148ff171d` | yes |
|
||||||
| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852 | `0x1859f0148048a2c1` |
|
| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852 | `0x1859f0148048a2c1` | yes |
|
||||||
| `common:msg.4th` | 4055 | `0x850a0382344ea6c4` |
|
| `common:msg.4th` | 4055 | `0x850a0382344ea6c4` | yes |
|
||||||
| `doe-campaign.4th` | 4060, 4061, 4062, 4063, 4064, 4065 | `0x3d4549142d91ec20` |
|
| `doe-campaign.4th` | 4060, 4061, 4062, 4063, 4064, 4065 | `0x3d4549142d91ec20` | yes |
|
||||||
| `doe.4th` | 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107 | `0xf154616d248e861f` |
|
| `doe.4th` | 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107 | `0xf154616d248e861f` | yes |
|
||||||
| `fabric.4th` | 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, 5000, 5001, 5002 | `0x9b1d061339cea98d` |
|
| `fabric.4th` | 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, 5000, 5001, 5002 | `0x9b1d061339cea98d` | yes |
|
||||||
| `font.4th` | 4925, 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985 | `0x720792b4fc758156` |
|
| `font.4th` | 4925, 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985 | `0x720792b4fc758156` | yes |
|
||||||
| `hermes:init.4th` | 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4114, 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4175, 4176 | `0xfbb1208133abbeef` |
|
| `hermes:init.4th` | 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4114, 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4175, 4176 | `0xfbb1208133abbeef` | yes |
|
||||||
| `init-0.4th` | 2200, 2201 | `0xd0a9550baf786bb3` |
|
| `init-0.4th` | 2200, 2201 | `0xd0a9550baf786bb3` | yes |
|
||||||
| `init-1.4th` | 4406, 4415, 4425, 4435 | `0x63e251adb0a03613` |
|
| `init-1.4th` | 4406, 4415, 4425, 4435 | `0x63e251adb0a03613` | yes |
|
||||||
| `init-2.4th` | 4506, 4515, 4525, 4535, 4545 | `0xf113b3d0bcccae47` |
|
| `init-2.4th` | 4506, 4515, 4525, 4535, 4545 | `0xf113b3d0bcccae47` | yes |
|
||||||
| `init-3.4th` | 4606, 4615, 4625, 4635, 4645, 4655, 4665 | `0x62b7a71576ad1041` |
|
| `init-3.4th` | 4606, 4615, 4625, 4635, 4645, 4655, 4665 | `0x62b7a71576ad1041` | yes |
|
||||||
| `init-4.4th` | 2130, 2131, 2132 | `0x89e3ef1db5ac0627` |
|
| `init-4.4th` | 2130, 2131, 2132 | `0x89e3ef1db5ac0627` | yes |
|
||||||
| `init-5.4th` | *(none — raw code capsule)* | `0xda0c179af10a46a9` |
|
| `init-5.4th` | *(none — raw code capsule)* | `0xda0c179af10a46a9` | yes |
|
||||||
| `init-6.4th` | 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095 | `0x06fc0ce1e369ef5a` |
|
| `init-6.4th` | 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095 | `0x06fc0ce1e369ef5a` | yes |
|
||||||
| `init-7.4th` | 2150 | `0xb88df2efeb753d64` |
|
| `init-7.4th` | 2150 | `0xb88df2efeb753d64` | yes |
|
||||||
| `init-8.4th` | 2160 | `0x714746312b72f83d` |
|
| `init-8.4th` | 2160 | `0x714746312b72f83d` | yes |
|
||||||
| `init-9.4th` | 4706, 4715, 4725, 4735, 4745 | `0x3f2bec73142aa424` |
|
| `init-9.4th` | 4706, 4715, 4725, 4735, 4745 | `0x3f2bec73142aa424` | yes |
|
||||||
| `init-l8-diverse.4th` | 4820, 4821, 4822 | `0xaa293201a6c91838` |
|
| `init-l8-diverse.4th` | 4820, 4821, 4822 | `0xaa293201a6c91838` | yes |
|
||||||
| `init-l8-omni.4th` | 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079 | `0x5979e314d6452045` |
|
| `init-l8-omni.4th` | 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079 | `0x5979e314d6452045` | yes |
|
||||||
| `init-l8-stable.4th` | 4806 | `0xdc3830f189063a9a` |
|
| `init-l8-stable.4th` | 4806 | `0xdc3830f189063a9a` | yes |
|
||||||
| `init-l8-temporal.4th` | 4830, 4831 | `0x51abd4c138246651` |
|
| `init-l8-temporal.4th` | 4830, 4831 | `0x51abd4c138246651` | yes |
|
||||||
| `init-l8-transition.4th` | 4840, 4841, 4842 | `0xbcc1a81976f0a4c9` |
|
| `init-l8-transition.4th` | 4840, 4841, 4842 | `0xbcc1a81976f0a4c9` | yes |
|
||||||
| `init-l8-volatile.4th` | 4810, 4811, 4812, 4813 | `0x98caabbbd92abac4` |
|
| `init-l8-volatile.4th` | 4810, 4811, 4812, 4813 | `0x98caabbbd92abac4` | yes |
|
||||||
| `init.4th` | 2049, 2050, 2057 | `0x214d424abd382707` |
|
| `init.4th` | 2049, 2050, 2057 | `0x214d424abd382707` | yes |
|
||||||
| `lib.4th` | 4050 | `0x1c77d7c9562a5b62` |
|
| `lib.4th` | 4050 | `0x1c77d7c9562a5b62` | yes |
|
||||||
| `process.4th` | 4300, 4301 | `0x781afc1dbd0294f7` |
|
| `process.4th` | 4300, 4301 | `0x781afc1dbd0294f7` | yes |
|
||||||
| `sdk.4th` | 5109, 5110, 5111, 5112, 5113, 5114, 5115 | `0x008fdbbb62c94a3a` |
|
| `sdk.4th` | 5109, 5110, 5111, 5112, 5113, 5114, 5115 | `0x008fdbbb62c94a3a` | yes |
|
||||||
| `turtle.4th` | 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108 | `0x4d470418ca543365` |
|
| `turtle.4th` | 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108 | `0x4d470418ca543365` | yes |
|
||||||
| `user-font-demo.4th` | 4200, 4201, 4202 | `0xce1fd7d1b581a56d` |
|
| `user-font-demo.4th` | 4200, 4201, 4202 | `0xce1fd7d1b581a56d` | yes |
|
||||||
| `zuse.4th` | 4016, 4017, 4018 | `0x3b31872d02a43d83` |
|
| `zuse.4th` | 4016, 4017, 4018 | `0x3b31872d02a43d83` | yes |
|
||||||
|
|
||||||
## Block Map (sorted by LBN)
|
## Block Map (sorted by LBN)
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+76
-39
@@ -169,6 +169,7 @@ typedef struct {
|
|||||||
uint64_t hash;
|
uint64_t hash;
|
||||||
int blocks[MAX_BLOCKS_PER_CAPSULE];
|
int blocks[MAX_BLOCKS_PER_CAPSULE];
|
||||||
int block_count;
|
int block_count;
|
||||||
|
int has_sig; /* 1 if signed this run (--manifest --sign-key <path>) */
|
||||||
} ManifestEntry;
|
} ManifestEntry;
|
||||||
|
|
||||||
static ManifestEntry manifest_entries[MAX_CAPSULES];
|
static ManifestEntry manifest_entries[MAX_CAPSULES];
|
||||||
@@ -607,6 +608,12 @@ static int manifest_file(const char *fpath, const struct stat *sb,
|
|||||||
e->block_count = collect_block_numbers(data, (size_t)sz,
|
e->block_count = collect_block_numbers(data, (size_t)sz,
|
||||||
e->blocks, MAX_BLOCKS_PER_CAPSULE);
|
e->blocks, MAX_BLOCKS_PER_CAPSULE);
|
||||||
qsort(e->blocks, (size_t)e->block_count, sizeof(int), cmp_int);
|
qsort(e->blocks, (size_t)e->block_count, sizeof(int), cmp_int);
|
||||||
|
e->has_sig = 0;
|
||||||
|
if (have_sign_seed) {
|
||||||
|
uint8_t sig[64];
|
||||||
|
sign_capsule_bytes(data, (size_t)sz, sig);
|
||||||
|
e->has_sig = 1;
|
||||||
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -654,8 +661,8 @@ static void generate_manifest(FILE *out) {
|
|||||||
|
|
||||||
/* Capsule summary */
|
/* Capsule summary */
|
||||||
fprintf(out, "## Capsule Summary\n\n");
|
fprintf(out, "## Capsule Summary\n\n");
|
||||||
fprintf(out, "| Capsule | Blocks claimed | xxHash64 |\n");
|
fprintf(out, "| Capsule | Blocks claimed | xxHash64 | Signed |\n");
|
||||||
fprintf(out, "|---------|----------------|----------|\n");
|
fprintf(out, "|---------|----------------|----------|--------|\n");
|
||||||
for (int i = 0; i < manifest_count; i++) {
|
for (int i = 0; i < manifest_count; i++) {
|
||||||
ManifestEntry *e = &manifest_entries[i];
|
ManifestEntry *e = &manifest_entries[i];
|
||||||
fprintf(out, "| `%s` | ", e->name);
|
fprintf(out, "| `%s` | ", e->name);
|
||||||
@@ -667,9 +674,16 @@ static void generate_manifest(FILE *out) {
|
|||||||
fprintf(out, "%d", e->blocks[j]);
|
fprintf(out, "%d", e->blocks[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(out, " | `0x%016" PRIx64 "` |\n", e->hash);
|
fprintf(out, " | `0x%016" PRIx64 "` | %s |\n", e->hash,
|
||||||
|
have_sign_seed ? (e->has_sig ? "yes" : "no") : "n/a");
|
||||||
}
|
}
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (!have_sign_seed) {
|
||||||
|
fprintf(out,
|
||||||
|
"*Signed column is `n/a`: this manifest run had no `--sign-key`. "
|
||||||
|
"Re-run with `--sign-key <path>` to check signing status "
|
||||||
|
"(does not modify or require rebuilding capsule_generated.c).*\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Block map sorted by LBN */
|
/* Block map sorted by LBN */
|
||||||
fprintf(out, "## Block Map (sorted by LBN)\n\n");
|
fprintf(out, "## Block Map (sorted by LBN)\n\n");
|
||||||
@@ -972,10 +986,57 @@ static void generate_output(FILE *out) {
|
|||||||
* Main
|
* Main
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
|
||||||
|
/* Loads key_path, extracts its Ed25519 seed into sign_seed, sets
|
||||||
|
* have_sign_seed=1 on success. Shared by build mode and --manifest mode
|
||||||
|
* (both accept an optional --sign-key <path>). Returns 0 on success,
|
||||||
|
* writes an ERROR to stderr and returns -1 on failure. */
|
||||||
|
static int load_sign_key(const char *key_path) {
|
||||||
|
FILE *kf = fopen(key_path, "rb");
|
||||||
|
if (!kf) {
|
||||||
|
fprintf(stderr, "mkcapsule: ERROR: cannot open key '%s'\n", key_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fseek(kf, 0, SEEK_END);
|
||||||
|
long klen = ftell(kf);
|
||||||
|
fseek(kf, 0, SEEK_SET);
|
||||||
|
uint8_t *kbuf = malloc((size_t)klen);
|
||||||
|
if (!kbuf || fread(kbuf, 1, (size_t)klen, kf) != (size_t)klen) {
|
||||||
|
fprintf(stderr, "mkcapsule: ERROR: cannot read key '%s'\n", key_path);
|
||||||
|
fclose(kf);
|
||||||
|
free(kbuf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fclose(kf);
|
||||||
|
if (pkcs8_extract_ed25519_seed(kbuf, (size_t)klen, sign_seed) != 0) {
|
||||||
|
fprintf(stderr, "mkcapsule: ERROR: '%s' is not a valid PKCS#8 "
|
||||||
|
"Ed25519 private key\n", key_path);
|
||||||
|
free(kbuf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(kbuf);
|
||||||
|
have_sign_seed = 1;
|
||||||
|
fprintf(stderr, "mkcapsule: signing capsules with key '%s'\n", key_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
/* --manifest mode: generate block ownership markdown */
|
/* --manifest mode: generate block ownership markdown. Optional
|
||||||
|
* --sign-key <keyfile> prefix: mkcapsule --manifest [--sign-key
|
||||||
|
* <keyfile>] <capsules_dir> [<out.md>] -- lets the manifest report
|
||||||
|
* real signing status without touching capsule_generated.c. */
|
||||||
if (argc >= 3 && strcmp(argv[1], "--manifest") == 0) {
|
if (argc >= 3 && strcmp(argv[1], "--manifest") == 0) {
|
||||||
base_dir = argv[2];
|
int a = 2;
|
||||||
|
if (argc >= 4 && strcmp(argv[2], "--sign-key") == 0) {
|
||||||
|
if (argc < 5) {
|
||||||
|
fprintf(stderr, "mkcapsule: ERROR: --manifest --sign-key "
|
||||||
|
"requires <keyfile> <capsules_dir>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (load_sign_key(argv[3]) != 0) return 1;
|
||||||
|
a = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_dir = argv[a];
|
||||||
base_dir_len = strlen(base_dir);
|
base_dir_len = strlen(base_dir);
|
||||||
while (base_dir_len > 0 && base_dir[base_dir_len - 1] == '/') base_dir_len--;
|
while (base_dir_len > 0 && base_dir[base_dir_len - 1] == '/') base_dir_len--;
|
||||||
|
|
||||||
@@ -985,18 +1046,19 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FILE *mout = stdout;
|
FILE *mout = stdout;
|
||||||
if (argc == 4) {
|
int have_out = (argc == a + 2);
|
||||||
mout = fopen(argv[3], "w");
|
if (have_out) {
|
||||||
|
mout = fopen(argv[a + 1], "w");
|
||||||
if (!mout) {
|
if (!mout) {
|
||||||
fprintf(stderr, "mkcapsule: ERROR: cannot create '%s'\n", argv[3]);
|
fprintf(stderr, "mkcapsule: ERROR: cannot create '%s'\n", argv[a + 1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generate_manifest(mout);
|
generate_manifest(mout);
|
||||||
if (mout != stdout) {
|
if (have_out) {
|
||||||
fclose(mout);
|
fclose(mout);
|
||||||
fprintf(stderr, "mkcapsule: manifest written to %s (%d capsule(s))\n",
|
fprintf(stderr, "mkcapsule: manifest written to %s (%d capsule(s))\n",
|
||||||
argv[3], manifest_count);
|
argv[a + 1], manifest_count);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1026,32 +1088,7 @@ int main(int argc, char **argv) {
|
|||||||
"<keyfile> <capsules_dir> <output.c>\n");
|
"<keyfile> <capsules_dir> <output.c>\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
const char *key_path = argv[2];
|
if (load_sign_key(argv[2]) != 0) return 1;
|
||||||
FILE *kf = fopen(key_path, "rb");
|
|
||||||
if (!kf) {
|
|
||||||
fprintf(stderr, "mkcapsule: ERROR: cannot open key '%s'\n", key_path);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
fseek(kf, 0, SEEK_END);
|
|
||||||
long klen = ftell(kf);
|
|
||||||
fseek(kf, 0, SEEK_SET);
|
|
||||||
uint8_t *kbuf = malloc((size_t)klen);
|
|
||||||
if (!kbuf || fread(kbuf, 1, (size_t)klen, kf) != (size_t)klen) {
|
|
||||||
fprintf(stderr, "mkcapsule: ERROR: cannot read key '%s'\n", key_path);
|
|
||||||
fclose(kf);
|
|
||||||
free(kbuf);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
fclose(kf);
|
|
||||||
if (pkcs8_extract_ed25519_seed(kbuf, (size_t)klen, sign_seed) != 0) {
|
|
||||||
fprintf(stderr, "mkcapsule: ERROR: '%s' is not a valid PKCS#8 "
|
|
||||||
"Ed25519 private key\n", key_path);
|
|
||||||
free(kbuf);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
free(kbuf);
|
|
||||||
have_sign_seed = 1;
|
|
||||||
fprintf(stderr, "mkcapsule: signing capsules with key '%s'\n", key_path);
|
|
||||||
arg0 = 3;
|
arg0 = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1061,8 +1098,8 @@ int main(int argc, char **argv) {
|
|||||||
" %s [--sign-key <keyfile>] <capsules_dir> <output.c>\n"
|
" %s [--sign-key <keyfile>] <capsules_dir> <output.c>\n"
|
||||||
" build capsule C source\n"
|
" build capsule C source\n"
|
||||||
" %s --lint <capsules_dir> lint all .4th files\n"
|
" %s --lint <capsules_dir> lint all .4th files\n"
|
||||||
" %s --manifest <capsules_dir> print block manifest (stdout)\n"
|
" %s --manifest [--sign-key <keyfile>] <capsules_dir> [<out.md>]\n"
|
||||||
" %s --manifest <capsules_dir> <out.md> write block manifest to file\n"
|
" print/write block manifest\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Lint checks (per .4th file):\n"
|
"Lint checks (per .4th file):\n"
|
||||||
" - each block opens with 'Block N'\n"
|
" - each block opens with 'Block N'\n"
|
||||||
@@ -1078,7 +1115,7 @@ int main(int argc, char **argv) {
|
|||||||
"\n"
|
"\n"
|
||||||
"Names are colon-separated relative paths (e.g. core:init.4th).\n"
|
"Names are colon-separated relative paths (e.g. core:init.4th).\n"
|
||||||
"Files whose encoded name exceeds %d bytes are skipped with a warning.\n",
|
"Files whose encoded name exceeds %d bytes are skipped with a warning.\n",
|
||||||
argv[0], argv[0], argv[0], argv[0], CAPSULE_NAME_MAX - 1);
|
argv[0], argv[0], argv[0], CAPSULE_NAME_MAX - 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user