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