[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220406015337.4000739-7-eric.snowberg@oracle.com>
Date: Tue, 5 Apr 2022 21:53:36 -0400
From: Eric Snowberg <eric.snowberg@...cle.com>
To: dhowells@...hat.com, dwmw2@...radead.org, jarkko@...nel.org,
zohar@...ux.ibm.com, linux-integrity@...r.kernel.org
Cc: herbert@...dor.apana.org.au, davem@...emloft.net,
dmitry.kasatkin@...il.com, jmorris@...ei.org, serge@...lyn.com,
roberto.sassu@...wei.com, nramas@...ux.microsoft.com,
eric.snowberg@...cle.com, pvorel@...e.cz, tiwai@...e.de,
keyrings@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-crypto@...r.kernel.org, linux-security-module@...r.kernel.org
Subject: [PATCH 6/7] KEYS: X.509: Flag Intermediate CA certs as built in
Currently X.509 Intermediate CA certs do not have the builtin root of trust
key flag set. Allow intermediate CA certs to be added. Requirements for an
intermediate CA include: Usage extension defined as keyCertSign, Basic
Constrains for CA is false, and Intermediate CA cert is signed by a current
builtin ROT key.
Signed-off-by: Eric Snowberg <eric.snowberg@...cle.com>
---
crypto/asymmetric_keys/x509_public_key.c | 14 ++++++++++++--
include/linux/ima.h | 16 ++++++++++++++++
include/linux/key-type.h | 1 +
security/keys/key.c | 5 +++++
4 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 7290e765f46b..9052dd761ea3 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -215,8 +215,18 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
prep->payload.data[asym_auth] = cert->sig;
prep->description = desc;
prep->quotalen = 100;
- if (cert->is_kcs_set && cert->self_signed && cert->is_root_ca)
- prep->payload_flags |= KEY_ALLOC_ROT;
+ if (cert->is_kcs_set) {
+ if (cert->self_signed && cert->is_root_ca)
+ prep->payload_flags |= KEY_ALLOC_ROT;
+ /*
+ * In this case it could be an Intermediate CA. Set
+ * KEY_MAYBE_ROT for now. If the restriction check
+ * passes later, the key will be allocated with the
+ * correct ROT flag.
+ */
+ else if (!cert->self_signed && !cert->is_root_ca)
+ prep->payload_flags |= KEY_MAYBE_ROT;
+ }
/* We've finished with the certificate */
cert->pub = NULL;
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 426b1744215e..3f23bccf880a 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -12,6 +12,7 @@
#include <linux/security.h>
#include <linux/kexec.h>
#include <crypto/hash_info.h>
+#include <keys/system_keyring.h>
struct linux_binprm;
#ifdef CONFIG_IMA
@@ -176,6 +177,21 @@ static inline void ima_post_key_create_or_update(struct key *keyring,
bool create) {}
#endif /* CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS */
+#ifdef CONFIG_ASYMMETRIC_KEY_TYPE
+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
+#define ima_validate_builtin_rot restrict_link_by_rot_builtin_and_secondary_trusted
+#else
+#define ima_validate_builtin_rot restrict_link_by_rot_builtin_trusted
+#endif
+#else
+static inline int ima_validate_builtin_rot(struct key *dest_keyring,
+ const struct key_type *type,
+ const union key_payload *payload,
+ struct key *unused){
+ return -EPERM;
+}
+#endif
+
#ifdef CONFIG_IMA_APPRAISE
extern bool is_ima_appraise_enabled(void);
extern void ima_inode_post_setattr(struct user_namespace *mnt_userns,
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index ed0aaad3849b..da09e68903e2 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -38,6 +38,7 @@ struct key_preparsed_payload {
time64_t expiry; /* Expiry time of key */
unsigned int payload_flags; /* Proposed payload flags */
#define KEY_ALLOC_ROT 0x0001 /* Proposed Root of Trust (ROT) key */
+#define KEY_MAYBE_ROT 0x0002 /* Proposed possible Root of Trust key */
} __randomize_layout;
typedef int (*request_key_actor_t)(struct key *auth_key, void *aux);
diff --git a/security/keys/key.c b/security/keys/key.c
index 732bb837fc51..c553040dcc02 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -900,6 +900,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
}
}
+ /* Previous restriction check passed therefore try to validate root of trust */
+ if ((prep.payload_flags & KEY_MAYBE_ROT) &&
+ !(ima_validate_builtin_rot(keyring, index_key.type, &prep.payload, NULL)))
+ prep.payload_flags |= KEY_ALLOC_ROT;
+
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
ret = key_permission(keyring_ref, KEY_NEED_WRITE);
--
2.27.0
Powered by blists - more mailing lists