diff options
-rw-r--r-- | crypto/asymmetric_keys/asymmetric_keys.h | 4 | ||||
-rw-r--r-- | crypto/asymmetric_keys/asymmetric_type.c | 89 | ||||
-rw-r--r-- | include/keys/asymmetric-type.h | 38 |
3 files changed, 131 insertions, 0 deletions
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h index a63c551c6557..917be6b985e7 100644 --- a/crypto/asymmetric_keys/asymmetric_keys.h +++ b/crypto/asymmetric_keys/asymmetric_keys.h | |||
@@ -10,6 +10,10 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | int asymmetric_keyid_match(const char *kid, const char *id); | 12 | int asymmetric_keyid_match(const char *kid, const char *id); |
13 | extern bool asymmetric_match_key_ids(const struct asymmetric_key_ids *kids, | ||
14 | const struct asymmetric_key_id *match_id); | ||
15 | |||
16 | extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id); | ||
13 | 17 | ||
14 | static inline const char *asymmetric_key_id(const struct key *key) | 18 | static inline const char *asymmetric_key_id(const struct key *key) |
15 | { | 19 | { |
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index 7755f918e8d9..92bfc438dd1d 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/ctype.h> | ||
18 | #include "asymmetric_keys.h" | 19 | #include "asymmetric_keys.h" |
19 | 20 | ||
20 | MODULE_LICENSE("GPL"); | 21 | MODULE_LICENSE("GPL"); |
@@ -22,6 +23,94 @@ MODULE_LICENSE("GPL"); | |||
22 | static LIST_HEAD(asymmetric_key_parsers); | 23 | static LIST_HEAD(asymmetric_key_parsers); |
23 | static DECLARE_RWSEM(asymmetric_key_parsers_sem); | 24 | static DECLARE_RWSEM(asymmetric_key_parsers_sem); |
24 | 25 | ||
26 | /** | ||
27 | * asymmetric_key_generate_id: Construct an asymmetric key ID | ||
28 | * @val_1: First binary blob | ||
29 | * @len_1: Length of first binary blob | ||
30 | * @val_2: Second binary blob | ||
31 | * @len_2: Length of second binary blob | ||
32 | * | ||
33 | * Construct an asymmetric key ID from a pair of binary blobs. | ||
34 | */ | ||
35 | struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, | ||
36 | size_t len_1, | ||
37 | const void *val_2, | ||
38 | size_t len_2) | ||
39 | { | ||
40 | struct asymmetric_key_id *kid; | ||
41 | |||
42 | kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, | ||
43 | GFP_KERNEL); | ||
44 | if (!kid) | ||
45 | return ERR_PTR(-ENOMEM); | ||
46 | kid->len = len_1 + len_2; | ||
47 | memcpy(kid->data, val_1, len_1); | ||
48 | memcpy(kid->data + len_1, val_2, len_2); | ||
49 | return kid; | ||
50 | } | ||
51 | EXPORT_SYMBOL_GPL(asymmetric_key_generate_id); | ||
52 | |||
53 | /** | ||
54 | * asymmetric_key_id_same - Return true if two asymmetric keys IDs are the same. | ||
55 | * @kid_1, @kid_2: The key IDs to compare | ||
56 | */ | ||
57 | bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1, | ||
58 | const struct asymmetric_key_id *kid2) | ||
59 | { | ||
60 | if (!kid1 || !kid2) | ||
61 | return false; | ||
62 | if (kid1->len != kid2->len) | ||
63 | return false; | ||
64 | return memcmp(kid1->data, kid2->data, kid1->len) == 0; | ||
65 | } | ||
66 | EXPORT_SYMBOL_GPL(asymmetric_key_id_same); | ||
67 | |||
68 | /** | ||
69 | * asymmetric_match_key_ids - Search asymmetric key IDs | ||
70 | * @kids: The list of key IDs to check | ||
71 | * @match_id: The key ID we're looking for | ||
72 | */ | ||
73 | bool asymmetric_match_key_ids(const struct asymmetric_key_ids *kids, | ||
74 | const struct asymmetric_key_id *match_id) | ||
75 | { | ||
76 | if (!kids || !match_id) | ||
77 | return false; | ||
78 | if (asymmetric_key_id_same(kids->id[0], match_id)) | ||
79 | return true; | ||
80 | if (asymmetric_key_id_same(kids->id[1], match_id)) | ||
81 | return true; | ||
82 | return false; | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(asymmetric_match_key_ids); | ||
85 | |||
86 | /** | ||
87 | * asymmetric_key_hex_to_key_id - Convert a hex string into a key ID. | ||
88 | * @id: The ID as a hex string. | ||
89 | */ | ||
90 | struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id) | ||
91 | { | ||
92 | struct asymmetric_key_id *match_id; | ||
93 | const char *p; | ||
94 | ptrdiff_t hexlen; | ||
95 | |||
96 | if (!*id) | ||
97 | return ERR_PTR(-EINVAL); | ||
98 | for (p = id; *p; p++) | ||
99 | if (!isxdigit(*p)) | ||
100 | return ERR_PTR(-EINVAL); | ||
101 | hexlen = p - id; | ||
102 | if (hexlen & 1) | ||
103 | return ERR_PTR(-EINVAL); | ||
104 | |||
105 | match_id = kmalloc(sizeof(struct asymmetric_key_id) + hexlen / 2, | ||
106 | GFP_KERNEL); | ||
107 | if (!match_id) | ||
108 | return ERR_PTR(-ENOMEM); | ||
109 | match_id->len = hexlen / 2; | ||
110 | (void)hex2bin(match_id->data, id, hexlen / 2); | ||
111 | return match_id; | ||
112 | } | ||
113 | |||
25 | /* | 114 | /* |
26 | * Match asymmetric key id with partial match | 115 | * Match asymmetric key id with partial match |
27 | * @id: key id to match in a form "id:<id>" | 116 | * @id: key id to match in a form "id:<id>" |
diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h index 7dd473496180..044ab0d3aa45 100644 --- a/include/keys/asymmetric-type.h +++ b/include/keys/asymmetric-type.h | |||
@@ -19,6 +19,44 @@ | |||
19 | extern struct key_type key_type_asymmetric; | 19 | extern struct key_type key_type_asymmetric; |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Identifiers for an asymmetric key ID. We have three ways of looking up a | ||
23 | * key derived from an X.509 certificate: | ||
24 | * | ||
25 | * (1) Serial Number & Issuer. Non-optional. This is the only valid way to | ||
26 | * map a PKCS#7 signature to an X.509 certificate. | ||
27 | * | ||
28 | * (2) Issuer & Subject Unique IDs. Optional. These were the original way to | ||
29 | * match X.509 certificates, but have fallen into disuse in favour of (3). | ||
30 | * | ||
31 | * (3) Auth & Subject Key Identifiers. Optional. SKIDs are only provided on | ||
32 | * CA keys that are intended to sign other keys, so don't appear in end | ||
33 | * user certificates unless forced. | ||
34 | * | ||
35 | * We could also support an PGP key identifier, which is just a SHA1 sum of the | ||
36 | * public key and certain parameters, but since we don't support PGP keys at | ||
37 | * the moment, we shall ignore those. | ||
38 | * | ||
39 | * What we actually do is provide a place where binary identifiers can be | ||
40 | * stashed and then compare against them when checking for an id match. | ||
41 | */ | ||
42 | struct asymmetric_key_id { | ||
43 | unsigned short len; | ||
44 | unsigned char data[]; | ||
45 | }; | ||
46 | |||
47 | struct asymmetric_key_ids { | ||
48 | void *id[2]; | ||
49 | }; | ||
50 | |||
51 | extern bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1, | ||
52 | const struct asymmetric_key_id *kid2); | ||
53 | |||
54 | extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, | ||
55 | size_t len_1, | ||
56 | const void *val_2, | ||
57 | size_t len_2); | ||
58 | |||
59 | /* | ||
22 | * The payload is at the discretion of the subtype. | 60 | * The payload is at the discretion of the subtype. |
23 | */ | 61 | */ |
24 | 62 | ||