···566566 possible to determine what the correct size should be.567567 This option provides an override for these situations.568568569569+ ca_keys= [KEYS] This parameter identifies a specific key(s) on570570+ the system trusted keyring to be used for certificate571571+ trust validation.572572+ format: { id:<keyid> | builtin }573573+569574 ccw_timeout_log [S390]570575 See Documentation/s390/CommonIO for details.571576
+2
crypto/asymmetric_keys/asymmetric_keys.h
···99 * 2 of the Licence, or (at your option) any later version.1010 */11111212+int asymmetric_keyid_match(const char *kid, const char *id);1313+1214static inline const char *asymmetric_key_id(const struct key *key)1315{1416 return key->type_data.p[1];
+32-19
crypto/asymmetric_keys/asymmetric_type.c
···2323static DECLARE_RWSEM(asymmetric_key_parsers_sem);24242525/*2626+ * Match asymmetric key id with partial match2727+ * @id: key id to match in a form "id:<id>"2828+ */2929+int asymmetric_keyid_match(const char *kid, const char *id)3030+{3131+ size_t idlen, kidlen;3232+3333+ if (!kid || !id)3434+ return 0;3535+3636+ /* make it possible to use id as in the request: "id:<id>" */3737+ if (strncmp(id, "id:", 3) == 0)3838+ id += 3;3939+4040+ /* Anything after here requires a partial match on the ID string */4141+ idlen = strlen(id);4242+ kidlen = strlen(kid);4343+ if (idlen > kidlen)4444+ return 0;4545+4646+ kid += kidlen - idlen;4747+ if (strcasecmp(id, kid) != 0)4848+ return 0;4949+5050+ return 1;5151+}5252+EXPORT_SYMBOL_GPL(asymmetric_keyid_match);5353+5454+/*2655 * Match asymmetric keys on (part of) their name2756 * We have some shorthand methods for matching keys. We allow:2857 *···6334{6435 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);6536 const char *spec = description;6666- const char *id, *kid;3737+ const char *id;6738 ptrdiff_t speclen;6868- size_t idlen, kidlen;69397040 if (!subtype || !spec || !*spec)7141 return 0;···8355 speclen = id - spec;8456 id++;85578686- /* Anything after here requires a partial match on the ID string */8787- kid = asymmetric_key_id(key);8888- if (!kid)8989- return 0;9090-9191- idlen = strlen(id);9292- kidlen = strlen(kid);9393- if (idlen > kidlen)9494- return 0;9595-9696- kid += kidlen - idlen;9797- if (strcasecmp(id, kid) != 0)9898- return 0;9999-100100- if (speclen == 2 &&101101- memcmp(spec, "id", 2) == 0)102102- return 1;5858+ if (speclen == 2 && memcmp(spec, "id", 2) == 0)5959+ return asymmetric_keyid_match(asymmetric_key_id(key), id);1036010461 if (speclen == subtype->name_len &&10562 memcmp(spec, subtype->name, speclen) == 0)
+108-1
crypto/asymmetric_keys/x509_public_key.c
···1818#include <linux/asn1_decoder.h>1919#include <keys/asymmetric-subtype.h>2020#include <keys/asymmetric-parser.h>2121+#include <keys/system_keyring.h>2122#include <crypto/hash.h>2223#include "asymmetric_keys.h"2324#include "public_key.h"2425#include "x509_parser.h"2626+2727+static bool use_builtin_keys;2828+static char *ca_keyid;2929+3030+#ifndef MODULE3131+static int __init ca_keys_setup(char *str)3232+{3333+ if (!str) /* default system keyring */3434+ return 1;3535+3636+ if (strncmp(str, "id:", 3) == 0)3737+ ca_keyid = str; /* owner key 'id:xxxxxx' */3838+ else if (strcmp(str, "builtin") == 0)3939+ use_builtin_keys = true;4040+4141+ return 1;4242+}4343+__setup("ca_keys=", ca_keys_setup);4444+#endif4545+4646+/*4747+ * Find a key in the given keyring by issuer and authority.4848+ */4949+static struct key *x509_request_asymmetric_key(struct key *keyring,5050+ const char *signer,5151+ size_t signer_len,5252+ const char *authority,5353+ size_t auth_len)5454+{5555+ key_ref_t key;5656+ char *id;5757+5858+ /* Construct an identifier. */5959+ id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL);6060+ if (!id)6161+ return ERR_PTR(-ENOMEM);6262+6363+ memcpy(id, signer, signer_len);6464+ id[signer_len + 0] = ':';6565+ id[signer_len + 1] = ' ';6666+ memcpy(id + signer_len + 2, authority, auth_len);6767+ id[signer_len + 2 + auth_len] = 0;6868+6969+ pr_debug("Look up: \"%s\"\n", id);7070+7171+ key = keyring_search(make_key_ref(keyring, 1),7272+ &key_type_asymmetric, id);7373+ if (IS_ERR(key))7474+ pr_debug("Request for module key '%s' err %ld\n",7575+ id, PTR_ERR(key));7676+ kfree(id);7777+7878+ if (IS_ERR(key)) {7979+ switch (PTR_ERR(key)) {8080+ /* Hide some search errors */8181+ case -EACCES:8282+ case -ENOTDIR:8383+ case -EAGAIN:8484+ return ERR_PTR(-ENOKEY);8585+ default:8686+ return ERR_CAST(key);8787+ }8888+ }8989+9090+ pr_devel("<==%s() = 0 [%x]\n", __func__,9191+ key_serial(key_ref_to_ptr(key)));9292+ return key_ref_to_ptr(key);9393+}25942695/*2796 * Set up the signature parameters in an X.509 certificate. This involves···172103EXPORT_SYMBOL_GPL(x509_check_signature);173104174105/*106106+ * Check the new certificate against the ones in the trust keyring. If one of107107+ * those is the signing key and validates the new certificate, then mark the108108+ * new certificate as being trusted.109109+ *110110+ * Return 0 if the new certificate was successfully validated, 1 if we couldn't111111+ * find a matching parent certificate in the trusted list and an error if there112112+ * is a matching certificate but the signature check fails.113113+ */114114+static int x509_validate_trust(struct x509_certificate *cert,115115+ struct key *trust_keyring)116116+{117117+ struct key *key;118118+ int ret = 1;119119+120120+ if (!trust_keyring)121121+ return -EOPNOTSUPP;122122+123123+ if (ca_keyid && !asymmetric_keyid_match(cert->authority, ca_keyid))124124+ return -EPERM;125125+126126+ key = x509_request_asymmetric_key(trust_keyring,127127+ cert->issuer, strlen(cert->issuer),128128+ cert->authority,129129+ strlen(cert->authority));130130+ if (!IS_ERR(key)) {131131+ if (!use_builtin_keys132132+ || test_bit(KEY_FLAG_BUILTIN, &key->flags))133133+ ret = x509_check_signature(key->payload.data, cert);134134+ key_put(key);135135+ }136136+ return ret;137137+}138138+139139+/*175140 * Attempt to parse a data blob for a key as an X509 certificate.176141 */177142static int x509_key_preparse(struct key_preparsed_payload *prep)···258155 /* Check the signature on the key if it appears to be self-signed */259156 if (!cert->authority ||260157 strcmp(cert->fingerprint, cert->authority) == 0) {261261- ret = x509_check_signature(cert->pub, cert);158158+ ret = x509_check_signature(cert->pub, cert); /* self-signed */262159 if (ret < 0)263160 goto error_free_cert;161161+ } else if (!prep->trusted) {162162+ ret = x509_validate_trust(cert, get_system_trusted_keyring());163163+ if (!ret)164164+ prep->trusted = 1;264165 }265166266167 /* Propose a description */
···170170#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */171171#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */172172#define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */173173+#define KEY_FLAG_BUILTIN 10 /* set if key is builtin */173174174175 /* the key type and key description string175176 * - the desc is used to match a key against search criteria
···123123 For more information on integrity appraisal refer to:124124 <http://linux-ima.sourceforge.net>125125 If unsure, say N.126126+127127+config IMA_TRUSTED_KEYRING128128+ bool "Require all keys on the .ima keyring be signed"129129+ depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING130130+ depends on INTEGRITY_ASYMMETRIC_KEYS131131+ select KEYS_DEBUG_PROC_KEYS132132+ default y133133+ help134134+ This option requires that all keys added to the .ima135135+ keyring be signed by a key on the system trusted keyring.
+12
security/integrity/ima/ima.h
···249249 return -EINVAL;250250}251251#endif /* CONFIG_IMA_LSM_RULES */252252+253253+#ifdef CONFIG_IMA_TRUSTED_KEYRING254254+static inline int ima_init_keyring(const unsigned int id)255255+{256256+ return integrity_init_keyring(id);257257+}258258+#else259259+static inline int ima_init_keyring(const unsigned int id)260260+{261261+ return 0;262262+}263263+#endif /* CONFIG_IMA_TRUSTED_KEYRING */252264#endif
+8-2
security/integrity/ima/ima_main.c
···325325326326 hash_setup(CONFIG_IMA_DEFAULT_HASH);327327 error = ima_init();328328- if (!error)329329- ima_initialized = 1;328328+ if (error)329329+ goto out;330330+331331+ error = ima_init_keyring(INTEGRITY_KEYRING_IMA);332332+ if (error)333333+ goto out;334334+ ima_initialized = 1;335335+out:330336 return error;331337}332338
+5
security/integrity/integrity.h
···124124int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,125125 const char *digest, int digestlen);126126127127+int integrity_init_keyring(const unsigned int id);127128#else128129129130static inline int integrity_digsig_verify(const unsigned int id,···134133 return -EOPNOTSUPP;135134}136135136136+static inline int integrity_init_keyring(const unsigned int id)137137+{138138+ return 0;139139+}137140#endif /* CONFIG_INTEGRITY_SIGNATURE */138141139142#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
+4-2
security/keys/keyctl.c
···3737 return ret;3838 if (ret == 0 || ret >= len)3939 return -EINVAL;4040- if (type[0] == '.')4141- return -EPERM;4240 type[len - 1] = '\0';4341 return 0;4442}···8486 if (!*description) {8587 kfree(description);8688 description = NULL;8989+ } else if ((description[0] == '.') &&9090+ (strncmp(type, "keyring", 7) == 0)) {9191+ ret = -EPERM;9292+ goto error2;8793 }8894 }8995