我想将IMA / EVM的证书加载到Linux密钥环中。
相关的shell命令是
ima_id=`keyctl newring _ima @u`
evm_id=`keyctl newring _evm @u`
evmctl import /etc/keys/x509_ima.der $ima_id
evmctl import /etc/keys/x509_evm.der $evm_id
除了权限问题之外,这几乎可以正常工作。
# keyctl show @u
Keyring
272896171 --alswrv 0 65534 keyring: _uid.0
406281657 --alswrv 0 0 \_ keyring: _ima
keyctl_read: Permission denied
在网络上搜索,我发现:https://github.com/systemd/systemd/issues/5522
解决方法是链接密钥环:
keyctl link @us @s
如果我在引导后在外壳上输入以下命令,则可以看到这些键:
# keyctl show @u
Keyring
272896171 --alswrv 0 65534 keyring: _uid.0
406281657 --alswrv 0 0 \_ keyring: _ima
647882074 --als--v 0 0 | \_ asymmetric: abc: gerhard signing key: 15733607aff5480b5eb8b59b501760f9c5d33965
19332842 --alswrv 0 0 \_ keyring: _evm
470827275 --als--v 0 0 \_ asymmetric: abc: gerhard signing key: 7e5959ee64090c7fabb6dd803e7d1f48e83c5970
到目前为止一切都很好...
要有用,我需要将这些内容放入initramfs
中。
我正在处理的系统是嵌入式Linux,在initramfs
期间我没有外壳。
因此,我使用syscall
来完成需要做的事情...
创建密钥环并导入密钥可以正常工作。 但是链接钥匙圈没有。
启动后,出现与上述相同的“权限被拒绝”错误。当我尝试执行具有IMA签名的文件时,也会收到错误消息。它说未找到“ _ima”钥匙圈。
如果我手动输入keyctl link @us @s
,一切都会恢复。
我的假设是在initramfs
期间与密钥环相关的内容尚未到位,但我无法掌握。
我用于链接的syscall
如下:
ret = syscall(__NR_keyctl, KEYCTL_LINK, KEY_SPEC_USER_SESSION_KEYRING, KEY_SPEC_SESSION_KEYRING, 0, 0);
我没有从通话中得到任何负面结果。
更新
我在此页面上找到了一些提示:https://mjg59.dreamwidth.org/37333.html
因此,顺序应如下:
$ keyctl add user testkey testdata @s
$ keyctl setperm 678913344 0x3f3f0000
$ keyctl link 678913344 @u
$ keyctl unlink 678913344 @s
这对密钥有效,但据我了解,对密钥环也应有效。
static void create_ima_keyring(void)
{
char *name = "_ima";
char *filename = "/etc/keys/x509_ima.der";
int ringid = syscall(__NR_add_key, "keyring", name, NULL, 0, KEY_SPEC_SESSION_KEYRING);
{
// Set permission for keyring ...
int ret = syscall(__NR_keyctl, KEYCTL_SETPERM, ringid, 0x3f3f0000, 0, 0);
// ... and link to @u
syscall(__NR_keyctl, KEYCTL_LINK, ringid, KEY_SPEC_USER_KEYRING);
int len;
unsigned char *pub = file2bin(filename, &len);
if (pub != NULL)
{
int keyid = syscall(__NR_add_key, "asymmetric", NULL, pub, len, ringid);
if (keyid >= 0)
{
int ret = syscall(__NR_keyctl, KEYCTL_SETPERM, keyid, 0x3f3f0000, 0, 0);
}
free(pub);
}
// TODO: Unlink from @s
}
}
在此示例中删除了错误处理。我没有得到任何错误结果。
现在,我从keyctl show @u
获得了预期的结果,但是仍无法识别密钥环。
执行签名的文件会再次导致错误消息:
digsig: no _ima keyring: -126
答案 0 :(得分:1)
对于您填充initramfs的实际步骤,我还不太清楚...尝试检查内容:(假设gzip压缩,也可以尝试xz / lz4 / none)
gzip -dkcq -S img '/path/to/initramfs.img' | cpio -t
我的第一个猜测是,您将发现initramfs img中不存在/etc/keys/x509-blahblah
。尤其是因为它们在启动时“未找到”,但在登录后仍可以工作。它还可能缺少必要的二进制文件/库或内核模块。
如果仅是密钥本身,则在允许的情况下将它们添加到任何initramfs生成工具的配置中应该相当简单。如果keyctl需要到同一物理存储的符号链接,则需要安排initramfs在挂载real_root之后运行任务,但是cpio可以在其中安装一个。 如果需要您手动添加加密模块,则可能会很有趣。
内核(从2.something?开始)还可以接受多个initramfs文件,它将合并。上次我查看大多数针对台式机的引导加载程序 did 可以执行此操作时,尽管在此问题上完全沉默,但...仅用键构建单独的initramfs映像就足够了并同时通过。以下应该可以创建一个。
cd /etc/keys
mkdir mkimg
find ./ -maxdepth 1 -type f |
sed 's/^[.]\///' |
cpio -o -H newc --no-absolute-filenames --renumber-inodes |
gzip -9qc - > ./mkimg/bootkeys.img'
我编写密钥的方式将在启动时将密钥转储到initramfs的根目录中,据我的经验,这比尝试合并目录要简单,但是可以根据需要进行更改。
编辑:我假设您的系统未配置为在pivot_root或某些类似的嵌入式人员事件之后联合安装rootfs?
答案 1 :(得分:0)
更多地阅读并深入研究配置后,发现还需要一个额外的配置标志。
我必须启用CONFIG_PERSISTENT_KEYRINGS=y
,现在可以使用该标志将密钥加载到initramfs
中,并在登录后稍后使用。
不再有“没有_ima keyring”投诉。