feat(sec): 二期签名鉴权 2A 最小闭环 (agent-185) — meow_verify(Ed25519验签CLI,公钥固化,TweetNaCl+SHA256单文件) + meow_sign(宿主keygen/sign,尾部180B footer签名块,私钥仅.keys/不入库) + nyai/meow_pkg_install 验签分级(有签必验/os.meow.*无签拒装/第三方直装告警/三重绑定/原签存.mpk.src导出保留) + svc_power IPC鉴权(SO_PEERCRED→/proc/pid/exe→包名/系统身份allowlist,系统动作仅os.meow.*或系统身份) + cmd_upgrade同步签名分级防绕过
meow_verify 37e50606; nyai f2938d28; svc_power e0494eb7; launcher 24c9ee5d(含热重载) 宿主验证12项全过(正例/篡负载/篡包名/无签系统包拒/第三方直装/降级拒/导出round-trip byte-identical/verify缺失宁缺勿装/footer容忍/E2E PERM/鉴权分类) 出入: TweetNaCl替orlp/ed25519(任务允许同等实现); 读级暂仍uid==0(用户随后定案放宽到任意调用者,待改); 系统身份allowlist为启发式
This commit is contained in:
1 parent
f50abae02a
commit
3f57d7fd4f
22 files changed
+1978
-15
No files matched your search
@@ -0,0 +1,77 @@
|
||||
/* meow_sig.h — .mpk 签名块格式(MPK_SIGNATURE_DESIGN §3.1)+ 被签消息构造(§3.1)。
|
||||
*
|
||||
* .mpk = [ tar.gz bytes ......................... ] [ meow_sig_block(定长 LE)]
|
||||
*
|
||||
* meow_sig_block(packed,总长 MEOW_SIG_BLOCK_LEN):
|
||||
* char magic[8]; "MEOWSIG1"
|
||||
* uint8_t alg; 1 = ed25519
|
||||
* uint8_t flags; 0
|
||||
* uint16_t pad; (0)
|
||||
* char package[64]; 权威包名(== app.json.package == 文件名茎)
|
||||
* uint8_t payload_sha256[32];sha256(整个 .mpk 去掉尾部 footer 的其余字节)
|
||||
* uint8_t sig[64]; Ed25519(pk, msg)
|
||||
* uint32_t msg_len; 实际签名的 msg 字节数(LE)
|
||||
* uint32_t block_len; 本块总长(LE;= MEOW_SIG_BLOCK_LEN)
|
||||
*
|
||||
* 被签消息 msg = "MEOWSIG1" || alg(1B) || package_len(4B,LE) || package || payload_sha256(32B)。
|
||||
* 本文件由 meow_verify 与 meow_sign 共用(meow_sign 用相对路径 include)。 */
|
||||
#ifndef MEOW_SIG_H
|
||||
#define MEOW_SIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MEOW_SIG_MAGIC "MEOWSIG1"
|
||||
#define MEOW_SIG_MAGIC_LEN 8
|
||||
#define MEOW_SIG_ALG_ED25519 1
|
||||
#define MEOW_SIG_PKG_MAX 64
|
||||
#define MEOW_SIG_SHA256_LEN 32
|
||||
#define MEOW_SIG_SIG_LEN 64
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t magic[MEOW_SIG_MAGIC_LEN];
|
||||
uint8_t alg;
|
||||
uint8_t flags;
|
||||
uint16_t pad;
|
||||
char package[MEOW_SIG_PKG_MAX];
|
||||
uint8_t payload_sha256[MEOW_SIG_SHA256_LEN];
|
||||
uint8_t sig[MEOW_SIG_SIG_LEN];
|
||||
uint32_t msg_len;
|
||||
uint32_t block_len;
|
||||
} meow_sig_block_t;
|
||||
|
||||
#define MEOW_SIG_BLOCK_LEN (sizeof(meow_sig_block_t)) /* 定长 180 */
|
||||
|
||||
/* 按字节读取 LE 的 uint32(避免 packed 解引用对齐告警) */
|
||||
static inline uint32_t meow_le32(const uint8_t *p)
|
||||
{
|
||||
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) |
|
||||
((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
|
||||
}
|
||||
static inline void meow_le32_put(uint8_t *p, uint32_t v)
|
||||
{
|
||||
p[0] = (uint8_t)(v & 0xff);
|
||||
p[1] = (uint8_t)((v >> 8) & 0xff);
|
||||
p[2] = (uint8_t)((v >> 16) & 0xff);
|
||||
p[3] = (uint8_t)((v >> 24) & 0xff);
|
||||
}
|
||||
|
||||
#define MEOW_SIG_MSG_MAX (MEOW_SIG_MAGIC_LEN + 1 + 4 + MEOW_SIG_PKG_MAX + MEOW_SIG_SHA256_LEN)
|
||||
|
||||
/* 按设计构造被签消息 msg = "MEOWSIG1" || alg(1B) || package_len(4B,LE) || package || payload_sha256(32B)。
|
||||
* 返回 msg 字节数。签名端与验签端必须用同一构造(meow_sign / meow_verify 共用)。 */
|
||||
static inline unsigned meow_sig_msg_build(char *out, const char *package,
|
||||
const uint8_t payload_sha256[MEOW_SIG_SHA256_LEN])
|
||||
{
|
||||
unsigned pkg_len = (unsigned)strlen(package);
|
||||
if (pkg_len > MEOW_SIG_PKG_MAX) pkg_len = MEOW_SIG_PKG_MAX;
|
||||
unsigned o = 0;
|
||||
memcpy(out + o, MEOW_SIG_MAGIC, MEOW_SIG_MAGIC_LEN); o += MEOW_SIG_MAGIC_LEN;
|
||||
out[o++] = MEOW_SIG_ALG_ED25519;
|
||||
meow_le32_put((uint8_t *)out + o, (uint32_t)pkg_len); o += 4;
|
||||
memcpy(out + o, package, pkg_len); o += pkg_len;
|
||||
memcpy(out + o, payload_sha256, MEOW_SIG_SHA256_LEN); o += MEOW_SIG_SHA256_LEN;
|
||||
return o;
|
||||
}
|
||||
|
||||
#endif /* MEOW_SIG_H */
|
||||
Reference in new issue
Block a user