| 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 |