/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. Licensed under the StarForth License, Version 1.0 */ /** * capsule_mint.h - MINT: mint a fresh identity onto a blank thumbdrive * (FABRIC-3.md §F.8/§F.19), the last piece of the original Tripod * vision. Writes a real keypair, a Zuse-signed cert, and a minimal * working default personality -- everything RUNCAP (capsule_runcap.h) * and CERTVERIFY need at a later attach. */ #ifndef STARKERNEL_CAPSULE_MINT_H #define STARKERNEL_CAPSULE_MINT_H #ifdef __STARKERNEL__ #include #include "vm.h" struct blkio_dev; typedef enum { MINT_OK = 0, MINT_ERR_ALREADY_MINTED, /* dev already reads as a recognized home-blocks * drive -- refuses rather than overwrite, * mirroring WRITE(10)'s own blank-media * posture (§F.8, decided 2026-08-28). */ MINT_ERR_NO_ZUSE_CERT, /* issuer_vm->zuse_cert_installed is 0 -- no * key to sign the new cert with. */ MINT_ERR_NO_ENTROPY, /* virtio_rng not ready. */ MINT_ERR_CERT_BUILD, /* x509_build_user_cert() failed (shouldn't * happen with fixed-size fields, but not * assumed away). */ MINT_ERR_WRITE_FAIL, /* a devblock write failed partway through -- * the drive may be left partially minted. */ MINT_ERR_INVALID_PROFILE, /* full_name/username missing or too long for * user_identity_seed_t's fixed fields, or * email/phone too long (both may be NULL/empty * -- that's "null", not invalid). */ } MintResult; /** * capsule_mint_identity - Mint a fresh identity onto dev. * * Layout written (devblock offsets from dev's own start; devblock 0 is * left alone, reserved for the block-subsystem's own generic header): * devblock 1 homeblocks_sig_t (HOMEBLOCKS_SIG_START_FBLOCK) * devblock 2 DER cert, Zuse-signed (cert_offset) * devblock 3 user_identity_seed_t (identity_src_offset) * devblock 4 default personality source (identity_src_offset+1) * * @param dev Already-open block device for the target drive. * @param issuer_vm The signing identity -- in practice always Hera's own * VM (Zuse's cert lives there, vm.h's zuse_cert_seed). * NULL means genesis mode (§F.21): no cert is built or * written (cert_offset/cert_devblocks stay 0) and * issuer_vm->zuse_cert_installed is never checked -- * used exactly once, to mint Zuse's own root identity, * which by definition has no existing Zuse to sign it. * @param full_name Required, NUL-terminated, fits user_identity_seed_t's * full_name field (§F.20). * @param username Required, NUL-terminated, fits its username field. * @param email NULL or empty string = null (field stays empty). * @param phone NULL or empty string = null (field stays empty). * @param out_pubkey Optional (may be NULL): filled with the newly * generated identity's own Ed25519 public key on * success. Genesis mode's only caller needs this, to * write it into the system-resident zuse_genesis_ * marker_t. * @param out_seed Optional (may be NULL): filled with the newly * generated identity's own Ed25519 seed on success. * Genesis mode's only caller needs this too, to * install the cert into Hera's own VM immediately * (vm_zuse_cert_install()) -- the seed otherwise only * ever lives on the minted thumbdrive. * @param drive_known_blank Pass 1 when the caller has *already* just run * homeblocks_sig_check() on dev and confirmed * HOMEBLOCKS_SIG_BLANK (e.g. capsule_zuse_boot_try_ * attach(), which must check sig_rc before it can even * decide to call this) -- skips this function's own * internal "refuse to overwrite" re-check, which * otherwise repeats the exact same full BOT read * sequence a second time for no reason (found live, * FABRIC-3.md §F.25/§F.26: the redundant check was * mistaken for a hang before the real cause -- leaked * `tail -f` processes from repeated hard kills during * the same debugging session -- was found). Pass 0 from * any caller (like MINT, mama_forth_words.c) that has * not already checked -- the safety check still applies * there. * @return MINT_OK on success, an error code otherwise. */ MintResult capsule_mint_identity(struct blkio_dev *dev, VM *issuer_vm, const char *full_name, const char *username, const char *email, const char *phone, uint8_t out_pubkey[32], uint8_t out_seed[32], int drive_known_blank); #endif /* __STARKERNEL__ */ #endif /* STARKERNEL_CAPSULE_MINT_H */