# tasign **Repository Path**: openkylin/tasign ## Basic Information - **Project Name**: tasign - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-04-10 - **Last Updated**: 2026-05-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # tasign-trae `tasign-trae` 是一个面向 TA ELF 的签名/验签工作区,核心 crate 为 `tasign`,并提供命令行工具 `tasign-tool` 与多套演示脚本。 当前支持: - CMS/PKCS#7 detached 签名与验签 - 签名算法:`sm2-sm3`、`rsa-sha256`、`ecdsa-sha256` - 对已嵌入 `.ta_signature` 的 ELF 做整包验签(`verify-elf`) - `write-elf` 通过 `objcopy` 写入 `.ta_signature`,并设置 `noload` - GmSSL 兼容 CMS 模式(`cms-compat=gmssl`,仅 `sm2-sm3` + attached + 无中间证书) ## 快速开始 ### 1) 构建与测试 ```bash cargo build -p tasign cargo test -p tasign ``` ### 2) CLI 帮助 ```bash tasign-tool ``` 若尚未安装,可临时用: ```bash cargo run -q -p tasign --bin tasign-tool ``` 会打印完整 usage,包含这些子命令: - `sign` - `verify` - `verify-elf` - `write-elf` - `plain` - `cms-sign` - `cms-extract` ### 3) 安装 #### 非 bjca(默认) ```bash # 从当前仓库源码安装 cargo install --path ./tasign --force # 或从 crates.io 安装 cargo install tasign --force ``` #### bjca 版本 ```bash # 编译链接时给出 BJCA 库目录(包含 libsvscc.so) export BJCA_LIB_DIR=/data/work/x1/xtee-bjca export BJCA_LIB_NAME=svscc # 运行时动态库搜索路径 export LD_LIBRARY_PATH=/data/work/x1/xtee-bjca:$LD_LIBRARY_PATH # 从当前仓库源码安装 bjca 版本 cargo install --path ./tasign --features bjca --force # 或从 crates.io 安装 bjca 版本 cargo install tasign --features bjca --force ``` 安装后建议检查: ```bash which tasign-tool tasign-tool ``` 若在 bjca 命令报 `cannot find -lsvscc`,说明是**链接期**找不到库,请先确认 `BJCA_LIB_DIR`(必要时可再设置 `LIBRARY_PATH=$BJCA_LIB_DIR:$LIBRARY_PATH`)。 ## 常用工作流 ### 工作流 A:ELF 端到端签名与验签(推荐) 1. 计算 `plain.bin` 并生成 `signature.bin` 2. 将 `signature.bin` 写入 ELF 的 `.ta_signature` 3. 使用 `verify-elf` 验证(可选带根证书) 示例(以下命令可直接执行): ```bash # 先准备一个 ELF:由 fixture 源码编译生成 a.out mkdir -p ./out gcc ./tasign/tests/fixtures/real_elf_app.c -o ./out/a.out ``` #### A) 使用内建 TEST 证书 ```bash tasign-tool sign \ --elf ./out/a.out \ --out-dir ./out/test \ --leaf-cert TEST \ --intermediate-cert TEST \ --intermediate-count 1 \ --algorithm sm2-sm3 \ --leaf-key TEST \ --leaf-key-pass TEST tasign-tool write-elf \ --input-elf ./out/a.out \ --signature-bin ./out/test/signature.bin \ --output-elf ./out/test/a.out.signed \ --objcopy objcopy tasign-tool verify-elf --elf ./out/test/a.out.signed && \ tasign-tool verify-elf --elf ./out/test/a.out.signed --ca-cert TEST ``` #### B) 使用 `tasign/tests/fixtures/gmssl` 指定证书 ```bash # B1) CA -> Intermediate -> Leaf tasign-tool sign \ --elf ./out/a.out \ --out-dir ./out/gmssl \ --leaf-cert ./tasign/tests/fixtures/gmssl/leaf.der \ --intermediate-cert ./tasign/tests/fixtures/gmssl/intermediate.der \ --intermediate-count 1 \ --algorithm sm2-sm3 \ --leaf-key ./tasign/tests/fixtures/gmssl/leaf.key \ --leaf-key-pass 123456 tasign-tool write-elf \ --input-elf ./out/a.out \ --signature-bin ./out/gmssl/signature.bin \ --output-elf ./out/gmssl/a.out.signed \ --objcopy objcopy tasign-tool verify-elf --elf ./out/gmssl/a.out.signed && \ tasign-tool verify-elf --elf ./out/gmssl/a.out.signed --ca-cert ./tasign/tests/fixtures/gmssl/ca.crt ``` ```bash # B2) CA -> Leaf(无中间证书) tasign-tool sign \ --elf ./out/a.out \ --out-dir ./out/gmssl-ca-leaf \ --leaf-cert ./tasign/tests/fixtures/gmssl/ca_leaf.der \ --support-intermediates false \ --intermediate-count 0 \ --algorithm sm2-sm3 \ --leaf-key ./tasign/tests/fixtures/gmssl/ca_leaf.key \ --leaf-key-pass 123456 tasign-tool write-elf \ --input-elf ./out/a.out \ --signature-bin ./out/gmssl-ca-leaf/signature.bin \ --output-elf ./out/gmssl-ca-leaf/a.out.signed \ --objcopy objcopy tasign-tool verify-elf --elf ./out/gmssl-ca-leaf/a.out.signed && \ tasign-tool verify-elf --elf ./out/gmssl-ca-leaf/a.out.signed --ca-cert ./tasign/tests/fixtures/gmssl/ca.crt ``` #### C) 使用 BJCA(`tasign-tool` 需启用 bjca feature 构建) ```bash cargo run -q -p tasign --features bjca --bin tasign-tool -- sign \ --elf ./out/a.out \ --out-dir ./out/bjca \ --bjca true \ --bjca-config /data/work/x1/xtee-bjca/BJCA_SVS_Config.ini \ --support-intermediates false \ --intermediate-count 0 \ --algorithm sm2-sm3 cargo run -q -p tasign --features bjca --bin tasign-tool -- write-elf \ --input-elf ./out/a.out \ --signature-bin ./out/bjca/signature.bin \ --output-elf ./out/bjca/a.out.signed \ --objcopy objcopy # CA 文件可由 bjca p7b 导出并清洗为纯 CERTIFICATE PEM 后使用 cargo run -q -p tasign --features bjca --bin tasign-tool -- verify-elf --elf ./out/bjca/a.out.signed && \ cargo run -q -p tasign --features bjca --bin tasign-tool -- verify-elf --elf ./out/bjca/a.out.signed --ca-cert tasign/tests/fixtures/certs/bjcasm2-ca-only.pem ``` `cargo install` 后若未带仓库里的 `tests/fixtures/gmssl`,可在 **`sign` 三步均传字面量 `TEST`** 使用**内建测试用**叶子证书/私钥/口令(`--leaf-cert` / `--leaf-key` / `--leaf-key-pass` 须同时为 `TEST`;无中间证时加 `--support-intermediates false --intermediate-count 0`,有 1 张中间证时加 `--intermediate-cert TEST --intermediate-count 1`)。`verify` / `verify-elf` 的 `--ca-cert` 也可传 `TEST` 以使用内嵌根证书。**仅用于联调/示例,非生产。** ### 工作流 B:Detached 验签(plain + pkcs7) ```bash tasign-tool verify \ --pkcs7 signature.bin \ --plain plain.bin \ --ca-cert ca.crt ``` ### 工作流 C:仅生成/提取 CMS ```bash # 生成 CMS(pkcs7 兼容) tasign-tool cms-sign \ --plain plain.bin \ --leaf-cert leaf.der \ --intermediate-cert intermediate.der \ --intermediate-count 1 \ --cms-attached false \ --cms-out der \ --cms-compat pkcs7 \ --algorithm ecdsa-sha256 \ --leaf-key leaf.key \ --leaf-key-pass "" \ --out signature.der # 提取签名结构 tasign-tool cms-extract \ --pkcs7 signature.der \ --out-signed-attrs signed_attrs.der \ --out-sm2-sig sig.bin \ --out-leaf-cert leaf.pem ``` ## GmSSL 兼容模式说明(重点) `cms-sign` 的 `--cms-compat gmssl` 用于生成可被 `gmssl cmsverify` 识别的兼容 CMS,限制如下: - 必须 `--cms-attached true` - 只支持 `--algorithm sm2-sm3` - 当前只支持不带中间证书(`--support-intermediates false --intermediate-count 0`) 典型用法: ```bash tasign-tool cms-sign \ --plain plain.bin \ --leaf-cert leaf.der \ --support-intermediates false \ --intermediate-count 0 \ --cms-attached true \ --cms-compat gmssl \ --cms-out pem \ --algorithm sm2-sm3 \ --leaf-key leaf.key \ --leaf-key-pass 123456 \ --out signature.pem ``` 注意: - `gmssl cmsverify` 常见输入为 PEM - `.ta_signature` 内推荐写入 DER(二进制);如需兼顾两端,可先 `pem -> der` 再 `write-elf` ## 证书与 fixture 项目主要使用 `tasign/tests/fixtures/gmssl` 下的证书数据: - `ca.crt` / `intermediate.crt` / `leaf.crt` / `leaf.key` - `ca_leaf.crt` / `ca_leaf.key`(CA 直接签发 leaf,用于无中间证书场景) BJCA 相关 fixture(`tasign/tests/fixtures/certs`): - `bjcasm2.p7b`:来自麒麟桌面系统包 `certaide-kylin` 的 BJCA SM2 CA 证书链样本(PKCS#7/P7B)。 - `bjcasm2-ca.pem`:由 `bjcasm2.p7b` 导出的 PEM(`openssl pkcs7 -print_certs` 输出,可能含 `subject=`/`issuer=` 辅助行)。 - `bjcasm2-ca-only.pem`:仅保留 `-----BEGIN CERTIFICATE-----` 块的清洗版,建议直接作为 `--ca-cert` 输入。 从 `.p7b` 生成 `ca-only.pem` 示例: ```bash openssl pkcs7 -in tasign/tests/fixtures/certs/bjcasm2.p7b -print_certs -out /tmp/bjca-ca.pem awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' /tmp/bjca-ca.pem > tasign/tests/fixtures/certs/bjcasm2-ca-only.pem ``` ## 脚本索引(`scripts/`) 以下脚本在当前方案下可直接作为参考: - `scripts/tasign_elf_sign_verify_sm2_demo.sh`:SM2,CA->Intermediate->Leaf,ELF 端到端 - `scripts/tasign_elf_sign_verify_sm2_compat_gmssl_demo.sh`:SM2 + GmSSL 兼容 CMS,含 `gmssl cmsverify` - `scripts/tasign_elf_sign_verify_rsa_demo.sh`:RSA 端到端 + `openssl cms -verify` 交叉验证 - `scripts/tasign_elf_sign_verify_ecdsa_demo.sh`:ECDSA 端到端 + `openssl cms -verify` 交叉验证 - `scripts/tasign_sign_verify_external_elf_with_fixtures.sh`:对外部 ELF 使用 fixture 证书签名验签 - `scripts/tasign_verify_gmssl_crosscheck.sh`:同一签名由 tasign 与 gmssl 双端交叉验证 - `scripts/bjca_sign_write_verify_smoke.sh`:BJCA 一键冒烟(`cargo run` 方式,含 `sign`/`write-elf`/`verify-elf`,并可测试 `--bjca-config` 省略时的 `/etc/BJCA_SVS_Config.ini` 回退) - `scripts/tamper_elf_text.sh`:修改已签名 ELF 中 `.text`(或其它节)的若干字节,便于对 `verify-elf` 做篡改负例测试 `bjca_sign_write_verify_smoke.sh` 用法: ```bash # [BJCA目录] [输出目录] ./scripts/bjca_sign_write_verify_smoke.sh /data/work/x1/xtee-bjca /tmp/tasign-bjca-smoke ``` 可选环境变量: - `BJCA_HOME`/`BJCA_LIB_DIR`/`BJCA_LIB_NAME`:BJCA 库与配置目录 - `BJCA_CONFIG`:显式配置路径(不设时优先 `BJCA_HOME/BJCA_SVS_Config.ini`,再 `/etc/BJCA_SVS_Config.ini`) - `BJCA_CA_PEM`:带 CA 验证用 PEM - `SKIP_NONE_CONFIG_TEST=1`:跳过“拷贝到 `/etc` 并不传 `--bjca-config`”回退测试 `tasign_sign_verify_external_elf_with_fixtures.sh` 的第一个参数**必须是 ELF 文件**(可执行文件、`.so`、`.o` 等),不能是目录、磁盘镜像或其它非 ELF 二进制。`write-elf` 依赖 GNU `objcopy`:若文件头不是 ELF,会失败;若**是 ELF 但目标机与主机不同**(例如 **AArch64/ARM** 可执行文件在 x86 主机上处理),系统自带的 `objcopy` 可能未编入该架构支持,同样会报 `Unable to recognise the format of the input file`。此时请安装交叉 binutils,并设置环境变量,例如 `OBJCOPY=aarch64-linux-gnu-objcopy`(具体 triplet 以你的工具链为准)。自检:`file <路径>`、`readelf -h <路径>`(查看 `Machine:`)。 ## 文档 - [Plain 协议(当前实现)](docs/plain_protocol.md) ## GmSSL 依赖说明 本仓库不包含上游 [GmSSL](https://github.com/guanzhi/GmSSL) 源码。需要 `gmssl` 的脚本/流程请自行安装或本地编译。 **解析顺序**(与 `tasign-tool`、`scripts/gmssl_path_resolve.sh` 一致): 1. **显式指定**:CLI `--gmssl <路径>`,或环境变量 **`GMSSL`**(非空); 2. **`PATH`** 中第一个可执行的 `gmssl`; 3. **默认路径**:仓库根下 `./GmSSL/build/bin/gmssl`(若不存在则沿父目录查找同名路径)。 动态库:若运行时报找不到 `libgmssl`,请设置: ```bash export LD_LIBRARY_PATH=/path/to/GmSSL/build/lib:$LD_LIBRARY_PATH ``` ## 内核验签(`kernel-verify`)与 `x86_64-unknown-none` `feature = "kernel-verify"` 下导出与 `std` 相同的整包验签入口 `verify_elf_signature`(内部:`ta_signature_section_bytes` → `plain_bytes_from_signed_elf` → `verify_cms_signature_with_ca_opt`),并可通过 `VerifyLimits` / `verify_elf_signature_with_limits`(见 `tasign/src/limits.rs`)收紧对不可信 ELF、CMS 与证书链的规模约束。 `mbedtls-sys` 交叉编译到 bare-metal 目标时,`mbedtls-build-helper` 会查找 **x86_64** musl 交叉 GCC(例如 `x86_64-linux-musl-gcc`)。请先将对应工具链 `bin` 加入 `PATH`(与 AArch64 musl 工具链不是同一套): ```bash export PATH=/data/tools/x86_64-linux-musl-cross/bin/:$PATH ``` 再执行: ```bash cargo check -p tasign --no-default-features --features kernel-verify --target x86_64-unknown-none ```