Produce immutable EVM signature

'evmctl sign -i <file>' generates immutable EVM signature.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
This commit is contained in:
Dmitry Kasatkin 2014-10-29 12:32:21 +02:00
parent f805d4d0fe
commit 92033dc404
2 changed files with 39 additions and 18 deletions

View File

@ -107,6 +107,7 @@ static char *search_type;
static int recursive; static int recursive;
static int msize; static int msize;
static dev_t fs_dev; static dev_t fs_dev;
static bool evm_immutable;
#define HMAC_FLAG_UUID 0x0001 #define HMAC_FLAG_UUID 0x0001
#define HMAC_FLAG_UUID_SET 0x0002 #define HMAC_FLAG_UUID_SET 0x0002
@ -318,24 +319,25 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
return -1; return -1;
} }
if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) { if (!evm_immutable) {
/* we cannot at the momement to get generation of special files.. if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) {
* kernel API does not support it */ /* we cannot at the momement to get generation of special files..
int fd = open(file, 0); * kernel API does not support it */
int fd = open(file, 0);
if (fd < 0) { if (fd < 0) {
log_err("Failed to open: %s\n", file); log_err("Failed to open: %s\n", file);
return -1; return -1;
}
if (ioctl(fd, FS_IOC_GETVERSION, &generation)) {
log_err("ioctl() failed\n");
return -1;
}
close(fd);
} }
if (ioctl(fd, FS_IOC_GETVERSION, &generation)) { log_info("generation: %u\n", generation);
log_err("ioctl() failed\n");
return -1;
}
close(fd);
} }
log_info("generation: %u\n", generation);
list_size = llistxattr(file, list, sizeof(list)); list_size = llistxattr(file, list, sizeof(list));
if (list_size < 0) { if (list_size < 0) {
log_err("llistxattr() failed\n"); log_err("llistxattr() failed\n");
@ -370,7 +372,14 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
memset(&hmac_misc, 0, sizeof(hmac_misc)); memset(&hmac_misc, 0, sizeof(hmac_misc));
if (msize == 0) { if (evm_immutable) {
struct h_misc_digsig *hmac = (struct h_misc_digsig *)&hmac_misc;
hmac_size = sizeof(*hmac);
hmac->uid = st.st_uid;
hmac->gid = st.st_gid;
hmac->mode = st.st_mode;
} else if (msize == 0) {
struct h_misc *hmac = (struct h_misc *)&hmac_misc; struct h_misc *hmac = (struct h_misc *)&hmac_misc;
hmac_size = sizeof(*hmac); hmac_size = sizeof(*hmac);
@ -408,7 +417,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
return 1; return 1;
} }
if (hmac_flags & HMAC_FLAG_UUID) { if (!evm_immutable && (hmac_flags & HMAC_FLAG_UUID)) {
err = get_uuid(&st, uuid); err = get_uuid(&st, uuid);
if (err) if (err)
return -1; return -1;
@ -447,6 +456,9 @@ static int sign_evm(const char *file, const char *key)
len++; len++;
sig[0] = EVM_IMA_XATTR_DIGSIG; sig[0] = EVM_IMA_XATTR_DIGSIG;
if (evm_immutable)
sig[1] = 3; /* immutable signature version */
if (sigdump || params.verbose >= LOG_INFO) if (sigdump || params.verbose >= LOG_INFO)
dump(sig, len); dump(sig, len);
@ -1539,7 +1551,7 @@ int main(int argc, char *argv[])
g_argc = argc; g_argc = argc;
while (1) { while (1) {
c = getopt_long(argc, argv, "hvnsda:p:fu::k:t:r", opts, &lind); c = getopt_long(argc, argv, "hvnsda:p:fu::k:t:ri", opts, &lind);
if (c == -1) if (c == -1)
break; break;
@ -1585,6 +1597,9 @@ int main(int argc, char *argv[])
case 'k': case 'k':
params.keyfile = optarg; params.keyfile = optarg;
break; break;
case 'i':
evm_immutable = true;
break;
case 't': case 't':
search_type = optarg; search_type = optarg;
break; break;
@ -1635,6 +1650,6 @@ int main(int argc, char *argv[])
ERR_free_strings(); ERR_free_strings();
EVP_cleanup(); EVP_cleanup();
BIO_free(NULL);
return err; return err;
} }

View File

@ -108,6 +108,12 @@ struct h_misc_64 {
unsigned short mode; unsigned short mode;
}; };
struct h_misc_digsig {
uid_t uid;
gid_t gid;
unsigned short mode;
};
enum pubkey_algo { enum pubkey_algo {
PUBKEY_ALGO_RSA, PUBKEY_ALGO_RSA,
PUBKEY_ALGO_MAX, PUBKEY_ALGO_MAX,