WIREBIND: real thumbdrive-attach call site, no manual steps

Assembles pieces already built and individually verified this session
-- CERTVERIFY (vm_identity_from_cert(), Phase A/B), RUNCAP, the
console-VM + user-VM pair (§F.22) -- into one automatic sequence,
replacing the RUNCAP-TEST/PAIR-TEST diagnostic words that exercised
each piece by hand.

New capsule_wirebind_try_attach() (capsule_wirebind.h/.c), called from
sk_repl_idle() alongside capsule_zuse_boot_try_attach() on every
HOMEBLOCKS_SIG_OK attach: sig->cert_offset==0 means this is Zuse's own
genesis-mode drive (no cert region) -- that's already
capsule_zuse_boot_try_attach()'s job, skip. Otherwise, with Zuse already
authenticated this boot (nothing to verify a regular cert against
otherwise), reads the cert devblock(s) and calls vm_identity_from_cert()
against mama_vm's own zuse_cert_pubkey and the drive's own drive_uuid.
On success: reads the drive's own user_identity_seed_t for its
username, births a console VM + RUNCAP-born user VM pair (idempotent --
no-ops if that username is already live this session), installs the
verified VMIdentity onto the user VM, and registers the "<username>~user"
pairing sk_repl_dispatch_line() (repl.c, §F.22) looks for. Deliberately
does NOT auto-USE the new console -- that stays an explicit,
ACL-gated step (BINDSTEP, §F.9), not something a bare attach should
trigger silently.

