diff mbox series

[LTP,v4,4/5] IMA: Add a test to verify measurement of certificate imported into a keyring

Message ID 20200820090824.3033-5-pvorel@suse.cz (mailing list archive)
State New, archived
Headers show
Series IMA: verify measurement of certificate imported into a keyring | expand

Commit Message

Petr Vorel Aug. 20, 2020, 9:08 a.m. UTC
From: Lachlan Sneff <t-josne@linux.microsoft.com>

The IMA subsystem supports measuring certificates that have been
imported into either system built-in or user-defined keyrings.
A test to verify measurement of a certificate imported
into a keyring is required.

Add an IMA measurement test that verifies that an x509 certificate
can be imported into a newly-created, user-defined keyring and measured
correctly by the IMA subsystem.

A certificate used by the test is included in the `datafiles/keys`
directory.

There can be restrictions on importing a certificate into a builtin
trusted keyring. For example, the `.ima` keyring requires that
imported certs be signed by a kernel private key in certain
kernel configurations. For this reason, this test defines
a user-defined keyring and imports a certificate into that.

Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Lachlan Sneff <t-josne@linux.microsoft.com>
[ pvorel: Added key_import_test into keycheck.policy, cleanup key,
reword instructions in README.md, LTP API related fixes ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
changes v3->v4:
* Add cleanup function for test2: remove key with keyctl clear ID
instead of running keyctl new_session > /dev/null which was reported
as problematic (and still affects other tests which are run after this one)

 .../kernel/security/integrity/ima/README.md   |  12 ++-
 .../integrity/ima/datafiles/ima_keys/Makefile |   2 +-
 .../ima/datafiles/ima_keys/keycheck.policy    |   2 +-
 .../ima/datafiles/ima_keys/x509_ima.der       | Bin 0 -> 650 bytes
 .../security/integrity/ima/tests/ima_keys.sh  |  70 ++++++++++++++++--
 5 files changed, 73 insertions(+), 13 deletions(-)
 create mode 100644 testcases/kernel/security/integrity/ima/datafiles/ima_keys/x509_ima.der

Comments

Mimi Zohar Aug. 26, 2020, 10:15 p.m. UTC | #1
On Thu, 2020-08-20 at 11:08 +0200, Petr Vorel wrote:

> @@ -63,4 +73,50 @@ test1()
>  	tst_res TPASS "specified keyrings were measured correctly"
>  }
> 
> +# Create a new keyring, import a certificate into it, and verify
> +# that the certificate is measured correctly by IMA.
> +test2()
> +{
> +	tst_require_cmds evmctl keyctl openssl
> +
> +	local cert_file="$TST_DATAROOT/x509_ima.der"
> +	local keyring_name="key_import_test"
> +	local temp_file="file.txt"
> +
> +	tst_res TINFO "verify measurement of certificate imported into a keyring"
> +
> +	if ! check_ima_policy_content "^measure.*func=KEY_CHECK.*keyrings=.*$keyring_name"; then
> +		tst_brk TCONF "IMA policy does not contain $keyring_name keyring"
> +	fi
> +
> +	KEYRING_ID=$(keyctl newring $keyring_name @s) || \
> +		tst_brk TBROK "unable to create a new keyring"
> +
> +	if ! tst_is_num $KEYRING_ID; then
> +		tst_brk TBROK "unable to parse the new keyring id ('$KEYRING_ID')"
> +	fi
> +

Instead of using TST_DATAROOT, which is defined as
"$LTPROOT/datafiles", use LTPROOT directly to define the path to the
cert.  Adding the following will allow the test to run from the build
directory.
 
      if [ ! -f $cert_file ]; then
              cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
      fi

Mimi

> +	evmctl import $cert_file $KEYRING_ID > /dev/null || \
> +		tst_brk TBROK "unable to import a certificate into $keyring_name keyring"
> +
Petr Vorel Aug. 27, 2020, 1:23 p.m. UTC | #2
Hi Mimi,

...
> > +	if ! tst_is_num $KEYRING_ID; then
> > +		tst_brk TBROK "unable to parse the new keyring id ('$KEYRING_ID')"
> > +	fi
> > +

> Instead of using TST_DATAROOT, which is defined as
> "$LTPROOT/datafiles", use LTPROOT directly to define the path to the
> cert.  Adding the following will allow the test to run from the build
> directory.

>       if [ ! -f $cert_file ]; then
>               cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
>       fi
Yes, this will work if you set LTPROOT to <ltp git>/testcases/kernel/security/integrity/ima/tests/:

$ cd <ltp git>/testcases/kernel/security/integrity/ima/tests/
$ LTPROOT=$PWD PATH="../../../../../lib/:.:$PATH" ./ima_keys.sh

But, according to doc [1] $LTPROOT is "Prefix for installed LTP, the default is
/opt/ltp.". Using it like this is confusing (if we want to misuse $LTPROOT, one
would expect it's a cloned git root directory). Running from git root it'd have
to be:

$ cd <ltp git>
$ LTPROOT=$PWD/testcases/kernel/security/integrity/ima/tests/ \
PATH="testcases/lib:testcases/kernel/security/integrity/ima/tests/:$PATH" ima_keys.sh

TL;DR: I'd really prefer people run IMA from installed LTP (make && make install
in both testcases/lib and testcases/kernel/security/integrity/ima/ is just enough),
but I'll add this hack to make your testing easier :). But fixing this in
tst_test.sh is really needed.

