[v4,3/6] KEYS: Restrict key linkage using a specific keychain
diff mbox

Message ID 20160707205337.2061-4-mathew.j.martineau@linux.intel.com
State New
Headers show

Commit Message

Mat Martineau July 7, 2016, 8:53 p.m. UTC
Adds restrict_link_by_signature_keyring(), which uses the restrict_key
member of the provided destination_keyring data structure as the
keyring to search for signing keys.

Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
---
 crypto/asymmetric_keys/restrict.c | 55 +++++++++++++++++++++++++++++++++++++++
 include/crypto/public_key.h       |  4 +++
 2 files changed, 59 insertions(+)

Comments

Petko Manolov July 9, 2016, 2:45 p.m. UTC | #1
On 16-07-07 13:53:34, Mat Martineau wrote:
> Adds restrict_link_by_signature_keyring(), which uses the restrict_key
> member of the provided destination_keyring data structure as the
> keyring to search for signing keys.
> 
> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
> ---
>  crypto/asymmetric_keys/restrict.c | 55 +++++++++++++++++++++++++++++++++++++++
>  include/crypto/public_key.h       |  4 +++
>  2 files changed, 59 insertions(+)
> 
> diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
> index ac4bddf..ba4f33f 100644
> --- a/crypto/asymmetric_keys/restrict.c
> +++ b/crypto/asymmetric_keys/restrict.c
> @@ -106,3 +106,58 @@ int restrict_link_by_signature(struct key *trust_keyring,
>  	key_put(key);
>  	return ret;
>  }
> +
> +/**
> + * restrict_link_by_keyring - Restrict additions to a ring of public
> + * keys using the restrict_key information stored in the ring.
> + * @destination_keyring: Keyring being linked to.
> + * @type: The type of key being added.
> + * @payload: The payload of the new key.
> + *
> + * Check the new certificate only against the keys in the
> + * destination_keyring->restrict_key ring. If one of those is the
> + * signing key and validates the new certificate, then mark the new
> + * certificate as being ok to link.
> + *
> + * Returns 0 if the new certificate was accepted, -ENOKEY if we
> + * couldn't find a matching parent certificate in the trusted list,
> + * -EKEYREJECTED if the signature check fails, and some other error if
> + * there is a matching certificate but the signature check cannot be
> + * performed.
> + */
> +int restrict_link_by_keyring(struct key *destination_keyring,
> +			     const struct key_type *type,
> +			     const union key_payload *payload)
> +{
> +	const struct public_key_signature *sig;
> +	struct key *key;
> +	int ret;
> +
> +	pr_devel("==>%s()\n", __func__);
> +
> +	if (!destination_keyring)
> +		return -ENOKEY;
> +	else if (destination_keyring->type != &key_type_keyring)
> +		return -EOPNOTSUPP;
> +
> +	if (!destination_keyring->restrict_key)
> +		return -ENOKEY;
> +
> +	if (type != &key_type_asymmetric)
> +		return -EOPNOTSUPP;
> +
> +	sig = payload->data[asym_auth];
> +	if (!sig->auth_ids[0] && !sig->auth_ids[1])
> +		return 0;

Are you certain you should return 'success' here?


		Petko


> +	/* See if we have a key that signed this one. */
> +	key = find_asymmetric_key(destination_keyring->restrict_key,
> +				  sig->auth_ids[0], sig->auth_ids[1],
> +				  false);
> +	if (IS_ERR(key))
> +		return -ENOKEY;
> +
> +	ret = verify_signature(key, sig);
> +	key_put(key);
> +	return ret;
> +}
> diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
> index c5e569b..53e8928 100644
> --- a/include/crypto/public_key.h
> +++ b/include/crypto/public_key.h
> @@ -58,6 +58,10 @@ extern int restrict_link_by_signature(struct key *trust_keyring,
>  				      const struct key_type *type,
>  				      const union key_payload *payload);
>  
> +extern int restrict_link_by_keyring(struct key *trust_keyring,
> +				    const struct key_type *type,
> +				    const union key_payload *payload);
> +
>  extern int query_asymmetric_key(const struct kernel_pkey_params *,
>  				struct kernel_pkey_query *);
>  
> -- 
> 2.9.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mat Martineau July 11, 2016, 9:57 p.m. UTC | #2
Petko,

On Sat, 9 Jul 2016, Petko Manolov wrote:

