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