NSS_IMPLEMENT nssCryptokiObject * nssToken_FindCertificateByEncodedCertificate ( NSSToken *token, nssSession *sessionOpt, NSSBER *encodedCertificate, nssTokenSearchType searchType, PRStatus *statusOpt ) { CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE cert_template[3]; CK_ULONG ctsize; nssCryptokiObject **objects; nssCryptokiObject *rvObject = NULL; NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); /* Set the search to token/session only if provided */ if (searchType == nssTokenSearchType_SessionOnly) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } else if (searchType == nssTokenSearchType_TokenOnly) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* get the object handle */ objects = find_objects_by_template(token, sessionOpt, cert_template, ctsize, 1, statusOpt); if (objects) { rvObject = objects[0]; nss_ZFreeIf(objects); } return rvObject; }
/* XXX ?there are no session cert objects, so only search token objects */ NSS_IMPLEMENT nssCryptokiObject * nssToken_FindPublicKeyByID ( NSSToken *token, nssSession *sessionOpt, NSSItem *keyID ) { CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE key_template[3]; CK_ULONG ktsize; nssCryptokiObject **objects; nssCryptokiObject *rvKey = NULL; NSS_CK_TEMPLATE_START(key_template, attr, ktsize); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); objects = find_objects_by_template(token, sessionOpt, key_template, ktsize, 1, NULL); if (objects) { rvKey = objects[0]; nss_ZFreeIf(objects); } return rvKey; }
NSS_IMPLEMENT PRStatus nssCryptokiPrivateKey_SetCertificate ( nssCryptokiObject *keyObject, nssSession *sessionOpt, const NSSUTF8 *nickname, NSSItem *id, NSSDER *subject ) { CK_RV ckrv; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE key_template[3]; CK_ULONG key_size; void *epv = nssToken_GetCryptokiEPV(keyObject->token); nssSession *session; NSSToken *token = keyObject->token; nssSession *defaultSession = nssToken_GetDefaultSession(token); PRBool createdSession = PR_FALSE; NSS_CK_TEMPLATE_START(key_template, attr, key_size); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size); if (sessionOpt) { if (!nssSession_IsReadWrite(sessionOpt)) { return PR_FAILURE; } session = sessionOpt; } else if (defaultSession && nssSession_IsReadWrite(defaultSession)) { session = defaultSession; } else { NSSSlot *slot = nssToken_GetSlot(token); session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); nssSlot_Destroy(slot); if (!session) { return PR_FAILURE; } createdSession = PR_TRUE; } ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, keyObject->handle, key_template, key_size); if (createdSession) { nssSession_Destroy(session); } return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_FindTrustForCertificate ( NSSToken *token, nssSession *sessionOpt, NSSDER *certEncoding, NSSDER *certIssuer, NSSDER *certSerial, nssTokenSearchType searchType ) { CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE tobj_template[5]; CK_ULONG tobj_size; nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; nssCryptokiObject *object = NULL, **objects; /* Don't ask the module to use an invalid session handle. */ if (!session || session->handle == CK_INVALID_SESSION) { PORT_SetError(SEC_ERROR_NO_TOKEN); return object; } NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); if (searchType == nssTokenSearchType_TokenOnly) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , certSerial); NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); objects = find_objects_by_template(token, session, tobj_template, tobj_size, 1, NULL); if (objects) { object = objects[0]; nss_ZFreeIf(objects); } return object; }
NSS_IMPLEMENT NSSPublicKey * NSSCertificate_GetPublicKey ( NSSCertificate *c ) { #if 0 CK_ATTRIBUTE pubktemplate[] = { { CKA_CLASS, NULL, 0 }, { CKA_ID, NULL, 0 }, { CKA_SUBJECT, NULL, 0 } }; PRStatus nssrv; CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]); NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey); if (c->id.size > 0) { /* CKA_ID */ NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]); } else { /* failure, yes? */ return (NSSPublicKey *)NULL; } if (c->subject.size > 0) { /* CKA_SUBJECT */ NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]); } else { /* failure, yes? */ return (NSSPublicKey *)NULL; } /* Try the cert's token first */ if (c->token) { nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count); } #endif /* Try all other key tokens */ return (NSSPublicKey *)NULL; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportCRL ( NSSToken *token, nssSession *sessionOpt, NSSDER *subject, NSSDER *encoding, PRBool isKRL, NSSUTF8 *url, PRBool asTokenObject ) { nssCryptokiObject *object; CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE crl_tmpl[6]; CK_ULONG crlsize; NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize); if (asTokenObject) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url); if (isKRL) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false); } NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize); /* import the crl object onto the token */ object = import_object(token, sessionOpt, crl_tmpl, crlsize); if (object && token->cache) { nssTokenObjectCache_ImportObject(token->cache, object, crlobjc, crl_tmpl, crlsize); } return object; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_FindCertificateByIssuerAndSerialNumber ( NSSToken *token, nssSession *sessionOpt, NSSDER *issuer, NSSDER *serial, nssTokenSearchType searchType, PRStatus *statusOpt ) { CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE_PTR serialAttr; CK_ATTRIBUTE cert_template[4]; CK_ULONG ctsize; nssCryptokiObject **objects; nssCryptokiObject *rvObject = NULL; NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); if (!token) { PORT_SetError(SEC_ERROR_NO_TOKEN); if (statusOpt) *statusOpt = PR_FAILURE; return NULL; } /* Set the search to token/session only if provided */ if (searchType == nssTokenSearchType_SessionOnly) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } else if ((searchType == nssTokenSearchType_TokenOnly) || (searchType == nssTokenSearchType_TokenForced)) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } /* Set the unique id */ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); serialAttr = attr; NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* get the object handle */ if (searchType == nssTokenSearchType_TokenForced) { objects = find_objects(token, sessionOpt, cert_template, ctsize, 1, statusOpt); } else { objects = find_objects_by_template(token, sessionOpt, cert_template, ctsize, 1, statusOpt); } if (objects) { rvObject = objects[0]; nss_ZFreeIf(objects); } /* * NSS used to incorrectly store serial numbers in their decoded form. * because of this old tokens have decoded serial numbers. */ if (!objects) { NSSItem serialDecode; PRStatus status; status = nssToken_decodeSerialItem(serial, &serialDecode); if (status != PR_SUCCESS) { return NULL; } NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr,CKA_SERIAL_NUMBER,&serialDecode); if (searchType == nssTokenSearchType_TokenForced) { objects = find_objects(token, sessionOpt, cert_template, ctsize, 1, statusOpt); } else { objects = find_objects_by_template(token, sessionOpt, cert_template, ctsize, 1, statusOpt); } if (objects) { rvObject = objects[0]; nss_ZFreeIf(objects); } } return rvObject; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportCertificate ( NSSToken *tok, nssSession *sessionOpt, NSSCertificateType certType, NSSItem *id, const NSSUTF8 *nickname, NSSDER *encoding, NSSDER *issuer, NSSDER *subject, NSSDER *serial, NSSASCII7 *email, PRBool asTokenObject ) { PRStatus status; CK_CERTIFICATE_TYPE cert_type; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE cert_tmpl[10]; CK_ULONG ctsize; nssTokenSearchType searchType; nssCryptokiObject *rvObject = NULL; if (!tok) { PORT_SetError(SEC_ERROR_NO_TOKEN); return NULL; } if (certType == NSSCertificateType_PKIX) { cert_type = CKC_X_509; } else { return (nssCryptokiObject *)NULL; } NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); if (asTokenObject) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); searchType = nssTokenSearchType_TokenOnly; } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); searchType = nssTokenSearchType_SessionOnly; } NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); if (email) { NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); } NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); /* see if the cert is already there */ rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok, sessionOpt, issuer, serial, searchType, NULL); if (rvObject) { NSSItem existingDER; NSSSlot *slot = nssToken_GetSlot(tok); nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE); if (!session) { nssCryptokiObject_Destroy(rvObject); nssSlot_Destroy(slot); return (nssCryptokiObject *)NULL; } /* Reject any attempt to import a new cert that has the same * issuer/serial as an existing cert, but does not have the * same encoding */ NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); status = nssCKObject_GetAttributes(rvObject->handle, cert_tmpl, ctsize, NULL, session, slot); NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); if (status == PR_SUCCESS) { if (!nssItem_Equal(encoding, &existingDER, NULL)) { nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); status = PR_FAILURE; } nss_ZFreeIf(existingDER.data); } if (status == PR_FAILURE) { nssCryptokiObject_Destroy(rvObject); nssSession_Destroy(session); nssSlot_Destroy(slot); return (nssCryptokiObject *)NULL; } /* according to PKCS#11, label, ID, issuer, and serial number * may change after the object has been created. For PKIX, the * last two attributes can't change, so for now we'll only worry * about the first two. */ NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); /* reset the mutable attributes on the token */ nssCKObject_SetAttributes(rvObject->handle, cert_tmpl, ctsize, session, slot); if (!rvObject->label && nickname) { rvObject->label = nssUTF8_Duplicate(nickname, NULL); } nssSession_Destroy(session); nssSlot_Destroy(slot); } else { /* Import the certificate onto the token */ rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize); } if (rvObject && tok->cache) { /* The cache will overwrite the attributes if the object already * exists. */ nssTokenObjectCache_ImportObject(tok->cache, rvObject, CKO_CERTIFICATE, cert_tmpl, ctsize); } return rvObject; }
/* Sigh. The methods to find objects declared above cause problems with * the low-level object cache in the softoken -- the objects are found in * toto, then one wave of GetAttributes is done, then another. Having a * large number of objects causes the cache to be thrashed, as the objects * are gone before there's any chance to ask for their attributes. * So, for now, bringing back traversal methods for certs. This way all of * the cert's attributes can be grabbed immediately after finding it, * increasing the likelihood that the cache takes care of it. */ NSS_IMPLEMENT PRStatus nssToken_TraverseCertificates ( NSSToken *token, nssSession *sessionOpt, nssTokenSearchType searchType, PRStatus (* callback)(nssCryptokiObject *instance, void *arg), void *arg ) { CK_RV ckrv; CK_ULONG count; CK_OBJECT_HANDLE *objectHandles; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE cert_template[2]; CK_ULONG ctsize; NSSArena *arena; PRStatus status; PRUint32 arraySize, numHandles; nssCryptokiObject **objects; void *epv = nssToken_GetCryptokiEPV(token); nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession; /* Don't ask the module to use an invalid session handle. */ if (!session || session->handle == CK_INVALID_SESSION) { PORT_SetError(SEC_ERROR_NO_TOKEN); return PR_FAILURE; } /* template for all certs */ NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); if (searchType == nssTokenSearchType_SessionOnly) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } else if (searchType == nssTokenSearchType_TokenOnly || searchType == nssTokenSearchType_TokenForced) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* the arena is only for the array of object handles */ arena = nssArena_Create(); if (!arena) { return PR_FAILURE; } arraySize = OBJECT_STACK_SIZE; numHandles = 0; objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize); if (!objectHandles) { goto loser; } nssSession_EnterMonitor(session); /* ==== session lock === */ /* Initialize the find with the template */ ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, cert_template, ctsize); if (ckrv != CKR_OK) { nssSession_ExitMonitor(session); goto loser; } while (PR_TRUE) { /* Issue the find for up to arraySize - numHandles objects */ ckrv = CKAPI(epv)->C_FindObjects(session->handle, objectHandles + numHandles, arraySize - numHandles, &count); if (ckrv != CKR_OK) { nssSession_ExitMonitor(session); goto loser; } /* bump the number of found objects */ numHandles += count; if (numHandles < arraySize) { break; } /* the array is filled, double it and continue */ arraySize *= 2; objectHandles = nss_ZREALLOCARRAY(objectHandles, CK_OBJECT_HANDLE, arraySize); if (!objectHandles) { nssSession_ExitMonitor(session); goto loser; } } ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); nssSession_ExitMonitor(session); /* ==== end session lock === */ if (ckrv != CKR_OK) { goto loser; } if (numHandles > 0) { objects = create_objects_from_handles(token, session, objectHandles, numHandles); if (objects) { nssCryptokiObject **op; for (op = objects; *op; op++) { status = (*callback)(*op, arg); } nss_ZFreeIf(objects); } } nssArena_Destroy(arena); return PR_SUCCESS; loser: nssArena_Destroy(arena); return PR_FAILURE; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportTrust ( NSSToken *tok, nssSession *sessionOpt, NSSDER *certEncoding, NSSDER *certIssuer, NSSDER *certSerial, nssTrustLevel serverAuth, nssTrustLevel clientAuth, nssTrustLevel codeSigning, nssTrustLevel emailProtection, PRBool stepUpApproved, PRBool asTokenObject ) { nssCryptokiObject *object; CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; CK_TRUST ckSA, ckCA, ckCS, ckEP; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE trust_tmpl[11]; CK_ULONG tsize; PRUint8 sha1[20]; /* this is cheating... */ PRUint8 md5[16]; NSSItem sha1_result, md5_result; sha1_result.data = sha1; sha1_result.size = sizeof sha1; md5_result.data = md5; md5_result.size = sizeof md5; sha1_hash(certEncoding, &sha1_result); md5_hash(certEncoding, &md5_result); ckSA = get_ck_trust(serverAuth); ckCA = get_ck_trust(clientAuth); ckCS = get_ck_trust(codeSigning); ckEP = get_ck_trust(emailProtection); NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize); if (asTokenObject) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result); /* now set the trust values */ NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP); if (stepUpApproved) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, &g_ck_false); } NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); /* import the trust object onto the token */ object = import_object(tok, sessionOpt, trust_tmpl, tsize); if (object && tok->cache) { nssTokenObjectCache_ImportObject(tok->cache, object, tobjc, trust_tmpl, tsize); } return object; }
NSS_IMPLEMENT PRStatus nssCryptokiTrust_GetAttributes( nssCryptokiObject *trustObject, nssSession *sessionOpt, NSSItem *sha1_hash, nssTrustLevel *serverAuth, nssTrustLevel *clientAuth, nssTrustLevel *codeSigning, nssTrustLevel *emailProtection, PRBool *stepUpApproved) { PRStatus status; NSSSlot *slot; nssSession *session; CK_BBOOL isToken = PR_FALSE; CK_BBOOL stepUp = PR_FALSE; CK_TRUST saTrust = CKT_NSS_TRUST_UNKNOWN; CK_TRUST caTrust = CKT_NSS_TRUST_UNKNOWN; CK_TRUST epTrust = CKT_NSS_TRUST_UNKNOWN; CK_TRUST csTrust = CKT_NSS_TRUST_UNKNOWN; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE trust_template[7]; CK_ATTRIBUTE_PTR sha1_hash_attr; CK_ULONG trust_size; /* Use the trust object to find the trust settings */ NSS_CK_TEMPLATE_START(trust_template, attr, trust_size); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp); sha1_hash_attr = attr; NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, sha1_hash); NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL, trustObject, CKO_NSS_TRUST, trust_template, trust_size); if (status != PR_SUCCESS) { session = sessionOpt ? sessionOpt : nssToken_GetDefaultSession(trustObject->token); if (!session) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FAILURE; } slot = nssToken_GetSlot(trustObject->token); status = nssCKObject_GetAttributes(trustObject->handle, trust_template, trust_size, NULL, session, slot); nssSlot_Destroy(slot); if (status != PR_SUCCESS) { return status; } } if (sha1_hash_attr->ulValueLen == -1) { /* The trust object does not have the CKA_CERT_SHA1_HASH attribute. */ sha1_hash_attr->ulValueLen = 0; } sha1_hash->size = sha1_hash_attr->ulValueLen; *serverAuth = get_nss_trust(saTrust); *clientAuth = get_nss_trust(caTrust); *emailProtection = get_nss_trust(epTrust); *codeSigning = get_nss_trust(csTrust); *stepUpApproved = stepUp; return PR_SUCCESS; }