lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