Skip to content

Commit

Permalink
certs: Make blacklist_vet_description() more strict
Browse files Browse the repository at this point in the history
Before exposing this new key type to user space, make sure that only
meaningful blacklisted hashes are accepted.  This is also checked for
builtin blacklisted hashes, but a following commit make sure that the
user will notice (at built time) and will fix the configuration if it
already included errors.

Check that a blacklist key description starts with a valid prefix and
then a valid hexadecimal string.

Cc: David Howells <[email protected]>
Cc: David Woodhouse <[email protected]>
Cc: Eric Snowberg <[email protected]>
Signed-off-by: Mickaël Salaün <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jarkko Sakkinen <[email protected]>
  • Loading branch information
l0kod authored and jarkkojs committed May 23, 2022
1 parent 141e523 commit bf21dc5
Showing 1 changed file with 36 additions and 10 deletions.
46 changes: 36 additions & 10 deletions certs/blacklist.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
#include "blacklist.h"
#include "common.h"

/*
* According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(),
* the size of the currently longest supported hash algorithm is 512 bits,
* which translates into 128 hex characters.
*/
#define MAX_HASH_LEN 128

static const char tbs_prefix[] = "tbs";
static const char bin_prefix[] = "bin";

static struct key *blacklist_keyring;

#ifdef CONFIG_SYSTEM_REVOCATION_LIST
Expand All @@ -32,24 +42,40 @@ extern __initconst const unsigned long revocation_certificate_list_size;
*/
static int blacklist_vet_description(const char *desc)
{
int n = 0;

if (*desc == ':')
return -EINVAL;
for (; *desc; desc++)
if (*desc == ':')
goto found_colon;
int i, prefix_len, tbs_step = 0, bin_step = 0;

/* The following algorithm only works if prefix lengths match. */
BUILD_BUG_ON(sizeof(tbs_prefix) != sizeof(bin_prefix));
prefix_len = sizeof(tbs_prefix) - 1;
for (i = 0; *desc; desc++, i++) {
if (*desc == ':') {
if (tbs_step == prefix_len)
goto found_colon;
if (bin_step == prefix_len)
goto found_colon;
return -EINVAL;
}
if (i >= prefix_len)
return -EINVAL;
if (*desc == tbs_prefix[i])
tbs_step++;
if (*desc == bin_prefix[i])
bin_step++;
}
return -EINVAL;

found_colon:
desc++;
for (; *desc; desc++) {
for (i = 0; *desc && i < MAX_HASH_LEN; desc++, i++) {
if (!isxdigit(*desc) || isupper(*desc))
return -EINVAL;
n++;
}
if (*desc)
/* The hash is greater than MAX_HASH_LEN. */
return -ENOPKG;

if (n == 0 || n & 1)
/* Checks for an even number of hexadecimal characters. */
if (i == 0 || i & 1)
return -EINVAL;
return 0;
}
Expand Down

0 comments on commit bf21dc5

Please sign in to comment.