> Mimi

Kind regards,
Petr

[1] https://github.com/linux-test-project/ltp/wiki/User-Guidelines
Petr Vorel Aug. 27, 2020, 1:55 p.m. UTC | #3
Hi Mimi,

> ...
> > > +	if ! tst_is_num $KEYRING_ID; then
> > > +		tst_brk TBROK "unable to parse the new keyring id ('$KEYRING_ID')"
> > > +	fi
> > > +

> > Instead of using TST_DATAROOT, which is defined as
> > "$LTPROOT/datafiles", use LTPROOT directly to define the path to the
> > cert.  Adding the following will allow the test to run from the build
> > directory.

> >       if [ ! -f $cert_file ]; then
> >               cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
> >       fi
> Yes, this will work if you set LTPROOT to <ltp git>/testcases/kernel/security/integrity/ima/tests/:

> $ cd <ltp git>/testcases/kernel/security/integrity/ima/tests/
> $ LTPROOT=$PWD PATH="../../../../../lib/:.:$PATH" ./ima_keys.sh

> But, according to doc [1] $LTPROOT is "Prefix for installed LTP, the default is
> /opt/ltp.". Using it like this is confusing (if we want to misuse $LTPROOT, one
> would expect it's a cloned git root directory). Running from git root it'd have
> to be:

> $ cd <ltp git>
> $ LTPROOT=$PWD/testcases/kernel/security/integrity/ima/tests/ \
> PATH="testcases/lib:testcases/kernel/security/integrity/ima/tests/:$PATH" ima_keys.sh

> TL;DR: I'd really prefer people run IMA from installed LTP (make && make install
> in both testcases/lib and testcases/kernel/security/integrity/ima/ is just enough),
> but I'll add this hack to make your testing easier :). But fixing this in
> tst_test.sh is really needed.

Suggesting this diff from v4:

+	# hack when running ima_keys.sh locally from ima_keys.sh directory
+	# LTPROOT=$PWD PATH="../../../../../lib/:.:$PATH" ./ima_keys.sh
+	if [ ! -f "$cert_file" ]; then
+		cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
+	fi

Visible also on
https://github.com/pevik/ltp/tree/Lachlan_Sneff/ima_keys.sh-second-test.v4.fixes

Not sure if you still doing review & testing, thus waiting for your comments
or tags.

Kind regards,
Petr

> > Mimi

> Kind regards,
> Petr

