Skip to contentSkip to conversation

KEYS: validate key trust with owner and builtin keys only

PATCH In review Dmitry Kasatkin 3 participants 6 messages Jun 12, 2014 – Jun 17, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover KEYS: validate key trust with owner and builtin keys only

This is a repost of the patchset cleanly on the top of linux-integrity next-trusted-keys branch.

Instead of allowing public keys, with certificates signed by any key on the system trusted keyring, to be added to a trusted keyring, this patch set further restricts the certificates to those signed by a particular key or builtin keys on the system keyring.

This patch defines a new kernel parameter 'keys_ownerid={id:xxx | builtin}' to use specific key or any builtin key.

Thanks,
Dmitry

Dmitry Kasatkin (2):
KEYS: validate certificate trust only with selected owner key
KEYS: validate certificate trust only with builtin keys

 Documentation/kernel-parameters.txt      |  5 +++++
 crypto/asymmetric_keys/x509_public_key.c | 32 ++++++++++++++++++++++++++++++--
 include/linux/key.h                      |  1 +
 kernel/system_keyring.c                  |  1 +
 4 files changed, 37 insertions(+), 2 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/2 KEYS: validate certificate trust only with selected owner key

Instead of allowing public keys, with certificates signed by any key on the system trusted keyring, to be added to a trusted keyring, this patch further restricts the certificates to those signed by a particular key on the system keyring.

This patch defines a new kernel parameter 'keys_ownerid' to specify owner's key id which must be used for trust validation of certificates.

Idea belongs to Mimi Zohar.

---
 Documentation/kernel-parameters.txt      |  5 +++++
 crypto/asymmetric_keys/x509_public_key.c | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)
Documentation/kernel-parameters.txt +5 -0
index 7116fda..7a810d3 100644
@@ -1434,6 +1434,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			use the HighMem zone if it exists, and the Normal
 			zone if it does not.
 
+	keys_ownerid=[KEYS] This parameter identifies a specific key(s) on
+			the system trusted keyring to be used for certificate
+			trust validation.
+			format: id:<keyid>
+
 	kgdbdbgp=	[KGDB,HW] kgdb over EHCI usb debug port.
 			Format: <Controller#>[,poll interval]
 			The controller # is the number of the ehci usb debug
crypto/asymmetric_keys/x509_public_key.c +23 -0
index 7a9b386..d46b790 100644
@@ -24,6 +24,19 @@
 #include "public_key.h"
 #include "x509_parser.h"
 
+static char *owner_keyid;
+static int __init default_owner_keyid_set(char *str)
+{
+	if (!str)		/* default system keyring */
+		return 1;
+
+	if (strncmp(str, "id:", 3) == 0)
+		owner_keyid = str;	/* owner local key 'id:xxxxxx' */
+
+	return 1;
+}
+__setup("keys_ownerid=", default_owner_keyid_set);
+
 /*
  * Find a key in the given keyring by issuer and authority.
  */
