]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2004,2011-2012,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // | |
26 | // transition - transition layer for CSSM API/SPI calls. | |
27 | // | |
28 | // This file defines all functions that connect the CSSM API (CSSM_*) | |
29 | // to a plugin's SPI (CSSM_SPI_*) functions. The bulk of these functions | |
30 | // is automatically generated by the Perl script transition.pl (thanks, Larry!) | |
31 | // from the cssm*.h official header files, under control of the configuration | |
32 | // file transition.cfg. Those that need special magic are marked "custom" in | |
33 | // transition.cfg and are defined here. | |
34 | // | |
35 | // @@@ Reconsider CSP locking for context operations | |
36 | // | |
37 | #include "cssmint.h" | |
38 | #include "attachfactory.h" | |
39 | #include "manager.h" | |
40 | #include "cssmcontext.h" | |
41 | #include <Security/cssmcspi.h> | |
42 | #include <Security/cssmdli.h> | |
43 | #include <Security/cssmcli.h> | |
44 | #include <Security/cssmaci.h> | |
45 | #include <Security/cssmtpi.h> | |
46 | #include <Security/cssmkrapi.h> | |
47 | #include <Security/cssmkrspi.h> | |
48 | #include <security_cdsa_utilities/cssmbridge.h> | |
49 | ||
50 | ||
51 | // | |
52 | // Names for the standard Attachment types | |
53 | // | |
54 | typedef StandardAttachment<CSSM_SERVICE_CSP, CSSM_SPI_CSP_FUNCS> CSPAttachment; | |
55 | typedef StandardAttachment<CSSM_SERVICE_DL, CSSM_SPI_DL_FUNCS> DLAttachment; | |
56 | typedef StandardAttachment<CSSM_SERVICE_CL, CSSM_SPI_CL_FUNCS> CLAttachment; | |
57 | typedef StandardAttachment<CSSM_SERVICE_AC, CSSM_SPI_AC_FUNCS> ACAttachment; | |
58 | typedef StandardAttachment<CSSM_SERVICE_TP, CSSM_SPI_TP_FUNCS> TPAttachment; | |
59 | ||
60 | ||
61 | // | |
62 | // A conditional locking class for always-right(TM) lock management. | |
63 | // | |
64 | class TransitLock { | |
65 | public: | |
66 | Attachment &attachment; | |
67 | ||
68 | TransitLock(Attachment &att) : attachment(att) | |
69 | { | |
70 | attachment.module.safeLock(); | |
71 | } | |
72 | ||
73 | ~TransitLock() | |
74 | { | |
75 | attachment.module.safeUnlock(); | |
76 | attachment.exit(); | |
77 | } | |
78 | }; | |
79 | ||
80 | ||
81 | // | |
82 | // Context management functions | |
83 | // | |
84 | CSSM_RETURN CSSMAPI | |
85 | CSSM_CSP_CreateSignatureContext (CSSM_CSP_HANDLE CSPHandle, | |
86 | CSSM_ALGORITHMS AlgorithmID, | |
87 | const CSSM_ACCESS_CREDENTIALS *AccessCred, | |
88 | const CSSM_KEY *Key, | |
89 | CSSM_CC_HANDLE *NewContextHandle) | |
90 | { | |
91 | BEGIN_API | |
92 | HandleContext::Maker maker(CSPHandle); | |
93 | maker.setup(AccessCred); | |
94 | maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY); | |
95 | maker.make(); | |
96 | maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred); | |
97 | maker.put(CSSM_ATTRIBUTE_KEY, Key); | |
98 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_SIGNATURE, AlgorithmID); | |
99 | END_API(CSSM) | |
100 | } | |
101 | ||
102 | ||
103 | CSSM_RETURN CSSMAPI | |
104 | CSSM_CSP_CreateSymmetricContext (CSSM_CSP_HANDLE CSPHandle, | |
105 | CSSM_ALGORITHMS AlgorithmID, | |
106 | CSSM_ENCRYPT_MODE Mode, | |
107 | const CSSM_ACCESS_CREDENTIALS *AccessCred, | |
108 | const CSSM_KEY *Key, | |
109 | const CSSM_DATA *InitVector, | |
110 | CSSM_PADDING Padding, | |
111 | void *Reserved, | |
112 | CSSM_CC_HANDLE *NewContextHandle) | |
113 | { | |
114 | BEGIN_API | |
115 | if (Reserved != NULL) | |
116 | CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER); | |
117 | HandleContext::Maker maker(CSPHandle); | |
118 | maker.setup(Mode); | |
119 | maker.setup(AccessCred); | |
120 | maker.setup(Key); | |
121 | maker.setup(InitVector); | |
122 | maker.setup(Padding); | |
123 | maker.make(); | |
124 | maker.put(CSSM_ATTRIBUTE_MODE, Mode); | |
125 | maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred); | |
126 | maker.put(CSSM_ATTRIBUTE_KEY, Key); | |
127 | maker.put(CSSM_ATTRIBUTE_INIT_VECTOR, InitVector); | |
128 | maker.put(CSSM_ATTRIBUTE_PADDING, Padding); | |
129 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_SYMMETRIC, AlgorithmID); | |
130 | END_API(CSSM) | |
131 | } | |
132 | ||
133 | ||
134 | CSSM_RETURN CSSMAPI | |
135 | CSSM_CSP_CreateDigestContext (CSSM_CSP_HANDLE CSPHandle, | |
136 | CSSM_ALGORITHMS AlgorithmID, | |
137 | CSSM_CC_HANDLE *NewContextHandle) | |
138 | { | |
139 | BEGIN_API | |
140 | HandleContext::Maker maker(CSPHandle); | |
141 | maker.make(); | |
142 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_DIGEST, AlgorithmID); | |
143 | END_API(CSSM) | |
144 | } | |
145 | ||
146 | ||
147 | CSSM_RETURN CSSMAPI | |
148 | CSSM_CSP_CreateMacContext (CSSM_CSP_HANDLE CSPHandle, | |
149 | CSSM_ALGORITHMS AlgorithmID, | |
150 | const CSSM_KEY *Key, | |
151 | CSSM_CC_HANDLE *NewContextHandle) | |
152 | { | |
153 | BEGIN_API | |
154 | HandleContext::Maker maker(CSPHandle); | |
155 | maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY); | |
156 | maker.make(); | |
157 | maker.put(CSSM_ATTRIBUTE_KEY, Key); | |
158 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_MAC, AlgorithmID); | |
159 | END_API(CSSM) | |
160 | } | |
161 | ||
162 | ||
163 | CSSM_RETURN CSSMAPI | |
164 | CSSM_CSP_CreateRandomGenContext (CSSM_CSP_HANDLE CSPHandle, | |
165 | CSSM_ALGORITHMS AlgorithmID, | |
166 | const CSSM_CRYPTO_DATA *Seed, | |
167 | CSSM_SIZE Length, | |
168 | CSSM_CC_HANDLE *NewContextHandle) | |
169 | { | |
170 | BEGIN_API | |
171 | HandleContext::Maker maker(CSPHandle); | |
172 | maker.setup(Seed); | |
173 | maker.setup(Length, CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE); | |
174 | maker.make(); | |
175 | maker.put(CSSM_ATTRIBUTE_SEED, Seed); | |
427c49bc | 176 | maker.put(CSSM_ATTRIBUTE_OUTPUT_SIZE, (uint32_t)Length); |
b1ab9ed8 A |
177 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_RANDOMGEN, AlgorithmID); |
178 | END_API(CSSM) | |
179 | } | |
180 | ||
181 | ||
182 | CSSM_RETURN CSSMAPI | |
183 | CSSM_CSP_CreateAsymmetricContext (CSSM_CSP_HANDLE CSPHandle, | |
184 | CSSM_ALGORITHMS AlgorithmID, | |
185 | const CSSM_ACCESS_CREDENTIALS *AccessCred, | |
186 | const CSSM_KEY *Key, | |
187 | CSSM_PADDING Padding, | |
188 | CSSM_CC_HANDLE *NewContextHandle) | |
189 | { | |
190 | BEGIN_API | |
191 | HandleContext::Maker maker(CSPHandle); | |
192 | maker.setup(AccessCred, CSSMERR_CSP_MISSING_ATTR_ACCESS_CREDENTIALS); | |
193 | maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY); | |
194 | maker.setup(Padding); | |
195 | maker.make(); | |
196 | maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred); | |
197 | maker.put(CSSM_ATTRIBUTE_KEY, Key); | |
198 | maker.put(CSSM_ATTRIBUTE_PADDING, Padding); | |
199 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_ASYMMETRIC, AlgorithmID); | |
200 | END_API(CSSM) | |
201 | } | |
202 | ||
203 | ||
204 | CSSM_RETURN CSSMAPI | |
205 | CSSM_CSP_CreateDeriveKeyContext (CSSM_CSP_HANDLE CSPHandle, | |
206 | CSSM_ALGORITHMS AlgorithmID, | |
207 | CSSM_KEY_TYPE DeriveKeyType, | |
208 | uint32 DeriveKeyLengthInBits, | |
209 | const CSSM_ACCESS_CREDENTIALS *AccessCred, | |
210 | const CSSM_KEY *BaseKey, | |
211 | uint32 IterationCount, | |
212 | const CSSM_DATA *Salt, | |
213 | const CSSM_CRYPTO_DATA *Seed, | |
214 | CSSM_CC_HANDLE *NewContextHandle) | |
215 | { | |
216 | BEGIN_API | |
217 | HandleContext::Maker maker(CSPHandle); | |
218 | maker.setup(DeriveKeyType, CSSMERR_CSP_INVALID_ATTR_KEY_TYPE); | |
219 | maker.setup(DeriveKeyLengthInBits, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH); | |
220 | maker.setup(AccessCred); | |
221 | maker.setup(BaseKey); | |
222 | maker.setup(IterationCount); | |
223 | maker.setup(Salt); | |
224 | maker.setup(Seed); | |
225 | maker.make(); | |
226 | maker.put(CSSM_ATTRIBUTE_KEY_TYPE, DeriveKeyType); | |
227 | maker.put(CSSM_ATTRIBUTE_KEY_LENGTH, DeriveKeyLengthInBits); | |
228 | maker.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, AccessCred); | |
229 | maker.put(CSSM_ATTRIBUTE_KEY, BaseKey); | |
230 | maker.put(CSSM_ATTRIBUTE_ITERATION_COUNT, IterationCount); | |
231 | maker.put(CSSM_ATTRIBUTE_SALT, Salt); | |
232 | maker.put(CSSM_ATTRIBUTE_SEED, Seed); | |
233 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_DERIVEKEY, AlgorithmID); | |
234 | END_API(CSSM) | |
235 | } | |
236 | ||
237 | ||
238 | CSSM_RETURN CSSMAPI | |
239 | CSSM_CSP_CreateKeyGenContext (CSSM_CSP_HANDLE CSPHandle, | |
240 | CSSM_ALGORITHMS AlgorithmID, | |
241 | uint32 KeySizeInBits, | |
242 | const CSSM_CRYPTO_DATA *Seed, | |
243 | const CSSM_DATA *Salt, | |
244 | const CSSM_DATE *StartDate, | |
245 | const CSSM_DATE *EndDate, | |
246 | const CSSM_DATA *Params, | |
247 | CSSM_CC_HANDLE *NewContextHandle) | |
248 | { | |
249 | BEGIN_API | |
250 | HandleContext::Maker maker(CSPHandle); | |
251 | maker.setup(KeySizeInBits, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH); | |
252 | maker.setup(Seed); | |
253 | maker.setup(Salt); | |
254 | maker.setup(StartDate); | |
255 | maker.setup(EndDate); | |
256 | maker.setup(Params); | |
257 | maker.make(); | |
258 | maker.put(CSSM_ATTRIBUTE_KEY_LENGTH, KeySizeInBits); | |
259 | maker.put(CSSM_ATTRIBUTE_SEED, Seed); | |
260 | maker.put(CSSM_ATTRIBUTE_SALT, Salt); | |
261 | maker.put(CSSM_ATTRIBUTE_START_DATE, StartDate); | |
262 | maker.put(CSSM_ATTRIBUTE_END_DATE, EndDate); | |
263 | maker.put(CSSM_ATTRIBUTE_ALG_PARAMS, Params); | |
264 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_KEYGEN, AlgorithmID); | |
265 | END_API(CSSM) | |
266 | } | |
267 | ||
268 | ||
269 | CSSM_RETURN CSSMAPI | |
270 | CSSM_CSP_CreatePassThroughContext (CSSM_CSP_HANDLE CSPHandle, | |
271 | const CSSM_KEY *Key, | |
272 | CSSM_CC_HANDLE *NewContextHandle) | |
273 | { | |
274 | BEGIN_API | |
275 | HandleContext::Maker maker(CSPHandle); | |
276 | maker.setup(Key, CSSMERR_CSP_MISSING_ATTR_KEY); | |
277 | maker.make(); | |
278 | maker.put(CSSM_ATTRIBUTE_KEY, Key); | |
279 | Required(NewContextHandle) = maker(CSSM_ALGCLASS_NONE, CSSM_ALGID_NONE); | |
280 | END_API(CSSM) | |
281 | } | |
282 | ||
283 | ||
284 | // | |
285 | // CSSM_GetContext makes a deep copy of a CSP context and hands it to the | |
286 | // caller. The result is NOT a HandleContext, but a bare Context that is | |
287 | // in no dictionaries etc. User must delete it by calling CSSM_FreeContext. | |
288 | // | |
289 | CSSM_RETURN CSSMAPI | |
290 | CSSM_GetContext (CSSM_CC_HANDLE CCHandle, | |
291 | CSSM_CONTEXT_PTR *ContextP) | |
292 | { | |
293 | BEGIN_API | |
427c49bc A |
294 | #warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE |
295 | HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE); | |
b1ab9ed8 A |
296 | Context *newContext = new(context.attachment) Context(context.type(), context.algorithm()); |
297 | try { | |
298 | newContext->CSPHandle = context.attachment.handle(); | |
299 | newContext->copyFrom(context, context.attachment); | |
300 | Required(ContextP) = newContext; | |
301 | } catch (...) { | |
302 | context.attachment.free(newContext); | |
303 | throw; | |
304 | } | |
305 | END_API(CSSM) | |
306 | } | |
307 | ||
308 | ||
309 | // | |
310 | // Since we allocated all the data in one fell heap, our FreeContext | |
311 | // function is disappointingly simple. | |
312 | // | |
313 | CSSM_RETURN CSSMAPI | |
314 | CSSM_FreeContext (CSSM_CONTEXT_PTR ContextP) | |
315 | { | |
316 | BEGIN_API | |
317 | Context *context = &Context::required(ContextP); | |
318 | context->destroy(context, HandleObject::find<CSPAttachment>(context->CSPHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE)); | |
319 | END_API(CSSM) | |
320 | } | |
321 | ||
322 | ||
323 | CSSM_RETURN CSSMAPI | |
324 | CSSM_SetContext (CSSM_CC_HANDLE CCHandle, | |
325 | const CSSM_CONTEXT *ContextP) | |
326 | { | |
327 | BEGIN_API | |
328 | const Context &source = Context::required(ContextP); | |
427c49bc A |
329 | #warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE |
330 | HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE); | |
b1ab9ed8 A |
331 | |
332 | CSSM_CONTEXT_ATTRIBUTE *oldAttributes = context.ContextAttributes; | |
333 | uint32 oldCount = context.NumberOfAttributes; | |
334 | CSSM_CONTEXT_TYPE oldType = context.ContextType; | |
335 | CSSM_ALGORITHMS oldAlgorithm = context.AlgorithmType; | |
336 | ||
337 | context.copyFrom(source, context.attachment); | |
338 | context.ContextType = source.ContextType; | |
339 | context.AlgorithmType = source.AlgorithmType; | |
340 | ||
341 | if (CSSM_RETURN err = context.validateChange(CSSM_CONTEXT_EVENT_UPDATE)) { | |
342 | context.attachment.free(context.ContextAttributes); // free rejected attribute blob | |
343 | context.ContextAttributes = oldAttributes; // restore... | |
344 | context.NumberOfAttributes = oldCount; // ... old | |
345 | context.ContextType = oldType; // ... values | |
346 | context.AlgorithmType = oldAlgorithm; // ... in context | |
347 | CssmError::throwMe(err); // tell the caller it failed | |
348 | } | |
349 | ||
350 | context.attachment.free(oldAttributes); | |
351 | END_API(CSSM) | |
352 | } | |
353 | ||
354 | ||
355 | CSSM_RETURN CSSMAPI | |
356 | CSSM_DeleteContext (CSSM_CC_HANDLE CCHandle) | |
357 | { | |
358 | BEGIN_API | |
359 | HandleContext &context = enterContext(CCHandle); | |
360 | StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit> | |
361 | _(context.attachment, true); | |
362 | ||
363 | // ignore error return from CSP event notify (can't decline deletion) | |
364 | context.validateChange(CSSM_CONTEXT_EVENT_DELETE); | |
365 | ||
366 | context.destroy(&context, context.attachment); | |
367 | END_API(CSSM) | |
368 | } | |
369 | ||
370 | ||
371 | // | |
372 | // The GetContextAttribute API is fatally flawed. The standard implies a deep | |
373 | // copy of the attribute value, but no release function exists. Instead, we | |
374 | // return a shallow copy (sharing structure) which you need not release, but | |
375 | // which becomes invalid when the source Context is destroyed. | |
376 | // | |
377 | CSSM_RETURN CSSMAPI | |
378 | CSSM_GetContextAttribute (const CSSM_CONTEXT *Context, | |
379 | uint32 AttributeType, | |
380 | CSSM_CONTEXT_ATTRIBUTE_PTR *ContextAttribute) | |
381 | { | |
382 | BEGIN_API | |
383 | CSSM_ATTRIBUTE_TYPE type = CSSM_ATTRIBUTE_TYPE(AttributeType); // CDSA defect | |
384 | Required(ContextAttribute) = Context::required(Context).find(type); | |
385 | END_API(CSSM) | |
386 | } | |
387 | ||
388 | ||
389 | CSSM_RETURN CSSMAPI | |
390 | CSSM_UpdateContextAttributes (CSSM_CC_HANDLE CCHandle, | |
391 | uint32 NumberAttributes, | |
392 | const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes) | |
393 | { | |
394 | BEGIN_API | |
427c49bc A |
395 | #warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE |
396 | HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE); | |
b1ab9ed8 A |
397 | context.mergeAttributes(ContextAttributes, NumberAttributes); |
398 | END_API(CSSM) | |
399 | } | |
400 | ||
401 | ||
402 | CSSM_RETURN CSSMAPI | |
403 | CSSM_DeleteContextAttributes (CSSM_CC_HANDLE CCHandle, | |
404 | uint32 NumberOfAttributes, | |
405 | const CSSM_CONTEXT_ATTRIBUTE *ContextAttributes) | |
406 | { | |
407 | BEGIN_API | |
408 | if (NumberOfAttributes == 0) | |
409 | return CSSM_OK; // I suppose | |
410 | Required(ContextAttributes); // preflight | |
427c49bc A |
411 | #warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE |
412 | HandleContext &context = HandleObject::find<HandleContext>((CSSM_HANDLE)CCHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE); | |
b1ab9ed8 A |
413 | for (uint32 n = 0; n < NumberOfAttributes; n++) |
414 | context.deleteAttribute(ContextAttributes[n].AttributeType); | |
415 | END_API(CSSM) | |
416 | } | |
417 | ||
418 | ||
419 | // | |
420 | // Miscellaneous odds and ends - these functions just need a wee bit of | |
421 | // manual massaging to fit. | |
422 | // | |
423 | CSSM_RETURN CSSMAPI | |
424 | CSSM_DigestDataClone (CSSM_CC_HANDLE ccHandle, | |
425 | CSSM_CC_HANDLE *newCCHandle) | |
426 | { | |
427 | BEGIN_API | |
427c49bc A |
428 | #warning Cast from CSSM_CC_HANDLE to CSSM_HANDLE |
429 | HandleContext &context = HandleObject::findAndLock<HandleContext>((CSSM_HANDLE)ccHandle, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE); | |
b1ab9ed8 A |
430 | TransitLock _(context.attachment); |
431 | HandleContext *newContext = | |
432 | new(context.attachment) HandleContext(context.attachment, context.type(), context.algorithm()); | |
433 | try { | |
434 | newContext->CSPHandle = context.attachment.handle(); | |
435 | newContext->copyFrom(context, context.attachment); | |
436 | context.attachment.downcalls.DigestDataClone(context.attachment.handle(), ccHandle, newContext->handle()); | |
437 | Required(newCCHandle) = newContext->handle(); | |
438 | } catch (...) { | |
439 | newContext->destroy(newContext, context.attachment); | |
440 | throw; | |
441 | } | |
442 | END_API(CSSM) | |
443 | } | |
444 | ||
445 | ||
446 | CSSM_RETURN CSSMAPI | |
447 | CSSM_QueryKeySizeInBits (CSSM_CSP_HANDLE CSPHandle, | |
448 | CSSM_CC_HANDLE ccHandle, | |
449 | const CSSM_KEY *key, | |
450 | CSSM_KEY_SIZE_PTR keySize) | |
451 | { | |
452 | //@@@ could afford not to lock attachment in have-CC case | |
453 | BEGIN_API | |
454 | Required(keySize); | |
455 | Context *context; | |
456 | CSPAttachment *attachment; | |
457 | if (ccHandle == (CSSM_CC_HANDLE) HandleObject::invalidHandle) { | |
458 | // key specified by CSPHandle and Key | |
459 | attachment = &enterAttachment<CSPAttachment>(CSPHandle); | |
460 | context = NULL; | |
461 | } else { | |
462 | // key specified by ccHandle | |
463 | HandleContext *ctx = &enterContext(ccHandle); | |
464 | try { | |
465 | attachment = &ctx->attachment; | |
466 | context = ctx; | |
467 | CSPHandle = context->CSPHandle; | |
468 | key = &context->get<CssmKey>(CSSM_ATTRIBUTE_KEY, | |
469 | CSSMERR_CSP_INVALID_KEY); | |
470 | } catch (...) { | |
471 | attachment->exit(); | |
472 | throw; | |
473 | } | |
474 | } | |
475 | TransitLock _(*attachment); | |
476 | CSSM_RETURN result = attachment->downcalls.QueryKeySizeInBits(CSPHandle, | |
477 | ccHandle, context, key, keySize); | |
478 | return result; | |
479 | END_API(CSSM) | |
480 | } | |
481 | ||
482 | ||
483 | CSSM_RETURN CSSMAPI | |
484 | CSSM_GenerateAlgorithmParams (CSSM_CC_HANDLE CCHandle, | |
485 | uint32 ParamBits, | |
486 | CSSM_DATA_PTR Param) | |
487 | { | |
488 | BEGIN_API | |
489 | // this function has more subtle locking than usual. Pay attention: | |
490 | ||
491 | // (1) Resolve context and ensure attachment exit | |
492 | HandleContext &context = enterContext(CCHandle); | |
493 | StLock<CountingMutex, &CountingMutex::enter, &CountingMutex::exit> _(context.attachment, true); | |
494 | ||
495 | // (2) Call CSP, acquiring module safe-lock for a moment (only) | |
496 | CSSM_CONTEXT_ATTRIBUTE_PTR attributes; | |
497 | uint32 count; | |
498 | { | |
499 | StLock<Module, &Module::safeLock, &Module::safeUnlock> _(context.attachment.module); | |
500 | if (CSSM_RETURN err = | |
501 | context.attachment.downcalls.GenerateAlgorithmParams(context.attachment.handle(), | |
502 | CCHandle, &context, | |
503 | ParamBits, Param, | |
504 | &count, &attributes)) | |
505 | CssmError::throwMe(err); | |
506 | } | |
507 | ||
508 | // (3) Merge the attributes returned into the context, which will (again) acquire the module safe-lock internally | |
509 | if (count) | |
510 | context.mergeAttributes(attributes, count); | |
511 | // the memory at (attributes, count) belongs to the CSP; don't free it here | |
512 | END_API(CSSM) | |
513 | } | |
514 | ||
515 | ||
516 | // | |
517 | // Include the auto-generated functions | |
518 | // | |
519 | #include <derived_src/transition.gen> |