Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: keystore.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)keystore.fth 1.4 07/04/10 | |
43 | purpose: | |
44 | copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | \ FWARC 2006/523 | |
48 | ||
49 | vocabulary keystore | |
50 | also keystore definitions | |
51 | ||
52 | headerless | |
53 | ||
54 | 1 value key-major | |
55 | 0 value key-minor | |
56 | h# 4f42504b4559 value key-svc-handle \ OBPKEY | |
57 | ||
58 | \ Keystore Data Message | |
59 | struct | |
60 | /l field >key-cmd | |
61 | constant /key-hdr | |
62 | ||
63 | \ Keystore Data Response | |
64 | struct | |
65 | /l field >key-response | |
66 | constant /key-response | |
67 | ||
68 | \ Keystore Updates Response | |
69 | struct | |
70 | /l field >key-updates-response | |
71 | /l field >key-updates-size | |
72 | constant /key-updates-hdr | |
73 | ||
74 | /key-hdr /key-response + constant /key-response-pkt | |
75 | ||
76 | d# 1024 constant MAX-VAR-SIZE | |
77 | MAX-VAR-SIZE /key-hdr + buffer: key-buf | |
78 | ||
79 | also domain-services | |
80 | MAX-DS-PAYLOAD constant MAX-UPDATES-SIZE \ that OBP can currently handle | |
81 | previous | |
82 | ||
83 | 0 value keystore-updates-buf \ allocated on the fly for MD updates | |
84 | 0 value keystore-backup? \ Differentiate between the two services | |
85 | ||
86 | : key-cmd! ( cmd pkt -- ) >key-cmd l! ; | |
87 | : key-cmd@ ( pkt -- cmd ) >key-cmd l@ ; | |
88 | : >key-payload ( pkt -- payload-adr ) /key-hdr + ; | |
89 | : key-response@ ( pkt -- response ) >key-payload >key-response l@ ; | |
90 | : >key-updates-payload ( pkt -- payload-adr ) | |
91 | >key-payload /key-updates-hdr + | |
92 | ; | |
93 | : keystore-updates-size@ ( pkt -- size ) /key-hdr + >key-updates-size l@ ; | |
94 | ||
95 | ||
96 | \ message types | |
97 | 0 constant KEYSTORE-SET-REQ | |
98 | 1 constant KEYSTORE-DELETE-REQ | |
99 | 2 constant KEYSTORE-SET-RESP | |
100 | 3 constant KEYSTORE-DELETE-RESP | |
101 | ||
102 | 4 constant KEYSTORE-UPDATES-REQ | |
103 | 5 constant KEYSTORE-UPDATES-RESP | |
104 | ||
105 | \ Response Result Codes | |
106 | 0 constant KEYSTORE-SUCCESS | |
107 | 1 constant KEYSTORE-NO-SPACE | |
108 | 2 constant KEYSTORE-INVALID-KEY | |
109 | 3 constant KEYSTORE-INVALID-VAL | |
110 | 4 constant KEYSTORE-NOT-PRESENT | |
111 | ||
112 | \ To coordinate handoffs between Solaris and OBP the state of the | |
113 | \ domain-service channel is stored away. If OBP needs to use the channel | |
114 | \ after it has been closed it will attempt to re-register its needed service | |
115 | 0 constant KEY-CLOSED | |
116 | 1 constant KEY-OPEN | |
117 | 2 constant KEY-ERROR | |
118 | ||
119 | KEY-CLOSED value key-service-state | |
120 | ||
121 | \ Domain-service interfaces | |
122 | \ Send buffer on the given service channel | |
123 | : send-ds-data ( buf len svc-handle -- error? ) | |
124 | [ also domain-services ] send-ds-data [ previous ] | |
125 | ; | |
126 | ||
127 | \ Receive a packet of at most len from the given service channel | |
128 | : receive-ds-data ( buf len svc-handle -- len' 0 | error ) | |
129 | [ also domain-services ] receive-ds-data [ previous ] | |
130 | ; | |
131 | ||
132 | \ Attempt to register $svc-id with svc-handle. Returns error/ack/nack | |
133 | : register-domain-service ( maj min svc-han $svc-id -- maj/min ack? 0 | -1 ) | |
134 | [ also domain-services ] register-domain-service [ previous ] | |
135 | ; | |
136 | ||
137 | \ Unregister the domain service negotiated on svc-handle | |
138 | : unregister-domain-service ( svc-handle -- error? ) | |
139 | [ also domain-services ] unregister-domain-service [ previous ] | |
140 | ; | |
141 | also ldc | |
142 | ||
143 | \ service IDs with Null Character embedded | |
144 | : $keystore ( -- $ ) " keystore"(00)" ; | |
145 | : $keystore-backup ( -- $ ) " keystore-backup"(00)" ; | |
146 | ||
147 | \ Both init-primary-service and init-secondary-service can be changed | |
148 | \ to begin/while loops with multiple calls to reigster-domain-service | |
149 | \ however right now we only support 1.0 so if we get a nack that's it. | |
150 | : init-primary-service ( -- error? ) | |
151 | key-major key-minor key-svc-handle $keystore | |
152 | register-domain-service ?dup 0= if ( maj/min ack? ) | |
153 | nip 0= ( nack? ) | |
154 | then | |
155 | dup 0= if 0 to keystore-backup? then | |
156 | ; | |
157 | ||
158 | : init-secondary-service ( -- error? ) | |
159 | key-major key-minor key-svc-handle $keystore-backup | |
160 | register-domain-service ?dup 0= if ( maj/min ack? ) | |
161 | nip 0= ( nack? ) | |
162 | then | |
163 | dup 0= if -1 to keystore-backup? then | |
164 | ; | |
165 | ||
166 | \ Attempt to Register one of the two keystore services | |
167 | : key-init ( -- error? ) | |
168 | init-primary-service dup if ( error? ) | |
169 | drop init-secondary-service ( error? ) | |
170 | then ( error? ) | |
171 | dup if | |
172 | KEY-CLOSED to key-service-state | |
173 | else | |
174 | KEY-OPEN to key-service-state | |
175 | then | |
176 | ; | |
177 | ||
178 | \ Unregister the keystore service | |
179 | : key-close ( -- ) | |
180 | key-service-state KEY-OPEN <> if exit then ( ) | |
181 | key-svc-handle unregister-domain-service ?dup if ( ) | |
182 | \ If LDC is not up then it has been reset, treat this as closed LDC | |
183 | \ which can be re-opened for later operations. | |
184 | LDC-NOTUP = if ( ) | |
185 | KEY-CLOSED to key-service-state ( ) | |
186 | else ( ) | |
187 | KEY-ERROR to key-service-state ( ) | |
188 | then ( ) | |
189 | else ( ) | |
190 | KEY-CLOSED to key-service-state ( ) | |
191 | then ( ) | |
192 | key-svc-handle 1+ to key-svc-handle \ new handle in case of re-register | |
193 | ; | |
194 | ||
195 | \ Bring up the keystore channel unless it is in the ERROR state | |
196 | : check-key-channel-state ( -- error? ) | |
197 | key-service-state case | |
198 | KEY-OPEN of 0 endof | |
199 | KEY-CLOSED of key-init endof | |
200 | KEY-ERROR of -1 endof | |
201 | endcase | |
202 | ; | |
203 | ||
204 | \ Store string as a null-terminated string and return pointer past the | |
205 | \ terminating null character. | |
206 | : $cstrput ( str len dest-adr -- end-adr ) | |
207 | swap 2dup ca+ >r move 0 r@ c! r> ca1+ | |
208 | ; | |
209 | ||
210 | d# 1024 buffer: str-buf | |
211 | ||
212 | \ " foo" " bar" becomes " foo"(00)"bar"(00)" | |
213 | : cat-with-nulls ( str len str2 len2 -- str' len' ) | |
214 | dup 3 pick + >r | |
215 | str-buf $cstrput $cstrput drop | |
216 | str-buf r> 2+ | |
217 | ; | |
218 | ||
219 | \ add trailing 0 | |
220 | : to-cstr ( buf len -- buf' len' ) | |
221 | tuck str-buf $cstrput drop ( len ) | |
222 | str-buf swap 1+ ( buf len' ) | |
223 | ; | |
224 | ||
225 | \ Wrap set data in a keystore packet to be sent to the domain services layer | |
226 | : assemble-set-pkt ( $data $name -- pkt len ) | |
227 | cat-with-nulls tuck key-buf ( $payload pkt ) | |
228 | KEYSTORE-SET-REQ over key-cmd! ( payload-len $payload pkt ) | |
229 | >key-payload swap move ( payload-len ) | |
230 | key-buf swap /key-hdr + ( pkt len ) | |
231 | ; | |
232 | ||
233 | \ Wrap unset data to be sent to the domain services layer | |
234 | : assemble-unset-pkt ( $name -- pkt len ) | |
235 | to-cstr tuck key-buf ( name-len $name pkt ) | |
236 | KEYSTORE-DELETE-REQ over key-cmd! ( name-len $name pkt ) | |
237 | >key-payload swap move ( name-len ) | |
238 | key-buf swap /key-hdr + ( pkt len ) | |
239 | ; | |
240 | ||
241 | \ Request any updates from the SP since it last created an MD | |
242 | : assemble-updates-req-pkt ( -- pkt len ) | |
243 | keystore-updates-buf ( pkt ) | |
244 | KEYSTORE-UPDATES-REQ over key-cmd! ( pkt ) | |
245 | /key-hdr ( pkt len ) | |
246 | ; | |
247 | ||
248 | : key-response? ( cmd -- key-response? ) | |
249 | dup KEYSTORE-DELETE-RESP = swap KEYSTORE-SET-RESP = or | |
250 | ; | |
251 | ||
252 | : key-updates-response? ( cmd -- ldv-updates-response? ) | |
253 | KEYSTORE-UPDATES-RESP = | |
254 | ; | |
255 | ||
256 | \ Wait for keystore response request | |
257 | : wait-for-key-response ( -- error ) | |
258 | key-buf ( buf ) | |
259 | begin | |
260 | dup /key-response-pkt key-svc-handle ( buf buf len handle ) | |
261 | receive-ds-data ?dup if ( buf len' | buf error ) | |
262 | dup LDC-NOTUP if | |
263 | cmn-warn[ " Waiting for key response but LDC is Not Up!" ]cmn-end | |
264 | \ Mark the service closed so that it can be opened again | |
265 | KEY-CLOSED to key-service-state ( ) | |
266 | then ( buf error ) | |
267 | nip exit ( error ) | |
268 | else ( buf len ) | |
269 | /key-response-pkt <> if ( buf ) | |
270 | cmn-warn[ | |
271 | " No Keystore response from Domain Service Providor " | |
272 | ]cmn-end | |
273 | drop -1 exit ( -1 ) | |
274 | then ( buf ) | |
275 | then | |
276 | dup key-cmd@ key-response? ( buf response? ) | |
277 | until | |
278 | ||
279 | key-response@ case | |
280 | KEYSTORE-SUCCESS of 0 endof | |
281 | KEYSTORE-NO-SPACE of " No Space" endof | |
282 | KEYSTORE-INVALID-KEY of " Invalid Key Name" endof | |
283 | KEYSTORE-INVALID-VAL of " Invalid Value" endof | |
284 | KEYSTORE-NOT-PRESENT of " Key not Present" endof | |
285 | 0 swap | |
286 | endcase | |
287 | dup if | |
288 | cmn-warn[ ]cmn-end -1 | |
289 | then | |
290 | ; | |
291 | ||
292 | \ The updates response could be large. The domain-service interface layer | |
293 | \ should be updated to handle variable length packets until it is, we default | |
294 | \ to the current max size of an OBP domain-service packet (8K) | |
295 | : wait-for-updates-response ( -- error ) | |
296 | keystore-updates-buf ( buf ) | |
297 | begin | |
298 | dup MAX-UPDATES-SIZE key-svc-handle ( buf buf len handle ) | |
299 | receive-ds-data ?dup if ( buf len' | buf error ) | |
300 | dup LDC-NOTUP = if ( buf error ) | |
301 | cmn-warn[ | |
302 | " Waiting for Keystore Response but LDC is Not Up!" | |
303 | ]cmn-end | |
304 | \ Mark the service closed so that it can be opened again | |
305 | KEY-CLOSED to key-service-state ( ) | |
306 | then ( buf error ) | |
307 | nip exit ( error ) | |
308 | else ( buf len ) | |
309 | 0= if ( buf ) | |
310 | drop -1 exit ( -1 ) | |
311 | then ( buf ) | |
312 | then | |
313 | dup key-cmd@ key-updates-response? ( buf response? ) | |
314 | until ( buf ) | |
315 | keystore-updates-size@ MAX-UPDATES-SIZE > dup if | |
316 | cmn-warn[ " Keystore error - Updates MD too large " ]cmn-end | |
317 | then | |
318 | ; | |
319 | ||
320 | ||
321 | headers | |
322 | ||
323 | : keystore-set ( $data $name -- ) | |
324 | check-key-channel-state if | |
325 | cmn-warn[ " Unable to store Security key" ]cmn-end | |
326 | 2drop 2drop exit | |
327 | then | |
328 | assemble-set-pkt ( pkt len ) | |
329 | key-svc-handle send-ds-data ?dup if ( | status ) | |
330 | LDC-NOTUP = if ( ) | |
331 | cmn-warn[ " Sending Keystore Set request but LDC is Not Up!" ]cmn-end | |
332 | \ Mark the service closed so that it can be opened again | |
333 | KEY-CLOSED to key-service-state ( ) | |
334 | else | |
335 | key-close ( ) | |
336 | then | |
337 | cmn-warn[ " Keystore Set request failed!" ]cmn-end | |
338 | exit ( ) | |
339 | then ( ) | |
340 | wait-for-key-response if | |
341 | cmn-warn[ " Unable to store security key" ]cmn-end | |
342 | then | |
343 | key-close | |
344 | ; | |
345 | ||
346 | : keystore-delete ( $name -- ) | |
347 | check-key-channel-state if | |
348 | cmn-warn[ " Unable to Delete Security key" ]cmn-end | |
349 | 2drop exit | |
350 | then | |
351 | assemble-unset-pkt ( buf len ) | |
352 | key-svc-handle send-ds-data ?dup if ( | status ) | |
353 | LDC-NOTUP = if ( ) | |
354 | cmn-warn[ " Sending Keystore Delete request but LDC is Not Up!" ]cmn-end | |
355 | \ Mark the service closed so that it can be opened again | |
356 | KEY-CLOSED to key-service-state ( ) | |
357 | else | |
358 | key-close ( ) | |
359 | then | |
360 | cmn-warn[ " Keystore Delete request failed!" ]cmn-end | |
361 | exit ( ) | |
362 | then ( ) | |
363 | wait-for-key-response if | |
364 | cmn-warn[ " Unable to Delete security key" ]cmn-end | |
365 | then | |
366 | key-close | |
367 | ; | |
368 | ||
369 | \ Get the next string property in MD node | |
370 | : get-next-str-prop ( node prop -- ent|0 ) | |
371 | begin ( node prop ) | |
372 | over swap md-next-prop dup ( node prop,prop|0,0 ) | |
373 | while | |
374 | dup md-prop-type ascii s = if ( node prop ) | |
375 | nip exit ( prop ) | |
376 | then ( node prop ) | |
377 | repeat | |
378 | nip ( 0 ) | |
379 | ; | |
380 | ||
381 | \ Load security keys from the "keystore" MD node. We do this before | |
382 | \ initializing the domain service to avoid redundant keystore-set calls | |
383 | : get-keystore ( -- ) | |
384 | 0 " keystore" md-find-node ?dup 0= if exit then | |
385 | 0 ( node 0 ) | |
386 | begin | |
387 | over swap get-next-str-prop ?dup ( [ node prop prop ] | [ node 0 ] ) | |
388 | while | |
389 | dup md-decode-prop drop ( node prop $data ) | |
390 | 2 pick md-prop-name ( node prop $data $name ) | |
391 | 2swap convert-key drop ( node prop $name data,len ) | |
392 | (set-security-key) drop ( node prop ) | |
393 | repeat | |
394 | drop | |
395 | ; | |
396 | ||
397 | \ Load keystore updates from a mini MD | |
398 | \ 1. Set keys as they appear under the keystore node | |
399 | \ 2. If the entry name is the reserved word "_delete"... delete the given | |
400 | \ in the property data field | |
401 | : update-keystore ( -- ) | |
402 | keystore-updates-buf >key-updates-payload md-set-working-md | |
403 | 0 " keystore" md-find-node ?dup if | |
404 | 0 ( node 0 ) | |
405 | begin | |
406 | over swap get-next-str-prop ?dup ( [ node prop prop ] | [ node 0 ] ) | |
407 | while | |
408 | dup md-decode-prop drop ( node prop $data ) | |
409 | 2 pick md-prop-name ( node prop $data $name ) | |
410 | 2dup " _delete" $= if ( node prop $data $name ) | |
411 | \ len 0 key = delete | |
412 | drop 0 (set-security-key) ( node prop error? ) | |
413 | drop ( node prop ) | |
414 | else | |
415 | 2swap convert-key drop ( node prop $name data,len ) | |
416 | (set-security-key) drop ( node prop ) | |
417 | then ( node prop ) | |
418 | repeat | |
419 | drop ( ) | |
420 | then | |
421 | 0 md-set-working-md \ This Line is VERY IMPORTANT | |
422 | ; | |
423 | ||
424 | \ Request a "mini'MD" from the SP that contains any changes to the | |
425 | \ keystore MD node since it last created a guest MD | |
426 | : get-keystore-updates ( -- ) | |
427 | check-key-channel-state if | |
428 | exit | |
429 | then | |
430 | \ Only meaningful when talking to the SP | |
431 | keystore-backup? if | |
432 | MAX-UPDATES-SIZE alloc-mem to keystore-updates-buf | |
433 | assemble-updates-req-pkt ( pkt len ) | |
434 | key-svc-handle send-ds-data ?dup if ( | status ) | |
435 | LDC-NOTUP = if ( ) | |
436 | cmn-warn[ | |
437 | " Sending Keystore Update request but LDC is Not Up!" | |
438 | ]cmn-end | |
439 | \ Mark the service closed so that it can be opened again | |
440 | KEY-CLOSED to key-service-state ( ) | |
441 | else | |
442 | key-close ( ) | |
443 | then | |
444 | cmn-warn[ " Error sending Keystore Updates request" ]cmn-end | |
445 | keystore-updates-buf MAX-UPDATES-SIZE free-mem | |
446 | exit ( ) | |
447 | then ( ) | |
448 | wait-for-updates-response 0= if ( ) | |
449 | update-keystore ( ) | |
450 | then ( ) | |
451 | keystore-updates-buf MAX-UPDATES-SIZE free-mem | |
452 | then ( ) | |
453 | key-close ( ) | |
454 | ; | |
455 | ||
456 | previous \ ldc | |
457 | ||
458 | headerless | |
459 | ||
460 | stand-init: Security Key Domain Service Init | |
461 | get-keystore | |
462 | get-keystore-updates | |
463 | ['] keystore-set is key-set | |
464 | ['] keystore-delete is key-delete | |
465 | ; | |
466 | ||
467 | previous definitions | |
468 |