fix(packaging): --generate-key 打印的 PinnedKey 改成 rustfmt 保持的多行形态(M265)
`--generate-key` 与「信任表是空的」报错里给人粘贴的 `PinnedKey` 原来是单行:
PinnedKey { key_id: "…", public_key_hex: "<64 hex>" },
这一行有 113+ 字符(即使 key_id 为空),超出 .rustfmt.toml 的 max_width = 100,
所以 `cargo fmt` **必然**把它拆成 4 行 —— 人贴单行 → 下一轮 fmt 改动 → 谁忘了跑 fmt
就把 fmt 红带进 main(T30 那次就是这条路径)。
改的是「打印模板」与文档,不是解析器(KID_RE 的 \s* 本来就吃两种形态):
- 新增 render_pinned_key(),字段各占一行、元素缩进 4/字段缩进 8、结尾逗号,
与 trust.rs 里 cargo fmt 生成的形状逐字一致;两条打印路径都走它。
- 提示文案不再暗示「贴完还要 fmt」,改成「贴完直接提交,不用再跑 fmt」。
- docs:signing.md §3 与 signing-runbook.md §2/§4/§8 的「那一行」→「那一段(4 行)」,
并在 runbook §7 明写这条断言在没装 rustfmt 时的退化边界。
- --self-test 新增形态断言:① 渲染结果 == 4 行期望字面量 ② 形状与 trust.rs 现存条目
(字段值抹平后逐行)一致 ③ 单行必然超 max_width、多行每行都不超 ④ 贴进标记之间能解析
⑤ 有 rustfmt 时在临时副本上真跑一遍,要求粘贴块字节不变(没有则打 note 跳过,不装成验过)。
This commit is contained in:
1 parent
cb051ca933
commit
66eb912df0
3 files changed
+128
-26
No files matched your search
@@ -14,7 +14,7 @@
|
||||
|
||||
| 环节 | 在哪 | 今天的状态 |
|
||||
|---|---|---|
|
||||
| 生成钥 | `sign_manifest.py --generate-key` | 有;打印 Secret JSON + `PinnedKey` 那一行 |
|
||||
| 生成钥 | `sign_manifest.py --generate-key` | 有;打印 Secret JSON + `PinnedKey` 那一段(多行,fmt 保持的形态) |
|
||||
| 钥 ↔ 信任表对账 | `sign_manifest.py --check-pinned-keyring` | 有;**今天必然红**(表空 ⇒ 「信任表是空的」) |
|
||||
| 签名 | `sign_manifest.py --sign dist/manifest.json` → `.sig` | 有;**今天必然红**(`ULL_MANIFEST_SIGNING_KEY` 没有,前面先红) |
|
||||
| 回验 | `sign_manifest.py --verify-pinned dist/manifest.json` | 有;**今天必然红**(表空 ⇒ 「无从回验」) |
|
||||
@@ -60,7 +60,8 @@ python3 packaging/sign_manifest.py --generate-key --key-id <key-id,例 ull-rel
|
||||
# 名字必须**逐字**是:ULL_MANIFEST_SIGNING_KEY
|
||||
# (等价 CLI:gh secret set ULL_MANIFEST_SIGNING_KEY,然后按提示粘贴,别用 -b 把值留在 shell 历史里)
|
||||
|
||||
# ③ 把打印出来的那一行 PinnedKey { … } 贴进 trust.rs 的 PINNED-KEYS 标记之间(标记本身别动)
|
||||
# ③ 把打印出来的那一段 PinnedKey(4 行,含结尾逗号)贴进 trust.rs 的 PINNED-KEYS 标记之间(标记本身别动)
|
||||
# 那个形状就是 cargo fmt 会保持的形态 —— 贴完**不用**再跑 fmt(压成一行反而会被 fmt 拆开)
|
||||
grep -n 'PINNED-KEYS' crates/core/src/update/trust.rs
|
||||
# 贴完提交这次改动 —— 公钥进 git 是对的:它是信任锚,本来就该公开可审计
|
||||
|
||||
@@ -78,7 +79,7 @@ python3 packaging/sign_manifest.py --verify-pinned dist/manifest.json # 期望
|
||||
|
||||
| 步 | 成功长什么样 | 失败长什么样 |
|
||||
|---|---|---|
|
||||
| ① | 打印 ① 私钥 JSON、② 一行 `PinnedKey`、③ 公钥十六进制;脚本自带「自己签自己验」自检 | `error: 自己签自己验不过` ⇒ 不要用这把钥,环境有问题 |
|
||||
| ① | 打印 ① 私钥 JSON、② 一段 4 行的 `PinnedKey`、③ 公钥十六进制;脚本自带「自己签自己验」自检 | `error: 自己签自己验不过` ⇒ 不要用这把钥,环境有问题 |
|
||||
| ② | `gh secret list` 里能看到 `ULL_MANIFEST_SIGNING_KEY` | 列表里没有 / 名字拼错(大小写、下划线) |
|
||||
| ③ | `check_signing_ready.py` 的 ① 从「未就绪」翻成「就绪」 | ① 仍说 0 条 ⇒ 贴到了标记**外面**(读数里会点名「另有 N 条在标记之外(key_id:…)」) |
|
||||
| ④ | `ok: 签名钥 … 已被钉住` | `签名钥(…)不在信任表里` ⇒ ②③ 不是同一把钥 |
|
||||
@@ -104,7 +105,7 @@ sign_manifest.py --verify-pinned dist/manifest.json # 用钉住的公钥回验
|
||||
secret,名字不对就是空串 ⇒ 签名步红,而错误文案会反过来指控「Secret 没配」。`release-publish.yml`
|
||||
已经声明了这一个(`required: false`,缺省走 fail-closed),照抄名字即可。
|
||||
2. **只配 Secret 没钉表**:`--check-pinned-keyring` 报「信任表是空的(fail-closed)」,并**直接打印**
|
||||
该贴的那一行 `PinnedKey`(只含公钥,安全)。照贴即可。
|
||||
该贴的那一段 4 行 `PinnedKey`(只含公钥,安全)。照贴即可,注意连 `error:` 前缀一起删掉再贴。
|
||||
3. **只钉表没配 Secret**:`--check-pinned-keyring` 报「没有签名密钥」。这不影响已有用户(表非空 ⇒
|
||||
他们能验签),但发不了新版。
|
||||
4. **Secret 与 trust.rs 是两把不同的钥**:最常见于「换过钥但只更新了一边」。判据是**公钥字节**,
|
||||
@@ -175,6 +176,10 @@ python3 packaging/sign_manifest.py --verify-pinned /tmp/verify/manifest.json
|
||||
②③ 两步要动 GitHub Secret 与 Rust 常量,同理。所以本手册是「按现有脚本的接口写的步骤」,
|
||||
首次执行时**以脚本的实际输出为准**,跑完请回来修正本文档。
|
||||
* **「用户机器上真的更新成功」**没有在本条里验:需要一次真 Release + 一台装着旧版本的机器。
|
||||
* **粘贴块「过一遍 fmt 不变形」只在有 `rustfmt` 的机器上是硬证据**:`sign_manifest.py --self-test` 会在
|
||||
临时副本上真跑一遍 `rustfmt` 比对;PATH 里没有 `rustfmt` 时它会打一行 `note: ... 跳过`,只剩
|
||||
「形状 == `trust.rs` 现存条目的形状」这条结构断言(抓得住回退成单行/缩进走样,抓不住 rustfmt 版本或
|
||||
`.rustfmt.toml` 改配置带来的排版变化)。
|
||||
* **ref 门只在本地验证过**(抽 `run:` 块用 Git Bash 跑 + 接线用例的文本变异),没有在真 Actions 上看过
|
||||
`secrets` 的求值结果 —— 第一次真跑请确认非 main ref 的 ② 显示「未判定」。
|
||||
|
||||
@@ -187,4 +192,4 @@ python3 packaging/sign_manifest.py --verify-pinned /tmp/verify/manifest.json
|
||||
| `packaging/tests/signing_ready_wiring_selftest.py` | 接线自测:不是门禁 / 不被 `uses:` / **ref 门** / 文档路径存在性 + 三处变异 |
|
||||
| `.github/workflows/signing-status.yml` | 把三行搬进 job summary 的**播报** workflow(不是门禁;种子只在 main 注入) |
|
||||
| `packaging/docs/signing.md` | 为什么签名、威胁模型、轮换纪律、四条发布侧命令的红法对照表 |
|
||||
| `packaging/sign_manifest.py` | 生成钥 / 签名 / 对账 / 回验的唯一实现(`--self-test` 跑 RFC 8032 向量) |
|
||||
| `packaging/sign_manifest.py` | 生成钥 / 签名 / 对账 / 回验的唯一实现(`--self-test` 跑 RFC 8032 向量 + 粘贴块形态) |
|
||||
Reference in new issue
Block a user