security/nss/lib/dev/ckhelper.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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/. */
     5 #include "pkcs11.h"
     7 #ifndef DEVM_H
     8 #include "devm.h"
     9 #endif /* DEVM_H */
    11 #ifndef CKHELPER_H
    12 #include "ckhelper.h"
    13 #endif /* CKHELPER_H */
    15 extern const NSSError NSS_ERROR_DEVICE_ERROR;
    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) };
    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) };
    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) };
    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) };
    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) };
    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 }
    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     }
   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 }
   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 }
   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 }
   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 }
   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 }
   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 }
   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     }
   316     status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
   317                                                 certObject, CKO_CERTIFICATE,
   318                                                 cert_template, template_size);
   319     if (status != PR_SUCCESS) {
   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 	}
   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     }
   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 }
   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 }
   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;
   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);
   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 	}
   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     }
   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 }
   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;
   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);
   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 	}
   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     }
   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 }
   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;
   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);
   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     }
   577     ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle,
   578                                            keyObject->handle,
   579                                            key_template,
   580                                            key_size);
   582     if (createdSession) {
   583 	nssSession_Destroy(session);
   584     }
   586     return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
   587 }

mercurial