> [1] https://github.com/linux-test-project/ltp/wiki/User-Guidelines
Mimi Zohar Aug. 27, 2020, 9:34 p.m. UTC | #4
Hi Petr,

On Thu, 2020-08-27 at 15:55 +0200, Petr Vorel wrote:

> > > > +	if ! tst_is_num $KEYRING_ID; then
> > > > +		tst_brk TBROK "unable to parse the new keyring id ('$KEYRING_ID')"
> > > > +	fi
> > > > +
> > > Instead of using TST_DATAROOT, which is defined as
> > > "$LTPROOT/datafiles", use LTPROOT directly to define the path to the
> > > cert.  Adding the following will allow the test to run from the build
> > > directory.
> > >       if [ ! -f $cert_file ]; then
> > >               cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
> > >       fi
> > Yes, this will work if you set LTPROOT to <ltp git>/testcases/kernel/security/integrity/ima/tests/:

When running any of the tests from build tree test directory -
ltp/testcases/kernel/security/integrity/ima/tests, supplying LTPROOT
isn't necessary. "IMA: Refactor datafiles directory" broke running the
other tests directly from the build tree as well.

> > $ cd <ltp git>/testcases/kernel/security/integrity/ima/tests/
> > $ LTPROOT=$PWD PATH="../../../../../lib/:.:$PATH" ./ima_keys.sh
> > But, according to doc [1] $LTPROOT is "Prefix for installed LTP, the default is
> > /opt/ltp.". Using it like this is confusing (if we want to misuse $LTPROOT, one
> > would expect it's a cloned git root directory). Running from git root it'd have
> > to be:
> > $ cd <ltp git>
> > $ LTPROOT=$PWD/testcases/kernel/security/integrity/ima/tests/ \
> > PATH="testcases/lib:testcases/kernel/security/integrity/ima/tests/:$PATH" ima_keys.sh
> > TL;DR: I'd really prefer people run IMA from installed LTP (make && make install
> > in both testcases/lib and testcases/kernel/security/integrity/ima/ is just enough),
> > but I'll add this hack to make your testing easier :). But fixing this in
> > tst_test.sh is really needed.

I'm looking ...

> 
> Suggesting this diff from v4:
> 
> +	# hack when running ima_keys.sh locally from ima_keys.sh directory
> +	# LTPROOT=$PWD PATH="../../../../../lib/:.:$PATH" ./ima_keys.sh
> +	if [ ! -f "$cert_file" ]; then
> +		cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
> +	fi
> 
> Visible also on
> https://github.com/pevik/ltp/tree/Lachlan_Sneff/ima_keys.sh-second-test.v4.fixes
> 
> Not sure if you still doing review & testing, thus waiting for your comments
> or tags.

Sorry, yes I'm planning to.

Mimi

> 
> Kind regards,
> Petr
> 
> > > Mimi
> > Kind regards,
> > Petr
> > [1] https://github.com/linux-test-project/ltp/wiki/User-Guidelines
Petr Vorel Aug. 27, 2020, 10:54 p.m. UTC | #5
Hi Mimi,

...
> > > > Instead of using TST_DATAROOT, which is defined as
> > > > "$LTPROOT/datafiles", use LTPROOT directly to define the path to the
> > > > cert.  Adding the following will allow the test to run from the build
> > > > directory.
> > > >       if [ ! -f $cert_file ]; then
> > > >               cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
> > > >       fi
> > > Yes, this will work if you set LTPROOT to <ltp git>/testcases/kernel/security/integrity/ima/tests/:

> When running any of the tests from build tree test directory -
> ltp/testcases/kernel/security/integrity/ima/tests, supplying LTPROOT
> isn't necessary. "IMA: Refactor datafiles directory" broke running the
> other tests directly from the build tree as well.
Correct, I overlooked $LTPROOT does not have to be set.
You're right, there is export LTPROOT="$PWD" in tst_test.sh.

The only broken tests are ima_policy.sh and ima_keys.sh. I fixed that workaround
in the commit "IMA: Refactor datafiles directory":

