[ima-evm-utils 2/5] evmctl: Allow importing external signature

Vivek Goyal vgoyal at redhat.com
Fri Sep 6 19:38:21 UTC 2013


It is possible that one uses external cryptographic engine to create
RSA PKCS1.5 signature of a file. Import these signatures and wrap it with
IMA specific metadata to convert it into IMA signature.

For example, one could do following.

$ echo "Hello World" > /tmp/data.txt
$ openssl dgst -sha256 -sign signing_key.priv.pem -out /tmp/data.sig /tmp/data.txt
$ evmctl ima_sig_import -x -a sha256 -k signing_key.x509.der /tmp/data.sig /tmp/data.txt

# Verify  signature
$ evmctl ima_verify -k signing_key.x509.der /tmp/data.txt

Signed-off-by: Vivek Goyal <vgoyal at redhat.com>
---
 src/evmctl.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/src/evmctl.c b/src/evmctl.c
index e24b9ed..3679e68 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1133,6 +1133,89 @@ static int cmd_sign_evm(struct command *cmd)
 	return sign_evm(file, key);
 }
 
+static int ima_sig_import_v2(const char *hashalgo, const char *keyfile, const char *rawsigfile, const char *file)
+{
+	unsigned char *rawsig;
+	int rawsigsz, len, ret = 0, memlock_len;
+	unsigned char sig[1024] = "\x03";
+	char name[20];
+	struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)(sig + 1);
+	RSA *key;
+
+	rawsig = file2bin(rawsigfile, NULL, &rawsigsz);
+	if (!rawsig) {
+		log_err("Unable to read file %s\n", rawsigfile);
+		return 1;
+	}
+
+	key = read_pub_key(keyfile);
+	if (!key) {
+		free(rawsig);
+		return 1;
+	}
+
+	hdr->version = 2;
+	hdr->hash_algo = get_hash_algo(hashalgo);
+
+	calc_keyid_v2(&hdr->keyid, name, key);
+	memcpy(hdr->sig, rawsig, rawsigsz);
+
+	len = rawsigsz;
+	hdr->sig_size = __cpu_to_be16(len);
+	len += sizeof(*hdr);
+	log_info("evm/ima signature: %d bytes\n", len);
+	if (sigdump || verbose >= LOG_INFO)
+		dump(sig + 1, len);
+
+	/* Add ima header */
+	len++;
+	if (memlock) {
+		memlock_len = add_memlock_info(sig + len);
+		len += memlock_len;
+	}
+
+	if (sigfile)
+		bin2file(file, "sig", sig, len);
+
+	if (xattr) {
+		ret = setxattr(file, "security.ima", sig, len, 0);
+		if (ret < 0) {
+			log_err("setxattr failed: %s\n", file);
+			goto out;
+		}
+	}
+
+out:
+	RSA_free(key);
+	free(rawsig);
+	return ret;
+}
+
+static int cmd_ima_sig_import(struct command *cmd)
+{
+	char *rawsigfile, *file, *key;
+
+	rawsigfile = g_argv[optind++];
+	file = g_argv[optind++];
+
+	if (!file || !rawsigfile) {
+		log_err("Parameters missing\n");
+		print_usage(cmd);
+		return -1;
+	}
+
+	key = keyfile ? : x509 ?
+			"/etc/keys/x509_evm.der" :
+			"/etc/keys/pubkey_evm.pem";
+
+	if (x509)
+		return ima_sig_import_v2(hash_algo, key, rawsigfile, file);
+	else {
+		log_err("Signature version 1 import not supported.\n");
+		return 1;
+	}
+}
+
 static int verify_hash_v1(const unsigned char *hash, int size, unsigned char *sig, int siglen, const char *keyfile)
 {
 	int err, len;
@@ -1694,6 +1777,7 @@ struct command cmds[] = {
 #ifdef DEBUG
 	{"hmac", cmd_hmac_evm, 0, "[--imahash | --imasig ] file", "Sign file metadata with HMAC using symmetric key (for testing purpose).\n"},
 #endif
+	{"ima_sig_import", cmd_ima_sig_import, 0, "[--x509] [-a hashalgo] [-k pubkey] signature file", "Make IMA signature from externally signed raw signature blob.\n"},
 	{0, 0, 0, NULL}
 };
 
-- 
1.8.3.1



More information about the kernel mailing list