Merge branch 'feat/m201-cfgkeyring-compile-time-strip-of-th'
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / unsafe 落点守门(集合必须恰好等于期望) (push) Canceled after 0s
Guards / design 零第三方依赖守门 (push) Canceled after 0s
Guards / presenter 零 UI 守门 (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Dev Guards / 架构与合规守门(同 main 口径) (push) Canceled after 0s
Dev Guards / fmt (rustfmt --check) (push) Canceled after 0s
Dev Guards / clippy (ubuntu) (push) Canceled after 0s

This commit is contained in:
AskaEth committed 2026-11-09 08:37:18 +08:00
commit 56402d97a1
1 file changed
+42 -14
+42 -14
View File
@@ -38,7 +38,8 @@
//! 测试/验收构建另有一把**只在** `cfg(test)` / `update-test-source` / `update-test-key` 三档里存在的 //! 测试/验收构建另有一把**只在** `cfg(test)` / `update-test-source` / `update-test-key` 三档里存在的
//! 测试钥(三档的口径见下面 `keyring()`):它的私钥种子就写在测试夹具里、公开可见,因此它可以签出 //! 测试钥(三档的口径见下面 `keyring()`):它的私钥种子就写在测试夹具里、公开可见,因此它可以签出
//! 「本仓库自己认得」的清单,但对任何正式构建毫无意义(正式表里没有它,`keyring()` 也不会把它并进 //! 「本仓库自己认得」的清单,但对任何正式构建毫无意义(正式表里没有它,`keyring()` 也不会把它并进
//! 信任表)。后两档(那两个 feature)各由 `packaging/check_test_source_off.py` / //! 信任表,而且那条目根本不进编译 —— 三档都不开的产物里连它的字节都没有,读数见 `keyring()`)。
//! 后两档(那两个 feature)各由 `packaging/check_test_source_off.py` /
//! `check_test_key_off.py` 守着 ——正式发布流水线与打包脚本都不许打开它们。 //! `check_test_key_off.py` 守着 ——正式发布流水线与打包脚本都不许打开它们。
//! (`cfg(test)` 那档不需要守门:发布构建里根本没有 `test` cfg。) //! (`cfg(test)` 那档不需要守门:发布构建里根本没有 `test` cfg。)
@@ -67,11 +68,24 @@ pub(crate) const PRODUCTION: &[PinnedKey] = &[
/// ///
/// 公钥由 `tests/support.rs` 里那串公开可见的 32 字节种子推出来(种子 = `ull-m190-test-key-seed-000000001`), /// 公钥由 `tests/support.rs` 里那串公开可见的 32 字节种子推出来(种子 = `ull-m190-test-key-seed-000000001`),
/// 两者一旦漂开,`tests/signature_cases.rs::pinned_test_key_matches_the_test_seed` 会当场红。 /// 两者一旦漂开,`tests/signature_cases.rs::pinned_test_key_matches_the_test_seed` 会当场红。
///
/// ⚠ 这个 `#[cfg]` 是**编译期剔除**,不是 `cfg!()` 那种「运行期值为假的分支」:不在这三档里时,
/// 下面这条条目根本不进编译(只剩再下面那条同名空表),所以那串十六进制与它的 `key_id`
/// 在产物里连字节都没有 —— 读数是实测的,见 `keyring()` 文档末尾那段。
#[cfg(any(test, feature = "update-test-source", feature = "update-test-key"))]
pub(crate) const TEST_ONLY: &[PinnedKey] = &[PinnedKey { pub(crate) const TEST_ONLY: &[PinnedKey] = &[PinnedKey {
key_id: "test-only-key", key_id: "test-only-key",
public_key_hex: "f3ea49a34ebda73d6500c9416f425e0358baf094b957baf3ea7daa6df63e876b", public_key_hex: "f3ea49a34ebda73d6500c9416f425e0358baf094b957baf3ea7daa6df63e876b",
}]; }];
/// 三档之外的 `TEST_ONLY`:空表。
///
/// 它存在的唯一目的,是让 [`keyring()`] 里那段「把测试钥并进来」的代码在**两档里写法一致**
/// (`keys` 的 `mut` 在两档里都有用处,不至于为 `unused_mut` 单独开 lint 口子)。空表本身就是
/// 「这段字节不在产物里」的全部内容 —— 真条目在上一档里。
#[cfg(not(any(test, feature = "update-test-source", feature = "update-test-key")))]
pub(crate) const TEST_ONLY: &[PinnedKey] = &[];
/// 本构建实际的信任锚(正式表 + 仅测试构建才有的那把测试钥)。 /// 本构建实际的信任锚(正式表 + 仅测试构建才有的那把测试钥)。
/// ///
/// 三档「仅测试」的口径,逐档说明为什么需要它: /// 三档「仅测试」的口径,逐档说明为什么需要它:
@@ -82,25 +96,39 @@ pub(crate) const TEST_ONLY: &[PinnedKey] = &[PinnedKey {
/// | `update-test-source` | CLI 的端到端验收(`--features update-test-source`) | 那是**另一个 target**,`cfg(test)` 不生效 | /// | `update-test-source` | CLI 的端到端验收(`--features update-test-source`) | 那是**另一个 target**,`cfg(test)` 不生效 |
/// | `update-test-key` | `crates/presenter` 的 `[dev-dependencies]` | presenter 的更新链路用例编译 core 时既无 `cfg(test)`,也不该打开 `update-test-source`(那条会同时给出「本地目录当更新源」这条路)。这一档**只**加一把公开的测试公钥,不开任何数据源开关 | /// | `update-test-key` | `crates/presenter` 的 `[dev-dependencies]` | presenter 的更新链路用例编译 core 时既无 `cfg(test)`,也不该打开 `update-test-source`(那条会同时给出「本地目录当更新源」这条路)。这一档**只**加一把公开的测试公钥,不开任何数据源开关 |
/// ///
/// 三者都**不会被 `keyring()` 并进信任表**:正式构建永远不认这把测试钥(官方构建三个 feature 都不开, /// 三档都不开的构建里,这把测试钥**既不被并进信任表,也不会被编进产物**(官方构建三个 feature 都不开,
/// 且 `check_test_source_off.py` / `check_test_key_off.py` 守着)。 /// 且 `check_test_source_off.py` / `check_test_key_off.py` 守着)。
/// ///
/// ⚠ **别把这句话读成「产物里没有这段字节」**:这里的门是 `cfg!()`,它只让分支**不可达**,不是 /// 这是**编译期**结论,不是运行期判据:门是 `#[cfg]`(三档之外 `TEST_ONLY` 只剩上面那条空表,
/// `#[cfg]` 的编译期剔除 —— `TEST_ONLY` 的**字节**照编在产物里(实测:无 feature 的 dev 与 /// 真条目根本不进编译),而不是 `cfg!()` 那种「运行期值为假的分支」—— 后者会把那段字节照编进产物。
/// `--release` 两档 core rlib 里,公钥十六进制与 `test-only-key` 都还在)。「字节级不在产物里」 ///
/// 这一点**未证**、也未在此声称;它与「装不上公开种子签出来的清单」无关(信任表里没有它,验签仍 /// 实测读数(本机 Windows + Git Bash,`grep -ac` 数的是命中行数,`grep` 退出码 1 = 零命中;
/// fail-closed)。要换成 `#[cfg]` 让字节真的消失,是另一条结构性改动。 /// `$HEX` = 上文 `TEST_ONLY` 里的 `public_key_hex`,`$KID` = 那条的 `key_id`):
///
/// ```text
/// $ CARGO_TARGET_DIR=... cargo build -p unlucky-core --lib # exit 0
/// $ grep -ac "$HEX" .../debug/libunlucky_core.rlib # 0
/// $ grep -ac "$KID" .../debug/libunlucky_core.rlib # 0
/// $ CARGO_TARGET_DIR=... cargo build -p unlucky-core --lib --release # exit 0
/// $ grep -ac "$HEX" .../release/libunlucky_core.rlib # 0
/// $ grep -ac "$KID" .../release/libunlucky_core.rlib # 0
/// $ CARGO_TARGET_DIR=...-key cargo build -p unlucky-core --lib --features update-test-key # exit 0
/// $ grep -ac "$HEX" ...-key/debug/libunlucky_core.rlib # 2
/// $ grep -ac "$KID" ...-key/debug/libunlucky_core.rlib # 2
/// ```
///
/// (最后两行是对照臂:真打开那一档时这两串**都在**,所以前六行的 0 不是「grep 坏了」。)
///
/// ⚠ 这份读数只到 **rlib 为止**:core 的 `--lib` 产物里没有那两串字节。**未验**的是最终链接出来的
/// exe 在 `lto = "fat"` + `strip = "symbols"` 之后是否还有那段字节 —— 那是链接期与 strip 的事,
/// 本条的判据(编译期剔除)管不到,别把上面六行读成「exe 里也不可能有」。另:无论有没有那段字节,
/// 验签都 fail-closed(信任表里没有这把钥)。
pub(crate) fn keyring() -> &'static [PinnedKey] { pub(crate) fn keyring() -> &'static [PinnedKey] {
static ALL: OnceLock<Vec<PinnedKey>> = OnceLock::new(); static ALL: OnceLock<Vec<PinnedKey>> = OnceLock::new();
ALL.get_or_init(|| { ALL.get_or_init(|| {
let mut keys = PRODUCTION.to_vec(); let mut keys = PRODUCTION.to_vec();
if cfg!(any( // 三档之外 `TEST_ONLY` 是上面那条空表,这一段等于什么都没并;三档之内才是真条目。
test, keys.extend_from_slice(TEST_ONLY);
feature = "update-test-source",
feature = "update-test-key"
)) {
keys.extend_from_slice(TEST_ONLY);
}
keys keys
}) })
} }