+++ testcases/kernel/security/integrity/ima/tests/ima_setup.sh
@@ -160,6 +160,11 @@ ima_setup()
 	BINARY_MEASUREMENTS="$IMA_DIR/binary_runtime_measurements"
 	IMA_POLICY="$IMA_DIR/policy"
 
+	# hack when running tests locally from tests directory
+	if [ ! -d "$TST_DATAROOT" ]; then
+		TST_DATAROOT="$LTPROOT/../datafiles/$TST_ID/"
+	fi
+
 	print_ima_config
 
 	if [ "$TST_NEEDS_DEVICE" = 1 ]; then
---

Again, pushed to:
https://github.com/pevik/ltp/tree/Lachlan_Sneff/ima_keys.sh-second-test.v4.fixes

Kind regards,
Petr
Mimi Zohar Aug. 27, 2020, 11:37 p.m. UTC | #6
On Fri, 2020-08-28 at 00:54 +0200, Petr Vorel wrote:
> Hi Mimi,
> 
> ...
> > > > > Instead of using TST_DATAROOT, which is defined as
> > > > > "$LTPROOT/datafiles", use LTPROOT directly to define the path to the
> > > > > cert.  Adding the following will allow the test to run from the build
> > > > > directory.
> > > > >       if [ ! -f $cert_file ]; then
> > > > >               cert_file="$LTPROOT/../datafiles/ima_keys/x509_ima.der"
> > > > >       fi
> > > > Yes, this will work if you set LTPROOT to <ltp git>/testcases/kernel/security/integrity/ima/tests/:
> > When running any of the tests from build tree test directory -
> > ltp/testcases/kernel/security/integrity/ima/tests, supplying LTPROOT
> > isn't necessary. "IMA: Refactor datafiles directory" broke running the
> > other tests directly from the build tree as well.
> Correct, I overlooked $LTPROOT does not have to be set.
> You're right, there is export LTPROOT="$PWD" in tst_test.sh.
> 
> The only broken tests are ima_policy.sh and ima_keys.sh. I fixed that workaround
> in the commit "IMA: Refactor datafiles directory":
> 
> +++ testcases/kernel/security/integrity/ima/tests/ima_setup.sh
> @@ -160,6 +160,11 @@ ima_setup()
>  	BINARY_MEASUREMENTS="$IMA_DIR/binary_runtime_measurements"
>  	IMA_POLICY="$IMA_DIR/policy"
>  
> +	# hack when running tests locally from tests directory
> +	if [ ! -d "$TST_DATAROOT" ]; then
> +		TST_DATAROOT="$LTPROOT/../datafiles/$TST_ID/"
> +	fi
> +

Thanks, Petr.  This works properly.  To remove the "hack", would
require running the test from "ima", not "ima/tests", but that would
require fixing how ima_setup.sh is called.   It also would still
require setting TST_DATAROOT to TST_DATAROOT/$TST_ID.

Mimi

>  	print_ima_config
>  
>  	if [ "$TST_NEEDS_DEVICE" = 1 ]; then
> ---
> 
> Again, pushed to:
> https://github.com/pevik/ltp/tree/Lachlan_Sneff/ima_keys.sh-second-test.v4.fixes
> 
> Kind regards,
> Petr
Petr Vorel Aug. 28, 2020, 6:05 a.m. UTC | #7
Hi Mimi,

> Thanks, Petr.  This works properly.  To remove the "hack", would
> require running the test from "ima", not "ima/tests", but that would
> require fixing how ima_setup.sh is called.   It also would still
> require setting TST_DATAROOT to TST_DATAROOT/$TST_ID.
Let's keep it and suppose people run tests from ima/tests.
This needs to be fixed on LTP side, I have it on my TODO list.

Anything else?
After that I'll work on ima_tpm.sh and after on policy automatic loading.
BTW there are also plans for reboot support [1] [2], that could be used as
workaround for configuration without CONFIG_IMA_READ_POLICY=y and
CONFIG_IMA_WRITE_POLICY=y.

