struct key *key_generate_new(void) { struct key *k; int s; k = key_alloc(); s = EC_KEY_generate_key(k->key); if (s == 0) { Log(LGPFX " EC_KEY_generate_key failed.\n"); goto exit; } s = EC_KEY_check_key(k->key); if (s == 0) { Log(LGPFX " EC_KEY_check_key failed.\n"); goto exit; } EC_KEY_set_conv_form(k->key, POINT_CONVERSION_COMPRESSED); ASSERT(k->pub_key == NULL); ASSERT(k->pub_len == 0); key_get_pubkey_int(k, &k->pub_key, &k->pub_len); return k; exit: key_free(k); return NULL; }
/* * allocate a new key in under-construction state and attempt to link it in to * the requested place * - may return a key that's already under construction instead */ static int construct_alloc_key(struct key_type *type, const char *description, struct key *dest_keyring, unsigned long flags, struct key_user *user, struct key **_key) { const struct cred *cred = current_cred(); struct key *key; key_ref_t key_ref; kenter("%s,%s,,,", type->name, description); mutex_lock(&user->cons_lock); key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred, KEY_POS_ALL, flags); if (IS_ERR(key)) goto alloc_failed; set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); down_write(&dest_keyring->sem); /* attach the key to the destination keyring under lock, but we do need * to do another check just in case someone beat us to it whilst we * waited for locks */ mutex_lock(&key_construction_mutex); key_ref = search_process_keyrings(type, description, type->match, cred); if (!IS_ERR(key_ref)) goto key_already_present; __key_link(dest_keyring, key); mutex_unlock(&key_construction_mutex); up_write(&dest_keyring->sem); mutex_unlock(&user->cons_lock); *_key = key; kleave(" = 0 [%d]", key_serial(key)); return 0; key_already_present: mutex_unlock(&key_construction_mutex); if (dest_keyring) up_write(&dest_keyring->sem); mutex_unlock(&user->cons_lock); key_put(key); *_key = key = key_ref_to_ptr(key_ref); kleave(" = -EINPROGRESS [%d]", key_serial(key)); return -EINPROGRESS; alloc_failed: mutex_unlock(&user->cons_lock); *_key = NULL; kleave(" = %ld", PTR_ERR(key)); return PTR_ERR(key); }
int init_cifs_idmap(void) { struct cred *cred; struct key *keyring; int ret; cFYI(1, "Registering the %s key type\n", cifs_idmap_key_type.name); cred = prepare_kernel_cred(NULL); if (!cred) return -ENOMEM; keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred, (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); goto failed_put_cred; } ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); if (ret < 0) goto failed_put_key; ret = register_key_type(&cifs_idmap_key_type); if (ret < 0) goto failed_put_key; set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); cred->thread_keyring = keyring; cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; root_cred = cred; spin_lock_init(&siduidlock); uidtree = RB_ROOT; spin_lock_init(&sidgidlock); gidtree = RB_ROOT; spin_lock_init(&uidsidlock); siduidtree = RB_ROOT; spin_lock_init(&gidsidlock); sidgidtree = RB_ROOT; register_shrinker(&cifs_shrinker); cFYI(1, "cifs idmap keyring: %d\n", key_serial(keyring)); return 0; failed_put_key: key_put(keyring); failed_put_cred: put_cred(cred); return ret; }
static void register_map(void) { if (im_map) return; im_map = key_alloc(); key_add(im_map, "Keystroke", &keystroke); key_add(im_map, "Mouse-event", &mouse_event); key_add(im_map, "Mode:set-mode", &set_mode); key_add(im_map, "Mode:set-numeric", &set_numeric); key_add(im_map, "Mode:set-extra", &set_extra); key_add_range(im_map, "Request:Notify:", "Request:Notify;", &request_notify); }
static void render_format_register_map(void) { rf_map = key_alloc(); key_add(rf_map, "render-line", &render_line); key_add(rf_map, "render-line-prev", &render_line_prev); key_add(rf_map, "Close", &format_close); key_add(rf_map, "Clone", &format_clone); key_add(rf_map, "Move-EOL", &format_move_line); key_add(rf_map, "Move-Char", &format_move_horiz); key_add(rf_map, "Move-Word", &format_move_horiz); key_add(rf_map, "Move-WORD", &format_move_horiz); }
int __init cifs_init_dns_resolver(void) { struct cred *cred; struct key *keyring; int ret; printk(KERN_NOTICE "Registering the %s key type\n", key_type_dns_resolver.name); /* create an override credential set with a special thread keyring in * which DNS requests are cached * * this is used to prevent malicious redirections from being installed * with add_key(). */ cred = prepare_kernel_cred(NULL); if (!cred) return -ENOMEM; keyring = key_alloc(&key_type_keyring, ".dns_resolver", 0, 0, cred, (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); goto failed_put_cred; } ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); if (ret < 0) goto failed_put_key; ret = register_key_type(&key_type_dns_resolver); if (ret < 0) goto failed_put_key; /* instruct request_key() to use this special keyring as a cache for * the results it looks up */ cred->thread_keyring = keyring; cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; dns_resolver_cache = cred; return 0; failed_put_key: key_put(keyring); failed_put_cred: put_cred(cred); return ret; }
/* * Load the compiled-in keys */ static __init int module_verify_init(void) { pr_notice("Initialise module verification\n"); modsign_keyring = key_alloc(&key_type_keyring, ".module_sign", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(modsign_keyring)) panic("Can't allocate module signing keyring\n"); if (key_instantiate_and_link(modsign_keyring, NULL, 0, NULL, NULL) < 0) panic("Can't instantiate module signing keyring\n"); return 0; }
/* * create a session keyring to be for the invokation of /sbin/request-key and * stick an authorisation token in it */ struct key *request_key_auth_new(struct key *target, struct key **_rkakey) { struct key *keyring, *rkakey = NULL; char desc[20]; int ret; kenter("%d,", target->serial); /* allocate a new session keyring */ sprintf(desc, "_req.%u", target->serial); keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); if (IS_ERR(keyring)) { kleave("= %ld", PTR_ERR(keyring)); return keyring; } /* allocate the auth key */ sprintf(desc, "%x", target->serial); rkakey = key_alloc(&key_type_request_key_auth, desc, current->fsuid, current->fsgid, KEY_USR_VIEW, 1); if (IS_ERR(rkakey)) { key_put(keyring); kleave("= %ld", PTR_ERR(rkakey)); return rkakey; } /* construct and attach to the keyring */ ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL); if (ret < 0) { key_revoke(rkakey); key_put(rkakey); key_put(keyring); kleave("= %d", ret); return ERR_PTR(ret); } *_rkakey = rkakey; kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial); return keyring; } /* end request_key_auth_new() */
static int nfs_idmap_init_keyring(void) { struct cred *cred; struct key *keyring; int ret = 0; printk(KERN_NOTICE "NFS: Registering the %s key type\n", key_type_id_resolver.name); cred = prepare_kernel_cred(NULL); if (!cred) return -ENOMEM; keyring = key_alloc(&key_type_keyring, ".id_resolver", 0, 0, cred, (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); goto failed_put_cred; } ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); if (ret < 0) goto failed_put_key; ret = register_key_type(&key_type_id_resolver); if (ret < 0) goto failed_put_key; set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); cred->thread_keyring = keyring; cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; id_resolver_cache = cred; return 0; failed_put_key: key_put(keyring); failed_put_cred: put_cred(cred); return ret; }
int nfs_idmap_init(void) { struct cred *cred; struct key *keyring; int ret = 0; ; cred = prepare_kernel_cred(NULL); if (!cred) return -ENOMEM; keyring = key_alloc(&key_type_keyring, ".id_resolver", 0, 0, cred, (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); goto failed_put_cred; } ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); if (ret < 0) goto failed_put_key; ret = register_key_type(&key_type_id_resolver); if (ret < 0) goto failed_put_key; cred->thread_keyring = keyring; cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; id_resolver_cache = cred; return 0; failed_put_key: key_put(keyring); failed_put_cred: put_cred(cred); return ret; }
/* * create an authorisation token for /sbin/request-key or whoever to gain * access to the caller's security data */ struct key *request_key_auth_new(struct key *target, const void *callout_info, size_t callout_len, struct key *dest_keyring) { struct request_key_auth *rka, *irka; const struct cred *cred = current->cred; struct key *authkey = NULL; char desc[20]; int ret; kenter("%d,", target->serial); /* allocate a auth record */ rka = kmalloc(sizeof(*rka), GFP_KERNEL); if (!rka) { kleave(" = -ENOMEM"); return ERR_PTR(-ENOMEM); } rka->callout_info = kmalloc(callout_len, GFP_KERNEL); if (!rka->callout_info) { kleave(" = -ENOMEM"); kfree(rka); return ERR_PTR(-ENOMEM); } /* see if the calling process is already servicing the key request of * another process */ if (cred->request_key_auth) { /* it is - use that instantiation context here too */ down_read(&cred->request_key_auth->sem); /* if the auth key has been revoked, then the key we're * servicing is already instantiated */ if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags)) goto auth_key_revoked; irka = cred->request_key_auth->payload.data; rka->cred = get_cred(irka->cred); rka->pid = irka->pid; up_read(&cred->request_key_auth->sem); } else { /* it isn't - use this process as the context */ rka->cred = get_cred(cred); rka->pid = current->pid; } rka->target_key = key_get(target); rka->dest_keyring = key_get(dest_keyring); memcpy(rka->callout_info, callout_info, callout_len); rka->callout_len = callout_len; /* allocate the auth key */ sprintf(desc, "%x", target->serial); authkey = key_alloc(&key_type_request_key_auth, desc, cred->fsuid, cred->fsgid, cred, KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(authkey)) { ret = PTR_ERR(authkey); goto error_alloc; } /* construct the auth key */ ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); if (ret < 0) goto error_inst; kleave(" = {%d,%d}", authkey->serial, atomic_read(&authkey->usage)); return authkey; auth_key_revoked: up_read(&cred->request_key_auth->sem); kfree(rka->callout_info); kfree(rka); kleave("= -EKEYREVOKED"); return ERR_PTR(-EKEYREVOKED); error_inst: key_revoke(authkey); key_put(authkey); error_alloc: key_put(rka->target_key); key_put(rka->dest_keyring); kfree(rka->callout_info); kfree(rka); kleave("= %d", ret); return ERR_PTR(ret); } /* end request_key_auth_new() */
/* * Allocate a new key in under-construction state and attempt to link it in to * the requested keyring. * * May return a key that's already under construction instead if there was a * race between two thread calling request_key(). */ static int construct_alloc_key(struct key_type *type, const char *description, struct key *dest_keyring, unsigned long flags, struct key_user *user, struct key **_key) { const struct cred *cred = current_cred(); unsigned long prealloc; struct key *key; key_ref_t key_ref; int ret; kenter("%s,%s,,,", type->name, description); *_key = NULL; mutex_lock(&user->cons_lock); key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred, KEY_POS_ALL, flags); if (IS_ERR(key)) goto alloc_failed; set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); if (dest_keyring) { ret = __key_link_begin(dest_keyring, type, description, &prealloc); if (ret < 0) goto link_prealloc_failed; } /* attach the key to the destination keyring under lock, but we do need * to do another check just in case someone beat us to it whilst we * waited for locks */ mutex_lock(&key_construction_mutex); key_ref = search_process_keyrings(type, description, type->match, cred); if (!IS_ERR(key_ref)) goto key_already_present; if (dest_keyring) __key_link(dest_keyring, key, &prealloc); mutex_unlock(&key_construction_mutex); if (dest_keyring) __key_link_end(dest_keyring, type, prealloc); mutex_unlock(&user->cons_lock); *_key = key; kleave(" = 0 [%d]", key_serial(key)); return 0; /* the key is now present - we tell the caller that we found it by * returning -EINPROGRESS */ key_already_present: key_put(key); mutex_unlock(&key_construction_mutex); key = key_ref_to_ptr(key_ref); if (dest_keyring) { ret = __key_link_check_live_key(dest_keyring, key); if (ret == 0) __key_link(dest_keyring, key, &prealloc); __key_link_end(dest_keyring, type, prealloc); if (ret < 0) goto link_check_failed; } mutex_unlock(&user->cons_lock); *_key = key; kleave(" = -EINPROGRESS [%d]", key_serial(key)); return -EINPROGRESS; link_check_failed: mutex_unlock(&user->cons_lock); key_put(key); kleave(" = %d [linkcheck]", ret); return ret; link_prealloc_failed: mutex_unlock(&user->cons_lock); kleave(" = %d [prelink]", ret); return ret; alloc_failed: mutex_unlock(&user->cons_lock); kleave(" = %ld", PTR_ERR(key)); return PTR_ERR(key); }
/* * Allocate a new key in under-construction state and attempt to link it in to * the requested keyring. * * May return a key that's already under construction instead if there was a * race between two thread calling request_key(). */ static int construct_alloc_key(struct keyring_search_context *ctx, struct key *dest_keyring, unsigned long flags, struct key_user *user, struct key **_key) { struct assoc_array_edit *edit; struct key *key; key_perm_t perm; key_ref_t key_ref; int ret; kenter("%s,%s,,,", ctx->index_key.type->name, ctx->index_key.description); *_key = NULL; mutex_lock(&user->cons_lock); perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; perm |= KEY_USR_VIEW; if (ctx->index_key.type->read) perm |= KEY_POS_READ; if (ctx->index_key.type == &key_type_keyring || ctx->index_key.type->update) perm |= KEY_POS_WRITE; key = key_alloc(ctx->index_key.type, ctx->index_key.description, ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred, perm, flags, NULL); if (IS_ERR(key)) goto alloc_failed; set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); if (dest_keyring) { ret = __key_link_begin(dest_keyring, &ctx->index_key, &edit); if (ret < 0) goto link_prealloc_failed; } /* attach the key to the destination keyring under lock, but we do need * to do another check just in case someone beat us to it whilst we * waited for locks */ mutex_lock(&key_construction_mutex); key_ref = search_process_keyrings(ctx); if (!IS_ERR(key_ref)) goto key_already_present; if (dest_keyring) __key_link(key, &edit); mutex_unlock(&key_construction_mutex); if (dest_keyring) __key_link_end(dest_keyring, &ctx->index_key, edit); mutex_unlock(&user->cons_lock); *_key = key; kleave(" = 0 [%d]", key_serial(key)); return 0; /* the key is now present - we tell the caller that we found it by * returning -EINPROGRESS */ key_already_present: key_put(key); mutex_unlock(&key_construction_mutex); key = key_ref_to_ptr(key_ref); if (dest_keyring) { ret = __key_link_check_live_key(dest_keyring, key); if (ret == 0) __key_link(key, &edit); __key_link_end(dest_keyring, &ctx->index_key, edit); if (ret < 0) goto link_check_failed; } mutex_unlock(&user->cons_lock); *_key = key; kleave(" = -EINPROGRESS [%d]", key_serial(key)); return -EINPROGRESS; link_check_failed: mutex_unlock(&user->cons_lock); key_put(key); kleave(" = %d [linkcheck]", ret); return ret; link_prealloc_failed: mutex_unlock(&user->cons_lock); key_put(key); kleave(" = %d [prelink]", ret); return ret; alloc_failed: mutex_unlock(&user->cons_lock); kleave(" = %ld", PTR_ERR(key)); return PTR_ERR(key); }
int init_cifs_idmap(void) { struct cred *cred; struct key *keyring; int ret; cFYI(1, "Registering the %s key type", cifs_idmap_key_type.name); /* create an override credential set with a special thread keyring in * which requests are cached * * this is used to prevent malicious redirections from being installed * with add_key(). */ cred = prepare_kernel_cred(NULL); if (!cred) return -ENOMEM; keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred, (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); goto failed_put_cred; } ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); if (ret < 0) goto failed_put_key; ret = register_key_type(&cifs_idmap_key_type); if (ret < 0) goto failed_put_key; /* instruct request_key() to use this special keyring as a cache for * the results it looks up */ set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); cred->thread_keyring = keyring; cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; root_cred = cred; spin_lock_init(&siduidlock); uidtree = RB_ROOT; spin_lock_init(&sidgidlock); gidtree = RB_ROOT; spin_lock_init(&uidsidlock); siduidtree = RB_ROOT; spin_lock_init(&gidsidlock); sidgidtree = RB_ROOT; register_shrinker(&cifs_shrinker); cFYI(1, "cifs idmap keyring: %d", key_serial(keyring)); return 0; failed_put_key: key_put(keyring); failed_put_cred: put_cred(cred); return ret; }
static bool wallet_alloc_key(struct wallet *wallet, const char *priv, const char *pub, const char *desc, time_t birth, bool spendable) { struct wallet_key *wkey; struct key *key; uint160 pub_key; size_t len; uint8 *buf; bool s; ASSERT(priv); key = NULL; buf = NULL; len = 0; memset(&pub_key, 0, sizeof pub_key); if (btc->wallet_state == WALLET_ENCRYPTED_LOCKED) { if (wallet->pass) { struct secure_area *sec_b58; uint8 *encPrivKey; size_t encLen; if (!wallet_verify_hmac(wallet, priv, &encPrivKey, &encLen)) { return 0; } s = crypt_decrypt(wallet->ckey, encPrivKey, encLen, &sec_b58); free(encPrivKey); ASSERT(s); /* * 'buf' is a sensitive buffer here. It should be backed by * a struct secure_area. */ s = b58_privkey_to_bytes((char *)sec_b58->buf, &buf, &len); secure_free(sec_b58); ASSERT(s); } else { uint8 *pkey; size_t plen; str_to_bytes(pub, &pkey, &plen); hash160_calc(pkey, plen, &pub_key); free(pkey); } } else { s = b58_privkey_to_bytes(priv, &buf, &len); ASSERT(s); } if (buf) { key = key_alloc(); key_set_privkey(key, buf, len); memset(buf, 0, len); free(buf); key_get_pubkey_hash160(key, &pub_key); } ASSERT(!uint160_iszero(&pub_key)); wkey = safe_calloc(1, sizeof *wkey); wkey->cfg_idx = hashtable_getnumentries(wallet->hash_keys); wkey->btc_addr = b58_pubkey_from_uint160(&pub_key); wkey->desc = desc ? safe_strdup(desc) : NULL; wkey->pub_key = pub_key; wkey->birth = birth; wkey->key = key; wkey->spendable = spendable; if (spendable == 0) { Log(LGPFX" funds on %s are not spendable.\n", wkey->btc_addr); } s = hashtable_insert(wallet->hash_keys, &pub_key, sizeof pub_key, wkey); ASSERT(s); return 1; }
static int construct_alloc_key(struct key_type *type, const char *description, struct key *dest_keyring, unsigned long flags, struct key_user *user, struct key **_key) { const struct cred *cred = current_cred(); unsigned long prealloc; struct key *key; key_ref_t key_ref; int ret; kenter("%s,%s,,,", type->name, description); *_key = NULL; mutex_lock(&user->cons_lock); key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred, KEY_POS_ALL, flags); if (IS_ERR(key)) goto alloc_failed; set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); if (dest_keyring) { ret = __key_link_begin(dest_keyring, type, description, &prealloc); if (ret < 0) goto link_prealloc_failed; } /* */ mutex_lock(&key_construction_mutex); key_ref = search_process_keyrings(type, description, type->match, cred); if (!IS_ERR(key_ref)) goto key_already_present; if (dest_keyring) __key_link(dest_keyring, key, &prealloc); mutex_unlock(&key_construction_mutex); if (dest_keyring) __key_link_end(dest_keyring, type, prealloc); mutex_unlock(&user->cons_lock); *_key = key; kleave(" = 0 [%d]", key_serial(key)); return 0; /* */ key_already_present: key_put(key); mutex_unlock(&key_construction_mutex); key = key_ref_to_ptr(key_ref); if (dest_keyring) { ret = __key_link_check_live_key(dest_keyring, key); if (ret == 0) __key_link(dest_keyring, key, &prealloc); __key_link_end(dest_keyring, type, prealloc); if (ret < 0) goto link_check_failed; } mutex_unlock(&user->cons_lock); *_key = key; kleave(" = -EINPROGRESS [%d]", key_serial(key)); return -EINPROGRESS; link_check_failed: mutex_unlock(&user->cons_lock); key_put(key); kleave(" = %d [linkcheck]", ret); return ret; link_prealloc_failed: mutex_unlock(&user->cons_lock); kleave(" = %d [prelink]", ret); return ret; alloc_failed: mutex_unlock(&user->cons_lock); kleave(" = %ld", PTR_ERR(key)); return PTR_ERR(key); }