Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0 |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 2 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 3 | ============================================= |
| 4 | Asymmetric / Public-key Cryptography Key Type |
| 5 | ============================================= |
| 6 | |
| 7 | .. Contents: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 8 | |
| 9 | - Overview. |
| 10 | - Key identification. |
| 11 | - Accessing asymmetric keys. |
| 12 | - Signature verification. |
| 13 | - Asymmetric key subtypes. |
| 14 | - Instantiation data parsers. |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 15 | - Keyring link restrictions. |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 16 | |
| 17 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 18 | Overview |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 19 | ======== |
| 20 | |
| 21 | The "asymmetric" key type is designed to be a container for the keys used in |
| 22 | public-key cryptography, without imposing any particular restrictions on the |
| 23 | form or mechanism of the cryptography or form of the key. |
| 24 | |
| 25 | The asymmetric key is given a subtype that defines what sort of data is |
| 26 | associated with the key and provides operations to describe and destroy it. |
| 27 | However, no requirement is made that the key data actually be stored in the |
| 28 | key. |
| 29 | |
| 30 | A completely in-kernel key retention and operation subtype can be defined, but |
| 31 | it would also be possible to provide access to cryptographic hardware (such as |
| 32 | a TPM) that might be used to both retain the relevant key and perform |
| 33 | operations using that key. In such a case, the asymmetric key would then |
| 34 | merely be an interface to the TPM driver. |
| 35 | |
| 36 | Also provided is the concept of a data parser. Data parsers are responsible |
| 37 | for extracting information from the blobs of data passed to the instantiation |
| 38 | function. The first data parser that recognises the blob gets to set the |
| 39 | subtype of the key and define the operations that can be done on that key. |
| 40 | |
| 41 | A data parser may interpret the data blob as containing the bits representing a |
| 42 | key, or it may interpret it as a reference to a key held somewhere else in the |
| 43 | system (for example, a TPM). |
| 44 | |
| 45 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 46 | Key Identification |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 47 | ================== |
| 48 | |
| 49 | If a key is added with an empty name, the instantiation data parsers are given |
| 50 | the opportunity to pre-parse a key and to determine the description the key |
| 51 | should be given from the content of the key. |
| 52 | |
| 53 | This can then be used to refer to the key, either by complete match or by |
| 54 | partial match. The key type may also use other criteria to refer to a key. |
| 55 | |
| 56 | The asymmetric key type's match function can then perform a wider range of |
| 57 | comparisons than just the straightforward comparison of the description with |
| 58 | the criterion string: |
| 59 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 60 | 1) If the criterion string is of the form "id:<hexdigits>" then the match |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 61 | function will examine a key's fingerprint to see if the hex digits given |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 62 | after the "id:" match the tail. For instance:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 63 | |
| 64 | keyctl search @s asymmetric id:5acc2142 |
| 65 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 66 | will match a key with fingerprint:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 67 | |
| 68 | 1A00 2040 7601 7889 DE11 882C 3823 04AD 5ACC 2142 |
| 69 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 70 | 2) If the criterion string is of the form "<subtype>:<hexdigits>" then the |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 71 | match will match the ID as in (1), but with the added restriction that |
| 72 | only keys of the specified subtype (e.g. tpm) will be matched. For |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 73 | instance:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 74 | |
| 75 | keyctl search @s asymmetric tpm:5acc2142 |
| 76 | |
| 77 | Looking in /proc/keys, the last 8 hex digits of the key fingerprint are |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 78 | displayed, along with the subtype:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 79 | |
Andrea Gelmini | b142f54 | 2016-05-21 13:36:43 +0200 | [diff] [blame] | 80 | 1a39e171 I----- 1 perm 3f010000 0 0 asymmetric modsign.0: DSA 5acc2142 [] |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 81 | |
| 82 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 83 | Accessing Asymmetric Keys |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 84 | ========================= |
| 85 | |
| 86 | For general access to asymmetric keys from within the kernel, the following |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 87 | inclusion is required:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 88 | |
| 89 | #include <crypto/public_key.h> |
| 90 | |
| 91 | This gives access to functions for dealing with asymmetric / public keys. |
| 92 | Three enums are defined there for representing public-key cryptography |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 93 | algorithms:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 94 | |
| 95 | enum pkey_algo |
| 96 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 97 | digest algorithms used by those:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 98 | |
| 99 | enum pkey_hash_algo |
| 100 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 101 | and key identifier representations:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 102 | |
| 103 | enum pkey_id_type |
| 104 | |
| 105 | Note that the key type representation types are required because key |
| 106 | identifiers from different standards aren't necessarily compatible. For |
| 107 | instance, PGP generates key identifiers by hashing the key data plus some |
| 108 | PGP-specific metadata, whereas X.509 has arbitrary certificate identifiers. |
| 109 | |
| 110 | The operations defined upon a key are: |
| 111 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 112 | 1) Signature verification. |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 113 | |
| 114 | Other operations are possible (such as encryption) with the same key data |
| 115 | required for verification, but not currently supported, and others |
| 116 | (eg. decryption and signature generation) require extra key data. |
| 117 | |
| 118 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 119 | Signature Verification |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 120 | ---------------------- |
| 121 | |
| 122 | An operation is provided to perform cryptographic signature verification, using |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 123 | an asymmetric key to provide or to provide access to the public key:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 124 | |
| 125 | int verify_signature(const struct key *key, |
| 126 | const struct public_key_signature *sig); |
| 127 | |
| 128 | The caller must have already obtained the key from some source and can then use |
| 129 | it to check the signature. The caller must have parsed the signature and |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 130 | transferred the relevant bits to the structure pointed to by sig:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 131 | |
| 132 | struct public_key_signature { |
| 133 | u8 *digest; |
| 134 | u8 digest_size; |
| 135 | enum pkey_hash_algo pkey_hash_algo : 8; |
| 136 | u8 nr_mpi; |
| 137 | union { |
| 138 | MPI mpi[2]; |
| 139 | ... |
| 140 | }; |
| 141 | }; |
| 142 | |
| 143 | The algorithm used must be noted in sig->pkey_hash_algo, and all the MPIs that |
| 144 | make up the actual signature must be stored in sig->mpi[] and the count of MPIs |
| 145 | placed in sig->nr_mpi. |
| 146 | |
| 147 | In addition, the data must have been digested by the caller and the resulting |
| 148 | hash must be pointed to by sig->digest and the size of the hash be placed in |
| 149 | sig->digest_size. |
| 150 | |
| 151 | The function will return 0 upon success or -EKEYREJECTED if the signature |
| 152 | doesn't match. |
| 153 | |
| 154 | The function may also return -ENOTSUPP if an unsupported public-key algorithm |
| 155 | or public-key/hash algorithm combination is specified or the key doesn't |
| 156 | support the operation; -EBADMSG or -ERANGE if some of the parameters have weird |
| 157 | data; or -ENOMEM if an allocation can't be performed. -EINVAL can be returned |
| 158 | if the key argument is the wrong type or is incompletely set up. |
| 159 | |
| 160 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 161 | Asymmetric Key Subtypes |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 162 | ======================= |
| 163 | |
| 164 | Asymmetric keys have a subtype that defines the set of operations that can be |
| 165 | performed on that key and that determines what data is attached as the key |
| 166 | payload. The payload format is entirely at the whim of the subtype. |
| 167 | |
| 168 | The subtype is selected by the key data parser and the parser must initialise |
| 169 | the data required for it. The asymmetric key retains a reference on the |
| 170 | subtype module. |
| 171 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 172 | The subtype definition structure can be found in:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 173 | |
| 174 | #include <keys/asymmetric-subtype.h> |
| 175 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 176 | and looks like the following:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 177 | |
| 178 | struct asymmetric_key_subtype { |
| 179 | struct module *owner; |
| 180 | const char *name; |
| 181 | |
| 182 | void (*describe)(const struct key *key, struct seq_file *m); |
| 183 | void (*destroy)(void *payload); |
David Howells | 5a30771 | 2018-10-09 17:47:07 +0100 | [diff] [blame] | 184 | int (*query)(const struct kernel_pkey_params *params, |
| 185 | struct kernel_pkey_query *info); |
| 186 | int (*eds_op)(struct kernel_pkey_params *params, |
| 187 | const void *in, void *out); |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 188 | int (*verify_signature)(const struct key *key, |
| 189 | const struct public_key_signature *sig); |
| 190 | }; |
| 191 | |
David Howells | 146aa8b | 2015-10-21 14:04:48 +0100 | [diff] [blame] | 192 | Asymmetric keys point to this with their payload[asym_subtype] member. |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 193 | |
| 194 | The owner and name fields should be set to the owning module and the name of |
| 195 | the subtype. Currently, the name is only used for print statements. |
| 196 | |
| 197 | There are a number of operations defined by the subtype: |
| 198 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 199 | 1) describe(). |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 200 | |
| 201 | Mandatory. This allows the subtype to display something in /proc/keys |
| 202 | against the key. For instance the name of the public key algorithm type |
| 203 | could be displayed. The key type will display the tail of the key |
| 204 | identity string after this. |
| 205 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 206 | 2) destroy(). |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 207 | |
| 208 | Mandatory. This should free the memory associated with the key. The |
| 209 | asymmetric key will look after freeing the fingerprint and releasing the |
| 210 | reference on the subtype module. |
| 211 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 212 | 3) query(). |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 213 | |
David Howells | 5a30771 | 2018-10-09 17:47:07 +0100 | [diff] [blame] | 214 | Mandatory. This is a function for querying the capabilities of a key. |
| 215 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 216 | 4) eds_op(). |
David Howells | 5a30771 | 2018-10-09 17:47:07 +0100 | [diff] [blame] | 217 | |
| 218 | Optional. This is the entry point for the encryption, decryption and |
| 219 | signature creation operations (which are distinguished by the operation ID |
| 220 | in the parameter struct). The subtype may do anything it likes to |
| 221 | implement an operation, including offloading to hardware. |
| 222 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 223 | 5) verify_signature(). |
David Howells | 5a30771 | 2018-10-09 17:47:07 +0100 | [diff] [blame] | 224 | |
| 225 | Optional. This is the entry point for signature verification. The |
| 226 | subtype may do anything it likes to implement an operation, including |
| 227 | offloading to hardware. |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 228 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 229 | Instantiation Data Parsers |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 230 | ========================== |
| 231 | |
| 232 | The asymmetric key type doesn't generally want to store or to deal with a raw |
| 233 | blob of data that holds the key data. It would have to parse it and error |
| 234 | check it each time it wanted to use it. Further, the contents of the blob may |
| 235 | have various checks that can be performed on it (eg. self-signatures, validity |
| 236 | dates) and may contain useful data about the key (identifiers, capabilities). |
| 237 | |
| 238 | Also, the blob may represent a pointer to some hardware containing the key |
| 239 | rather than the key itself. |
| 240 | |
| 241 | Examples of blob formats for which parsers could be implemented include: |
| 242 | |
| 243 | - OpenPGP packet stream [RFC 4880]. |
| 244 | - X.509 ASN.1 stream. |
| 245 | - Pointer to TPM key. |
| 246 | - Pointer to UEFI key. |
David Howells | 3c58b23 | 2018-10-09 17:47:46 +0100 | [diff] [blame] | 247 | - PKCS#8 private key [RFC 5208]. |
| 248 | - PKCS#5 encrypted private key [RFC 2898]. |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 249 | |
| 250 | During key instantiation each parser in the list is tried until one doesn't |
| 251 | return -EBADMSG. |
| 252 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 253 | The parser definition structure can be found in:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 254 | |
| 255 | #include <keys/asymmetric-parser.h> |
| 256 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 257 | and looks like the following:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 258 | |
| 259 | struct asymmetric_key_parser { |
| 260 | struct module *owner; |
| 261 | const char *name; |
| 262 | |
| 263 | int (*parse)(struct key_preparsed_payload *prep); |
| 264 | }; |
| 265 | |
| 266 | The owner and name fields should be set to the owning module and the name of |
| 267 | the parser. |
| 268 | |
| 269 | There is currently only a single operation defined by the parser, and it is |
| 270 | mandatory: |
| 271 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 272 | 1) parse(). |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 273 | |
| 274 | This is called to preparse the key from the key creation and update paths. |
| 275 | In particular, it is called during the key creation _before_ a key is |
| 276 | allocated, and as such, is permitted to provide the key's description in |
| 277 | the case that the caller declines to do so. |
| 278 | |
| 279 | The caller passes a pointer to the following struct with all of the fields |
| 280 | cleared, except for data, datalen and quotalen [see |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 281 | Documentation/security/keys/core.rst]:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 282 | |
| 283 | struct key_preparsed_payload { |
| 284 | char *description; |
David Howells | 146aa8b | 2015-10-21 14:04:48 +0100 | [diff] [blame] | 285 | void *payload[4]; |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 286 | const void *data; |
| 287 | size_t datalen; |
| 288 | size_t quotalen; |
| 289 | }; |
| 290 | |
| 291 | The instantiation data is in a blob pointed to by data and is datalen in |
| 292 | size. The parse() function is not permitted to change these two values at |
| 293 | all, and shouldn't change any of the other values _unless_ they are |
| 294 | recognise the blob format and will not return -EBADMSG to indicate it is |
| 295 | not theirs. |
| 296 | |
| 297 | If the parser is happy with the blob, it should propose a description for |
David Howells | 146aa8b | 2015-10-21 14:04:48 +0100 | [diff] [blame] | 298 | the key and attach it to ->description, ->payload[asym_subtype] should be |
| 299 | set to point to the subtype to be used, ->payload[asym_crypto] should be |
| 300 | set to point to the initialised data for that subtype, |
| 301 | ->payload[asym_key_ids] should point to one or more hex fingerprints and |
| 302 | quotalen should be updated to indicate how much quota this key should |
| 303 | account for. |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 304 | |
David Howells | 146aa8b | 2015-10-21 14:04:48 +0100 | [diff] [blame] | 305 | When clearing up, the data attached to ->payload[asym_key_ids] and |
| 306 | ->description will be kfree()'d and the data attached to |
| 307 | ->payload[asm_crypto] will be passed to the subtype's ->destroy() method |
| 308 | to be disposed of. A module reference for the subtype pointed to by |
| 309 | ->payload[asym_subtype] will be put. |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 310 | |
| 311 | |
| 312 | If the data format is not recognised, -EBADMSG should be returned. If it |
| 313 | is recognised, but the key cannot for some reason be set up, some other |
| 314 | negative error code should be returned. On success, 0 should be returned. |
| 315 | |
| 316 | The key's fingerprint string may be partially matched upon. For a |
| 317 | public-key algorithm such as RSA and DSA this will likely be a printable |
| 318 | hex version of the key's fingerprint. |
| 319 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 320 | Functions are provided to register and unregister parsers:: |
David Howells | 9a83b46 | 2012-09-13 15:17:21 +0100 | [diff] [blame] | 321 | |
| 322 | int register_asymmetric_key_parser(struct asymmetric_key_parser *parser); |
| 323 | void unregister_asymmetric_key_parser(struct asymmetric_key_parser *subtype); |
| 324 | |
| 325 | Parsers may not have the same name. The names are otherwise only used for |
| 326 | displaying in debugging messages. |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 327 | |
| 328 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 329 | Keyring Link Restrictions |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 330 | ========================= |
| 331 | |
| 332 | Keyrings created from userspace using add_key can be configured to check the |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 333 | signature of the key being linked. Keys without a valid signature are not |
| 334 | allowed to link. |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 335 | |
| 336 | Several restriction methods are available: |
| 337 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 338 | 1) Restrict using the kernel builtin trusted keyring |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 339 | |
| 340 | - Option string used with KEYCTL_RESTRICT_KEYRING: |
| 341 | - "builtin_trusted" |
| 342 | |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 343 | The kernel builtin trusted keyring will be searched for the signing key. |
| 344 | If the builtin trusted keyring is not configured, all links will be |
| 345 | rejected. The ca_keys kernel parameter also affects which keys are used |
| 346 | for signature verification. |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 347 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 348 | 2) Restrict using the kernel builtin and secondary trusted keyrings |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 349 | |
| 350 | - Option string used with KEYCTL_RESTRICT_KEYRING: |
| 351 | - "builtin_and_secondary_trusted" |
| 352 | |
| 353 | The kernel builtin and secondary trusted keyrings will be searched for the |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 354 | signing key. If the secondary trusted keyring is not configured, this |
| 355 | restriction will behave like the "builtin_trusted" option. The ca_keys |
| 356 | kernel parameter also affects which keys are used for signature |
| 357 | verification. |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 358 | |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 359 | 3) Restrict using a separate key or keyring |
Mat Martineau | 7e3c4d2 | 2016-06-27 16:45:16 -0700 | [diff] [blame] | 360 | |
| 361 | - Option string used with KEYCTL_RESTRICT_KEYRING: |
Mat Martineau | 8e323a0 | 2016-10-04 16:42:45 -0700 | [diff] [blame] | 362 | - "key_or_keyring:<key or keyring serial number>[:chain]" |
Mat Martineau | 7e3c4d2 | 2016-06-27 16:45:16 -0700 | [diff] [blame] | 363 | |
| 364 | Whenever a key link is requested, the link will only succeed if the key |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 365 | being linked is signed by one of the designated keys. This key may be |
Mat Martineau | 7e3c4d2 | 2016-06-27 16:45:16 -0700 | [diff] [blame] | 366 | specified directly by providing a serial number for one asymmetric key, or |
| 367 | a group of keys may be searched for the signing key by providing the |
| 368 | serial number for a keyring. |
| 369 | |
Mat Martineau | 8e323a0 | 2016-10-04 16:42:45 -0700 | [diff] [blame] | 370 | When the "chain" option is provided at the end of the string, the keys |
| 371 | within the destination keyring will also be searched for signing keys. |
| 372 | This allows for verification of certificate chains by adding each |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 373 | certificate in order (starting closest to the root) to a keyring. For |
| 374 | instance, one keyring can be populated with links to a set of root |
| 375 | certificates, with a separate, restricted keyring set up for each |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 376 | certificate chain to be validated:: |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 377 | |
| 378 | # Create and populate a keyring for root certificates |
| 379 | root_id=`keyctl add keyring root-certs "" @s` |
| 380 | keyctl padd asymmetric "" $root_id < root1.cert |
| 381 | keyctl padd asymmetric "" $root_id < root2.cert |
| 382 | |
| 383 | # Create and restrict a keyring for the certificate chain |
| 384 | chain_id=`keyctl add keyring chain "" @s` |
| 385 | keyctl restrict_keyring $chain_id asymmetric key_or_keyring:$root_id:chain |
| 386 | |
| 387 | # Attempt to add each certificate in the chain, starting with the |
| 388 | # certificate closest to the root. |
| 389 | keyctl padd asymmetric "" $chain_id < intermediateA.cert |
| 390 | keyctl padd asymmetric "" $chain_id < intermediateB.cert |
| 391 | keyctl padd asymmetric "" $chain_id < end-entity.cert |
| 392 | |
| 393 | If the final end-entity certificate is successfully added to the "chain" |
| 394 | keyring, we can be certain that it has a valid signing chain going back to |
| 395 | one of the root certificates. |
| 396 | |
| 397 | A single keyring can be used to verify a chain of signatures by |
Mauro Carvalho Chehab | 0efaaa8 | 2020-06-15 08:50:08 +0200 | [diff] [blame] | 398 | restricting the keyring after linking the root certificate:: |
Mat Martineau | 7228b66 | 2017-07-13 13:17:03 +0100 | [diff] [blame] | 399 | |
| 400 | # Create a keyring for the certificate chain and add the root |
| 401 | chain2_id=`keyctl add keyring chain2 "" @s` |
| 402 | keyctl padd asymmetric "" $chain2_id < root1.cert |
| 403 | |
| 404 | # Restrict the keyring that already has root1.cert linked. The cert |
| 405 | # will remain linked by the keyring. |
| 406 | keyctl restrict_keyring $chain2_id asymmetric key_or_keyring:0:chain |
| 407 | |
| 408 | # Attempt to add each certificate in the chain, starting with the |
| 409 | # certificate closest to the root. |
| 410 | keyctl padd asymmetric "" $chain2_id < intermediateA.cert |
| 411 | keyctl padd asymmetric "" $chain2_id < intermediateB.cert |
| 412 | keyctl padd asymmetric "" $chain2_id < end-entity.cert |
| 413 | |
| 414 | If the final end-entity certificate is successfully added to the "chain2" |
| 415 | keyring, we can be certain that there is a valid signing chain going back |
| 416 | to the root certificate that was added before the keyring was restricted. |
| 417 | |
Mat Martineau | 8e323a0 | 2016-10-04 16:42:45 -0700 | [diff] [blame] | 418 | |
Mat Martineau | 97d3aa0f | 2016-05-06 14:25:39 -0700 | [diff] [blame] | 419 | In all of these cases, if the signing key is found the signature of the key to |
| 420 | be linked will be verified using the signing key. The requested key is added |
| 421 | to the keyring only if the signature is successfully verified. -ENOKEY is |
| 422 | returned if the parent certificate could not be found, or -EKEYREJECTED is |
| 423 | returned if the signature check fails or the key is blacklisted. Other errors |
| 424 | may be returned if the signature check could not be performed. |