[1] http://lists.linux.it/pipermail/ltp/2020-August/018636.html
[2] http://lists.linux.it/pipermail/ltp/2020-August/018658.html

> Mimi

Kind regards,
Petr
Mimi Zohar Aug. 28, 2020, 10:59 a.m. UTC | #8
On Thu, 2020-08-20 at 11:08 +0200, Petr Vorel wrote:
> From: Lachlan Sneff <t-josne@linux.microsoft.com>
> 
> The IMA subsystem supports measuring certificates that have been
> imported into either system built-in or user-defined keyrings.
> A test to verify measurement of a certificate imported
> into a keyring is required.
> 
> Add an IMA measurement test that verifies that an x509 certificate
> can be imported into a newly-created, user-defined keyring and measured
> correctly by the IMA subsystem.
> 
> A certificate used by the test is included in the `datafiles/keys`
> directory.
> 
> There can be restrictions on importing a certificate into a builtin
> trusted keyring. For example, the `.ima` keyring requires that
> imported certs be signed by a kernel private key in certain
> kernel configurations. For this reason, this test defines
> a user-defined keyring and imports a certificate into that.

FYI, similar restrictions could be defined for userspace keyrings. 
Refer to Mat Martineau's LSS 2019 talk titled "Using and Implementing
Keyring Restrictions for Userspace" and the keyctl's "restrict_keyring"
option.

Mimi
Mimi Zohar Aug. 28, 2020, 11 a.m. UTC | #9
On Fri, 2020-08-28 at 08:05 +0200, Petr Vorel wrote:
> Hi Mimi,
> 
> > Thanks, Petr.  This works properly.  To remove the "hack", would
> > require running the test from "ima", not "ima/tests", but that would
> > require fixing how ima_setup.sh is called.   It also would still
> > require setting TST_DATAROOT to TST_DATAROOT/$TST_ID.
> Let's keep it and suppose people run tests from ima/tests.
> This needs to be fixed on LTP side, I have it on my TODO list.

Sure
> 
> Anything else?
> After that I'll work on ima_tpm.sh and after on policy automatic loading.
> BTW there are also plans for reboot support [1] [2], that could be used as
> workaround for configuration without CONFIG_IMA_READ_POLICY=y and
> CONFIG_IMA_WRITE_POLICY=y.
> 
> [1] http://lists.linux.it/pipermail/ltp/2020-August/018636.html
> [2] http://lists.linux.it/pipermail/ltp/2020-August/018658.html

Sounds good!

Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> for the entire patch set.

thanks,

Mimi
Mimi Zohar Aug. 28, 2020, 11:19 a.m. UTC | #10
On Fri, 2020-08-28 at 08:05 +0200, Petr Vorel wrote:
> BTW there are also plans for reboot support [1] [2], that could be used as
> workaround for configuration without CONFIG_IMA_READ_POLICY=y and
> CONFIG_IMA_WRITE_POLICY=y.

The reboot support could also be used for carrying the IMA measurement
list across kexec and verifying the TPM PCRs.

Mimi
Petr Vorel Aug. 28, 2020, 12:40 p.m. UTC | #11
Hi Mimi,

...
> > Anything else?
> > After that I'll work on ima_tpm.sh and after on policy automatic loading.
> > BTW there are also plans for reboot support [1] [2], that could be used as
> > workaround for configuration without CONFIG_IMA_READ_POLICY=y and
> > CONFIG_IMA_WRITE_POLICY=y.

> > [1] http://lists.linux.it/pipermail/ltp/2020-August/018636.html
> > [2] http://lists.linux.it/pipermail/ltp/2020-August/018658.html

> Sounds good!

> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> for the entire patch set.

Thanks a lot for your review and testing!
Merged the rest of the patchset (first commit was already merged on Monday).

