Я хочу загрузить сертификаты для IMA / EVM в цепочки ключей Linux.
Связанные команды оболочки:
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