@@ -169,6 +182,16 @@ static int x509_validate_trust(struct x509_certificate *cert,
 	if (!trust_keyring)
 		return -EOPNOTSUPP;
 
+	if (owner_keyid) {
+		/* validate trust only with the owner_keyid if specified */
+		/* partial match of keyid according to the asymmetric_type.c */
+		int idlen = strlen(owner_keyid) - 3; /* - id: */
+		int authlen = strlen(cert->authority);
+		char *auth = cert->authority + authlen - idlen;
+		if (idlen > authlen || strcasecmp(owner_keyid + 3, auth))
+			return -EPERM;
+	}
+
 	key = x509_request_asymmetric_key(trust_keyring,
 					  cert->issuer, strlen(cert->issuer),
 					  cert->authority,
Signature · 1 line
1.9.1
#2 lore raw

Re: [PATCH v1a 1/2] KEYS: validate certificate trust only with selected owner key

Quoted 60 lines · Dmitry Kasatkin

Instead of allowing public keys, with certificates signed by any key on the system trusted keyring, to be added to a trusted keyring, this patch further restricts the certificates to those signed by a particular key on the system keyring.

This patch defines a new kernel parameter 'keys_ownerid' to specify owner's key id which must be used for trust validation of certificates.

Idea belongs to Mimi Zohar.

---
 Documentation/kernel-parameters.txt      |  5 +++++
 crypto/asymmetric_keys/x509_public_key.c | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)
Documentation/kernel-parameters.txt +5 -0
index 7116fda..7a810d3 100644
@@ -1434,6 +1434,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			use the HighMem zone if it exists, and the Normal
 			zone if it does not.
 
+	keys_ownerid=[KEYS] This parameter identifies a specific key(s) on
+			the system trusted keyring to be used for certificate
+			trust validation.
+			format: id:<keyid>
+
 	kgdbdbgp=	[KGDB,HW] kgdb over EHCI usb debug port.
 			Format: <Controller#>[,poll interval]
 			The controller # is the number of the ehci usb debug
crypto/asymmetric_keys/x509_public_key.c +13 -0
index 7a9b386..d46b790 100644
@@ -24,6 +24,19 @@
 #include "public_key.h"
 #include "x509_parser.h"
 
+static char *owner_keyid;
+static int __init default_owner_keyid_set(char *str)
+{
+	if (!str)		/* default system keyring */
+		return 1;
+
+	if (strncmp(str, "id:", 3) == 0)
+		owner_keyid = str;	/* owner local key 'id:xxxxxx' */
+
+	return 1;
+}
+__setup("keys_ownerid=", default_owner_keyid_set);
+
 /*
  * Find a key in the given keyring by issuer and authority.
  */
@@ -169,6 +182,16 @@ static int x509_validate_trust(struct x509_certificate *cert,
 	if (!trust_keyring)
 		return -EOPNOTSUPP;
 

crypto/asymmetric_keys/x509_public_key.c static int x509_validate_trust(struct x509_certificate *cert, · line 194

Quoted 10 lines
crypto/asymmetric_keys/x509_public_key.c +10 -0
+	if (owner_keyid) {
+		/* validate trust only with the owner_keyid if specified */
+		/* partial match of keyid according to the asymmetric_type.c */
+		int idlen = strlen(owner_keyid) - 3; /* - id: */
+		int authlen = strlen(cert->authority);
+		char *auth = cert->authority + authlen - idlen;
+		if (idlen > authlen || strcasecmp(owner_keyid + 3, auth))
+			return -EPERM;
+	}
+

We shouldn't hard code the test here, but use the key type's match function. For example, the "KEYS: define an owner trusted keyring" (v4) patch defined a key_match() function.

thanks,

Mimi

Quoted 3 lines
crypto/asymmetric_keys/x509_public_key.c +0 -0
 	key = x509_request_asymmetric_key(trust_keyring,
 					  cert->issuer, strlen(cert->issuer),
 					  cert->authority,
#3 lore raw

Re: [PATCH v1a 1/2] KEYS: validate certificate trust only with selected owner key

Quoted 75 lines · Mimi Zohar
Quoted 60 lines · Dmitry Kasatkin

Instead of allowing public keys, with certificates signed by any key on the system trusted keyring, to be added to a trusted keyring, this patch further restricts the certificates to those signed by a particular key on the system keyring.

This patch defines a new kernel parameter 'keys_ownerid' to specify owner's key id which must be used for trust validation of certificates.

Idea belongs to Mimi Zohar.

---
 Documentation/kernel-parameters.txt      |  5 +++++
 crypto/asymmetric_keys/x509_public_key.c | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)
Documentation/kernel-parameters.txt +5 -0
index 7116fda..7a810d3 100644
@@ -1434,6 +1434,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			use the HighMem zone if it exists, and the Normal
 			zone if it does not.
 
+	keys_ownerid=[KEYS] This parameter identifies a specific key(s) on
+			the system trusted keyring to be used for certificate
+			trust validation.
+			format: id:<keyid>
+
 	kgdbdbgp=	[KGDB,HW] kgdb over EHCI usb debug port.
 			Format: <Controller#>[,poll interval]
 			The controller # is the number of the ehci usb debug
crypto/asymmetric_keys/x509_public_key.c +13 -0
index 7a9b386..d46b790 100644
@@ -24,6 +24,19 @@
 #include "public_key.h"
 #include "x509_parser.h"
 
+static char *owner_keyid;
+static int __init default_owner_keyid_set(char *str)
+{
+	if (!str)		/* default system keyring */
+		return 1;
+
+	if (strncmp(str, "id:", 3) == 0)
+		owner_keyid = str;	/* owner local key 'id:xxxxxx' */
+
+	return 1;
+}
+__setup("keys_ownerid=", default_owner_keyid_set);
+
 /*
  * Find a key in the given keyring by issuer and authority.
  */
@@ -169,6 +182,16 @@ static int x509_validate_trust(struct x509_certificate *cert,
 	if (!trust_keyring)
 		return -EOPNOTSUPP;
 

crypto/asymmetric_keys/x509_public_key.c static int x509_validate_trust(struct x509_certificate *cert, · line 194

Quoted 10 lines
crypto/asymmetric_keys/x509_public_key.c +10 -0
+	if (owner_keyid) {
+		/* validate trust only with the owner_keyid if specified */
+		/* partial match of keyid according to the asymmetric_type.c */
+		int idlen = strlen(owner_keyid) - 3; /* - id: */
+		int authlen = strlen(cert->authority);
+		char *auth = cert->authority + authlen - idlen;
+		if (idlen > authlen || strcasecmp(owner_keyid + 3, auth))
+			return -EPERM;
+	}
+

We shouldn't hard code the test here, but use the key type's match function. For example, the "KEYS: define an owner trusted keyring" (v4) patch defined a key_match() function.

Quoted 1 line

thanks,

Right.

I addressed this in the following patchset.

Thanks.

Quoted 14 lines

Mimi

crypto/asymmetric_keys/x509_public_key.c static int x509_validate_trust(struct x509_certificate *cert, · line 197

Quoted 3 lines
crypto/asymmetric_keys/x509_public_key.c +0 -0
 	key = x509_request_asymmetric_key(trust_keyring,
 					  cert->issuer, strlen(cert->issuer),
 					  cert->authority,

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

PATCH 2/2 KEYS: validate certificate trust only with builtin keys

In reply to Dmitry Kasatkin

Instead of allowing public keys, with certificates signed by any key on the system trusted keyring, to be added to a trusted keyring, this patch further restricts the certificates to those signed only by builtin keys on the system keyring.

This patch defines a new option 'builtin' for the kernel parameter 'keys_ownerid' to allow trust validation using builtin keys.

Idea belongs to Mimi Zohar.

---
 Documentation/kernel-parameters.txt      | 2 +-
 crypto/asymmetric_keys/x509_public_key.c | 9 +++++++--
 include/linux/key.h                      | 1 +
 kernel/system_keyring.c                  | 1 +
 4 files changed, 10 insertions(+), 3 deletions(-)
Documentation/kernel-parameters.txt +1 -1
index 7a810d3..336dabe 100644
@@ -1437,7 +1437,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	keys_ownerid=[KEYS] This parameter identifies a specific key(s) on
 			the system trusted keyring to be used for certificate
 			trust validation.
-			format: id:<keyid>
+			format: { id:<keyid> | builtin }
 
 	kgdbdbgp=	[KGDB,HW] kgdb over EHCI usb debug port.
 			Format: <Controller#>[,poll interval]
crypto/asymmetric_keys/x509_public_key.c +7 -2
index d46b790..c3805a8 100644
@@ -24,6 +24,7 @@
 #include "public_key.h"
 #include "x509_parser.h"
 
+static bool builtin_keys;
 static char *owner_keyid;
 static int __init default_owner_keyid_set(char *str)
 {
@@ -32,6 +33,8 @@ static int __init default_owner_keyid_set(char *str)
 
 	if (strncmp(str, "id:", 3) == 0)
 		owner_keyid = str;	/* owner local key 'id:xxxxxx' */
+	else if (strcmp(str, "builtin") == 0)
+		builtin_keys = true;
 
 	return 1;
 }
@@ -197,8 +200,10 @@ static int x509_validate_trust(struct x509_certificate *cert,
 					  cert->authority,
 					  strlen(cert->authority));
 	if (!IS_ERR(key))  {
-		pk = key->payload.data;
-		ret = x509_check_signature(pk, cert);
+		if (!builtin_keys || test_bit(KEY_FLAG_BUILTIN, &key->flags)) {
+			pk = key->payload.data;
+			ret = x509_check_signature(pk, cert);
+		}
 		key_put(key);
 	}
 	return ret;
include/linux/key.h +1 -0
index cd0abb8..67c8e7e 100644
@@ -170,6 +170,7 @@ struct key {
 #define KEY_FLAG_INVALIDATED	7	/* set if key has been invalidated */
 #define KEY_FLAG_TRUSTED	8	/* set if key is trusted */
 #define KEY_FLAG_TRUSTED_ONLY	9	/* set if keyring only accepts links to trusted keys */
+#define KEY_FLAG_BUILTIN	10	/* set if key is builtin */
 
 	/* the key type and key description string
 	 * - the desc is used to match a key against search criteria
kernel/system_keyring.c +1 -0
index 52ebc70..875f64e 100644
@@ -89,6 +89,7 @@ static __init int load_system_certificate_list(void)
 			pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
 			       PTR_ERR(key));
 		} else {
+			set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags);
 			pr_notice("Loaded X.509 cert '%s'\n",
 				  key_ref_to_ptr(key)->description);
 			key_ref_put(key);
Signature · 1 line
1.9.1
#5 lore raw

Re: [PATCH v1a 2/2] KEYS: validate certificate trust only with builtin keys

Quoted 7 lines · Dmitry Kasatkin

Instead of allowing public keys, with certificates signed by any key on the system trusted keyring, to be added to a trusted keyring, this patch further restricts the certificates to those signed only by builtin keys on the system keyring.

This patch defines a new option 'builtin' for the kernel parameter 'keys_ownerid' to allow trust validation using builtin keys.

Thanks, this patch works without a separate 'owned' trusted keyring, but we need to wait until the UEFI key patches are upstreamed.

thanks,

Mimi

Quoted 81 lines

Idea belongs to Mimi Zohar.

---
 Documentation/kernel-parameters.txt      | 2 +-
 crypto/asymmetric_keys/x509_public_key.c | 9 +++++++--
 include/linux/key.h                      | 1 +
 kernel/system_keyring.c                  | 1 +
 4 files changed, 10 insertions(+), 3 deletions(-)
Documentation/kernel-parameters.txt +1 -1
index 7a810d3..336dabe 100644
@@ -1437,7 +1437,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	keys_ownerid=[KEYS] This parameter identifies a specific key(s) on
 			the system trusted keyring to be used for certificate
 			trust validation.
-			format: id:<keyid>
+			format: { id:<keyid> | builtin }
 
 	kgdbdbgp=	[KGDB,HW] kgdb over EHCI usb debug port.
 			Format: <Controller#>[,poll interval]
crypto/asymmetric_keys/x509_public_key.c +7 -2
index d46b790..c3805a8 100644
@@ -24,6 +24,7 @@
 #include "public_key.h"
 #include "x509_parser.h"
 
+static bool builtin_keys;
 static char *owner_keyid;
 static int __init default_owner_keyid_set(char *str)
 {
@@ -32,6 +33,8 @@ static int __init default_owner_keyid_set(char *str)
 
 	if (strncmp(str, "id:", 3) == 0)
 		owner_keyid = str;	/* owner local key 'id:xxxxxx' */
+	else if (strcmp(str, "builtin") == 0)
+		builtin_keys = true;
 
 	return 1;
 }
@@ -197,8 +200,10 @@ static int x509_validate_trust(struct x509_certificate *cert,
 					  cert->authority,
 					  strlen(cert->authority));
 	if (!IS_ERR(key))  {
-		pk = key->payload.data;
-		ret = x509_check_signature(pk, cert);
+		if (!builtin_keys || test_bit(KEY_FLAG_BUILTIN, &key->flags)) {
+			pk = key->payload.data;
+			ret = x509_check_signature(pk, cert);
+		}
 		key_put(key);
 	}
 	return ret;
include/linux/key.h +1 -0
index cd0abb8..67c8e7e 100644
@@ -170,6 +170,7 @@ struct key {
 #define KEY_FLAG_INVALIDATED	7	/* set if key has been invalidated */
 #define KEY_FLAG_TRUSTED	8	/* set if key is trusted */
 #define KEY_FLAG_TRUSTED_ONLY	9	/* set if keyring only accepts links to trusted keys */
+#define KEY_FLAG_BUILTIN	10	/* set if key is builtin */
 
 	/* the key type and key description string
 	 * - the desc is used to match a key against search criteria
kernel/system_keyring.c +1 -0
index 52ebc70..875f64e 100644
@@ -89,6 +89,7 @@ static __init int load_system_certificate_list(void)
 			pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
 			       PTR_ERR(key));
 		} else {
+			set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags);
 			pr_notice("Loaded X.509 cert '%s'\n",
 				  key_ref_to_ptr(key)->description);
 			key_ref_put(key);