Kind regards,
Petr
Petr Vorel Aug. 28, 2020, 12:49 p.m. UTC | #12
> On Fri, 2020-08-28 at 08:05 +0200, Petr Vorel wrote:
> > BTW there are also plans for reboot support [1] [2], that could be used as
> > workaround for configuration without CONFIG_IMA_READ_POLICY=y and
> > CONFIG_IMA_WRITE_POLICY=y.

> The reboot support could also be used for carrying the IMA measurement
> list across kexec and verifying the TPM PCRs.
Adding into my TODO list. I'd just run whole test ima_kexec.sh twice and reboot
in between.

> Mimi

Kind regards,
Petr
Mimi Zohar Aug. 28, 2020, 3:21 p.m. UTC | #13
On Fri, 2020-08-28 at 14:49 +0200, Petr Vorel wrote:
> > On Fri, 2020-08-28 at 08:05 +0200, Petr Vorel wrote:
> > > BTW there are also plans for reboot support [1] [2], that could be used as
> > > workaround for configuration without CONFIG_IMA_READ_POLICY=y and
> > > CONFIG_IMA_WRITE_POLICY=y.
> > The reboot support could also be used for carrying the IMA measurement
> > list across kexec and verifying the TPM PCRs.

> Adding into my TODO list. I'd just run whole test ima_kexec.sh twice and reboot
> in between.

The ima_kexec.sh tests measures the kexec boot cmdline and kernel
image.   What's needed is walking the measurement list re-calculating
the PCRs and then verifying them against the actual TPM PCRs.  Maybe
running the ima_tpm.sh test twice.

Mimi
Petr Vorel Aug. 31, 2020, 10:29 a.m. UTC | #14
Hi Mimi,

> On Fri, 2020-08-28 at 14:49 +0200, Petr Vorel wrote:
> > > On Fri, 2020-08-28 at 08:05 +0200, Petr Vorel wrote:
> > > > BTW there are also plans for reboot support [1] [2], that could be used as
> > > > workaround for configuration without CONFIG_IMA_READ_POLICY=y and
> > > > CONFIG_IMA_WRITE_POLICY=y.
> > > The reboot support could also be used for carrying the IMA measurement
> > > list across kexec and verifying the TPM PCRs.

> > Adding into my TODO list. I'd just run whole test ima_kexec.sh twice and reboot
> > in between.

> The ima_kexec.sh tests measures the kexec boot cmdline and kernel
> image.   What's needed is walking the measurement list re-calculating
> the PCRs and then verifying them against the actual TPM PCRs.  Maybe
> running the ima_tpm.sh test twice.
Right, thanks for clarification :).

It takes some time till reboot implementation in LTP API is implemented. But I
hope to send fix for TPM 2.0 and sha256 hash (these changes in v5.8) for
ima_tpm.sh this week.


Kind regards,
Petr
diff mbox series

Patch

diff --git a/testcases/kernel/security/integrity/ima/README.md b/testcases/kernel/security/integrity/ima/README.md
index 392e1e868..68d046678 100644
--- a/testcases/kernel/security/integrity/ima/README.md
+++ b/testcases/kernel/security/integrity/ima/README.md
@@ -16,11 +16,15 @@  space, may contain equivalent measurement tcb rules, detecting them would
 require `IMA_READ_POLICY=y` therefore ignore this option.
 
 ### IMA key test
-`ima_keys.sh` requires a readable IMA policy, as well as a loaded policy
-with `func=KEY_CHECK keyrings=...`, see example in `keycheck.policy`.
+The measuring keys test (first test) in `ima_keys.sh` requires a readable IMA
+policy, as well as a loaded measure policy with `func=KEY_CHECK keyrings=...`.
 
-As well as what's required for the IMA tests, the following are also required
--in the kernel configuration:
+The certificate import test (second test) require measure policy with
+`func=KEY_CHECK keyrings=key_import_test`. Valid policy for both is in
+`keycheck.policy`.
+
+As well as what's required for the IMA tests, key tests require reading the IMA
+policy allowed in the kernel configuration:
 ```
 CONFIG_IMA_READ_POLICY=y
 ```
