|
|
@@ -1,19 +1,19 @@
|
|
|
- ===================
|
|
|
- KEY REQUEST SERVICE
|
|
|
- ===================
|
|
|
+===================
|
|
|
+Key Request Service
|
|
|
+===================
|
|
|
|
|
|
The key request service is part of the key retention service (refer to
|
|
|
Documentation/security/keys.txt). This document explains more fully how
|
|
|
the requesting algorithm works.
|
|
|
|
|
|
The process starts by either the kernel requesting a service by calling
|
|
|
-request_key*():
|
|
|
+``request_key*()``::
|
|
|
|
|
|
struct key *request_key(const struct key_type *type,
|
|
|
const char *description,
|
|
|
const char *callout_info);
|
|
|
|
|
|
-or:
|
|
|
+or::
|
|
|
|
|
|
struct key *request_key_with_auxdata(const struct key_type *type,
|
|
|
const char *description,
|
|
|
@@ -21,14 +21,14 @@ or:
|
|
|
size_t callout_len,
|
|
|
void *aux);
|
|
|
|
|
|
-or:
|
|
|
+or::
|
|
|
|
|
|
struct key *request_key_async(const struct key_type *type,
|
|
|
const char *description,
|
|
|
const char *callout_info,
|
|
|
size_t callout_len);
|
|
|
|
|
|
-or:
|
|
|
+or::
|
|
|
|
|
|
struct key *request_key_async_with_auxdata(const struct key_type *type,
|
|
|
const char *description,
|
|
|
@@ -36,7 +36,7 @@ or:
|
|
|
size_t callout_len,
|
|
|
void *aux);
|
|
|
|
|
|
-Or by userspace invoking the request_key system call:
|
|
|
+Or by userspace invoking the request_key system call::
|
|
|
|
|
|
key_serial_t request_key(const char *type,
|
|
|
const char *description,
|
|
|
@@ -67,38 +67,37 @@ own upcall mechanisms. If they do, then those should be substituted for the
|
|
|
forking and execution of /sbin/request-key.
|
|
|
|
|
|
|
|
|
-===========
|
|
|
-THE PROCESS
|
|
|
+The Process
|
|
|
===========
|
|
|
|
|
|
A request proceeds in the following manner:
|
|
|
|
|
|
- (1) Process A calls request_key() [the userspace syscall calls the kernel
|
|
|
+ 1) Process A calls request_key() [the userspace syscall calls the kernel
|
|
|
interface].
|
|
|
|
|
|
- (2) request_key() searches the process's subscribed keyrings to see if there's
|
|
|
+ 2) request_key() searches the process's subscribed keyrings to see if there's
|
|
|
a suitable key there. If there is, it returns the key. If there isn't,
|
|
|
and callout_info is not set, an error is returned. Otherwise the process
|
|
|
proceeds to the next step.
|
|
|
|
|
|
- (3) request_key() sees that A doesn't have the desired key yet, so it creates
|
|
|
+ 3) request_key() sees that A doesn't have the desired key yet, so it creates
|
|
|
two things:
|
|
|
|
|
|
- (a) An uninstantiated key U of requested type and description.
|
|
|
+ a) An uninstantiated key U of requested type and description.
|
|
|
|
|
|
- (b) An authorisation key V that refers to key U and notes that process A
|
|
|
+ b) An authorisation key V that refers to key U and notes that process A
|
|
|
is the context in which key U should be instantiated and secured, and
|
|
|
from which associated key requests may be satisfied.
|
|
|
|
|
|
- (4) request_key() then forks and executes /sbin/request-key with a new session
|
|
|
+ 4) request_key() then forks and executes /sbin/request-key with a new session
|
|
|
keyring that contains a link to auth key V.
|
|
|
|
|
|
- (5) /sbin/request-key assumes the authority associated with key U.
|
|
|
+ 5) /sbin/request-key assumes the authority associated with key U.
|
|
|
|
|
|
- (6) /sbin/request-key execs an appropriate program to perform the actual
|
|
|
+ 6) /sbin/request-key execs an appropriate program to perform the actual
|
|
|
instantiation.
|
|
|
|
|
|
- (7) The program may want to access another key from A's context (say a
|
|
|
+ 7) The program may want to access another key from A's context (say a
|
|
|
Kerberos TGT key). It just requests the appropriate key, and the keyring
|
|
|
search notes that the session keyring has auth key V in its bottom level.
|
|
|
|
|
|
@@ -110,10 +109,10 @@ A request proceeds in the following manner:
|
|
|
instantiate key U, using key W as a reference (perhaps it contacts a
|
|
|
Kerberos server using the TGT) and then instantiates key U.
|
|
|
|
|
|
- (9) Upon instantiating key U, auth key V is automatically revoked so that it
|
|
|
+ 9) Upon instantiating key U, auth key V is automatically revoked so that it
|
|
|
may not be used again.
|
|
|
|
|
|
-(10) The program then exits 0 and request_key() deletes key V and returns key
|
|
|
+ 10) The program then exits 0 and request_key() deletes key V and returns key
|
|
|
U to the caller.
|
|
|
|
|
|
This also extends further. If key W (step 7 above) didn't exist, key W would
|
|
|
@@ -127,8 +126,7 @@ This is because process A's keyrings can't simply be attached to
|
|
|
of them, and (b) it requires the same UID/GID/Groups all the way through.
|
|
|
|
|
|
|
|
|
-====================================
|
|
|
-NEGATIVE INSTANTIATION AND REJECTION
|
|
|
+Negative Instantiation And Rejection
|
|
|
====================================
|
|
|
|
|
|
Rather than instantiating a key, it is possible for the possessor of an
|
|
|
@@ -145,23 +143,22 @@ signal, the key under construction will be automatically negatively
|
|
|
instantiated for a short amount of time.
|
|
|
|
|
|
|
|
|
-====================
|
|
|
-THE SEARCH ALGORITHM
|
|
|
+The Search Algorithm
|
|
|
====================
|
|
|
|
|
|
A search of any particular keyring proceeds in the following fashion:
|
|
|
|
|
|
- (1) When the key management code searches for a key (keyring_search_aux) it
|
|
|
+ 1) When the key management code searches for a key (keyring_search_aux) it
|
|
|
firstly calls key_permission(SEARCH) on the keyring it's starting with,
|
|
|
if this denies permission, it doesn't search further.
|
|
|
|
|
|
- (2) It considers all the non-keyring keys within that keyring and, if any key
|
|
|
+ 2) It considers all the non-keyring keys within that keyring and, if any key
|
|
|
matches the criteria specified, calls key_permission(SEARCH) on it to see
|
|
|
if the key is allowed to be found. If it is, that key is returned; if
|
|
|
not, the search continues, and the error code is retained if of higher
|
|
|
priority than the one currently set.
|
|
|
|
|
|
- (3) It then considers all the keyring-type keys in the keyring it's currently
|
|
|
+ 3) It then considers all the keyring-type keys in the keyring it's currently
|
|
|
searching. It calls key_permission(SEARCH) on each keyring, and if this
|
|
|
grants permission, it recurses, executing steps (2) and (3) on that
|
|
|
keyring.
|
|
|
@@ -173,20 +170,20 @@ returned.
|
|
|
When search_process_keyrings() is invoked, it performs the following searches
|
|
|
until one succeeds:
|
|
|
|
|
|
- (1) If extant, the process's thread keyring is searched.
|
|
|
+ 1) If extant, the process's thread keyring is searched.
|
|
|
|
|
|
- (2) If extant, the process's process keyring is searched.
|
|
|
+ 2) If extant, the process's process keyring is searched.
|
|
|
|
|
|
- (3) The process's session keyring is searched.
|
|
|
+ 3) The process's session keyring is searched.
|
|
|
|
|
|
- (4) If the process has assumed the authority associated with a request_key()
|
|
|
+ 4) If the process has assumed the authority associated with a request_key()
|
|
|
authorisation key then:
|
|
|
|
|
|
- (a) If extant, the calling process's thread keyring is searched.
|
|
|
+ a) If extant, the calling process's thread keyring is searched.
|
|
|
|
|
|
- (b) If extant, the calling process's process keyring is searched.
|
|
|
+ b) If extant, the calling process's process keyring is searched.
|
|
|
|
|
|
- (c) The calling process's session keyring is searched.
|
|
|
+ c) The calling process's session keyring is searched.
|
|
|
|
|
|
The moment one succeeds, all pending errors are discarded and the found key is
|
|
|
returned.
|
|
|
@@ -194,7 +191,7 @@ returned.
|
|
|
Only if all these fail does the whole thing fail with the highest priority
|
|
|
error. Note that several errors may have come from LSM.
|
|
|
|
|
|
-The error priority is:
|
|
|
+The error priority is::
|
|
|
|
|
|
EKEYREVOKED > EKEYEXPIRED > ENOKEY
|
|
|
|