> On 16-07-07 13:53:34, Mat Martineau wrote:
>> Adds restrict_link_by_signature_keyring(), which uses the restrict_key
>> member of the provided destination_keyring data structure as the
>> keyring to search for signing keys.
>>
>> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
>> ---
>>  crypto/asymmetric_keys/restrict.c | 55 +++++++++++++++++++++++++++++++++++++++
>>  include/crypto/public_key.h       |  4 +++
>>  2 files changed, 59 insertions(+)
>>
>> diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
>> index ac4bddf..ba4f33f 100644
>> --- a/crypto/asymmetric_keys/restrict.c
>> +++ b/crypto/asymmetric_keys/restrict.c
>> @@ -106,3 +106,58 @@ int restrict_link_by_signature(struct key *trust_keyring,
>>  	key_put(key);
>>  	return ret;
>>  }
>> +
>> +/**
>> + * restrict_link_by_keyring - Restrict additions to a ring of public
>> + * keys using the restrict_key information stored in the ring.
>> + * @destination_keyring: Keyring being linked to.
>> + * @type: The type of key being added.
>> + * @payload: The payload of the new key.
>> + *
>> + * Check the new certificate only against the keys in the
>> + * destination_keyring->restrict_key ring. If one of those is the
>> + * signing key and validates the new certificate, then mark the new
>> + * certificate as being ok to link.
>> + *
>> + * Returns 0 if the new certificate was accepted, -ENOKEY if we
>> + * couldn't find a matching parent certificate in the trusted list,
>> + * -EKEYREJECTED if the signature check fails, and some other error if
>> + * there is a matching certificate but the signature check cannot be
>> + * performed.
>> + */
>> +int restrict_link_by_keyring(struct key *destination_keyring,
>> +			     const struct key_type *type,
>> +			     const union key_payload *payload)
>> +{
>> +	const struct public_key_signature *sig;
>> +	struct key *key;
>> +	int ret;
>> +
>> +	pr_devel("==>%s()\n", __func__);
>> +
>> +	if (!destination_keyring)
>> +		return -ENOKEY;
>> +	else if (destination_keyring->type != &key_type_keyring)
>> +		return -EOPNOTSUPP;
>> +
>> +	if (!destination_keyring->restrict_key)
>> +		return -ENOKEY;
>> +
>> +	if (type != &key_type_asymmetric)
>> +		return -EOPNOTSUPP;
>> +
>> +	sig = payload->data[asym_auth];
>> +	if (!sig->auth_ids[0] && !sig->auth_ids[1])
>> +		return 0;
>
> Are you certain you should return 'success' here?

No, that does not seem right here or in the restrict_link_by_signature 
function that it came from. I will change it here and send a patch for 
restrict_link_by_signature.


Mat

>> +	/* See if we have a key that signed this one. */
>> +	key = find_asymmetric_key(destination_keyring->restrict_key,
>> +				  sig->auth_ids[0], sig->auth_ids[1],
>> +				  false);
>> +	if (IS_ERR(key))
>> +		return -ENOKEY;
>> +
>> +	ret = verify_signature(key, sig);
>> +	key_put(key);
>> +	return ret;
>> +}
>> diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
>> index c5e569b..53e8928 100644
>> --- a/include/crypto/public_key.h
>> +++ b/include/crypto/public_key.h
>> @@ -58,6 +58,10 @@ extern int restrict_link_by_signature(struct key *trust_keyring,
>>  				      const struct key_type *type,
>>  				      const union key_payload *payload);
>>
>> +extern int restrict_link_by_keyring(struct key *trust_keyring,
>> +				    const struct key_type *type,
>> +				    const union key_payload *payload);
>> +
>>  extern int query_asymmetric_key(const struct kernel_pkey_params *,
>>  				struct kernel_pkey_query *);
>>
>> --

--
Mat Martineau
Intel OTC
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
index ac4bddf..ba4f33f 100644
--- a/crypto/asymmetric_keys/restrict.c
+++ b/crypto/asymmetric_keys/restrict.c
@@ -106,3 +106,58 @@  int restrict_link_by_signature(struct key *trust_keyring,
 	key_put(key);
 	return ret;
 }
+
+/**
+ * restrict_link_by_keyring - Restrict additions to a ring of public
+ * keys using the restrict_key information stored in the ring.
+ * @destination_keyring: Keyring being linked to.
+ * @type: The type of key being added.
+ * @payload: The payload of the new key.
+ *
+ * Check the new certificate only against the keys in the
+ * destination_keyring->restrict_key ring. If one of those is the
+ * signing key and validates the new certificate, then mark the new
+ * certificate as being ok to link.
+ *
+ * Returns 0 if the new certificate was accepted, -ENOKEY if we
+ * couldn't find a matching parent certificate in the trusted list,
+ * -EKEYREJECTED if the signature check fails, and some other error if
+ * there is a matching certificate but the signature check cannot be
+ * performed.
+ */
+int restrict_link_by_keyring(struct key *destination_keyring,
+			     const struct key_type *type,
+			     const union key_payload *payload)
+{
+	const struct public_key_signature *sig;
+	struct key *key;
+	int ret;
+
+	pr_devel("==>%s()\n", __func__);
+
+	if (!destination_keyring)
+		return -ENOKEY;
+	else if (destination_keyring->type != &key_type_keyring)
+		return -EOPNOTSUPP;
+
+	if (!destination_keyring->restrict_key)
+		return -ENOKEY;
+
+	if (type != &key_type_asymmetric)
+		return -EOPNOTSUPP;
+
+	sig = payload->data[asym_auth];
+	if (!sig->auth_ids[0] && !sig->auth_ids[1])
+		return 0;
+
+	/* See if we have a key that signed this one. */
+	key = find_asymmetric_key(destination_keyring->restrict_key,
+				  sig->auth_ids[0], sig->auth_ids[1],
+				  false);
+	if (IS_ERR(key))
+		return -ENOKEY;
+
+	ret = verify_signature(key, sig);
+	key_put(key);
+	return ret;
+}
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index c5e569b..53e8928 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -58,6 +58,10 @@  extern int restrict_link_by_signature(struct key *trust_keyring,
 				      const struct key_type *type,
 				      const union key_payload *payload);
 
+extern int restrict_link_by_keyring(struct key *trust_keyring,
+				    const struct key_type *type,
+				    const union key_payload *payload);
+
 extern int query_asymmetric_key(const struct kernel_pkey_params *,
 				struct kernel_pkey_query *);