diff mbox series

[RFC,1/8] key: add l_key_search

Message ID 20221118211624.19298-2-prestwoj@gmail.com (mailing list archive)
State New
Headers show
Series Crypto operations by key ID | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
prestwoj/iwd-ci-makedistcheck fail Make Distcheck Make FAIL: ../../src/crypto.c: In function ‘crypto_psk_from_passphrase’: ../../src/crypto.c:576:41: warning: passing argument 3 of ‘l_cert_pkcs5_pbkdf2’ makes integer from pointer without a cast [-Wint-conversion] 576 | ssid, ssid_len, 4096, | ^~~~ | | | const unsigned char * In file included from ./ell/ell.h:36, from ../../src/crypto.c:34: ../../ell/cert.h:78:40: note: expected ‘size_t’ {aka ‘long unsigned int’} but argument is of type ‘const unsigned char *’ 78 | size_t pass_len, | ~~~~~~~^~~~~~~~ ../../src/crypto.c:576:47: warning: passing argument 4 of ‘l_cert_pkcs5_pbkdf2’ makes pointer from integer without a cast [-Wint-conversion] 576 | ssid, ssid_len, 4096, | ^~~~~~~~ | | | size_t {aka long unsigned int} In file included from ./ell/ell.h:36, from ../../src/crypto.c:34: ../../ell/cert.h:79:48: note: expected ‘const uint8_t *’ {aka ‘const unsigned char *’} but argument is of type ‘size_t’ {aka ‘long unsigned int’} 79 | const uint8_t *salt, size_t salt_len, | ~~~~~~~~~~~~~~~^~~~ ../../src/crypto.c:577:41: warning: passing argument 6 of ‘l_cert_pkcs5_pbkdf2’ makes integer from pointer without a cast [-Wint-conversion] 577 | psk, sizeof(psk)); | ^~~ | | | unsigned char * In file included from ./ell/ell.h:36, from ../../src/crypto.c:34: ../../ell/cert.h:80:46: note: expected ‘unsigned int’ but argument is of type ‘unsigned char *’ 80 | unsigned int iter_count, | ~~~~~~~~~~~~~^~~~~~~~~~ ../../src/crypto.c:577:46: warning: passing argument 7 of ‘l_cert_pkcs5_pbkdf2’ makes pointer from integer without a cast [-Wint-conversion] 577 | psk, sizeof(psk)); | ^~~~~~~~~~~ | | | long unsigned int In file included from ./ell/ell.h:36, from ../../src/crypto.c:34: ../../ell/cert.h:81:42: note: expected ‘uint8_t *’ {aka ‘unsigned char *’} but argument is of type ‘long unsigned int’ 81 | uint8_t *out_dk, size_t dk_len); | ~~~~~~~~~^~~~~~ ../../src/crypto.c:575:18: error: too few arguments to function ‘l_cert_pkcs5_pbkdf2’ 575 | result = l_cert_pkcs5_pbkdf2(L_CHECKSUM_SHA1, passphrase, | ^~~~~~~~~~~~~~~~~~~ In file included from ./ell/ell.h:36, from ../../src/crypto.c:34: ../../ell/cert.h:77:6: note: declared here 77 | bool l_cert_pkcs5_pbkdf2(enum l_checksum_type type, const char *password, | ^~~~~~~~~~~~~~~~~~~ make[2]: *** [Makefile:2407: src/crypto.o] Error 1 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [Makefile:1586: all] Error 2 make: *** [Makefile:3184: distcheck] Error 1
prestwoj/iwd-ci-build success Build - Configure
prestwoj/iwd-ci-makecheckvalgrind fail Make FAIL: src/crypto.c: In function ‘crypto_psk_from_passphrase’: src/crypto.c:576:41: error: passing argument 3 of ‘l_cert_pkcs5_pbkdf2’ makes integer from pointer without a cast [-Werror=int-conversion] 576 | ssid, ssid_len, 4096, | ^~~~ | | | const unsigned char * In file included from ./ell/ell.h:36, from src/crypto.c:34: ./ell/cert.h:78:40: note: expected ‘size_t’ {aka ‘long unsigned int’} but argument is of type ‘const unsigned char *’ 78 | size_t pass_len, | ~~~~~~~^~~~~~~~ src/crypto.c:576:47: error: passing argument 4 of ‘l_cert_pkcs5_pbkdf2’ makes pointer from integer without a cast [-Werror=int-conversion] 576 | ssid, ssid_len, 4096, | ^~~~~~~~ | | | size_t {aka long unsigned int} In file included from ./ell/ell.h:36, from src/crypto.c:34: ./ell/cert.h:79:48: note: expected ‘const uint8_t *’ {aka ‘const unsigned char *’} but argument is of type ‘size_t’ {aka ‘long unsigned int’} 79 | const uint8_t *salt, size_t salt_len, | ~~~~~~~~~~~~~~~^~~~ src/crypto.c:577:41: error: passing argument 6 of ‘l_cert_pkcs5_pbkdf2’ makes integer from pointer without a cast [-Werror=int-conversion] 577 | psk, sizeof(psk)); | ^~~ | | | unsigned char * In file included from ./ell/ell.h:36, from src/crypto.c:34: ./ell/cert.h:80:46: note: expected ‘unsigned int’ but argument is of type ‘unsigned char *’ 80 | unsigned int iter_count, | ~~~~~~~~~~~~~^~~~~~~~~~ src/crypto.c:577:46: error: passing argument 7 of ‘l_cert_pkcs5_pbkdf2’ makes pointer from integer without a cast [-Werror=int-conversion] 577 | psk, sizeof(psk)); | ^~~~~~~~~~~ | | | long unsigned int In file included from ./ell/ell.h:36, from src/crypto.c:34: ./ell/cert.h:81:42: note: expected ‘uint8_t *’ {aka ‘unsigned char *’} but argument is of type ‘long unsigned int’ 81 | uint8_t *out_dk, size_t dk_len); | ~~~~~~~~~^~~~~~ src/crypto.c:575:18: error: too few arguments to function ‘l_cert_pkcs5_pbkdf2’ 575 | result = l_cert_pkcs5_pbkdf2(L_CHECKSUM_SHA1, passphrase, | ^~~~~~~~~~~~~~~~~~~ In file included from ./ell/ell.h:36, from src/crypto.c:34: ./ell/cert.h:77:6: note: declared here 77 | bool l_cert_pkcs5_pbkdf2(enum l_checksum_type type, const char *password, | ^~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[1]: *** [Makefile:2407: src/crypto.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:1586: all] Error 2
prestwoj/iwd-ci-makecheck pending makecheck SKIP
prestwoj/iwd-ci-testrunner pending testrunner SKIP
prestwoj/iwd-ci-clang fail Clang IWD - make FAIL: src/crypto.c:577:22: error: too few arguments to function call, expected 8, have 7 psk, sizeof(psk)); ^ ./ell/cert.h:77:6: note: 'l_cert_pkcs5_pbkdf2' declared here bool l_cert_pkcs5_pbkdf2(enum l_checksum_type type, const char *password, ^ 1 error generated. make[1]: *** [Makefile:2407: src/crypto.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:1586: all] Error 2

Commit Message

James Prestwood Nov. 18, 2022, 9:16 p.m. UTC
Search for a key by type, keyring name, and description. Returns the
key ID or an error if not found.
---
 ell/ell.sym |  1 +
 ell/key.c   | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 ell/key.h   |  3 +++
 3 files changed, 50 insertions(+)

Comments

Denis Kenzior Nov. 22, 2022, 4:43 p.m. UTC | #1
Hi James,

On 11/18/22 15:16, James Prestwood wrote:
> Search for a key by type, keyring name, and description. Returns the
> key ID or an error if not found.
> ---
>   ell/ell.sym |  1 +
>   ell/key.c   | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>   ell/key.h   |  3 +++
>   3 files changed, 50 insertions(+)
> 

<snip>

> @@ -283,6 +303,32 @@ static bool setup_internal_keyring(void)
>   	return true;
>   }
>   
> +LIB_EXPORT int32_t l_key_search(enum l_key_type type, const char *keyring,

How likely are we to search some custom keyring?  Wouldn't we generally be 
searching a user/default user session keyrings?

> +					const char *description)
> +{
> +	long keyring_id;
> +	long key_id;
> +
> +	if (unlikely((size_t)type >= L_ARRAY_SIZE(key_type_names)))
> +		return -EINVAL;
> +
> +	if (unlikely(!keyring || !description))
> +		return -EINVAL;
> +
> +	/* Find the ID of the keyring */
> +	keyring_id = kernel_key_request("keyring", keyring);
> +	if (keyring_id < 0)
> +		return -ENOENT;
> +
> +	/* Search for the key by type/description */
> +	key_id = kernel_key_search(keyring_id, key_type_names[type],
> +					description);
> +	if (key_id < 0)
> +		return -ENOENT;
> +
> +	return key_id;
> +}
> +
>   LIB_EXPORT struct l_key *l_key_new(enum l_key_type type, const void *payload,
>   					size_t payload_length)
>   {

Regards,
-Denis
Denis Kenzior Nov. 22, 2022, 5:09 p.m. UTC | #2
Hi James,

>>> +LIB_EXPORT int32_t l_key_search(enum l_key_type type, const char
>>> *keyring,
>>
>> How likely are we to search some custom keyring?  Wouldn't we
>> generally be
>> searching a user/default user session keyrings?
> 
> I was just leaning on the side of flexibility. I don't really care
> either way but figured an extra argument was fine even if we end up
> calling it with "user".

So this function would perform some sort of !strcmp conversion between "user" 
and KEY_SPEC_USER_KEYRING?  That's fine I suppose.

Alternatively you can ignore that for now and if you really need to search 
keyrings that are not "standard", then one can introduce l_keyring_search() or 
something later.

Regards,
-Denis
James Prestwood Nov. 22, 2022, 5:16 p.m. UTC | #3
On Tue, 2022-11-22 at 10:43 -0600, Denis Kenzior wrote:
> Hi James,
> 
> On 11/18/22 15:16, James Prestwood wrote:
> > Search for a key by type, keyring name, and description. Returns
> > the
> > key ID or an error if not found.
> > ---
> >   ell/ell.sym |  1 +
> >   ell/key.c   | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> >   ell/key.h   |  3 +++
> >   3 files changed, 50 insertions(+)
> > 
> 
> <snip>
> 
> > @@ -283,6 +303,32 @@ static bool setup_internal_keyring(void)
> >         return true;
> >   }
> >   
> > +LIB_EXPORT int32_t l_key_search(enum l_key_type type, const char
> > *keyring,
> 
> How likely are we to search some custom keyring?  Wouldn't we
> generally be 
> searching a user/default user session keyrings?

I was just leaning on the side of flexibility. I don't really care
either way but figured an extra argument was fine even if we end up
calling it with "user".

> 
> > +                                       const char *description)
> > +{
> > +       long keyring_id;
> > +       long key_id;
> > +
> > +       if (unlikely((size_t)type >= L_ARRAY_SIZE(key_type_names)))
> > +               return -EINVAL;
> > +
> > +       if (unlikely(!keyring || !description))
> > +               return -EINVAL;
> > +
> > +       /* Find the ID of the keyring */
> > +       keyring_id = kernel_key_request("keyring", keyring);
> > +       if (keyring_id < 0)
> > +               return -ENOENT;
> > +
> > +       /* Search for the key by type/description */
> > +       key_id = kernel_key_search(keyring_id,
> > key_type_names[type],
> > +                                       description);
> > +       if (key_id < 0)
> > +               return -ENOENT;
> > +
> > +       return key_id;
> > +}
> > +
> >   LIB_EXPORT struct l_key *l_key_new(enum l_key_type type, const
> > void *payload,
> >                                         size_t payload_length)
> >   {
> 
> Regards,
> -Denis
James Prestwood Nov. 22, 2022, 6:34 p.m. UTC | #4
On Tue, 2022-11-22 at 11:09 -0600, Denis Kenzior wrote:
> Hi James,
> 
> > > > +LIB_EXPORT int32_t l_key_search(enum l_key_type type, const
> > > > char
> > > > *keyring,
> > > 
> > > How likely are we to search some custom keyring?  Wouldn't we
> > > generally be
> > > searching a user/default user session keyrings?
> > 
> > I was just leaning on the side of flexibility. I don't really care
> > either way but figured an extra argument was fine even if we end up
> > calling it with "user".
> 
> So this function would perform some sort of !strcmp conversion
> between "user" 
> and KEY_SPEC_USER_KEYRING?  That's fine I suppose.

Ah, I kinda overlooked the fact the user keyring is actually named
something like "_uid.foo". And in theory "user" could be an actual
custom keyring... So defaulting to KEYS_SPEC_USER_KEYRING seems like
the most logical option, and if we need custom keyrings we could add
l_keyring_search().

> 
> Regards,
> -Denis
diff mbox series

Patch

diff --git a/ell/ell.sym b/ell/ell.sym
index 6df9024..414b288 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -387,6 +387,7 @@  global:
 	l_key_decrypt;
 	l_key_sign;
 	l_key_verify;
+	l_key_search;
 	l_keyring_new;
 	l_keyring_restrict;
 	l_keyring_free;
diff --git a/ell/key.c b/ell/key.c
index 24374a5..5a82531 100644
--- a/ell/key.c
+++ b/ell/key.c
@@ -270,6 +270,26 @@  static long kernel_key_verify(int32_t serial,
 	return result >= 0 ? result : -errno;
 }
 
+static long kernel_key_request(const char *type, const char *description)
+{
+	long result;
+
+	result = syscall(__NR_request_key, type, description, NULL, 0);
+
+	return result >= 0 ? result : -errno;
+}
+
+static long kernel_key_search(int32_t keyring_id, const char *type,
+				const char *description)
+{
+	long result;
+
+	result = syscall(__NR_keyctl, KEYCTL_SEARCH, keyring_id, type,
+				description, 0);
+
+	return result >= 0 ? result : -errno;
+}
+
 static bool setup_internal_keyring(void)
 {
 	internal_keyring = kernel_add_key("keyring", "ell-internal", NULL, 0,
@@ -283,6 +303,32 @@  static bool setup_internal_keyring(void)
 	return true;
 }
 
+LIB_EXPORT int32_t l_key_search(enum l_key_type type, const char *keyring,
+					const char *description)
+{
+	long keyring_id;
+	long key_id;
+
+	if (unlikely((size_t)type >= L_ARRAY_SIZE(key_type_names)))
+		return -EINVAL;
+
+	if (unlikely(!keyring || !description))
+		return -EINVAL;
+
+	/* Find the ID of the keyring */
+	keyring_id = kernel_key_request("keyring", keyring);
+	if (keyring_id < 0)
+		return -ENOENT;
+
+	/* Search for the key by type/description */
+	key_id = kernel_key_search(keyring_id, key_type_names[type],
+					description);
+	if (key_id < 0)
+		return -ENOENT;
+
+	return key_id;
+}
+
 LIB_EXPORT struct l_key *l_key_new(enum l_key_type type, const void *payload,
 					size_t payload_length)
 {
diff --git a/ell/key.h b/ell/key.h
index 6897105..5fe8e00 100644
--- a/ell/key.h
+++ b/ell/key.h
@@ -62,6 +62,9 @@  enum l_key_cipher_type {
 struct l_key *l_key_new(enum l_key_type type, const void *payload,
 			size_t payload_length);
 
+int32_t l_key_search(enum l_key_type type, const char *keyring,
+					const char *description);
+
 void l_key_free(struct l_key *key);
 void l_key_free_norevoke(struct l_key *key);