security/nss/lib/dev/ckhelper.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial