2023-09-06 20:31:39

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] certs: Add the ability to add only CA certificates to the secondary trusted keyring

On 9/6/23 2:32 PM, Denis Glazkov wrote:

> When building a chain of trust for IMA certificates issued from

It's a shame I forgot what IMA stands for... and even Google doesn't
give any suitable value...

> intermediate certificates using a secondary trusted keying, there
> is no way to restrict the addition of IMA certificates to trusted
> certificates, since any certificate signed by an built-in or
> secondary trusted certificate can be added to the secondary
> trusted keying.
>
> With root privileges, an attacker can load a certificate intended
> for IMA into the trusted certificates and sign the kernel modules
> with the corresponding private key. This allows an attacker to
> load untrusted modules into kernel space.
>
> This patch adds the configuration that once enabled, only
> certificates that meet the following requirements can be added
> to the secondary trusted keying:
>
> 1. The certificate is a CA.

Oh, and I also forgot what CA stands for... :-/

> 2. The certificate must be used for verifying a CA's signatures.
> 3. The certificate must not be used for digital signatures.
>
> Signed-off-by: Denis Glazkov <[email protected]>
[...]

> diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> index 9de610bf1f4b..8d45c19ba92e 100644
> --- a/certs/system_keyring.c
> +++ b/certs/system_keyring.c
> @@ -90,6 +90,10 @@ int restrict_link_by_builtin_and_secondary_trusted(
> const union key_payload *payload,
> struct key *restrict_key)
> {
> +#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
> + struct public_key *pub;
> +#endif

Mhm, why this is not a part of the *if* block in the next hunk?
You don't use this variable outside that block...

[...]
> @@ -99,6 +103,23 @@ int restrict_link_by_builtin_and_secondary_trusted(
> /* Allow the builtin keyring to be added to the secondary */
> return 0;
>
> +#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
> + if (dest_keyring == secondary_trusted_keys) {
> + if (type != &key_type_asymmetric)
> + return -EOPNOTSUPP;
> +
> + pub = payload->data[asym_crypto];

I'm not seeing this index declared in Linus' repo...

> + if (!pub)
> + return -ENOPKG;
> + if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
> + return -EPERM;
> + if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
> + return -EPERM;
> + if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
> + return -EPERM;
> + }
> +#endif
> +
> return restrict_link_by_signature(dest_keyring, type, payload,
> secondary_trusted_keys);
> }

MBR, Sergey


2023-09-08 18:04:39

by Denis Glazkov

[permalink] [raw]
Subject: [PATCH v2] certs: Add option to disallow non-CA certificates in secondary trusted keying

The Linux kernel has an IMA (Integrity Measurement Architecture)
subsystem to check the integrity of the file system based on digital
signatures. IMA uses certificates in `.ima` keying to check integrity.

Only certificates issued by one of the trusted CA (Certificate Authority)
certificates can be added to the `.ima` keying.

The Linux kernel now has a secondary trusted keying to which trusted
certificates from user space can be added if you have superuser
privileges. Previously, all trusted certificates were in the built-in
trusted keying, which could not be modified from user space.
Trusted certificates were placed in the built-in trusted keying at
kernel compile time.

The secondary trusted keying is designed so that any certificates that
are signed by one of the trusted CA certificates in the built-in or
secondary trusted keyring can be added to it.

Let's imagine that we have the following certificate trust chain:

┌───────────────────────────┬─────────────────────┐
│ │ ┌───────┐ │
│ │ │ │ │
┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
│.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
├─────────────────────┤ ├────────────────────────┤ ├───────────┤
│ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
└─────────────────────┘ └────────────────────────┘ └───────────┘

Issues Restricted by
-------------► ──────────────►

Since the IMA certificate is signed by a CA certificate from a secondary
trusted keying, an attacker with superuser privileges will be able to
add the IMA certificate to the secondary trusted keying. That is, the IMA
certificate will become trusted.

Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
loaded into kernel space if they are signed with one of the trusted
certificates, an attacker could sign untrusted kernel modules with
the private key corresponding to the IMA certificate and successfully
load the untrusted modules into kernel space.

This patch adds the configuration that once enabled, only
certificates that meet the following requirements can be added
to the secondary trusted keying:

1. The certificate is a CA (Certificate Authority)
2. The certificate must be used for verifying a CA's signatures
3. The certificate must not be used for digital signatures

Signed-off-by: Denis Glazkov <[email protected]>
---
v1 -> v2:
- Rebase the patch from `linux-next` to the main `linux` repo master branch
- Make the commit message more detailed
- Move the variable declaration to the `if` block
- Replace `#ifdef` with `IS_ENABLED` macro
---
certs/Kconfig | 9 +++++++++
certs/system_keyring.c | 16 ++++++++++++++++
2 files changed, 25 insertions(+)

diff --git a/certs/Kconfig b/certs/Kconfig
index 1f109b070877..4a4dc8aab892 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING
those keys are not blacklisted and are vouched for by a key built
into the kernel or already in the secondary trusted keyring.

+config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
+ bool "Allow only CA certificates to be added to the secondary trusted keyring"
+ depends on SECONDARY_TRUSTED_KEYRING
+ help
+ If set, only CA certificates can be added to the secondary trusted keyring.
+ An acceptable CA certificate must include the `keyCertSign` value in
+ the `keyUsage` field. CA certificates that include the `digitalSignature`
+ value in the `keyUsage` field will not be accepted.
+
config SYSTEM_BLACKLIST_KEYRING
bool "Provide system-wide ring of blacklisted keys"
depends on KEYS
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 9de610bf1f4b..ee14447374e7 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted(
/* Allow the builtin keyring to be added to the secondary */
return 0;

+ if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) &&
+ dest_keyring == secondary_trusted_keys) {
+ const struct public_key *pub = payload->data[asym_crypto];
+
+ if (type != &key_type_asymmetric)
+ return -EOPNOTSUPP;
+ if (!pub)
+ return -ENOPKG;
+ if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
+ return -EPERM;
+ if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
+ return -EPERM;
+ if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
+ return -EPERM;
+ }
+
return restrict_link_by_signature(dest_keyring, type, payload,
secondary_trusted_keys);
}
--
2.34.1

2023-09-12 14:46:24

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v2] certs: Add option to disallow non-CA certificates in secondary trusted keying

On Fri Sep 8, 2023 at 3:14 PM EEST, Denis Glazkov wrote:
> The Linux kernel has an IMA (Integrity Measurement Architecture)
> subsystem to check the integrity of the file system based on digital
> signatures. IMA uses certificates in `.ima` keying to check integrity.
>
> Only certificates issued by one of the trusted CA (Certificate Authority)
> certificates can be added to the `.ima` keying.
>
> The Linux kernel now has a secondary trusted keying to which trusted
> certificates from user space can be added if you have superuser
> privileges. Previously, all trusted certificates were in the built-in
> trusted keying, which could not be modified from user space.
> Trusted certificates were placed in the built-in trusted keying at
> kernel compile time.
>
> The secondary trusted keying is designed so that any certificates that
> are signed by one of the trusted CA certificates in the built-in or
> secondary trusted keyring can be added to it.
>
> Let's imagine that we have the following certificate trust chain:
>
> ┌───────────────────────────┬─────────────────────┐
> │ │ ┌───────┐ │
> │ │ │ │ │
> ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
> │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
> ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
> │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
> └─────────────────────┘ └────────────────────────┘ └───────────┘
>
> Issues Restricted by
> -------------► ──────────────►
>
> Since the IMA certificate is signed by a CA certificate from a secondary
> trusted keying, an attacker with superuser privileges will be able to
> add the IMA certificate to the secondary trusted keying. That is, the IMA
> certificate will become trusted.
>
> Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
> loaded into kernel space if they are signed with one of the trusted
> certificates, an attacker could sign untrusted kernel modules with
> the private key corresponding to the IMA certificate and successfully
> load the untrusted modules into kernel space.
>
> This patch adds the configuration that once enabled, only
> certificates that meet the following requirements can be added
> to the secondary trusted keying:
>
> 1. The certificate is a CA (Certificate Authority)
> 2. The certificate must be used for verifying a CA's signatures
> 3. The certificate must not be used for digital signatures
>
> Signed-off-by: Denis Glazkov <[email protected]>

s/keying/keyring/ (multiple)

Have you considered instead making mod_verify_sig() more robust?
Obviously this would mean making selection of keys in
verify_pkcs7_signature() more robust (see the documentation of
'trusted_keys').

The this would be also less niche feature to pick for distributors
if it was just concerning module loading, and have associated config
flag over there.

BR, Jarkko

2023-09-15 18:07:44

by Denis Glazkov

[permalink] [raw]
Subject: Re: [PATCH v2] certs: Add option to disallow non-CA certificates in secondary trusted keying

On Tue, Sep 12 2023 at 01:15 AM +0300, Jarkko Sakkinen wrote:
> On Fri Sep 8, 2023 at 3:14 PM EEST, Denis Glazkov wrote:
> > The Linux kernel has an IMA (Integrity Measurement Architecture)
> > subsystem to check the integrity of the file system based on digital
> > signatures. IMA uses certificates in `.ima` keying to check integrity.
> >
> > Only certificates issued by one of the trusted CA (Certificate Authority)
> > certificates can be added to the `.ima` keying.
> >
> > The Linux kernel now has a secondary trusted keying to which trusted
> > certificates from user space can be added if you have superuser
> > privileges. Previously, all trusted certificates were in the built-in
> > trusted keying, which could not be modified from user space.
> > Trusted certificates were placed in the built-in trusted keying at
> > kernel compile time.
> >
> > The secondary trusted keying is designed so that any certificates that
> > are signed by one of the trusted CA certificates in the built-in or
> > secondary trusted keyring can be added to it.
> >
> > Let's imagine that we have the following certificate trust chain:
> >
> > ┌───────────────────────────┬─────────────────────┐
> > │ │ ┌───────┐ │
> > │ │ │ │ │
> > ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
> > │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
> > ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
> > │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
> > └─────────────────────┘ └────────────────────────┘ └───────────┘
> >
> > Issues Restricted by
> > -------------► ──────────────►
> >
> > Since the IMA certificate is signed by a CA certificate from a secondary
> > trusted keying, an attacker with superuser privileges will be able to
> > add the IMA certificate to the secondary trusted keying. That is, the IMA
> > certificate will become trusted.
> >
> > Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
> > loaded into kernel space if they are signed with one of the trusted
> > certificates, an attacker could sign untrusted kernel modules with
> > the private key corresponding to the IMA certificate and successfully
> > load the untrusted modules into kernel space.
> >
> > This patch adds the configuration that once enabled, only
> > certificates that meet the following requirements can be added
> > to the secondary trusted keying:
> >
> > 1. The certificate is a CA (Certificate Authority)
> > 2. The certificate must be used for verifying a CA's signatures
> > 3. The certificate must not be used for digital signatures
> >
> > Signed-off-by: Denis Glazkov <[email protected]>
>
> s/keying/keyring/ (multiple)
>
> Have you considered instead making mod_verify_sig() more robust?
> Obviously this would mean making selection of keys in
> verify_pkcs7_signature() more robust (see the documentation of
> 'trusted_keys').
>
> The this would be also less niche feature to pick for distributors
> if it was just concerning module loading, and have associated config
> flag over there.
>
> BR, Jarkko

Jarkko, thank you for your suggestion.

This patch was created not to solve only the problem of loading
untrusted kernel modules, but to make it possible to use a secondary
trusted keying only as a part of a chain of trust containing only
CA certificates with no digital signature capability.

Let's imagine that tomorrow we have a new kernel feature, similar
to kernel modules in terms of its impact on system security, which
also uses trusted certificates for signature verification.

If at this point we solve only the problem of loading untrusted
kernel modules, and not the problem of the entire trusted keys
system, we will need to add a new kernel option each time to solve
a similar problem for each new kernel feature that uses trusted
certificates.

BR, Denis

2023-09-25 17:09:25

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v2] certs: Add option to disallow non-CA certificates in secondary trusted keying

On Fri Sep 15, 2023 at 8:50 PM EEST, Denis Glazkov wrote:
> On Tue, Sep 12 2023 at 01:15 AM +0300, Jarkko Sakkinen wrote:
> > On Fri Sep 8, 2023 at 3:14 PM EEST, Denis Glazkov wrote:
> > > The Linux kernel has an IMA (Integrity Measurement Architecture)
> > > subsystem to check the integrity of the file system based on digital
> > > signatures. IMA uses certificates in `.ima` keying to check integrity.
> > >
> > > Only certificates issued by one of the trusted CA (Certificate Authority)
> > > certificates can be added to the `.ima` keying.
> > >
> > > The Linux kernel now has a secondary trusted keying to which trusted
> > > certificates from user space can be added if you have superuser
> > > privileges. Previously, all trusted certificates were in the built-in
> > > trusted keying, which could not be modified from user space.
> > > Trusted certificates were placed in the built-in trusted keying at
> > > kernel compile time.
> > >
> > > The secondary trusted keying is designed so that any certificates that
> > > are signed by one of the trusted CA certificates in the built-in or
> > > secondary trusted keyring can be added to it.
> > >
> > > Let's imagine that we have the following certificate trust chain:
> > >
> > > ┌───────────────────────────┬─────────────────────┐
> > > │ │ ┌───────┐ │
> > > │ │ │ │ │
> > > ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
> > > │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
> > > ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
> > > │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
> > > └─────────────────────┘ └────────────────────────┘ └───────────┘
> > >
> > > Issues Restricted by
> > > -------------► ──────────────►
> > >
> > > Since the IMA certificate is signed by a CA certificate from a secondary
> > > trusted keying, an attacker with superuser privileges will be able to
> > > add the IMA certificate to the secondary trusted keying. That is, the IMA
> > > certificate will become trusted.
> > >
> > > Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
> > > loaded into kernel space if they are signed with one of the trusted
> > > certificates, an attacker could sign untrusted kernel modules with
> > > the private key corresponding to the IMA certificate and successfully
> > > load the untrusted modules into kernel space.
> > >
> > > This patch adds the configuration that once enabled, only
> > > certificates that meet the following requirements can be added
> > > to the secondary trusted keying:
> > >
> > > 1. The certificate is a CA (Certificate Authority)
> > > 2. The certificate must be used for verifying a CA's signatures
> > > 3. The certificate must not be used for digital signatures
> > >
> > > Signed-off-by: Denis Glazkov <[email protected]>
> >
> > s/keying/keyring/ (multiple)
> >
> > Have you considered instead making mod_verify_sig() more robust?
> > Obviously this would mean making selection of keys in
> > verify_pkcs7_signature() more robust (see the documentation of
> > 'trusted_keys').
> >
> > The this would be also less niche feature to pick for distributors
> > if it was just concerning module loading, and have associated config
> > flag over there.
> >
> > BR, Jarkko
>
> Jarkko, thank you for your suggestion.
>
> This patch was created not to solve only the problem of loading
> untrusted kernel modules, but to make it possible to use a secondary
> trusted keying only as a part of a chain of trust containing only
> CA certificates with no digital signature capability.
>
> Let's imagine that tomorrow we have a new kernel feature, similar
> to kernel modules in terms of its impact on system security, which
> also uses trusted certificates for signature verification.
>
> If at this point we solve only the problem of loading untrusted
> kernel modules, and not the problem of the entire trusted keys
> system, we will need to add a new kernel option each time to solve
> a similar problem for each new kernel feature that uses trusted
> certificates.

Ok, I guessed so but given what I read from commit message I had to ask :-)

The description is very detailed and of good quality, and also what you
say CONFIG_MODULE_SIG is just fine but for completeness it would be good
to mention that purpose and goal is to fully close the gap with any
possible feature that might go without CA certificates (*in addition*).

> BR, Denis

BR, Jarkko

2023-10-02 10:54:10

by Denis Glazkov

[permalink] [raw]
Subject: [PATCH v3] certs: Add option to disallow non-CA certificates in secondary trusted keying

The Linux kernel has an IMA (Integrity Measurement Architecture)
subsystem to check the integrity of the file system based on digital
signatures. IMA uses certificates in `.ima` keying to check integrity.

Only certificates issued by one of the trusted CA (Certificate Authority)
certificates can be added to the `.ima` keying.

The Linux kernel now has a secondary trusted keying to which trusted
certificates from user space can be added if you have superuser
privileges. Previously, all trusted certificates were in the built-in
trusted keying, which could not be modified from user space.
Trusted certificates were placed in the built-in trusted keying at
kernel compile time.

The secondary trusted keying is designed so that any certificates that
are signed by one of the trusted CA certificates in the built-in or
secondary trusted keyring can be added to it.

Let's imagine that we have the following certificate trust chain:

┌───────────────────────────┬─────────────────────┐
│ │ ┌───────┐ │
│ │ │ │ │
┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
│.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
├─────────────────────┤ ├────────────────────────┤ ├───────────┤
│ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
└─────────────────────┘ └────────────────────────┘ └───────────┘

Issues Restricted by
-------------► ──────────────►

Since the IMA certificate is signed by a CA certificate from a secondary
trusted keying, an attacker with superuser privileges will be able to
add the IMA certificate to the secondary trusted keying. That is, the IMA
certificate will become trusted.

Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
loaded into kernel space if they are signed with one of the trusted
certificates, an attacker could sign untrusted kernel modules with
the private key corresponding to the IMA certificate and successfully
load the untrusted modules into kernel space.

This patch was created not to solve only the problem of loading
untrusted kernel modules, but to make it possible to use a secondary
trusted keying only as a part of a chain of trust containing only
CA certificates with no digital signature capability. This will
help avoid similar problems when new features appear in the linux
kernel that are similar to kernel modules in terms of their impact
on system security, which will also use trusted certificates for
signature verification.

This patch adds the configuration that once enabled, only
certificates that meet the following requirements can be added
to the secondary trusted keying:

1. The certificate is a CA (Certificate Authority)
2. The certificate must be used for verifying a CA's signatures
3. The certificate must not be used for digital signatures

Signed-off-by: Denis Glazkov <[email protected]>
---
v1 -> v2:
- Rebase the patch from `linux-next` to the main `linux` repo master branch
- Make the commit message more detailed
- Move the variable declaration to the `if` block
- Replace `#ifdef` with `IS_ENABLED` macro

v2 -> v3:
- Add the purpose and goal of the patch to the commit message
---
certs/Kconfig | 9 +++++++++
certs/system_keyring.c | 16 ++++++++++++++++
2 files changed, 25 insertions(+)

diff --git a/certs/Kconfig b/certs/Kconfig
index 1f109b070877..4a4dc8aab892 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING
those keys are not blacklisted and are vouched for by a key built
into the kernel or already in the secondary trusted keyring.

+config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
+ bool "Allow only CA certificates to be added to the secondary trusted keyring"
+ depends on SECONDARY_TRUSTED_KEYRING
+ help
+ If set, only CA certificates can be added to the secondary trusted keyring.
+ An acceptable CA certificate must include the `keyCertSign` value in
+ the `keyUsage` field. CA certificates that include the `digitalSignature`
+ value in the `keyUsage` field will not be accepted.
+
config SYSTEM_BLACKLIST_KEYRING
bool "Provide system-wide ring of blacklisted keys"
depends on KEYS
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 9de610bf1f4b..ee14447374e7 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted(
/* Allow the builtin keyring to be added to the secondary */
return 0;

+ if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) &&
+ dest_keyring == secondary_trusted_keys) {
+ const struct public_key *pub = payload->data[asym_crypto];
+
+ if (type != &key_type_asymmetric)
+ return -EOPNOTSUPP;
+ if (!pub)
+ return -ENOPKG;
+ if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
+ return -EPERM;
+ if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
+ return -EPERM;
+ if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
+ return -EPERM;
+ }
+
return restrict_link_by_signature(dest_keyring, type, payload,
secondary_trusted_keys);
}
--
2.34.1

2023-10-02 23:50:22

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3] certs: Add option to disallow non-CA certificates in secondary trusted keying

On Mon Oct 2, 2023 at 1:46 PM EEST, Denis Glazkov wrote:
> The Linux kernel has an IMA (Integrity Measurement Architecture)
> subsystem to check the integrity of the file system based on digital
> signatures. IMA uses certificates in `.ima` keying to check integrity.
>
> Only certificates issued by one of the trusted CA (Certificate Authority)
> certificates can be added to the `.ima` keying.
>
> The Linux kernel now has a secondary trusted keying to which trusted
> certificates from user space can be added if you have superuser
> privileges. Previously, all trusted certificates were in the built-in
> trusted keying, which could not be modified from user space.
> Trusted certificates were placed in the built-in trusted keying at
> kernel compile time.
>
> The secondary trusted keying is designed so that any certificates that
> are signed by one of the trusted CA certificates in the built-in or
> secondary trusted keyring can be added to it.
>
> Let's imagine that we have the following certificate trust chain:
>
> ┌───────────────────────────┬─────────────────────┐
> │ │ ┌───────┐ │
> │ │ │ │ │
> ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
> │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
> ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
> │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
> └─────────────────────┘ └────────────────────────┘ └───────────┘
>
> Issues Restricted by
> -------------► ──────────────►
>
> Since the IMA certificate is signed by a CA certificate from a secondary
> trusted keying, an attacker with superuser privileges will be able to
> add the IMA certificate to the secondary trusted keying. That is, the IMA
> certificate will become trusted.
>
> Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
> loaded into kernel space if they are signed with one of the trusted
> certificates, an attacker could sign untrusted kernel modules with
> the private key corresponding to the IMA certificate and successfully
> load the untrusted modules into kernel space.
>
> This patch was created not to solve only the problem of loading
> untrusted kernel modules, but to make it possible to use a secondary
> trusted keying only as a part of a chain of trust containing only
> CA certificates with no digital signature capability. This will
> help avoid similar problems when new features appear in the linux
> kernel that are similar to kernel modules in terms of their impact
> on system security, which will also use trusted certificates for
> signature verification.
>
> This patch adds the configuration that once enabled, only
> certificates that meet the following requirements can be added
> to the secondary trusted keying:
>
> 1. The certificate is a CA (Certificate Authority)
> 2. The certificate must be used for verifying a CA's signatures
> 3. The certificate must not be used for digital signatures
>
> Signed-off-by: Denis Glazkov <[email protected]>
> ---
> v1 -> v2:
> - Rebase the patch from `linux-next` to the main `linux` repo master branch
> - Make the commit message more detailed
> - Move the variable declaration to the `if` block
> - Replace `#ifdef` with `IS_ENABLED` macro
>
> v2 -> v3:
> - Add the purpose and goal of the patch to the commit message
> ---
> certs/Kconfig | 9 +++++++++
> certs/system_keyring.c | 16 ++++++++++++++++
> 2 files changed, 25 insertions(+)
>
> diff --git a/certs/Kconfig b/certs/Kconfig
> index 1f109b070877..4a4dc8aab892 100644
> --- a/certs/Kconfig
> +++ b/certs/Kconfig
> @@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING
> those keys are not blacklisted and are vouched for by a key built
> into the kernel or already in the secondary trusted keyring.
>
> +config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
> + bool "Allow only CA certificates to be added to the secondary trusted keyring"
> + depends on SECONDARY_TRUSTED_KEYRING
> + help
> + If set, only CA certificates can be added to the secondary trusted keyring.
> + An acceptable CA certificate must include the `keyCertSign` value in
> + the `keyUsage` field. CA certificates that include the `digitalSignature`
> + value in the `keyUsage` field will not be accepted.
> +
> config SYSTEM_BLACKLIST_KEYRING
> bool "Provide system-wide ring of blacklisted keys"
> depends on KEYS
> diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> index 9de610bf1f4b..ee14447374e7 100644
> --- a/certs/system_keyring.c
> +++ b/certs/system_keyring.c
> @@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted(
> /* Allow the builtin keyring to be added to the secondary */
> return 0;
>
> + if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) &&
> + dest_keyring == secondary_trusted_keys) {
> + const struct public_key *pub = payload->data[asym_crypto];
> +
> + if (type != &key_type_asymmetric)
> + return -EOPNOTSUPP;
> + if (!pub)
> + return -ENOPKG;
> + if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
> + return -EPERM;
> + if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
> + return -EPERM;
> + if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
> + return -EPERM;
> + }
> +
> return restrict_link_by_signature(dest_keyring, type, payload,
> secondary_trusted_keys);
> }
> --
> 2.34.1

I don't think this does any harm. What do you think Mimi?

BR, Jarkko

2023-10-03 19:04:52

by Eric Snowberg

[permalink] [raw]
Subject: Re: [PATCH v3] certs: Add option to disallow non-CA certificates in secondary trusted keying



> On Oct 2, 2023, at 5:49 PM, Jarkko Sakkinen <[email protected]> wrote:
>
> On Mon Oct 2, 2023 at 1:46 PM EEST, Denis Glazkov wrote:
>> The Linux kernel has an IMA (Integrity Measurement Architecture)
>> subsystem to check the integrity of the file system based on digital
>> signatures. IMA uses certificates in `.ima` keying to check integrity.
>>
>> Only certificates issued by one of the trusted CA (Certificate Authority)
>> certificates can be added to the `.ima` keying.
>>
>> The Linux kernel now has a secondary trusted keying to which trusted
>> certificates from user space can be added if you have superuser
>> privileges. Previously, all trusted certificates were in the built-in
>> trusted keying, which could not be modified from user space.
>> Trusted certificates were placed in the built-in trusted keying at
>> kernel compile time.
>>
>> The secondary trusted keying is designed so that any certificates that
>> are signed by one of the trusted CA certificates in the built-in or
>> secondary trusted keyring can be added to it.
>>
>> Let's imagine that we have the following certificate trust chain:
>>
>> ┌───────────────────────────┬─────────────────────┐
>> │ │ ┌───────┐ │
>> │ │ │ │ │
>> ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
>> │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
>> ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
>> │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
>> └─────────────────────┘ └────────────────────────┘ └───────────┘
>>
>> Issues Restricted by
>> -------------► ──────────────►
>>
>> Since the IMA certificate is signed by a CA certificate from a secondary
>> trusted keying, an attacker with superuser privileges will be able to
>> add the IMA certificate to the secondary trusted keying. That is, the IMA
>> certificate will become trusted.
>>
>> Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
>> loaded into kernel space if they are signed with one of the trusted
>> certificates, an attacker could sign untrusted kernel modules with
>> the private key corresponding to the IMA certificate and successfully
>> load the untrusted modules into kernel space.
>>
>> This patch was created not to solve only the problem of loading
>> untrusted kernel modules, but to make it possible to use a secondary
>> trusted keying only as a part of a chain of trust containing only
>> CA certificates with no digital signature capability. This will
>> help avoid similar problems when new features appear in the linux
>> kernel that are similar to kernel modules in terms of their impact
>> on system security, which will also use trusted certificates for
>> signature verification.
>>
>> This patch adds the configuration that once enabled, only
>> certificates that meet the following requirements can be added
>> to the secondary trusted keying:
>>
>> 1. The certificate is a CA (Certificate Authority)
>> 2. The certificate must be used for verifying a CA's signatures
>> 3. The certificate must not be used for digital signatures
>>
>> Signed-off-by: Denis Glazkov <[email protected]>
>> ---
>> v1 -> v2:
>> - Rebase the patch from `linux-next` to the main `linux` repo master branch
>> - Make the commit message more detailed
>> - Move the variable declaration to the `if` block
>> - Replace `#ifdef` with `IS_ENABLED` macro
>>
>> v2 -> v3:
>> - Add the purpose and goal of the patch to the commit message
>> ---
>> certs/Kconfig | 9 +++++++++
>> certs/system_keyring.c | 16 ++++++++++++++++
>> 2 files changed, 25 insertions(+)
>>
>> diff --git a/certs/Kconfig b/certs/Kconfig
>> index 1f109b070877..4a4dc8aab892 100644
>> --- a/certs/Kconfig
>> +++ b/certs/Kconfig
>> @@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING
>> those keys are not blacklisted and are vouched for by a key built
>> into the kernel or already in the secondary trusted keyring.
>>
>> +config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
>> + bool "Allow only CA certificates to be added to the secondary trusted keyring"
>> + depends on SECONDARY_TRUSTED_KEYRING
>> + help
>> + If set, only CA certificates can be added to the secondary trusted keyring.
>> + An acceptable CA certificate must include the `keyCertSign` value in
>> + the `keyUsage` field. CA certificates that include the `digitalSignature`
>> + value in the `keyUsage` field will not be accepted.
>> +
>> config SYSTEM_BLACKLIST_KEYRING
>> bool "Provide system-wide ring of blacklisted keys"
>> depends on KEYS
>> diff --git a/certs/system_keyring.c b/certs/system_keyring.c
>> index 9de610bf1f4b..ee14447374e7 100644
>> --- a/certs/system_keyring.c
>> +++ b/certs/system_keyring.c
>> @@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted(
>> /* Allow the builtin keyring to be added to the secondary */
>> return 0;
>>
>> + if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) &&
>> + dest_keyring == secondary_trusted_keys) {
>> + const struct public_key *pub = payload->data[asym_crypto];
>> +
>> + if (type != &key_type_asymmetric)
>> + return -EOPNOTSUPP;
>> + if (!pub)
>> + return -ENOPKG;
>> + if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
>> + return -EPERM;
>> + if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
>> + return -EPERM;
>> + if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
>> + return -EPERM;
>> + }
>> +
>> return restrict_link_by_signature(dest_keyring, type, payload,
>> secondary_trusted_keys);
>> }
>> --
>> 2.34.1
>
> I don't think this does any harm.

Right or wrong, there do seem to be Intermediate CA’s that have the
digital signature usage set [1].

1. https://www.digicert.com/kb/digicert-root-certificates.htm#intermediates

> What do you think Mimi?

2023-10-05 21:33:56

by Denis Glazkov

[permalink] [raw]
Subject: Re: [PATCH v3] certs: Add option to disallow non-CA certificates in secondary trusted keying

On Tue, Oct 3 2023 at 07:04 PM +0000, Eric Snowberg wrote:
>
> > On Oct 2, 2023, at 5:49 PM, Jarkko Sakkinen <[email protected]> wrote:
> >
> > On Mon Oct 2, 2023 at 1:46 PM EEST, Denis Glazkov wrote:
> > > The Linux kernel has an IMA (Integrity Measurement Architecture)
> > > subsystem to check the integrity of the file system based on digital
> > > signatures. IMA uses certificates in `.ima` keying to check integrity.
> > >
> > > Only certificates issued by one of the trusted CA (Certificate Authority)
> > > certificates can be added to the `.ima` keying.
> > >
> > > The Linux kernel now has a secondary trusted keying to which trusted
> > > certificates from user space can be added if you have superuser
> > > privileges. Previously, all trusted certificates were in the built-in
> > > trusted keying, which could not be modified from user space.
> > > Trusted certificates were placed in the built-in trusted keying at
> > > kernel compile time.
> > >
> > > The secondary trusted keying is designed so that any certificates that
> > > are signed by one of the trusted CA certificates in the built-in or
> > > secondary trusted keyring can be added to it.
> > >
> > > Let's imagine that we have the following certificate trust chain:
> > >
> > > ┌───────────────────────────┬─────────────────────┐
> > > │ │ ┌───────┐ │
> > > │ │ │ │ │
> > > ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
> > > │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
> > > ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
> > > │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
> > > └─────────────────────┘ └────────────────────────┘ └───────────┘
> > >
> > > Issues Restricted by
> > > -------------► ──────────────►
> > >
> > > Since the IMA certificate is signed by a CA certificate from a secondary
> > > trusted keying, an attacker with superuser privileges will be able to
> > > add the IMA certificate to the secondary trusted keying. That is, the IMA
> > > certificate will become trusted.
> > >
> > > Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
> > > loaded into kernel space if they are signed with one of the trusted
> > > certificates, an attacker could sign untrusted kernel modules with
> > > the private key corresponding to the IMA certificate and successfully
> > > load the untrusted modules into kernel space.
> > >
> > > This patch was created not to solve only the problem of loading
> > > untrusted kernel modules, but to make it possible to use a secondary
> > > trusted keying only as a part of a chain of trust containing only
> > > CA certificates with no digital signature capability. This will
> > > help avoid similar problems when new features appear in the linux
> > > kernel that are similar to kernel modules in terms of their impact
> > > on system security, which will also use trusted certificates for
> > > signature verification.
> > >
> > > This patch adds the configuration that once enabled, only
> > > certificates that meet the following requirements can be added
> > > to the secondary trusted keying:
> > >
> > > 1. The certificate is a CA (Certificate Authority)
> > > 2. The certificate must be used for verifying a CA's signatures
> > > 3. The certificate must not be used for digital signatures
> > >
> > > Signed-off-by: Denis Glazkov <[email protected]>
> > > ---
> > > v1 -> v2:
> > > - Rebase the patch from `linux-next` to the main `linux` repo master branch
> > > - Make the commit message more detailed
> > > - Move the variable declaration to the `if` block
> > > - Replace `#ifdef` with `IS_ENABLED` macro
> > >
> > > v2 -> v3:
> > > - Add the purpose and goal of the patch to the commit message
> > > ---
> > > certs/Kconfig | 9 +++++++++
> > > certs/system_keyring.c | 16 ++++++++++++++++
> > > 2 files changed, 25 insertions(+)
> > >
> > > diff --git a/certs/Kconfig b/certs/Kconfig
> > > index 1f109b070877..4a4dc8aab892 100644
> > > --- a/certs/Kconfig
> > > +++ b/certs/Kconfig
> > > @@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING
> > > those keys are not blacklisted and are vouched for by a key built
> > > into the kernel or already in the secondary trusted keyring.
> > >
> > > +config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
> > > + bool "Allow only CA certificates to be added to the secondary trusted keyring"
> > > + depends on SECONDARY_TRUSTED_KEYRING
> > > + help
> > > + If set, only CA certificates can be added to the secondary trusted keyring.
> > > + An acceptable CA certificate must include the `keyCertSign` value in
> > > + the `keyUsage` field. CA certificates that include the `digitalSignature`
> > > + value in the `keyUsage` field will not be accepted.
> > > +
> > > config SYSTEM_BLACKLIST_KEYRING
> > > bool "Provide system-wide ring of blacklisted keys"
> > > depends on KEYS
> > > diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> > > index 9de610bf1f4b..ee14447374e7 100644
> > > --- a/certs/system_keyring.c
> > > +++ b/certs/system_keyring.c
> > > @@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted(
> > > /* Allow the builtin keyring to be added to the secondary */
> > > return 0;
> > >
> > > + if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) &&
> > > + dest_keyring == secondary_trusted_keys) {
> > > + const struct public_key *pub = payload->data[asym_crypto];
> > > +
> > > + if (type != &key_type_asymmetric)
> > > + return -EOPNOTSUPP;
> > > + if (!pub)
> > > + return -ENOPKG;
> > > + if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
> > > + return -EPERM;
> > > + if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
> > > + return -EPERM;
> > > + if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
> > > + return -EPERM;
> > > + }
> > > +
> > > return restrict_link_by_signature(dest_keyring, type, payload,
> > > secondary_trusted_keys);
> > > }
> > > --
> > > 2.34.1
> >
> > I don't think this does any harm.
>
> Right or wrong, there do seem to be Intermediate CA’s that have the
> digital signature usage set [1].
>
> 1. https://www.digicert.com/kb/digicert-root-certificates.htm#intermediates

I was surprised to see that intermediate CA certificates issued by
DigiCert can be used for digital signature. Since in idea all that
is required from intermediate CA certificates is to be a member of
the chain of trust and to issue end-user certificates that should
be used for digital signatures.

In my opinion for these two purposes there is no need to add digital
signature rights to the intermediate CA certificate. This is probably
because most of these intermediate CA certificates are used on the
web, where they most likely have additional use cases.

It is difficult for me to imagine using such intermediate CA
certificates in Linux trusted keyrings, since they are practically
no different from end-user certificates, which can be used to
verify module signatures.

That's why this patch includes an additional check to make sure that
the certificate does not have digital signature rights, which will
protect the secondary trusted keyring from the scenario described in
the commit message.

BR, Denis

2023-10-09 14:11:02

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3] certs: Add option to disallow non-CA certificates in secondary trusted keying

On Tue, 2023-10-03 at 02:49 +0300, Jarkko Sakkinen wrote:
> On Mon Oct 2, 2023 at 1:46 PM EEST, Denis Glazkov wrote:
> > The Linux kernel has an IMA (Integrity Measurement Architecture)
> > subsystem to check the integrity of the file system based on digital
> > signatures. IMA uses certificates in `.ima` keying to check integrity.
> >
> > Only certificates issued by one of the trusted CA (Certificate Authority)
> > certificates can be added to the `.ima` keying.
> >
> > The Linux kernel now has a secondary trusted keying to which trusted
> > certificates from user space can be added if you have superuser
> > privileges. Previously, all trusted certificates were in the built-in
> > trusted keying, which could not be modified from user space.
> > Trusted certificates were placed in the built-in trusted keying at
> > kernel compile time.
> >
> > The secondary trusted keying is designed so that any certificates that
> > are signed by one of the trusted CA certificates in the built-in or
> > secondary trusted keyring can be added to it.
> >
> > Let's imagine that we have the following certificate trust chain:
> >
> > ┌───────────────────────────┬─────────────────────┐
> > │ │ ┌───────┐ │
> > │ │ │ │ │
> > ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
> > │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
> > ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
> > │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
> > └─────────────────────┘ └────────────────────────┘ └───────────┘
> >
> > Issues Restricted by
> > -------------► ──────────────►
> >
> > Since the IMA certificate is signed by a CA certificate from a secondary
> > trusted keying, an attacker with superuser privileges will be able to
> > add the IMA certificate to the secondary trusted keying. That is, the IMA
> > certificate will become trusted.
> >
> > Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
> > loaded into kernel space if they are signed with one of the trusted
> > certificates, an attacker could sign untrusted kernel modules with
> > the private key corresponding to the IMA certificate and successfully
> > load the untrusted modules into kernel space.
> >
> > This patch was created not to solve only the problem of loading
> > untrusted kernel modules, but to make it possible to use a secondary
> > trusted keying only as a part of a chain of trust containing only
> > CA certificates with no digital signature capability. This will
> > help avoid similar problems when new features appear in the linux
> > kernel that are similar to kernel modules in terms of their impact
> > on system security, which will also use trusted certificates for
> > signature verification.
> >
> > This patch adds the configuration that once enabled, only
> > certificates that meet the following requirements can be added
> > to the secondary trusted keying:
> >
> > 1. The certificate is a CA (Certificate Authority)
> > 2. The certificate must be used for verifying a CA's signatures
> > 3. The certificate must not be used for digital signatures
> >
> > Signed-off-by: Denis Glazkov <[email protected]>
> > ---
> > v1 -> v2:
> > - Rebase the patch from `linux-next` to the main `linux` repo master branch
> > - Make the commit message more detailed
> > - Move the variable declaration to the `if` block
> > - Replace `#ifdef` with `IS_ENABLED` macro
> >
> > v2 -> v3:
> > - Add the purpose and goal of the patch to the commit message
> > ---
> > certs/Kconfig | 9 +++++++++
> > certs/system_keyring.c | 16 ++++++++++++++++
> > 2 files changed, 25 insertions(+)
> >
> > diff --git a/certs/Kconfig b/certs/Kconfig
> > index 1f109b070877..4a4dc8aab892 100644
> > --- a/certs/Kconfig
> > +++ b/certs/Kconfig
> > @@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING
> > those keys are not blacklisted and are vouched for by a key built
> > into the kernel or already in the secondary trusted keyring.
> >
> > +config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
> > + bool "Allow only CA certificates to be added to the secondary trusted keyring"
> > + depends on SECONDARY_TRUSTED_KEYRING
> > + help
> > + If set, only CA certificates can be added to the secondary trusted keyring.
> > + An acceptable CA certificate must include the `keyCertSign` value in
> > + the `keyUsage` field. CA certificates that include the `digitalSignature`
> > + value in the `keyUsage` field will not be accepted.
> > +
> > config SYSTEM_BLACKLIST_KEYRING
> > bool "Provide system-wide ring of blacklisted keys"
> > depends on KEYS
> > diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> > index 9de610bf1f4b..ee14447374e7 100644
> > --- a/certs/system_keyring.c
> > +++ b/certs/system_keyring.c
> > @@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted(
> > /* Allow the builtin keyring to be added to the secondary */
> > return 0;
> >
> > + if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) &&
> > + dest_keyring == secondary_trusted_keys) {
> > + const struct public_key *pub = payload->data[asym_crypto];
> > +
> > + if (type != &key_type_asymmetric)
> > + return -EOPNOTSUPP;
> > + if (!pub)
> > + return -ENOPKG;
> > + if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
> > + return -EPERM;
> > + if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
> > + return -EPERM;
> > + if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
> > + return -EPERM;
> > + }
> > +
> > return restrict_link_by_signature(dest_keyring, type, payload,
> > secondary_trusted_keys);
> > }
> > --
> > 2.34.1
>
> I don't think this does any harm. What do you think Mimi?

I really like the idea of only allowing CA keys to be loaded onto the
secondary trusted keyring. However, the secondary trusted keyring has
been around a long time with the ability of loading non CA keys. Is
the real concern here about loading non CA keys signed by keys on the
builtin keyring or the new machine keyring?

It would make sense for the new Kconfig to somehow require
INTEGRITY_CA_MACHINE_KEYRING_MAX, if INTEGRITY_MACHINE_KEYRING is
configured.

--
thanks,

Mimi

2023-10-17 12:43:39

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3] certs: Add option to disallow non-CA certificates in secondary trusted keying

