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