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