diff --git a/testcases/kernel/security/integrity/ima/datafiles/ima_keys/Makefile b/testcases/kernel/security/integrity/ima/datafiles/ima_keys/Makefile
index 452321843..ac7ce33ab 100644
--- a/testcases/kernel/security/integrity/ima/datafiles/ima_keys/Makefile
+++ b/testcases/kernel/security/integrity/ima/datafiles/ima_keys/Makefile
@@ -6,6 +6,6 @@  top_srcdir	?= ../../../../../../..
 include	$(top_srcdir)/include/mk/env_pre.mk
 
 INSTALL_DIR		:= testcases/data/ima_keys
-INSTALL_TARGETS	:= *.policy
+INSTALL_TARGETS	:= *.policy x509_ima.der
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/security/integrity/ima/datafiles/ima_keys/keycheck.policy b/testcases/kernel/security/integrity/ima/datafiles/ima_keys/keycheck.policy
index 3f1934a3d..623162002 100644
--- a/testcases/kernel/security/integrity/ima/datafiles/ima_keys/keycheck.policy
+++ b/testcases/kernel/security/integrity/ima/datafiles/ima_keys/keycheck.policy
@@ -1 +1 @@ 
-measure func=KEY_CHECK keyrings=.ima|.evm|.builtin_trusted_keys|.blacklist template=ima-buf
+measure func=KEY_CHECK keyrings=.ima|.evm|.builtin_trusted_keys|.blacklist|key_import_test template=ima-buf
diff --git a/testcases/kernel/security/integrity/ima/datafiles/ima_keys/x509_ima.der b/testcases/kernel/security/integrity/ima/datafiles/ima_keys/x509_ima.der
new file mode 100644
index 0000000000000000000000000000000000000000..92be058da22adffa9d6b6e51efa0c737ebbbbdcd
GIT binary patch
literal 650
zcmXqLVrnyJVtl`VnTe5!NhJD#vj69`9|BBf8}FEsx@^_9$Clp>c-c6$+C196^D;7W
zvoaV27z!HjvoVLVaPe?t<QJFZCFZ6YN*hRmgqV4R$}{p4b2Al+Gt=`j^U@WvQ!5SS
z3}oO&a59SVLzFncG#ki?^BP(jSQr@@7#Ud_7)6Qm8W{k&hEOgIY;2s5>?=lA2Ij_I
z27|^<rp88wchfeduxmMW^j9qUxkIugeev4q7u7yrJR_rW$*!>VOo=tim8DK0r^FsU
zl)K`}`+CO4@4KBkoLmcj?fH`%wbDvU<d=4Z>6-SMf6Eh}{&)1rdsOoNQ-1fgBQ1t{
zVTqGwuK95LlFE)6i{@=vlP6!2`Y}x<BF&oXU_nlDxy@C+CNp&=W=00a#jys_20XwZ
zl@(@W{LjK<z+k`);_<VvFf*|?7|4P+d@N!tBCNWX-0#?!UAx9s`mgFmW+nI2#6kmk
zkhC(3gn?Lt$m4W@56wQ)?QVKW<nOtpT)HJrB?Q^`z&K?FdV8b(y8m)~mOOvswu^9m
z-o7mOwCAzaT*~`Y4wxFtmNA_89`W;j{r#iww*5OC5vgEziqD_%=ki$*`;s}`Pfwi{
zbotZ0X`ckHOmaVLm85n@E9hN_K;~PUB>DFAzh(;(UoMln9V>g;W#-LUGS7A`nYQKY
WBem{7L5JThS+;$vggi%(*E;~nlJ80Y

literal 0
HcmV?d00001

diff --git a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh
index 015a3c115..ad3cbbdc7 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh
@@ -6,12 +6,18 @@ 
 #
 # Verify that keys are measured correctly based on policy.
 
-TST_NEEDS_CMDS="cut grep sed tr xxd"
-TST_CNT=1
+TST_NEEDS_CMDS="cmp cut grep sed tr xxd"
+TST_CNT=2
 TST_NEEDS_DEVICE=1
+TST_CLEANUP=cleanup
 
 . ima_setup.sh
 
+cleanup()
+{
+	tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID
+}
+
 # Based on https://lkml.org/lkml/2019/12/13/564.
 # (450d0fd51564 - "IMA: Call workqueue functions to measure queued keys")
 test1()
@@ -29,13 +35,15 @@  test1()
 	keycheck_line=$(echo "$keycheck_lines" | grep "keyrings" | head -n1)
 
 	if [ -z "$keycheck_line" ]; then
-		tst_brk TCONF "ima policy does not specify a keyrings to check"
+		tst_res TCONF "IMA policy does not specify a keyrings to check"
+		return
 	fi
 
 	keyrings=$(echo "$keycheck_line" | tr " " "\n" | grep "keyrings" | \
 		sed "s/\./\\\./g" | cut -d'=' -f2)
 	if [ -z "$keyrings" ]; then
-		tst_brk TCONF "ima policy has a keyring key-value specifier, but no specified keyrings"
+		tst_res TCONF "IMA policy has a keyring key-value specifier, but no specified keyrings"
+		return
 	fi
 
 	templates=$(echo "$keycheck_line" | tr " " "\n" | grep "template" | \
@@ -51,11 +59,13 @@  test1()
 
 		echo "$line" | cut -d' ' -f6 | xxd -r -p > $test_file
 
-		expected_digest="$(compute_digest $algorithm $test_file)" || \
-			tst_brk TCONF "cannot compute digest for $algorithm"
+		if ! expected_digest="$(compute_digest $algorithm $test_file)"; then
+			tst_res TCONF "cannot compute digest for $algorithm"
+			return
+		fi
 
 		if [ "$digest" != "$expected_digest" ]; then
-			tst_res TFAIL "incorrect digest was found for the ($keyring) keyring"
+			tst_res TFAIL "incorrect digest was found for $keyring keyring"
 			return
 		fi
 	done
@@ -63,4 +73,50 @@  test1()
 	tst_res TPASS "specified keyrings were measured correctly"
 }
 
+# Create a new keyring, import a certificate into it, and verify
+# that the certificate is measured correctly by IMA.
+test2()
+{
+	tst_require_cmds evmctl keyctl openssl
+
+	local cert_file="$TST_DATAROOT/x509_ima.der"
+	local keyring_name="key_import_test"
+	local temp_file="file.txt"
+
+	tst_res TINFO "verify measurement of certificate imported into a keyring"
+
+	if ! check_ima_policy_content "^measure.*func=KEY_CHECK.*keyrings=.*$keyring_name"; then
+		tst_brk TCONF "IMA policy does not contain $keyring_name keyring"
+	fi
+
+	KEYRING_ID=$(keyctl newring $keyring_name @s) || \
+		tst_brk TBROK "unable to create a new keyring"
+
+	if ! tst_is_num $KEYRING_ID; then
+		tst_brk TBROK "unable to parse the new keyring id ('$KEYRING_ID')"
+	fi
+
+	evmctl import $cert_file $KEYRING_ID > /dev/null || \
+		tst_brk TBROK "unable to import a certificate into $keyring_name keyring"
+
+	grep $keyring_name $ASCII_MEASUREMENTS | tail -n1 | cut -d' ' -f6 | \
+		xxd -r -p > $temp_file
+
+	if [ ! -s $temp_file ]; then
+		tst_res TFAIL "keyring $keyring_name not found in $ASCII_MEASUREMENTS"
+		return
+	fi
+
+	if ! openssl x509 -in $temp_file -inform der > /dev/null; then
+		tst_res TFAIL "logged certificate is not a valid x509 certificate"
+		return
+	fi
+
+	if cmp -s $temp_file $cert_file; then
+		tst_res TPASS "logged certificate matches the original"
+	else
+		tst_res TFAIL "logged certificate does not match original"
+	fi
+}
+
 tst_run