Root/
Source at commit ec7cab4cbb721bff91ec924ec691efd8daf36579 created 12 years 8 months ago. By Maarten ter Huurne, MIPS: JZ4740: A320: Updated quickstart documentation. | |
---|---|
1 | =================== |
2 | KEY REQUEST SERVICE |
3 | =================== |
4 | |
5 | The key request service is part of the key retention service (refer to |
6 | Documentation/keys.txt). This document explains more fully how the requesting |
7 | algorithm works. |
8 | |
9 | The process starts by either the kernel requesting a service by calling |
10 | request_key*(): |
11 | |
12 | struct key *request_key(const struct key_type *type, |
13 | const char *description, |
14 | const char *callout_info); |
15 | |
16 | or: |
17 | |
18 | struct key *request_key_with_auxdata(const struct key_type *type, |
19 | const char *description, |
20 | const char *callout_info, |
21 | size_t callout_len, |
22 | void *aux); |
23 | |
24 | or: |
25 | |
26 | struct key *request_key_async(const struct key_type *type, |
27 | const char *description, |
28 | const char *callout_info, |
29 | size_t callout_len); |
30 | |
31 | or: |
32 | |
33 | struct key *request_key_async_with_auxdata(const struct key_type *type, |
34 | const char *description, |
35 | const char *callout_info, |
36 | size_t callout_len, |
37 | void *aux); |
38 | |
39 | Or by userspace invoking the request_key system call: |
40 | |
41 | key_serial_t request_key(const char *type, |
42 | const char *description, |
43 | const char *callout_info, |
44 | key_serial_t dest_keyring); |
45 | |
46 | The main difference between the access points is that the in-kernel interface |
47 | does not need to link the key to a keyring to prevent it from being immediately |
48 | destroyed. The kernel interface returns a pointer directly to the key, and |
49 | it's up to the caller to destroy the key. |
50 | |
51 | The request_key*_with_auxdata() calls are like the in-kernel request_key*() |
52 | calls, except that they permit auxiliary data to be passed to the upcaller (the |
53 | default is NULL). This is only useful for those key types that define their |
54 | own upcall mechanism rather than using /sbin/request-key. |
55 | |
56 | The two async in-kernel calls may return keys that are still in the process of |
57 | being constructed. The two non-async ones will wait for construction to |
58 | complete first. |
59 | |
60 | The userspace interface links the key to a keyring associated with the process |
61 | to prevent the key from going away, and returns the serial number of the key to |
62 | the caller. |
63 | |
64 | |
65 | The following example assumes that the key types involved don't define their |
66 | own upcall mechanisms. If they do, then those should be substituted for the |
67 | forking and execution of /sbin/request-key. |
68 | |
69 | |
70 | =========== |
71 | THE PROCESS |
72 | =========== |
73 | |
74 | A request proceeds in the following manner: |
75 | |
76 | (1) Process A calls request_key() [the userspace syscall calls the kernel |
77 | interface]. |
78 | |
79 | (2) request_key() searches the process's subscribed keyrings to see if there's |
80 | a suitable key there. If there is, it returns the key. If there isn't, |
81 | and callout_info is not set, an error is returned. Otherwise the process |
82 | proceeds to the next step. |
83 | |
84 | (3) request_key() sees that A doesn't have the desired key yet, so it creates |
85 | two things: |
86 | |
87 | (a) An uninstantiated key U of requested type and description. |
88 | |
89 | (b) An authorisation key V that refers to key U and notes that process A |
90 | is the context in which key U should be instantiated and secured, and |
91 | from which associated key requests may be satisfied. |
92 | |
93 | (4) request_key() then forks and executes /sbin/request-key with a new session |
94 | keyring that contains a link to auth key V. |
95 | |
96 | (5) /sbin/request-key assumes the authority associated with key U. |
97 | |
98 | (6) /sbin/request-key execs an appropriate program to perform the actual |
99 | instantiation. |
100 | |
101 | (7) The program may want to access another key from A's context (say a |
102 | Kerberos TGT key). It just requests the appropriate key, and the keyring |
103 | search notes that the session keyring has auth key V in its bottom level. |
104 | |
105 | This will permit it to then search the keyrings of process A with the |
106 | UID, GID, groups and security info of process A as if it was process A, |
107 | and come up with key W. |
108 | |
109 | (8) The program then does what it must to get the data with which to |
110 | instantiate key U, using key W as a reference (perhaps it contacts a |
111 | Kerberos server using the TGT) and then instantiates key U. |
112 | |
113 | (9) Upon instantiating key U, auth key V is automatically revoked so that it |
114 | may not be used again. |
115 | |
116 | (10) The program then exits 0 and request_key() deletes key V and returns key |
117 | U to the caller. |
118 | |
119 | This also extends further. If key W (step 7 above) didn't exist, key W would |
120 | be created uninstantiated, another auth key (X) would be created (as per step |
121 | 3) and another copy of /sbin/request-key spawned (as per step 4); but the |
122 | context specified by auth key X will still be process A, as it was in auth key |
123 | V. |
124 | |
125 | This is because process A's keyrings can't simply be attached to |
126 | /sbin/request-key at the appropriate places because (a) execve will discard two |
127 | of them, and (b) it requires the same UID/GID/Groups all the way through. |
128 | |
129 | |
130 | ==================================== |
131 | NEGATIVE INSTANTIATION AND REJECTION |
132 | ==================================== |
133 | |
134 | Rather than instantiating a key, it is possible for the possessor of an |
135 | authorisation key to negatively instantiate a key that's under construction. |
136 | This is a short duration placeholder that causes any attempt at re-requesting |
137 | the key whilst it exists to fail with error ENOKEY if negated or the specified |
138 | error if rejected. |
139 | |
140 | This is provided to prevent excessive repeated spawning of /sbin/request-key |
141 | processes for a key that will never be obtainable. |
142 | |
143 | Should the /sbin/request-key process exit anything other than 0 or die on a |
144 | signal, the key under construction will be automatically negatively |
145 | instantiated for a short amount of time. |
146 | |
147 | |
148 | ==================== |
149 | THE SEARCH ALGORITHM |
150 | ==================== |
151 | |
152 | A search of any particular keyring proceeds in the following fashion: |
153 | |
154 | (1) When the key management code searches for a key (keyring_search_aux) it |
155 | firstly calls key_permission(SEARCH) on the keyring it's starting with, |
156 | if this denies permission, it doesn't search further. |
157 | |
158 | (2) It considers all the non-keyring keys within that keyring and, if any key |
159 | matches the criteria specified, calls key_permission(SEARCH) on it to see |
160 | if the key is allowed to be found. If it is, that key is returned; if |
161 | not, the search continues, and the error code is retained if of higher |
162 | priority than the one currently set. |
163 | |
164 | (3) It then considers all the keyring-type keys in the keyring it's currently |
165 | searching. It calls key_permission(SEARCH) on each keyring, and if this |
166 | grants permission, it recurses, executing steps (2) and (3) on that |
167 | keyring. |
168 | |
169 | The process stops immediately a valid key is found with permission granted to |
170 | use it. Any error from a previous match attempt is discarded and the key is |
171 | returned. |
172 | |
173 | When search_process_keyrings() is invoked, it performs the following searches |
174 | until one succeeds: |
175 | |
176 | (1) If extant, the process's thread keyring is searched. |
177 | |
178 | (2) If extant, the process's process keyring is searched. |
179 | |
180 | (3) The process's session keyring is searched. |
181 | |
182 | (4) If the process has assumed the authority associated with a request_key() |
183 | authorisation key then: |
184 | |
185 | (a) If extant, the calling process's thread keyring is searched. |
186 | |
187 | (b) If extant, the calling process's process keyring is searched. |
188 | |
189 | (c) The calling process's session keyring is searched. |
190 | |
191 | The moment one succeeds, all pending errors are discarded and the found key is |
192 | returned. |
193 | |
194 | Only if all these fail does the whole thing fail with the highest priority |
195 | error. Note that several errors may have come from LSM. |
196 | |
197 | The error priority is: |
198 | |
199 | EKEYREVOKED > EKEYEXPIRED > ENOKEY |
200 | |
201 | EACCES/EPERM are only returned on a direct search of a specific keyring where |
202 | the basal keyring does not grant Search permission. |
203 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9