Hello community,
here is the log from the commit of package ima-evm-utils for openSUSE:Factory checked in at 2015-12-03 13:32:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ima-evm-utils (Old)
and /work/SRC/openSUSE:Factory/.ima-evm-utils.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ima-evm-utils"
Changes:
--------
--- /work/SRC/openSUSE:Factory/ima-evm-utils/ima-evm-utils.changes 2015-01-24 22:20:42.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.ima-evm-utils.new/ima-evm-utils.changes 2015-12-03 13:32:51.000000000 +0100
@@ -1,0 +2,10 @@
+Wed Dec 2 13:44:58 UTC 2015 - p.drouand@gmail.com
+
+- Update to version 1.0
+ * Recursive hashing
+ * Immutable EVM signatures (experimental)
+ * Command 'ima_clear' to remove xattrs
+ * Support for passing password to the library
+ * Support for asking password safely from the user
+
+-------------------------------------------------------------------
Old:
----
ima-evm-utils-0.9.tar.gz
New:
----
ima-evm-utils-1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ima-evm-utils.spec ++++++
--- /var/tmp/diff_new_pack.Zwvqf7/_old 2015-12-03 13:32:51.000000000 +0100
+++ /var/tmp/diff_new_pack.Zwvqf7/_new 2015-12-03 13:32:51.000000000 +0100
@@ -19,12 +19,12 @@
%define libname libimaevm%{sover}
Name: ima-evm-utils
-Version: 0.9
+Version: 1.0
Release: 0
Summary: IMA/EVM control utility
License: LGPL-2.1+
Group: System/Libraries
-URL: http://sourceforge.net/projects/linux-ima/
+Url: http://sourceforge.net/projects/linux-ima/
Source0: http://downloads.sourceforge.net/project/linux-ima/ima-evm-utils/%{name}-%{version}.tar.gz
Patch2: ima-evm-utils-fix-docbook-xsl-directory.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
++++++ ima-evm-utils-0.9.tar.gz -> ima-evm-utils-1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ima-evm-utils-0.9/ChangeLog new/ima-evm-utils-1.0/ChangeLog
--- old/ima-evm-utils-0.9/ChangeLog 2014-09-23 14:09:05.000000000 +0200
+++ new/ima-evm-utils-1.0/ChangeLog 2015-07-30 20:28:53.000000000 +0200
@@ -1,3 +1,12 @@
+2014-07-30 Dmitry Kasatkin
+
+ version 1.0
+ * Recursive hashing
+ * Immutable EVM signatures (experimental)
+ * Command 'ima_clear' to remove xattrs
+ * Support for passing password to the library
+ * Support for asking password safely from the user
+
2014-09-23 Dmitry Kasatkin
version 0.9
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ima-evm-utils-0.9/README new/ima-evm-utils-1.0/README
--- old/ima-evm-utils-0.9/README 2014-09-23 14:09:05.000000000 +0200
+++ new/ima-evm-utils-1.0/README 2015-07-30 20:28:53.000000000 +0200
@@ -403,7 +403,7 @@
Latest version of keyctl allows to import X509 public key certificates:
- cat /etc/keys/x509_ima.der | keyctl padd asymmetric '' @ima_id
+ cat /etc/keys/x509_ima.der | keyctl padd asymmetric '' $ima_id
FILES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ima-evm-utils-0.9/configure.ac new/ima-evm-utils-1.0/configure.ac
--- old/ima-evm-utils-0.9/configure.ac 2014-09-23 14:09:05.000000000 +0200
+++ new/ima-evm-utils-1.0/configure.ac 2015-07-30 20:28:53.000000000 +0200
@@ -1,7 +1,7 @@
# autoconf script
AC_PREREQ([2.65])
-AC_INIT(ima-evm-utils, 0.9, d.kasatkin@samsung.com)
+AC_INIT(ima-evm-utils, 1.0, dmitry.kasatkin@huawei.com)
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ima-evm-utils-0.9/packaging/ima-evm-utils.spec new/ima-evm-utils-1.0/packaging/ima-evm-utils.spec
--- old/ima-evm-utils-0.9/packaging/ima-evm-utils.spec 2014-09-23 14:09:05.000000000 +0200
+++ new/ima-evm-utils-1.0/packaging/ima-evm-utils.spec 2015-07-30 20:28:53.000000000 +0200
@@ -1,5 +1,5 @@
Name: ima-evm-utils
-Version: 0.9
+Version: 1.0
Release: 1%{?dist}
Summary: ima-evm-utils - IMA/EVM control utility
Group: System/Libraries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ima-evm-utils-0.9/src/evmctl.c new/ima-evm-utils-1.0/src/evmctl.c
--- old/ima-evm-utils-0.9/src/evmctl.c 2014-09-23 14:09:05.000000000 +0200
+++ new/ima-evm-utils-1.0/src/evmctl.c 2015-07-30 20:28:53.000000000 +0200
@@ -54,6 +54,7 @@
#include
#include
#include
+#include
#include
#include
@@ -107,6 +108,7 @@
static int recursive;
static int msize;
static dev_t fs_dev;
+static bool evm_immutable;
#define HMAC_FLAG_UUID 0x0001
#define HMAC_FLAG_UUID_SET 0x0002
@@ -318,24 +320,25 @@
return -1;
}
- if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) {
- /* we cannot at the momement to get generation of special files..
- * kernel API does not support it */
- int fd = open(file, 0);
+ if (!evm_immutable) {
+ if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) {
+ /* we cannot at the momement to get generation of special files..
+ * kernel API does not support it */
+ int fd = open(file, 0);
- if (fd < 0) {
- log_err("Failed to open: %s\n", file);
- return -1;
- }
- if (ioctl(fd, FS_IOC_GETVERSION, &generation)) {
- log_err("ioctl() failed\n");
- return -1;
+ if (fd < 0) {
+ log_err("Failed to open: %s\n", file);
+ return -1;
+ }
+ if (ioctl(fd, FS_IOC_GETVERSION, &generation)) {
+ log_err("ioctl() failed\n");
+ return -1;
+ }
+ close(fd);
}
- close(fd);
+ log_info("generation: %u\n", generation);
}
- log_info("generation: %u\n", generation);
-
list_size = llistxattr(file, list, sizeof(list));
if (list_size < 0) {
log_err("llistxattr() failed\n");
@@ -370,7 +373,14 @@
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;
hmac_size = sizeof(*hmac);
@@ -408,7 +418,7 @@
return 1;
}
- if (hmac_flags & HMAC_FLAG_UUID) {
+ if (!evm_immutable && (hmac_flags & HMAC_FLAG_UUID)) {
err = get_uuid(&st, uuid);
if (err)
return -1;
@@ -439,7 +449,7 @@
if (len <= 1)
return len;
- len = sign_hash("sha1", hash, len, key, sig + 1);
+ len = sign_hash("sha1", hash, len, key, NULL, sig + 1);
if (len <= 1)
return len;
@@ -447,6 +457,9 @@
len++;
sig[0] = EVM_IMA_XATTR_DIGSIG;
+ if (evm_immutable)
+ sig[1] = 3; /* immutable signature version */
+
if (sigdump || params.verbose >= LOG_INFO)
dump(sig, len);
@@ -499,19 +512,6 @@
return 0;
}
-static int cmd_hash_ima(struct command *cmd)
-{
- char *file = g_argv[optind++];
-
- if (!file) {
- log_err("Parameters missing\n");
- print_usage(cmd);
- return -1;
- }
-
- return hash_ima(file);
-}
-
static int sign_ima(const char *file, const char *key)
{
unsigned char hash[64];
@@ -522,7 +522,7 @@
if (len <= 1)
return len;
- len = sign_hash(params.hash_algo, hash, len, key, sig + 1);
+ len = sign_hash(params.hash_algo, hash, len, key, NULL, sig + 1);
if (len <= 1)
return len;
@@ -577,21 +577,12 @@
return dts;
}
-static int sign_ima_file(const char *file)
-{
- char *key;
-
- key = params.keyfile ? : "/etc/keys/privkey_evm.pem";
-
- return sign_ima(file, key);
-}
-
-static int cmd_sign_ima(struct command *cmd)
+static int do_cmd(struct command *cmd, find_cb_t func)
{
- char *file = g_argv[optind++];
+ char *path = g_argv[optind++];
int err, dts = REG_MASK; /* only regular files by default */
- if (!file) {
+ if (!path) {
log_err("Parameters missing\n");
print_usage(cmd);
return -1;
@@ -599,21 +590,41 @@
if (recursive) {
if (search_type) {
- dts = get_file_type(file, search_type);
+ dts = get_file_type(path, search_type);
if (dts < 0)
return dts;
}
- err = find(file, dts, sign_ima_file);
+ err = find(path, dts, func);
} else {
- err = sign_ima_file(file);
+ err = func(path);
}
return err;
}
+static int cmd_hash_ima(struct command *cmd)
+{
+ return do_cmd(cmd, hash_ima);
+}
+
+static int sign_ima_file(const char *file)
+{
+ const char *key;
+
+ key = params.keyfile ? : "/etc/keys/privkey_evm.pem";
+
+ return sign_ima(file, key);
+}
+
+static int cmd_sign_ima(struct command *cmd)
+{
+ return do_cmd(cmd, sign_ima_file);
+}
+
static int cmd_sign_hash(struct command *cmd)
{
- char *key, *token, *line = NULL;
+ const char *key;
+ char *token, *line = NULL;
int hashlen = 0;
size_t line_len;
ssize_t len;
@@ -635,7 +646,7 @@
hex2bin(hash, line, hashlen);
siglen = sign_hash(params.hash_algo, hash, hashlen/2,
- key, sig + 1);
+ key, NULL, sig + 1);
if (siglen <= 1)
return siglen;
@@ -656,7 +667,7 @@
static int sign_evm_path(const char *file)
{
- char *key;
+ const char *key;
int err;
key = params.keyfile ? : "/etc/keys/privkey_evm.pem";
@@ -678,27 +689,7 @@
static int cmd_sign_evm(struct command *cmd)
{
- char *path = g_argv[optind++];
- int err, dts = REG_MASK; /* only regular files by default */
-
- if (!path) {
- log_err("Parameters missing\n");
- print_usage(cmd);
- return -1;
- }
-
- if (recursive) {
- if (search_type) {
- dts = get_file_type(path, search_type);
- if (dts < 0)
- return dts;
- }
- err = find(path, dts, sign_evm_path);
- } else {
- err = sign_evm_path(path);
- }
-
- return err;
+ return do_cmd(cmd, sign_evm_path);
}
static int verify_evm(const char *file)
@@ -1012,7 +1003,7 @@
static int cmd_hmac_evm(struct command *cmd)
{
- char *key, *file = g_argv[optind++];
+ const char *key, *file = g_argv[optind++];
int err;
if (!file) {
@@ -1129,29 +1120,22 @@
static int cmd_ima_fix(struct command *cmd)
{
- char *path = g_argv[optind++];
- int err, dts = REG_MASK; /* only regular files by default */
-
- if (!path) {
- log_err("Parameters missing\n");
- print_usage(cmd);
- return -1;
- }
+ return do_cmd(cmd, ima_fix);
+}
- if (recursive) {
- if (search_type) {
- dts = get_file_type(path, search_type);
- if (dts < 0)
- return dts;
- }
- err = find(path, dts, ima_fix);
- } else {
- err = ima_fix(path);
- }
+static int ima_clear(const char *path)
+{
+ log_info("%s\n", path);
+ lremovexattr(path, "security.ima");
+ lremovexattr(path, "security.evm");
- return err;
+ return 0;
}
+static int cmd_ima_clear(struct command *cmd)
+{
+ return do_cmd(cmd, ima_clear);
+}
static char *pcrs = "/sys/class/misc/tpm0/device/pcrs";
@@ -1485,14 +1469,15 @@
{"--version", NULL, 0, ""},
{"help", cmd_help, 0, "<command>"},
{"import", cmd_import, 0, "[--rsa] pubkey keyring", "Import public key into the keyring.\n"},
- {"sign", cmd_sign_evm, 0, "[-r] [--imahash | --imasig ] [--key key] [--pass password] file", "Sign file metadata.\n"},
+ {"sign", cmd_sign_evm, 0, "[-r] [--imahash | --imasig ] [--key key] [--pass [password] file", "Sign file metadata.\n"},
{"verify", cmd_verify_evm, 0, "file", "Verify EVM signature (for debugging).\n"},
- {"ima_sign", cmd_sign_ima, 0, "[--sigfile] [--key key] [--pass password] file", "Make file content signature.\n"},
+ {"ima_sign", cmd_sign_ima, 0, "[--sigfile] [--key key] [--pass [password] file", "Make file content signature.\n"},
{"ima_verify", cmd_verify_ima, 0, "file", "Verify IMA signature (for debugging).\n"},
{"ima_hash", cmd_hash_ima, 0, "file", "Make file content hash.\n"},
{"ima_measurement", cmd_ima_measurement, 0, "file", "Verify measurement list (experimental).\n"},
{"ima_fix", cmd_ima_fix, 0, "[-t fdsxm] path", "Recursively fix IMA/EVM xattrs in fix mode.\n"},
- {"sign_hash", cmd_sign_hash, 0, "[--key key] [--pass password]", "Sign hashes from shaXsum output.\n"},
+ {"ima_clear", cmd_ima_clear, 0, "[-t fdsxm] path", "Recursively remove IMA/EVM xattrs.\n"},
+ {"sign_hash", cmd_sign_hash, 0, "[--key key] [--pass [password]", "Sign hashes from shaXsum output.\n"},
#ifdef DEBUG
{"hmac", cmd_hmac_evm, 0, "[--imahash | --imasig ] file", "Sign file metadata with HMAC using symmetric key (for testing purpose).\n"},
#endif
@@ -1504,7 +1489,7 @@
{"imasig", 0, 0, 's'},
{"imahash", 0, 0, 'd'},
{"hashalgo", 1, 0, 'a'},
- {"pass", 1, 0, 'p'},
+ {"pass", 2, 0, 'p'},
{"sigfile", 0, 0, 'f'},
{"uuid", 2, 0, 'u'},
{"rsa", 0, 0, '1'},
@@ -1519,6 +1504,40 @@
};
+static char *get_password(void)
+{
+ struct termios flags, tmp_flags;
+ char *password, *pwd;
+ int passlen = 64;
+
+ password = malloc(passlen);
+ if (!password) {
+ perror("malloc");
+ return NULL;
+ }
+
+ tcgetattr(fileno(stdin), &flags);
+ tmp_flags = flags;
+ tmp_flags.c_lflag &= ~ECHO;
+ tmp_flags.c_lflag |= ECHONL;
+
+ if (tcsetattr(fileno(stdin), TCSANOW, &tmp_flags) != 0) {
+ perror("tcsetattr");
+ return NULL;
+ }
+
+ printf("PEM password: ");
+ pwd = fgets(password, passlen, stdin);
+
+ /* restore terminal */
+ if (tcsetattr(fileno(stdin), TCSANOW, &flags) != 0) {
+ perror("tcsetattr");
+ return NULL;
+ }
+
+ return pwd;
+}
+
int main(int argc, char *argv[])
{
int err = 0, c, lind;
@@ -1527,7 +1546,7 @@
g_argc = argc;
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)
break;
@@ -1554,7 +1573,10 @@
params.hash_algo = optarg;
break;
case 'p':
- params.keypass = optarg;
+ if (optarg)
+ params.keypass = optarg;
+ else
+ params.keypass = get_password();
break;
case 'f':
sigfile = 1;
@@ -1573,6 +1595,9 @@
case 'k':
params.keyfile = optarg;
break;
+ case 'i':
+ evm_immutable = true;
+ break;
case 't':
search_type = optarg;
break;
@@ -1600,9 +1625,6 @@
}
}
- OpenSSL_add_all_algorithms();
- ERR_load_crypto_strings();
-
if (argv[optind] == NULL)
usage();
else
@@ -1623,6 +1645,6 @@
ERR_free_strings();
EVP_cleanup();
-
+ BIO_free(NULL);
return err;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ima-evm-utils-0.9/src/imaevm.h new/ima-evm-utils-1.0/src/imaevm.h
--- old/ima-evm-utils-0.9/src/imaevm.h 2014-09-23 14:09:05.000000000 +0200
+++ new/ima-evm-utils-1.0/src/imaevm.h 2015-07-30 20:28:53.000000000 +0200
@@ -108,6 +108,12 @@
unsigned short mode;
};
+struct h_misc_digsig {
+ uid_t uid;
+ gid_t gid;
+ unsigned short mode;
+};
+
enum pubkey_algo {
PUBKEY_ALGO_RSA,
PUBKEY_ALGO_MAX,
@@ -172,8 +178,8 @@
int verbose;
int x509;
const char *hash_algo;
- char *keyfile;
- char *keypass;
+ const char *keyfile;
+ const char *keypass;
};
struct RSA_ASN1_template {
@@ -195,7 +201,7 @@
void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key);
int key2bin(RSA *key, unsigned char *pub);
-int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, unsigned char *sig);
+int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen);
int ima_verify_signature(const char *file, unsigned char *sig, int siglen);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ima-evm-utils-0.9/src/libimaevm.c new/ima-evm-utils-1.0/src/libimaevm.c
--- old/ima-evm-utils-0.9/src/libimaevm.c 2014-09-23 14:09:05.000000000 +0200
+++ new/ima-evm-utils-1.0/src/libimaevm.c 2015-07-30 20:28:53.000000000 +0200
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include "imaevm.h"
@@ -130,6 +131,8 @@
.hash_algo = "sha1",
};
+static void __attribute__ ((constructor)) libinit(void);
+
void do_dump(FILE *fp, const void *ptr, int len, bool cr)
{
int i;
@@ -488,7 +491,7 @@
int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen)
{
- char *key;
+ const char *key;
int x509;
verify_hash_fn_t verify_hash;
@@ -608,7 +611,7 @@
free(pkey);
}
-static RSA *read_priv_key(const char *keyfile, char *keypass)
+static RSA *read_priv_key(const char *keyfile, const char *keypass)
{
FILE *fp;
RSA *key;
@@ -618,9 +621,14 @@
log_err("Failed to open keyfile: %s\n", keyfile);
return NULL;
}
- key = PEM_read_RSAPrivateKey(fp, NULL, NULL, keypass);
- if (!key)
- log_err("PEM_read_RSAPrivateKey() failed\n");
+ ERR_load_crypto_strings();
+ key = PEM_read_RSAPrivateKey(fp, NULL, NULL, (void *)keypass);
+ if (!key) {
+ char str[256];
+
+ ERR_error_string(ERR_get_error(), str);
+ log_err("PEM_read_RSAPrivateKey() failed: %s\n", str);
+ }
fclose(fp);
return key;
@@ -786,8 +794,18 @@
return len;
}
-int sign_hash(const char *hashalgo, const unsigned char *hash, int size, const char *keyfile, unsigned char *sig)
+
+int sign_hash(const char *hashalgo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig)
{
+ if (keypass)
+ params.keypass = keypass;
+
return params.x509 ? sign_hash_v2(hashalgo, hash, size, keyfile, sig) :
sign_hash_v1(hashalgo, hash, size, keyfile, sig);
}
+
+static void libinit()
+{
+ OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+}