OLD | NEW |
| (Empty) |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 #include "pkcs11.h" | |
6 | |
7 #ifndef DEVM_H | |
8 #include "devm.h" | |
9 #endif /* DEVM_H */ | |
10 | |
11 #ifndef CKHELPER_H | |
12 #include "ckhelper.h" | |
13 #endif /* CKHELPER_H */ | |
14 | |
15 extern const NSSError NSS_ERROR_DEVICE_ERROR; | |
16 | |
17 static const CK_BBOOL s_true = CK_TRUE; | |
18 NSS_IMPLEMENT_DATA const NSSItem | |
19 g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) }; | |
20 | |
21 static const CK_BBOOL s_false = CK_FALSE; | |
22 NSS_IMPLEMENT_DATA const NSSItem | |
23 g_ck_false = { (CK_VOID_PTR)&s_false, sizeof(s_false) }; | |
24 | |
25 static const CK_OBJECT_CLASS s_class_cert = CKO_CERTIFICATE; | |
26 NSS_IMPLEMENT_DATA const NSSItem | |
27 g_ck_class_cert = { (CK_VOID_PTR)&s_class_cert, sizeof(s_class_cert) }; | |
28 | |
29 static const CK_OBJECT_CLASS s_class_pubkey = CKO_PUBLIC_KEY; | |
30 NSS_IMPLEMENT_DATA const NSSItem | |
31 g_ck_class_pubkey = { (CK_VOID_PTR)&s_class_pubkey, sizeof(s_class_pubkey) }
; | |
32 | |
33 static const CK_OBJECT_CLASS s_class_privkey = CKO_PRIVATE_KEY; | |
34 NSS_IMPLEMENT_DATA const NSSItem | |
35 g_ck_class_privkey = { (CK_VOID_PTR)&s_class_privkey, sizeof(s_class_privkey
) }; | |
36 | |
37 static PRBool | |
38 is_string_attribute( | |
39 CK_ATTRIBUTE_TYPE aType) | |
40 { | |
41 PRBool isString; | |
42 switch (aType) { | |
43 case CKA_LABEL: | |
44 case CKA_NSS_EMAIL: | |
45 isString = PR_TRUE; | |
46 break; | |
47 default: | |
48 isString = PR_FALSE; | |
49 break; | |
50 } | |
51 return isString; | |
52 } | |
53 | |
54 NSS_IMPLEMENT PRStatus | |
55 nssCKObject_GetAttributes( | |
56 CK_OBJECT_HANDLE object, | |
57 CK_ATTRIBUTE_PTR obj_template, | |
58 CK_ULONG count, | |
59 NSSArena *arenaOpt, | |
60 nssSession *session, | |
61 NSSSlot *slot) | |
62 { | |
63 nssArenaMark *mark = NULL; | |
64 CK_SESSION_HANDLE hSession; | |
65 CK_ULONG i = 0; | |
66 CK_RV ckrv; | |
67 PRStatus nssrv; | |
68 PRBool alloced = PR_FALSE; | |
69 void *epv = nssSlot_GetCryptokiEPV(slot); | |
70 hSession = session->handle; | |
71 if (arenaOpt) { | |
72 mark = nssArena_Mark(arenaOpt); | |
73 if (!mark) { | |
74 goto loser; | |
75 } | |
76 } | |
77 nssSession_EnterMonitor(session); | |
78 /* XXX kinda hacky, if the storage size is already in the first template | |
79 * item, then skip the alloc portion | |
80 */ | |
81 if (obj_template[0].ulValueLen == 0) { | |
82 /* Get the storage size needed for each attribute */ | |
83 ckrv = CKAPI(epv)->C_GetAttributeValue(hSession, | |
84 object, obj_template, count); | |
85 if (ckrv != CKR_OK && | |
86 ckrv != CKR_ATTRIBUTE_TYPE_INVALID && | |
87 ckrv != CKR_ATTRIBUTE_SENSITIVE) { | |
88 nssSession_ExitMonitor(session); | |
89 nss_SetError(NSS_ERROR_DEVICE_ERROR); | |
90 goto loser; | |
91 } | |
92 /* Allocate memory for each attribute. */ | |
93 for (i = 0; i < count; i++) { | |
94 CK_ULONG ulValueLen = obj_template[i].ulValueLen; | |
95 if (ulValueLen == 0 || ulValueLen == (CK_ULONG)-1) { | |
96 obj_template[i].pValue = NULL; | |
97 obj_template[i].ulValueLen = 0; | |
98 continue; | |
99 } | |
100 if (is_string_attribute(obj_template[i].type)) { | |
101 ulValueLen++; | |
102 } | |
103 obj_template[i].pValue = nss_ZAlloc(arenaOpt, ulValueLen); | |
104 if (!obj_template[i].pValue) { | |
105 nssSession_ExitMonitor(session); | |
106 goto loser; | |
107 } | |
108 } | |
109 alloced = PR_TRUE; | |
110 } | |
111 /* Obtain the actual attribute values. */ | |
112 ckrv = CKAPI(epv)->C_GetAttributeValue(hSession, | |
113 object, obj_template, count); | |
114 nssSession_ExitMonitor(session); | |
115 if (ckrv != CKR_OK && | |
116 ckrv != CKR_ATTRIBUTE_TYPE_INVALID && | |
117 ckrv != CKR_ATTRIBUTE_SENSITIVE) { | |
118 nss_SetError(NSS_ERROR_DEVICE_ERROR); | |
119 goto loser; | |
120 } | |
121 if (alloced && arenaOpt) { | |
122 nssrv = nssArena_Unmark(arenaOpt, mark); | |
123 if (nssrv != PR_SUCCESS) { | |
124 goto loser; | |
125 } | |
126 } | |
127 | |
128 if (count > 1 && ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || | |
129 (ckrv == CKR_ATTRIBUTE_SENSITIVE))) { | |
130 /* old tokens would keep the length of '0' and not deal with any | |
131 * of the attributes we passed. For those tokens read them one at | |
132 * a time */ | |
133 for (i = 0; i < count; i++) { | |
134 if ((obj_template[i].ulValueLen == 0) || | |
135 (obj_template[i].ulValueLen == -1)) { | |
136 obj_template[i].ulValueLen = 0; | |
137 (void)nssCKObject_GetAttributes(object, &obj_template[i], 1, | |
138 arenaOpt, session, slot); | |
139 } | |
140 } | |
141 } | |
142 return PR_SUCCESS; | |
143 loser: | |
144 if (alloced) { | |
145 if (arenaOpt) { | |
146 /* release all arena memory allocated before the failure. */ | |
147 (void)nssArena_Release(arenaOpt, mark); | |
148 } else { | |
149 CK_ULONG j; | |
150 /* free each heap object that was allocated before the failure. */ | |
151 for (j = 0; j < i; j++) { | |
152 nss_ZFreeIf(obj_template[j].pValue); | |
153 } | |
154 } | |
155 } | |
156 return PR_FAILURE; | |
157 } | |
158 | |
159 NSS_IMPLEMENT PRStatus | |
160 nssCKObject_GetAttributeItem( | |
161 CK_OBJECT_HANDLE object, | |
162 CK_ATTRIBUTE_TYPE attribute, | |
163 NSSArena *arenaOpt, | |
164 nssSession *session, | |
165 NSSSlot *slot, | |
166 NSSItem *rvItem) | |
167 { | |
168 CK_ATTRIBUTE attr = { 0, NULL, 0 }; | |
169 PRStatus nssrv; | |
170 attr.type = attribute; | |
171 nssrv = nssCKObject_GetAttributes(object, &attr, 1, | |
172 arenaOpt, session, slot); | |
173 if (nssrv != PR_SUCCESS) { | |
174 return nssrv; | |
175 } | |
176 rvItem->data = (void *)attr.pValue; | |
177 rvItem->size = (PRUint32)attr.ulValueLen; | |
178 return PR_SUCCESS; | |
179 } | |
180 | |
181 NSS_IMPLEMENT PRBool | |
182 nssCKObject_IsAttributeTrue( | |
183 CK_OBJECT_HANDLE object, | |
184 CK_ATTRIBUTE_TYPE attribute, | |
185 nssSession *session, | |
186 NSSSlot *slot, | |
187 PRStatus *rvStatus) | |
188 { | |
189 CK_BBOOL bool; | |
190 CK_ATTRIBUTE_PTR attr; | |
191 CK_ATTRIBUTE atemplate = { 0, NULL, 0 }; | |
192 CK_RV ckrv; | |
193 void *epv = nssSlot_GetCryptokiEPV(slot); | |
194 attr = &atemplate; | |
195 NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool); | |
196 nssSession_EnterMonitor(session); | |
197 ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object, | |
198 &atemplate, 1); | |
199 nssSession_ExitMonitor(session); | |
200 if (ckrv != CKR_OK) { | |
201 *rvStatus = PR_FAILURE; | |
202 return PR_FALSE; | |
203 } | |
204 *rvStatus = PR_SUCCESS; | |
205 return (PRBool)(bool == CK_TRUE); | |
206 } | |
207 | |
208 NSS_IMPLEMENT PRStatus | |
209 nssCKObject_SetAttributes( | |
210 CK_OBJECT_HANDLE object, | |
211 CK_ATTRIBUTE_PTR obj_template, | |
212 CK_ULONG count, | |
213 nssSession *session, | |
214 NSSSlot *slot) | |
215 { | |
216 CK_RV ckrv; | |
217 void *epv = nssSlot_GetCryptokiEPV(slot); | |
218 nssSession_EnterMonitor(session); | |
219 ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object, | |
220 obj_template, count); | |
221 nssSession_ExitMonitor(session); | |
222 if (ckrv == CKR_OK) { | |
223 return PR_SUCCESS; | |
224 } else { | |
225 return PR_FAILURE; | |
226 } | |
227 } | |
228 | |
229 NSS_IMPLEMENT PRBool | |
230 nssCKObject_IsTokenObjectTemplate( | |
231 CK_ATTRIBUTE_PTR objectTemplate, | |
232 CK_ULONG otsize) | |
233 { | |
234 CK_ULONG ul; | |
235 for (ul = 0; ul < otsize; ul++) { | |
236 if (objectTemplate[ul].type == CKA_TOKEN) { | |
237 return (*((CK_BBOOL *)objectTemplate[ul].pValue) == CK_TRUE); | |
238 } | |
239 } | |
240 return PR_FALSE; | |
241 } | |
242 | |
243 static NSSCertificateType | |
244 nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) | |
245 { | |
246 CK_CERTIFICATE_TYPE ckCertType; | |
247 if (!attrib->pValue) { | |
248 /* default to PKIX */ | |
249 return NSSCertificateType_PKIX; | |
250 } | |
251 ckCertType = *((CK_ULONG *)attrib->pValue); | |
252 switch (ckCertType) { | |
253 case CKC_X_509: | |
254 return NSSCertificateType_PKIX; | |
255 default: | |
256 break; | |
257 } | |
258 return NSSCertificateType_Unknown; | |
259 } | |
260 | |
261 /* incoming pointers must be valid */ | |
262 NSS_IMPLEMENT PRStatus | |
263 nssCryptokiCertificate_GetAttributes( | |
264 nssCryptokiObject *certObject, | |
265 nssSession *sessionOpt, | |
266 NSSArena *arenaOpt, | |
267 NSSCertificateType *certTypeOpt, | |
268 NSSItem *idOpt, | |
269 NSSDER *encodingOpt, | |
270 NSSDER *issuerOpt, | |
271 NSSDER *serialOpt, | |
272 NSSDER *subjectOpt) | |
273 { | |
274 PRStatus status; | |
275 PRUint32 i; | |
276 nssSession *session; | |
277 NSSSlot *slot; | |
278 CK_ULONG template_size; | |
279 CK_ATTRIBUTE_PTR attr; | |
280 CK_ATTRIBUTE cert_template[6]; | |
281 /* Set up a template of all options chosen by caller */ | |
282 NSS_CK_TEMPLATE_START(cert_template, attr, template_size); | |
283 if (certTypeOpt) { | |
284 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE); | |
285 } | |
286 if (idOpt) { | |
287 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID); | |
288 } | |
289 if (encodingOpt) { | |
290 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); | |
291 } | |
292 if (issuerOpt) { | |
293 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER); | |
294 } | |
295 if (serialOpt) { | |
296 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER); | |
297 } | |
298 if (subjectOpt) { | |
299 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT); | |
300 } | |
301 NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size); | |
302 if (template_size == 0) { | |
303 /* caller didn't want anything */ | |
304 return PR_SUCCESS; | |
305 } | |
306 | |
307 status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt, | |
308 certObject, CKO_CERTIFICATE, | |
309 cert_template, template_size); | |
310 if (status != PR_SUCCESS) { | |
311 | |
312 session = sessionOpt ? sessionOpt | |
313 : nssToken_GetDefaultSession(certObject->token); | |
314 if (!session) { | |
315 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); | |
316 return PR_FAILURE; | |
317 } | |
318 | |
319 slot = nssToken_GetSlot(certObject->token); | |
320 status = nssCKObject_GetAttributes(certObject->handle, | |
321 cert_template, template_size, | |
322 arenaOpt, session, slot); | |
323 nssSlot_Destroy(slot); | |
324 if (status != PR_SUCCESS) { | |
325 return status; | |
326 } | |
327 } | |
328 | |
329 i = 0; | |
330 if (certTypeOpt) { | |
331 *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); | |
332 i++; | |
333 } | |
334 if (idOpt) { | |
335 NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); | |
336 i++; | |
337 } | |
338 if (encodingOpt) { | |
339 NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); | |
340 i++; | |
341 } | |
342 if (issuerOpt) { | |
343 NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); | |
344 i++; | |
345 } | |
346 if (serialOpt) { | |
347 NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); | |
348 i++; | |
349 } | |
350 if (subjectOpt) { | |
351 NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); | |
352 i++; | |
353 } | |
354 return PR_SUCCESS; | |
355 } | |
356 | |
357 static nssTrustLevel | |
358 get_nss_trust( | |
359 CK_TRUST ckt) | |
360 { | |
361 nssTrustLevel t; | |
362 switch (ckt) { | |
363 case CKT_NSS_NOT_TRUSTED: | |
364 t = nssTrustLevel_NotTrusted; | |
365 break; | |
366 case CKT_NSS_TRUSTED_DELEGATOR: | |
367 t = nssTrustLevel_TrustedDelegator; | |
368 break; | |
369 case CKT_NSS_VALID_DELEGATOR: | |
370 t = nssTrustLevel_ValidDelegator; | |
371 break; | |
372 case CKT_NSS_TRUSTED: | |
373 t = nssTrustLevel_Trusted; | |
374 break; | |
375 case CKT_NSS_MUST_VERIFY_TRUST: | |
376 t = nssTrustLevel_MustVerify; | |
377 break; | |
378 case CKT_NSS_TRUST_UNKNOWN: | |
379 default: | |
380 t = nssTrustLevel_Unknown; | |
381 break; | |
382 } | |
383 return t; | |
384 } | |
385 | |
386 NSS_IMPLEMENT PRStatus | |
387 nssCryptokiTrust_GetAttributes( | |
388 nssCryptokiObject *trustObject, | |
389 nssSession *sessionOpt, | |
390 NSSItem *sha1_hash, | |
391 nssTrustLevel *serverAuth, | |
392 nssTrustLevel *clientAuth, | |
393 nssTrustLevel *codeSigning, | |
394 nssTrustLevel *emailProtection, | |
395 PRBool *stepUpApproved) | |
396 { | |
397 PRStatus status; | |
398 NSSSlot *slot; | |
399 nssSession *session; | |
400 CK_BBOOL isToken = PR_FALSE; | |
401 CK_BBOOL stepUp = PR_FALSE; | |
402 CK_TRUST saTrust = CKT_NSS_TRUST_UNKNOWN; | |
403 CK_TRUST caTrust = CKT_NSS_TRUST_UNKNOWN; | |
404 CK_TRUST epTrust = CKT_NSS_TRUST_UNKNOWN; | |
405 CK_TRUST csTrust = CKT_NSS_TRUST_UNKNOWN; | |
406 CK_ATTRIBUTE_PTR attr; | |
407 CK_ATTRIBUTE trust_template[7]; | |
408 CK_ATTRIBUTE_PTR sha1_hash_attr; | |
409 CK_ULONG trust_size; | |
410 | |
411 /* Use the trust object to find the trust settings */ | |
412 NSS_CK_TEMPLATE_START(trust_template, attr, trust_size); | |
413 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken); | |
414 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust); | |
415 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust); | |
416 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust); | |
417 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); | |
418 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp); | |
419 sha1_hash_attr = attr; | |
420 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, sha1_hash); | |
421 NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); | |
422 | |
423 status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL, | |
424 trustObject, | |
425 CKO_NSS_TRUST, | |
426 trust_template, trust_size); | |
427 if (status != PR_SUCCESS) { | |
428 session = sessionOpt ? sessionOpt | |
429 : nssToken_GetDefaultSession(trustObject->token); | |
430 if (!session) { | |
431 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); | |
432 return PR_FAILURE; | |
433 } | |
434 | |
435 slot = nssToken_GetSlot(trustObject->token); | |
436 status = nssCKObject_GetAttributes(trustObject->handle, | |
437 trust_template, trust_size, | |
438 NULL, session, slot); | |
439 nssSlot_Destroy(slot); | |
440 if (status != PR_SUCCESS) { | |
441 return status; | |
442 } | |
443 } | |
444 | |
445 if (sha1_hash_attr->ulValueLen == -1) { | |
446 /* The trust object does not have the CKA_CERT_SHA1_HASH attribute. */ | |
447 sha1_hash_attr->ulValueLen = 0; | |
448 } | |
449 sha1_hash->size = sha1_hash_attr->ulValueLen; | |
450 *serverAuth = get_nss_trust(saTrust); | |
451 *clientAuth = get_nss_trust(caTrust); | |
452 *emailProtection = get_nss_trust(epTrust); | |
453 *codeSigning = get_nss_trust(csTrust); | |
454 *stepUpApproved = stepUp; | |
455 return PR_SUCCESS; | |
456 } | |
457 | |
458 NSS_IMPLEMENT PRStatus | |
459 nssCryptokiCRL_GetAttributes( | |
460 nssCryptokiObject *crlObject, | |
461 nssSession *sessionOpt, | |
462 NSSArena *arenaOpt, | |
463 NSSItem *encodingOpt, | |
464 NSSItem *subjectOpt, | |
465 CK_ULONG *crl_class, | |
466 NSSUTF8 **urlOpt, | |
467 PRBool *isKRLOpt) | |
468 { | |
469 PRStatus status; | |
470 NSSSlot *slot; | |
471 nssSession *session; | |
472 CK_ATTRIBUTE_PTR attr; | |
473 CK_ATTRIBUTE crl_template[7]; | |
474 CK_ULONG crl_size; | |
475 PRUint32 i; | |
476 | |
477 NSS_CK_TEMPLATE_START(crl_template, attr, crl_size); | |
478 if (crl_class) { | |
479 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS); | |
480 } | |
481 if (encodingOpt) { | |
482 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); | |
483 } | |
484 if (urlOpt) { | |
485 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_URL); | |
486 } | |
487 if (isKRLOpt) { | |
488 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_KRL); | |
489 } | |
490 if (subjectOpt) { | |
491 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT); | |
492 } | |
493 NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size); | |
494 | |
495 status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL, | |
496 crlObject, | |
497 CKO_NSS_CRL, | |
498 crl_template, crl_size); | |
499 if (status != PR_SUCCESS) { | |
500 session = sessionOpt ? sessionOpt | |
501 : nssToken_GetDefaultSession(crlObject->token); | |
502 if (session == NULL) { | |
503 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); | |
504 return PR_FAILURE; | |
505 } | |
506 | |
507 slot = nssToken_GetSlot(crlObject->token); | |
508 status = nssCKObject_GetAttributes(crlObject->handle, | |
509 crl_template, crl_size, | |
510 arenaOpt, session, slot); | |
511 nssSlot_Destroy(slot); | |
512 if (status != PR_SUCCESS) { | |
513 return status; | |
514 } | |
515 } | |
516 | |
517 i = 0; | |
518 if (crl_class) { | |
519 NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class); | |
520 i++; | |
521 } | |
522 if (encodingOpt) { | |
523 NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); | |
524 i++; | |
525 } | |
526 if (urlOpt) { | |
527 NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); | |
528 i++; | |
529 } | |
530 if (isKRLOpt) { | |
531 NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); | |
532 i++; | |
533 } | |
534 if (subjectOpt) { | |
535 NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); | |
536 i++; | |
537 } | |
538 return PR_SUCCESS; | |
539 } | |
540 | |
541 NSS_IMPLEMENT PRStatus | |
542 nssCryptokiPrivateKey_SetCertificate( | |
543 nssCryptokiObject *keyObject, | |
544 nssSession *sessionOpt, | |
545 const NSSUTF8 *nickname, | |
546 NSSItem *id, | |
547 NSSDER *subject) | |
548 { | |
549 CK_RV ckrv; | |
550 CK_ATTRIBUTE_PTR attr; | |
551 CK_ATTRIBUTE key_template[3]; | |
552 CK_ULONG key_size; | |
553 void *epv = nssToken_GetCryptokiEPV(keyObject->token); | |
554 nssSession *session; | |
555 NSSToken *token = keyObject->token; | |
556 nssSession *defaultSession = nssToken_GetDefaultSession(token); | |
557 PRBool createdSession = PR_FALSE; | |
558 | |
559 NSS_CK_TEMPLATE_START(key_template, attr, key_size); | |
560 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); | |
561 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); | |
562 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | |
563 NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size); | |
564 | |
565 if (sessionOpt) { | |
566 if (!nssSession_IsReadWrite(sessionOpt)) { | |
567 return PR_FAILURE; | |
568 } | |
569 session = sessionOpt; | |
570 } else if (defaultSession && nssSession_IsReadWrite(defaultSession)) { | |
571 session = defaultSession; | |
572 } else { | |
573 NSSSlot *slot = nssToken_GetSlot(token); | |
574 session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); | |
575 nssSlot_Destroy(slot); | |
576 if (!session) { | |
577 return PR_FAILURE; | |
578 } | |
579 createdSession = PR_TRUE; | |
580 } | |
581 | |
582 ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, | |
583 keyObject->handle, | |
584 key_template, | |
585 key_size); | |
586 | |
587 if (createdSession) { | |
588 nssSession_Destroy(session); | |
589 } | |
590 | |
591 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; | |
592 } | |
OLD | NEW |