On Mon, 2023-10-09 at 10:10 -0400, Mimi Zohar wrote:
> On Tue, 2023-10-03 at 02:49 +0300, Jarkko Sakkinen wrote:
> > On Mon Oct 2, 2023 at 1:46 PM EEST, Denis Glazkov wrote:
> > > The Linux kernel has an IMA (Integrity Measurement Architecture)
> > > subsystem to check the integrity of the file system based on digital
> > > signatures. IMA uses certificates in `.ima` keying to check integrity.
> > >
> > > Only certificates issued by one of the trusted CA (Certificate Authority)
> > > certificates can be added to the `.ima` keying.
> > >
> > > The Linux kernel now has a secondary trusted keying to which trusted
> > > certificates from user space can be added if you have superuser
> > > privileges. Previously, all trusted certificates were in the built-in
> > > trusted keying, which could not be modified from user space.
> > > Trusted certificates were placed in the built-in trusted keying at
> > > kernel compile time.
> > >
> > > The secondary trusted keying is designed so that any certificates that
> > > are signed by one of the trusted CA certificates in the built-in or
> > > secondary trusted keyring can be added to it.
> > >
> > > Let's imagine that we have the following certificate trust chain:
> > >
> > > ┌───────────────────────────┬─────────────────────┐
> > > │ │ ┌───────┐ │
> > > │ │ │ │ │
> > > ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐
> > > │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │
> > > ├─────────────────────┤ ├────────────────────────┤ ├───────────┤
> > > │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │
> > > └─────────────────────┘ └────────────────────────┘ └───────────┘
> > >
> > > Issues Restricted by
> > > -------------► ──────────────►
> > >
> > > Since the IMA certificate is signed by a CA certificate from a secondary
> > > trusted keying, an attacker with superuser privileges will be able to
> > > add the IMA certificate to the secondary trusted keying. That is, the IMA
> > > certificate will become trusted.
> > >
> > > Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be
> > > loaded into kernel space if they are signed with one of the trusted
> > > certificates, an attacker could sign untrusted kernel modules with
> > > the private key corresponding to the IMA certificate and successfully
> > > load the untrusted modules into kernel space.
> > >
> > > This patch was created not to solve only the problem of loading
> > > untrusted kernel modules, but to make it possible to use a secondary
> > > trusted keying only as a part of a chain of trust containing only
> > > CA certificates with no digital signature capability. This will
> > > help avoid similar problems when new features appear in the linux
> > > kernel that are similar to kernel modules in terms of their impact
> > > on system security, which will also use trusted certificates for
> > > signature verification.
> > >
> > > This patch adds the configuration that once enabled, only
> > > certificates that meet the following requirements can be added
> > > to the secondary trusted keying:
> > >
> > > 1. The certificate is a CA (Certificate Authority)
> > > 2. The certificate must be used for verifying a CA's signatures
> > > 3. The certificate must not be used for digital signatures
> > >
> > > Signed-off-by: Denis Glazkov <[email protected]>
> > > ---
> > > v1 -> v2:
> > > - Rebase the patch from `linux-next` to the main `linux` repo master branch
> > > - Make the commit message more detailed
> > > - Move the variable declaration to the `if` block
> > > - Replace `#ifdef` with `IS_ENABLED` macro
> > >
> > > v2 -> v3:
> > > - Add the purpose and goal of the patch to the commit message
> > > ---
> > > certs/Kconfig | 9 +++++++++
> > > certs/system_keyring.c | 16 ++++++++++++++++
> > > 2 files changed, 25 insertions(+)
> > >
> > > diff --git a/certs/Kconfig b/certs/Kconfig
> > > index 1f109b070877..4a4dc8aab892 100644
> > > --- a/certs/Kconfig
> > > +++ b/certs/Kconfig
> > > @@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING
> > > those keys are not blacklisted and are vouched for by a key built
> > > into the kernel or already in the secondary trusted keyring.
> > >
> > > +config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY
> > > + bool "Allow only CA certificates to be added to the secondary trusted keyring"
> > > + depends on SECONDARY_TRUSTED_KEYRING
> > > + help
> > > + If set, only CA certificates can be added to the secondary trusted keyring.
> > > + An acceptable CA certificate must include the `keyCertSign` value in
> > > + the `keyUsage` field. CA certificates that include the `digitalSignature`
> > > + value in the `keyUsage` field will not be accepted.
> > > +
> > > config SYSTEM_BLACKLIST_KEYRING
> > > bool "Provide system-wide ring of blacklisted keys"
> > > depends on KEYS
> > > diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> > > index 9de610bf1f4b..ee14447374e7 100644
> > > --- a/certs/system_keyring.c
> > > +++ b/certs/system_keyring.c
> > > @@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted(
> > > /* Allow the builtin keyring to be added to the secondary */
> > > return 0;
> > >
> > > + if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) &&
> > > + dest_keyring == secondary_trusted_keys) {
> > > + const struct public_key *pub = payload->data[asym_crypto];
> > > +
> > > + if (type != &key_type_asymmetric)
> > > + return -EOPNOTSUPP;
> > > + if (!pub)
> > > + return -ENOPKG;
> > > + if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags))
> > > + return -EPERM;
> > > + if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags))
> > > + return -EPERM;
> > > + if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags))
> > > + return -EPERM;
> > > + }
> > > +
> > > return restrict_link_by_signature(dest_keyring, type, payload,
> > > secondary_trusted_keys);
> > > }
> > > --
> > > 2.34.1
> >
> > I don't think this does any harm. What do you think Mimi?
>
> I really like the idea of only allowing CA keys to be loaded onto the
> secondary trusted keyring. However, the secondary trusted keyring has
> been around a long time with the ability of loading non CA keys. Is
> the real concern here about loading non CA keys signed by keys on the
> builtin keyring or the new machine keyring?
>
> It would make sense for the new Kconfig to somehow require
> INTEGRITY_CA_MACHINE_KEYRING_MAX, if INTEGRITY_MACHINE_KEYRING is
> configured.

This patch allows CA certificates signed by any key either linked to or
on the secondary keyring to be loaded onto the secondary keyring.

I just posted "[RFC PATCH] certs: Only allow certs signed by keys on
the builtin keyring" as an alternative. It only allows loading
certificates onto the secondary keyring signed by a key on the builtin
keyring.

--
thanks,

Mimi