Verified end-to-end live in QEMU, including a genuine negative case:
attached disk/user1.img (signed by a different, earlier-session Zuse
instance) and got a correct "cert verification FAILED -- drive
refused" -- proof the check is real, not a rubber stamp. Minted a
fresh identity with this boot's own Zuse, reattached, and got
"WIREBIND: SamS attached and ready" printed with zero manual commands,
followed by a working USE + async WELCOME relay end to end (queued,
no UNKNOWN WORD, delivered and executed in the paired user VM on the
next idle tick). Clean 3-architecture regression: Hermes/Artemis both
birth live, no unexpected ACL denials or UNKNOWN WORD.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZGkimpfyh63EZyRkNbkPD
This commit is contained in:
Robert Allan James
2026-08-28 16:57:17 -04:00
co-authored by Claude Sonnet 5
parent c9cf9b09d9
commit 6fc0ee33a9
8 changed files with 28841 additions and 1 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# Capsule Block Manifest — Auto-generated
<!-- Generated by mkcapsule --manifest 2026-08-28T20:37:43Z -->
<!-- Generated by mkcapsule --manifest 2026-08-28T20:55:57Z -->
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
<!-- Hand-written justifications and immutability notes live -->
<!-- in MANIFEST.md alongside this auto-generated index. -->
BIN
View File
Binary file not shown.
+60
View File
@@ -0,0 +1,60 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 20232025 Robert A. James
All rights reserved.
Licensed under the StarForth License, Version 1.0
*/
/**
* capsule_wirebind.h - WIREBIND: the real thumbdrive-attach call site
* (FABRIC-3.md §F.5/§F.23). Assembles pieces already built and
* individually verified this session -- CERTVERIFY (vm_identity.h's
* vm_identity_from_cert()), RUNCAP (capsule_runcap.h), the console-VM +
* user-VM pair (capsule_console.h, sk_repl_dispatch_line() in repl.c) --
* into one automatic sequence, replacing the RUNCAP-TEST/PAIR-TEST
* diagnostic words that exercised each piece by hand.
*/
#ifndef STARKERNEL_CAPSULE_WIREBIND_H
#define STARKERNEL_CAPSULE_WIREBIND_H
#ifdef __STARKERNEL__
#include "starkernel/homeblocks_sig.h"
#include "vm.h"
struct blkio_dev;
/**
* capsule_wirebind_try_attach - Try to verify and bind a just-attached
* regular (non-Zuse) identity drive.
*
* No-op if sig->cert_offset is 0 (a genesis-mode Zuse drive has no cert
* region -- that's capsule_zuse_boot_try_attach()'s own job, not this
* one's) or if mama_vm has no installed Zuse cert yet (nothing to verify
* the attached cert against). Otherwise: reads the cert devblock(s),
* calls vm_identity_from_cert() against mama_vm's own zuse_cert_pubkey
* and sig->drive_uuid. On success, reads the drive's own
* user_identity_seed_t for its username and births a console VM +
* RUNCAP-born user VM pair (idempotent -- no-ops if that username is
* already live this session), installs the verified VMIdentity onto the
* user VM, and registers the "<username>~user" pairing
* (sk_repl_dispatch_line(), repl.c, looks for this). Does NOT USE the
* new console automatically -- that stays an explicit, later,
* ACL-gated step (BINDSTEP, §F.9), not something a bare attach should
* trigger silently.
*
* @param dev The just-attached, already-open block device.
* @param sig Its already-checked homeblocks_sig_t.
* @param mama_vm Hera's own VM (the verifier -- her zuse_cert_pubkey is
* the trust root regular user certs are checked against).
*/
void capsule_wirebind_try_attach(struct blkio_dev *dev,
const homeblocks_sig_t *sig,
VM *mama_vm);
#endif /* __STARKERNEL__ */
#endif /* STARKERNEL_CAPSULE_WIREBIND_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+146
View File
@@ -0,0 +1,146 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 20232025 Robert A. James
All rights reserved.
Licensed under the StarForth License, Version 1.0
*/
#ifndef __STARKERNEL__
#error "capsule_wirebind.c is kernel-only"
#endif
#include "starkernel/capsule_wirebind.h"
#include "starkernel/capsule_birth.h"
#include "starkernel/capsule_runcap.h"
#include "starkernel/capsule_console.h"
#include "starkernel/vm_identity.h"
#include "starkernel/user_identity_seed.h"
#include "starkernel/console.h"
#include "blkio.h"
#include "freestanding/stdio.h"
#include <string.h>
/* WIREBIND_CERT_MAX_DEVBLOCKS: a sane upper bound on how much cert
* content this reads, independent of whatever sig->cert_devblocks
* claims -- MINT (capsule_mint.c) only ever writes 1 devblock's worth
* (a real cert is ~150-250 bytes), so 4 devblocks (16KB) is already
* generous headroom, not a real constraint. */
#define WIREBIND_CERT_MAX_DEVBLOCKS 4u
/* Read exactly one devblock (4096 bytes) at devblock offset `devblock`
* -- same convention capsule_runcap.c/capsule_mint.c already use. */
static int read_devblock(struct blkio_dev *dev, uint32_t devblock, uint8_t *buf4096) {
uint32_t base = devblock * 4u;
for (uint32_t i = 0; i < 4u; i++) {
if (blkio_read((blkio_dev_t *)dev, base + i,
buf4096 + (size_t)i * BLKIO_FORTH_BLOCK_SIZE) != BLKIO_OK) {
return -1;
}
}
return 0;
}
void capsule_wirebind_try_attach(struct blkio_dev *dev,
const homeblocks_sig_t *sig,
VM *mama_vm) {
if (!dev || !sig || !mama_vm) return;
/* Genesis-mode Zuse drives have no cert region -- capsule_zuse_boot_
* try_attach() already owns that case. */
if (sig->cert_offset == 0 || sig->cert_devblocks == 0) return;
/* Nothing to verify a regular cert against until Zuse herself has
* authenticated this boot. */
if (!mama_vm->zuse_cert_installed) return;
/* Read the cert region into a local buffer. */
uint32_t n_devblocks = sig->cert_devblocks;
if (n_devblocks > WIREBIND_CERT_MAX_DEVBLOCKS) n_devblocks = WIREBIND_CERT_MAX_DEVBLOCKS;
uint8_t cert_der[WIREBIND_CERT_MAX_DEVBLOCKS * 4096];
for (uint32_t d = 0; d < n_devblocks; d++) {
if (read_devblock(dev, sig->cert_offset + d, cert_der + (size_t)d * 4096) != 0) {
console_println("WIREBIND: cert read failed");
return;
}
}
size_t cert_len = (size_t)n_devblocks * 4096;
VMIdentity identity;
memset(&identity, 0, sizeof(identity));
if (vm_identity_from_cert(&identity, cert_der, cert_len,
mama_vm->zuse_cert_pubkey, sig->drive_uuid,
0 /* acl_caps: no bits assigned yet, §F.2 */) != 0) {
console_println("WIREBIND: cert verification FAILED -- drive refused");
return;
}
/* Verified. Read the drive's own profile for its username. */
if (sig->identity_src_offset == 0 || sig->identity_src_devblocks < 1) {
console_println("WIREBIND: verified cert but no identity_src region -- refusing");
return;
}
user_identity_seed_t idrec;
if (read_devblock(dev, sig->identity_src_offset, (uint8_t *)&idrec) != 0 ||
idrec.magic != USER_IDENTITY_SEED_MAGIC) {
console_println("WIREBIND: verified cert but identity record unreadable -- refusing");
return;
}
char username[USER_IDENTITY_USERNAME_MAX];
memcpy(username, idrec.username, sizeof(username));
username[sizeof(username) - 1] = '\0'; /* defensive; MINT already NUL-terminates */
char user_vm_name[USER_IDENTITY_USERNAME_MAX + 8];
size_t ulen = strlen(username);
if (ulen == 0 || ulen + 6 > sizeof(user_vm_name)) {
console_println("WIREBIND: empty or oversized username -- refusing");
return;
}
memcpy(user_vm_name, username, ulen);
memcpy(user_vm_name + ulen, "~user", 6);
/* Idempotent: already bound this session (console VM already live
* under this username) -- nothing to do. Matches BIRTH's own
* idempotent convention. */
{
VMRegistryEntry existing;
if (capsule_vm_find_by_name(username, &existing) == 0 &&
existing.state == VM_STATE_LIVE) {
return;
}
}
VMUuid console_id, user_id;
void *console_ctx = (void *)0;
void *user_ctx = (void *)0;
if (capsule_console_birth(username, &console_id, &console_ctx) != CAPSULE_RUN_OK) {
console_println("WIREBIND: console VM birth FAILED");
return;
}
if (capsule_runcap_birth(dev, sig, user_vm_name, &user_id, &user_ctx) != CAPSULE_RUN_OK) {
console_println("WIREBIND: user VM birth FAILED");
return;
}
/* Install the verified identity onto the user VM -- the one BINDSTEP
* (§F.9) will later re-verify against on every USE. */
if (user_ctx) {
((VM *)user_ctx)->identity = identity;
}
/* Register the pairing in the console's own routing table, index 3
* -- the fixed convention sk_repl_dispatch_line() (repl.c) uses. */
{
char reg_cmd[sizeof(user_vm_name) + 32];
int n = snprintf(reg_cmd, sizeof(reg_cmd), "S\" %s\" 3 VM-NAME-REG", user_vm_name);
if (n > 0 && (size_t)n < sizeof(reg_cmd)) {
vm_interpret((VM *)console_ctx, reg_cmd);
}
}
console_puts("WIREBIND: ");
console_puts(username);
console_println(" attached and ready -- USE it to begin");
}
+13
View File
@@ -39,6 +39,7 @@
#include "starkernel/homeblocks_sig.h"
#include "starkernel/capsule_birth.h"
#include "starkernel/capsule_zuse_boot.h"
#include "starkernel/capsule_wirebind.h"
#include "starkernel/capsule_run.h"
#include "starkernel/vm/bootstrap/sk_vm_bootstrap.h"
#include "block_subsystem.h"
@@ -195,6 +196,18 @@ static void sk_repl_idle(VM *active_vm)
* detect it). No-ops immediately if Zuse already has a real
* identity this boot. */
capsule_zuse_boot_try_attach(&usb_blk_dev, sig_rc, &sig, (VM *)sk_get_mama_vm());
/* FABRIC-3.md §F.5/§F.23 (WIREBIND): the real thumbdrive-
* attach call site for a regular (non-Zuse) identity --
* verify-then-birth-then-pair, replacing the RUNCAP-TEST/
* PAIR-TEST diagnostic words that exercised each piece by
* hand. Only meaningful for a drive that actually checked
* out (HOMEBLOCKS_SIG_OK); capsule_wirebind_try_attach()
* itself no-ops for a genesis-mode Zuse drive (no cert
* region) or before Zuse has authenticated this boot. */
if (sig_rc == HOMEBLOCKS_SIG_OK) {
capsule_wirebind_try_attach(&usb_blk_dev, &sig, (VM *)sk_get_mama_vm());
}
}
if (rc == 0 && blk_subsys_attach_device(&usb_blk_dev) == BLK_OK) {
xdev->bot_msc_attached = 1;