From patchwork Mon Jan 22 14:54:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mimi Zohar X-Patchwork-Id: 10178681 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4A681600F5 for ; Mon, 22 Jan 2018 14:54:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3EDDB20453 for ; Mon, 22 Jan 2018 14:54:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 33B8A20246; Mon, 22 Jan 2018 14:54:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B854520453 for ; Mon, 22 Jan 2018 14:54:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751161AbeAVOyc (ORCPT ); Mon, 22 Jan 2018 09:54:32 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:45518 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751121AbeAVOy3 (ORCPT ); Mon, 22 Jan 2018 09:54:29 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w0MEplCj119477 for ; Mon, 22 Jan 2018 09:54:28 -0500 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0a-001b2d01.pphosted.com with ESMTP id 2fne9eam0v-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 22 Jan 2018 09:54:28 -0500 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 22 Jan 2018 14:54:26 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 22 Jan 2018 14:54:24 -0000 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w0MEsOcG47317038; Mon, 22 Jan 2018 14:54:24 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9847052041; Mon, 22 Jan 2018 13:46:48 +0000 (GMT) Received: from localhost.ibm.com (unknown [9.80.102.7]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id D99B45203F; Mon, 22 Jan 2018 13:46:47 +0000 (GMT) From: Mimi Zohar To: linux-integrity@vger.kernel.org Cc: Dmitry Kasatkin , Roberto Sassu , "Bruno E . O . Meneguele" , Mimi Zohar Subject: [PATCH 05/10] ima-evm-utils: support verifying the measurement list using multiple keys Date: Mon, 22 Jan 2018 09:54:00 -0500 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516632845-7087-1-git-send-email-zohar@linux.vnet.ibm.com> References: <1516632845-7087-1-git-send-email-zohar@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18012214-0020-0000-0000-000003ED69CC X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18012214-0021-0000-0000-0000427FB210 Message-Id: <1516632845-7087-6-git-send-email-zohar@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-01-22_06:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1801220211 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On a running system, different software packages might be signed by different parties. Support verifying signatures in the measurement list using multiple public keys(eg. -k "key1, key2, ..."). Signed-off-by: Mimi Zohar --- README | 2 +- src/evmctl.c | 4 +++ src/imaevm.h | 1 + src/libimaevm.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/README b/README index da828cf..1c4bc7a 100644 --- a/README +++ b/README @@ -31,7 +31,7 @@ COMMANDS ima_sign [--sigfile] [--key key] [--pass password] file ima_verify file ima_hash file - ima_measurement file + ima_measurement [--key "key1, key2, ..."] file ima_fix [-t fdsxm] path sign_hash [--key key] [--pass password] hmac [--imahash | --imasig ] file diff --git a/src/evmctl.c b/src/evmctl.c index 746fc09..e0ed93d 100644 --- a/src/evmctl.c +++ b/src/evmctl.c @@ -1419,6 +1419,10 @@ static int ima_measurement(const char *file) return -1; } + /* Support multiple public keys */ + if (params.keyfile) + init_public_keys(params.keyfile); + while (fread(&entry.header, sizeof(entry.header), 1, fp)) { ima_extend_pcr(pcr, entry.header.digest, SHA_DIGEST_LENGTH); diff --git a/src/imaevm.h b/src/imaevm.h index e397743..ea6a7b1 100644 --- a/src/imaevm.h +++ b/src/imaevm.h @@ -205,5 +205,6 @@ int key2bin(RSA *key, unsigned char *pub); 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); +void init_public_keys(const char *keyfiles); #endif diff --git a/src/libimaevm.c b/src/libimaevm.c index a92deed..0ad290a 100644 --- a/src/libimaevm.c +++ b/src/libimaevm.c @@ -408,6 +408,61 @@ int verify_hash_v1(const unsigned char *hash, int size, unsigned char *sig, int return 0; } +struct public_key_entry { + struct public_key_entry *next; + uint32_t keyid; + char name[9]; + RSA *key; +}; +static struct public_key_entry *public_keys = NULL; + +static RSA *find_keyid(uint32_t keyid) +{ + struct public_key_entry *entry; + + for (entry = public_keys; entry != NULL; entry = entry->next) { + if (entry->keyid == keyid) + return entry->key; + } + return NULL; +} + +void init_public_keys(const char *keyfiles) +{ + struct public_key_entry *entry; + char *tmp_keyfiles; + char *keyfile; + int i = 1; + + tmp_keyfiles = strdup(keyfiles); + + while ((keyfile = strsep(&tmp_keyfiles, ", \t")) != NULL) { + if (!keyfile) + break; + if ((*keyfile == '\0') || (*keyfile == ' ') || + (*keyfile == '\t')) + continue; + + entry = malloc(sizeof(struct public_key_entry)); + if (!entry) { + perror("malloc"); + break; + } + + entry->key = read_pub_key(keyfile, 1); + if (!entry->key) { + free(entry); + continue; + } + + calc_keyid_v2(&entry->keyid, entry->name, entry->key); + sprintf(entry->name, "%x", __be32_to_cpup(&entry->keyid)); + log_info("key %d: %s %s\n", i++, entry->name, keyfile); + entry->next = public_keys; + public_keys = entry; + } +} + int verify_hash_v2(const unsigned char *hash, int size, unsigned char *sig, int siglen, const char *keyfile) { int err, len; @@ -419,12 +474,22 @@ int verify_hash_v2(const unsigned char *hash, int size, unsigned char *sig, int log_info("hash: "); log_dump(hash, size); - key = read_pub_key(keyfile, 1); - if (!key) - return 1; + if (public_keys) { + key = find_keyid(hdr->keyid); + if (!key) { + log_err("Unknown keyid: %x\n", + __be32_to_cpup(&hdr->keyid)); + return -1; + } + } else { + key = read_pub_key(keyfile, 1); + if (!key) + return 1; + } - err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr), out, key, RSA_PKCS1_PADDING); - RSA_free(key); + + err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr), + out, key, RSA_PKCS1_PADDING); if (err < 0) { log_err("RSA_public_decrypt() failed: %d\n", err); return 1;