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