Index: mozilla/security/nss/lib/dev/devtoken.c |
=================================================================== |
--- mozilla/security/nss/lib/dev/devtoken.c (revision 191424) |
+++ mozilla/security/nss/lib/dev/devtoken.c (working copy) |
@@ -1,1584 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
- |
-#ifdef DEBUG |
-static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.57 $ $Date: 2012/04/25 14:49:42 $"; |
-#endif /* DEBUG */ |
- |
-#include "pkcs11.h" |
- |
-#ifndef DEVM_H |
-#include "devm.h" |
-#endif /* DEVM_H */ |
- |
-#ifndef CKHELPER_H |
-#include "ckhelper.h" |
-#endif /* CKHELPER_H */ |
- |
-#include "pk11func.h" |
-#include "dev3hack.h" |
-#include "secerr.h" |
- |
-extern const NSSError NSS_ERROR_NOT_FOUND; |
-extern const NSSError NSS_ERROR_INVALID_ARGUMENT; |
-extern const NSSError NSS_ERROR_PKCS11; |
- |
-/* The number of object handles to grab during each call to C_FindObjects */ |
-#define OBJECT_STACK_SIZE 16 |
- |
-NSS_IMPLEMENT PRStatus |
-nssToken_Destroy ( |
- NSSToken *tok |
-) |
-{ |
- if (tok) { |
- if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) { |
- PZ_DestroyLock(tok->base.lock); |
- nssTokenObjectCache_Destroy(tok->cache); |
- /* The token holds the first/last reference to the slot. |
- * When the token is actually destroyed, that ref must go too. |
- */ |
- (void)nssSlot_Destroy(tok->slot); |
- return nssArena_Destroy(tok->base.arena); |
- } |
- } |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT void |
-nssToken_Remove ( |
- NSSToken *tok |
-) |
-{ |
- nssTokenObjectCache_Clear(tok->cache); |
-} |
- |
-NSS_IMPLEMENT void |
-NSSToken_Destroy ( |
- NSSToken *tok |
-) |
-{ |
- (void)nssToken_Destroy(tok); |
-} |
- |
-NSS_IMPLEMENT NSSToken * |
-nssToken_AddRef ( |
- NSSToken *tok |
-) |
-{ |
- PR_ATOMIC_INCREMENT(&tok->base.refCount); |
- return tok; |
-} |
- |
-NSS_IMPLEMENT NSSSlot * |
-nssToken_GetSlot ( |
- NSSToken *tok |
-) |
-{ |
- return nssSlot_AddRef(tok->slot); |
-} |
- |
-NSS_IMPLEMENT void * |
-nssToken_GetCryptokiEPV ( |
- NSSToken *token |
-) |
-{ |
- return nssSlot_GetCryptokiEPV(token->slot); |
-} |
- |
-NSS_IMPLEMENT nssSession * |
-nssToken_GetDefaultSession ( |
- NSSToken *token |
-) |
-{ |
- return token->defaultSession; |
-} |
- |
-NSS_IMPLEMENT NSSUTF8 * |
-nssToken_GetName ( |
- NSSToken *tok |
-) |
-{ |
- if (tok == NULL) { |
- return ""; |
- } |
- if (tok->base.name[0] == 0) { |
- (void) nssSlot_IsTokenPresent(tok->slot); |
- } |
- return tok->base.name; |
-} |
- |
-NSS_IMPLEMENT NSSUTF8 * |
-NSSToken_GetName ( |
- NSSToken *token |
-) |
-{ |
- return nssToken_GetName(token); |
-} |
- |
-NSS_IMPLEMENT PRBool |
-nssToken_IsLoginRequired ( |
- NSSToken *token |
-) |
-{ |
- return (token->ckFlags & CKF_LOGIN_REQUIRED); |
-} |
- |
-NSS_IMPLEMENT PRBool |
-nssToken_NeedsPINInitialization ( |
- NSSToken *token |
-) |
-{ |
- return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED)); |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssToken_DeleteStoredObject ( |
- nssCryptokiObject *instance |
-) |
-{ |
- CK_RV ckrv; |
- PRStatus status; |
- PRBool createdSession = PR_FALSE; |
- NSSToken *token = instance->token; |
- nssSession *session = NULL; |
- void *epv = nssToken_GetCryptokiEPV(instance->token); |
- if (token->cache) { |
- nssTokenObjectCache_RemoveObject(token->cache, instance); |
- } |
- if (instance->isTokenObject) { |
- if (token->defaultSession && |
- nssSession_IsReadWrite(token->defaultSession)) { |
- session = token->defaultSession; |
- } else { |
- session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); |
- createdSession = PR_TRUE; |
- } |
- } |
- if (session == NULL) { |
- return PR_FAILURE; |
- } |
- nssSession_EnterMonitor(session); |
- ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle); |
- nssSession_ExitMonitor(session); |
- if (createdSession) { |
- nssSession_Destroy(session); |
- } |
- status = PR_SUCCESS; |
- if (ckrv != CKR_OK) { |
- status = PR_FAILURE; |
- /* use the error stack to pass the PKCS #11 error out */ |
- nss_SetError(ckrv); |
- nss_SetError(NSS_ERROR_PKCS11); |
- } |
- return status; |
-} |
- |
-static nssCryptokiObject * |
-import_object ( |
- NSSToken *tok, |
- nssSession *sessionOpt, |
- CK_ATTRIBUTE_PTR objectTemplate, |
- CK_ULONG otsize |
-) |
-{ |
- nssSession *session = NULL; |
- PRBool createdSession = PR_FALSE; |
- nssCryptokiObject *object = NULL; |
- CK_OBJECT_HANDLE handle; |
- CK_RV ckrv; |
- void *epv = nssToken_GetCryptokiEPV(tok); |
- if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) { |
- if (sessionOpt) { |
- if (!nssSession_IsReadWrite(sessionOpt)) { |
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
- return NULL; |
- } |
- session = sessionOpt; |
- } else if (tok->defaultSession && |
- nssSession_IsReadWrite(tok->defaultSession)) { |
- session = tok->defaultSession; |
- } else { |
- session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE); |
- createdSession = PR_TRUE; |
- } |
- } else { |
- session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
- } |
- if (session == NULL) { |
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
- return NULL; |
- } |
- nssSession_EnterMonitor(session); |
- ckrv = CKAPI(epv)->C_CreateObject(session->handle, |
- objectTemplate, otsize, |
- &handle); |
- nssSession_ExitMonitor(session); |
- if (ckrv == CKR_OK) { |
- object = nssCryptokiObject_Create(tok, session, handle); |
- } else { |
- nss_SetError(ckrv); |
- nss_SetError(NSS_ERROR_PKCS11); |
- } |
- if (createdSession) { |
- nssSession_Destroy(session); |
- } |
- return object; |
-} |
- |
-static nssCryptokiObject ** |
-create_objects_from_handles ( |
- NSSToken *tok, |
- nssSession *session, |
- CK_OBJECT_HANDLE *handles, |
- PRUint32 numH |
-) |
-{ |
- nssCryptokiObject **objects; |
- objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1); |
- if (objects) { |
- PRInt32 i; |
- for (i=0; i<(PRInt32)numH; i++) { |
- objects[i] = nssCryptokiObject_Create(tok, session, handles[i]); |
- if (!objects[i]) { |
- for (--i; i>0; --i) { |
- nssCryptokiObject_Destroy(objects[i]); |
- } |
- nss_ZFreeIf(objects); |
- objects = NULL; |
- break; |
- } |
- } |
- } |
- return objects; |
-} |
- |
-static nssCryptokiObject ** |
-find_objects ( |
- NSSToken *tok, |
- nssSession *sessionOpt, |
- CK_ATTRIBUTE_PTR obj_template, |
- CK_ULONG otsize, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_RV ckrv = CKR_OK; |
- CK_ULONG count; |
- CK_OBJECT_HANDLE *objectHandles = NULL; |
- CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE]; |
- PRUint32 arraySize, numHandles; |
- void *epv = nssToken_GetCryptokiEPV(tok); |
- nssCryptokiObject **objects; |
- nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
- |
- /* Don't ask the module to use an invalid session handle. */ |
- if (!session || session->handle == CK_INVALID_SESSION) { |
- ckrv = CKR_SESSION_HANDLE_INVALID; |
- goto loser; |
- } |
- |
- /* the arena is only for the array of object handles */ |
- if (maximumOpt > 0) { |
- arraySize = maximumOpt; |
- } else { |
- arraySize = OBJECT_STACK_SIZE; |
- } |
- numHandles = 0; |
- if (arraySize <= OBJECT_STACK_SIZE) { |
- objectHandles = staticObjects; |
- } else { |
- objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize); |
- } |
- if (!objectHandles) { |
- ckrv = CKR_HOST_MEMORY; |
- goto loser; |
- } |
- nssSession_EnterMonitor(session); /* ==== session lock === */ |
- /* Initialize the find with the template */ |
- ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, |
- obj_template, otsize); |
- 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 (maximumOpt > 0 || numHandles < arraySize) { |
- /* When a maximum is provided, the search is done all at once, |
- * so the search is finished. If the number returned was less |
- * than the number sought, the search is finished. |
- */ |
- break; |
- } |
- /* the array is filled, double it and continue */ |
- arraySize *= 2; |
- if (objectHandles == staticObjects) { |
- objectHandles = nss_ZNEWARRAY(NULL,CK_OBJECT_HANDLE, arraySize); |
- if (objectHandles) { |
- PORT_Memcpy(objectHandles, staticObjects, |
- OBJECT_STACK_SIZE * sizeof(objectHandles[1])); |
- } |
- } else { |
- objectHandles = nss_ZREALLOCARRAY(objectHandles, |
- CK_OBJECT_HANDLE, |
- arraySize); |
- } |
- if (!objectHandles) { |
- nssSession_ExitMonitor(session); |
- ckrv = CKR_HOST_MEMORY; |
- 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(tok, session, |
- objectHandles, numHandles); |
- } else { |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- objects = NULL; |
- } |
- if (objectHandles && objectHandles != staticObjects) { |
- nss_ZFreeIf(objectHandles); |
- } |
- if (statusOpt) *statusOpt = PR_SUCCESS; |
- return objects; |
-loser: |
- if (objectHandles && objectHandles != staticObjects) { |
- nss_ZFreeIf(objectHandles); |
- } |
- /* |
- * These errors should be treated the same as if the objects just weren't |
- * found.. |
- */ |
- if ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || |
- (ckrv == CKR_ATTRIBUTE_VALUE_INVALID) || |
- (ckrv == CKR_DATA_INVALID) || |
- (ckrv == CKR_DATA_LEN_RANGE) || |
- (ckrv == CKR_FUNCTION_NOT_SUPPORTED) || |
- (ckrv == CKR_TEMPLATE_INCOMPLETE) || |
- (ckrv == CKR_TEMPLATE_INCONSISTENT)) { |
- |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- if (statusOpt) *statusOpt = PR_SUCCESS; |
- } else { |
- nss_SetError(ckrv); |
- nss_SetError(NSS_ERROR_PKCS11); |
- if (statusOpt) *statusOpt = PR_FAILURE; |
- } |
- return (nssCryptokiObject **)NULL; |
-} |
- |
-static nssCryptokiObject ** |
-find_objects_by_template ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- CK_ATTRIBUTE_PTR obj_template, |
- CK_ULONG otsize, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1; |
- nssCryptokiObject **objects = NULL; |
- PRUint32 i; |
- |
- if (!token) { |
- PORT_SetError(SEC_ERROR_NO_TOKEN); |
- if (statusOpt) |
- *statusOpt = PR_FAILURE; |
- return NULL; |
- } |
- for (i=0; i<otsize; i++) { |
- if (obj_template[i].type == CKA_CLASS) { |
- objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; |
- break; |
- } |
- } |
- PR_ASSERT(i < otsize); |
- if (i == otsize) { |
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
- if (statusOpt) *statusOpt = PR_FAILURE; |
- return NULL; |
- } |
- /* If these objects are being cached, try looking there first */ |
- if (token->cache && |
- nssTokenObjectCache_HaveObjectClass(token->cache, objclass)) |
- { |
- PRStatus status; |
- objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache, |
- objclass, |
- obj_template, |
- otsize, |
- maximumOpt, |
- &status); |
- if (status == PR_SUCCESS) { |
- if (statusOpt) *statusOpt = status; |
- return objects; |
- } |
- } |
- /* Either they are not cached, or cache failed; look on token. */ |
- objects = find_objects(token, sessionOpt, |
- obj_template, otsize, |
- maximumOpt, statusOpt); |
- return objects; |
-} |
- |
-extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; |
- |
-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; |
-} |
- |
-/* traverse all objects of the given class - this should only happen |
- * if the token has been marked as "traversable" |
- */ |
-NSS_IMPLEMENT nssCryptokiObject ** |
-nssToken_FindObjects ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- CK_OBJECT_CLASS objclass, |
- nssTokenSearchType searchType, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_ATTRIBUTE_PTR attr; |
- CK_ATTRIBUTE obj_template[2]; |
- CK_ULONG obj_size; |
- nssCryptokiObject **objects; |
- NSS_CK_TEMPLATE_START(obj_template, attr, obj_size); |
- /* 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); |
- } |
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, objclass); |
- NSS_CK_TEMPLATE_FINISH(obj_template, attr, obj_size); |
- |
- if (searchType == nssTokenSearchType_TokenForced) { |
- objects = find_objects(token, sessionOpt, |
- obj_template, obj_size, |
- maximumOpt, statusOpt); |
- } else { |
- objects = find_objects_by_template(token, sessionOpt, |
- obj_template, obj_size, |
- maximumOpt, statusOpt); |
- } |
- return objects; |
-} |
- |
-NSS_IMPLEMENT nssCryptokiObject ** |
-nssToken_FindCertificatesBySubject ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- NSSDER *subject, |
- nssTokenSearchType searchType, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_ATTRIBUTE_PTR attr; |
- CK_ATTRIBUTE subj_template[3]; |
- CK_ULONG stsize; |
- nssCryptokiObject **objects; |
- NSS_CK_TEMPLATE_START(subj_template, attr, stsize); |
- /* 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_SUBJECT, subject); |
- NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); |
- /* now locate the token certs matching this template */ |
- objects = find_objects_by_template(token, sessionOpt, |
- subj_template, stsize, |
- maximumOpt, statusOpt); |
- return objects; |
-} |
- |
-NSS_IMPLEMENT nssCryptokiObject ** |
-nssToken_FindCertificatesByNickname ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- const NSSUTF8 *name, |
- nssTokenSearchType searchType, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_ATTRIBUTE_PTR attr; |
- CK_ATTRIBUTE nick_template[3]; |
- CK_ULONG ntsize; |
- nssCryptokiObject **objects; |
- NSS_CK_TEMPLATE_START(nick_template, attr, ntsize); |
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name); |
- /* 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_TEMPLATE_FINISH(nick_template, attr, ntsize); |
- /* now locate the token certs matching this template */ |
- objects = find_objects_by_template(token, sessionOpt, |
- nick_template, ntsize, |
- maximumOpt, statusOpt); |
- if (!objects) { |
- /* This is to workaround the fact that PKCS#11 doesn't specify |
- * whether the '\0' should be included. XXX Is that still true? |
- * im - this is not needed by the current softoken. However, I'm |
- * leaving it in until I have surveyed more tokens to see if it needed. |
- * well, its needed by the builtin token... |
- */ |
- nick_template[0].ulValueLen++; |
- objects = find_objects_by_template(token, sessionOpt, |
- nick_template, ntsize, |
- maximumOpt, statusOpt); |
- } |
- return objects; |
-} |
- |
-/* XXX |
- * This function *does not* use the token object cache, because not even |
- * the softoken will return a value for CKA_NSS_EMAIL from a call |
- * to GetAttributes. The softoken does allow searches with that attribute, |
- * it just won't return a value for it. |
- */ |
-NSS_IMPLEMENT nssCryptokiObject ** |
-nssToken_FindCertificatesByEmail ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- NSSASCII7 *email, |
- nssTokenSearchType searchType, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_ATTRIBUTE_PTR attr; |
- CK_ATTRIBUTE email_template[3]; |
- CK_ULONG etsize; |
- nssCryptokiObject **objects; |
- NSS_CK_TEMPLATE_START(email_template, attr, etsize); |
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); |
- /* 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_TEMPLATE_FINISH(email_template, attr, etsize); |
- /* now locate the token certs matching this template */ |
- objects = find_objects(token, sessionOpt, |
- email_template, etsize, |
- maximumOpt, statusOpt); |
- if (!objects) { |
- /* This is to workaround the fact that PKCS#11 doesn't specify |
- * whether the '\0' should be included. XXX Is that still true? |
- * im - this is not needed by the current softoken. However, I'm |
- * leaving it in until I have surveyed more tokens to see if it needed. |
- * well, its needed by the builtin token... |
- */ |
- email_template[0].ulValueLen++; |
- objects = find_objects(token, sessionOpt, |
- email_template, etsize, |
- maximumOpt, statusOpt); |
- } |
- return objects; |
-} |
- |
-NSS_IMPLEMENT nssCryptokiObject ** |
-nssToken_FindCertificatesByID ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- NSSItem *id, |
- nssTokenSearchType searchType, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_ATTRIBUTE_PTR attr; |
- CK_ATTRIBUTE id_template[3]; |
- CK_ULONG idtsize; |
- nssCryptokiObject **objects; |
- NSS_CK_TEMPLATE_START(id_template, attr, idtsize); |
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
- /* 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_TEMPLATE_FINISH(id_template, attr, idtsize); |
- /* now locate the token certs matching this template */ |
- objects = find_objects_by_template(token, sessionOpt, |
- id_template, idtsize, |
- maximumOpt, statusOpt); |
- return objects; |
-} |
- |
-/* |
- * decode the serial item and return our result. |
- * NOTE serialDecode's data is really stored in serial. Don't free it. |
- */ |
-static PRStatus |
-nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode) |
-{ |
- unsigned char *data = (unsigned char *)serial->data; |
- int data_left, data_len, index; |
- |
- if ((serial->size >= 3) && (data[0] == 0x2)) { |
- /* remove the der encoding of the serial number before generating the |
- * key.. */ |
- data_left = serial->size-2; |
- data_len = data[1]; |
- index = 2; |
- |
- /* extended length ? (not very likely for a serial number) */ |
- if (data_len & 0x80) { |
- int len_count = data_len & 0x7f; |
- |
- data_len = 0; |
- data_left -= len_count; |
- if (data_left > 0) { |
- while (len_count --) { |
- data_len = (data_len << 8) | data[index++]; |
- } |
- } |
- } |
- /* XXX leaving any leading zeros on the serial number for backwards |
- * compatibility |
- */ |
- /* not a valid der, must be just an unlucky serial number value */ |
- if (data_len == data_left) { |
- serialDecode->size = data_len; |
- serialDecode->data = &data[index]; |
- return PR_SUCCESS; |
- } |
- } |
- return PR_FAILURE; |
-} |
- |
-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_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; |
-} |
- |
-NSS_IMPLEMENT nssCryptokiObject ** |
-nssToken_FindPrivateKeys ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- nssTokenSearchType searchType, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_ATTRIBUTE_PTR attr; |
- CK_ATTRIBUTE key_template[2]; |
- CK_ULONG ktsize; |
- nssCryptokiObject **objects; |
- |
- NSS_CK_TEMPLATE_START(key_template, attr, ktsize); |
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); |
- 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_TEMPLATE_FINISH(key_template, attr, ktsize); |
- |
- objects = find_objects_by_template(token, sessionOpt, |
- key_template, ktsize, |
- maximumOpt, statusOpt); |
- return objects; |
-} |
- |
-/* XXX ?there are no session cert objects, so only search token objects */ |
-NSS_IMPLEMENT nssCryptokiObject * |
-nssToken_FindPrivateKeyByID ( |
- 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_privkey); |
- 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; |
-} |
- |
-/* 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; |
-} |
- |
-static void |
-sha1_hash(NSSItem *input, NSSItem *output) |
-{ |
- NSSAlgorithmAndParameters *ap; |
- PK11SlotInfo *internal = PK11_GetInternalSlot(); |
- NSSToken *token = PK11Slot_GetNSSToken(internal); |
- ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL); |
- (void)nssToken_Digest(token, NULL, ap, input, output, NULL); |
- PK11_FreeSlot(token->pk11slot); |
- nss_ZFreeIf(ap); |
-} |
- |
-static void |
-md5_hash(NSSItem *input, NSSItem *output) |
-{ |
- NSSAlgorithmAndParameters *ap; |
- PK11SlotInfo *internal = PK11_GetInternalSlot(); |
- NSSToken *token = PK11Slot_GetNSSToken(internal); |
- ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); |
- (void)nssToken_Digest(token, NULL, ap, input, output, NULL); |
- PK11_FreeSlot(token->pk11slot); |
- nss_ZFreeIf(ap); |
-} |
- |
-static CK_TRUST |
-get_ck_trust ( |
- nssTrustLevel nssTrust |
-) |
-{ |
- CK_TRUST t; |
- switch (nssTrust) { |
- case nssTrustLevel_NotTrusted: t = CKT_NSS_NOT_TRUSTED; break; |
- case nssTrustLevel_TrustedDelegator: t = CKT_NSS_TRUSTED_DELEGATOR; |
- break; |
- case nssTrustLevel_ValidDelegator: t = CKT_NSS_VALID_DELEGATOR; break; |
- case nssTrustLevel_Trusted: t = CKT_NSS_TRUSTED; break; |
- case nssTrustLevel_MustVerify: t = CKT_NSS_MUST_VERIFY_TRUST; break; |
- case nssTrustLevel_Unknown: |
- default: t = CKT_NSS_TRUST_UNKNOWN; break; |
- } |
- return t; |
-} |
- |
-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 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 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_FindCRLsBySubject ( |
- NSSToken *token, |
- nssSession *sessionOpt, |
- NSSDER *subject, |
- nssTokenSearchType searchType, |
- PRUint32 maximumOpt, |
- PRStatus *statusOpt |
-) |
-{ |
- CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; |
- CK_ATTRIBUTE_PTR attr; |
- CK_ATTRIBUTE crlobj_template[3]; |
- CK_ULONG crlobj_size; |
- nssCryptokiObject **objects = NULL; |
- 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 objects; |
- } |
- |
- NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size); |
- 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_VAR( attr, CKA_CLASS, crlobjc); |
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
- NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); |
- |
- objects = find_objects_by_template(token, session, |
- crlobj_template, crlobj_size, |
- maximumOpt, statusOpt); |
- return objects; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssToken_GetCachedObjectAttributes ( |
- NSSToken *token, |
- NSSArena *arenaOpt, |
- nssCryptokiObject *object, |
- CK_OBJECT_CLASS objclass, |
- CK_ATTRIBUTE_PTR atemplate, |
- CK_ULONG atlen |
-) |
-{ |
- if (!token->cache) { |
- return PR_FAILURE; |
- } |
- return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt, |
- object, objclass, |
- atemplate, atlen); |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-nssToken_Digest ( |
- NSSToken *tok, |
- nssSession *sessionOpt, |
- NSSAlgorithmAndParameters *ap, |
- NSSItem *data, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- CK_RV ckrv; |
- CK_ULONG digestLen; |
- CK_BYTE_PTR digest; |
- NSSItem *rvItem = NULL; |
- void *epv = nssToken_GetCryptokiEPV(tok); |
- nssSession *session = (sessionOpt) ? sessionOpt : tok->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 rvItem; |
- } |
- |
- nssSession_EnterMonitor(session); |
- ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); |
- if (ckrv != CKR_OK) { |
- nssSession_ExitMonitor(session); |
- return NULL; |
- } |
-#if 0 |
- /* XXX the standard says this should work, but it doesn't */ |
- ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen); |
- if (ckrv != CKR_OK) { |
- nssSession_ExitMonitor(session); |
- return NULL; |
- } |
-#endif |
- digestLen = 0; /* XXX for now */ |
- digest = NULL; |
- if (rvOpt) { |
- if (rvOpt->size > 0 && rvOpt->size < digestLen) { |
- nssSession_ExitMonitor(session); |
- /* the error should be bad args */ |
- return NULL; |
- } |
- if (rvOpt->data) { |
- digest = rvOpt->data; |
- } |
- digestLen = rvOpt->size; |
- } |
- if (!digest) { |
- digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); |
- if (!digest) { |
- nssSession_ExitMonitor(session); |
- return NULL; |
- } |
- } |
- ckrv = CKAPI(epv)->C_Digest(session->handle, |
- (CK_BYTE_PTR)data->data, |
- (CK_ULONG)data->size, |
- (CK_BYTE_PTR)digest, |
- &digestLen); |
- nssSession_ExitMonitor(session); |
- if (ckrv != CKR_OK) { |
- nss_ZFreeIf(digest); |
- return NULL; |
- } |
- if (!rvOpt) { |
- rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); |
- } |
- return rvItem; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssToken_BeginDigest ( |
- NSSToken *tok, |
- nssSession *sessionOpt, |
- NSSAlgorithmAndParameters *ap |
-) |
-{ |
- CK_RV ckrv; |
- void *epv = nssToken_GetCryptokiEPV(tok); |
- nssSession *session = (sessionOpt) ? sessionOpt : tok->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; |
- } |
- |
- nssSession_EnterMonitor(session); |
- ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); |
- nssSession_ExitMonitor(session); |
- return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssToken_ContinueDigest ( |
- NSSToken *tok, |
- nssSession *sessionOpt, |
- NSSItem *item |
-) |
-{ |
- CK_RV ckrv; |
- void *epv = nssToken_GetCryptokiEPV(tok); |
- nssSession *session = (sessionOpt) ? sessionOpt : tok->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; |
- } |
- |
- nssSession_EnterMonitor(session); |
- ckrv = CKAPI(epv)->C_DigestUpdate(session->handle, |
- (CK_BYTE_PTR)item->data, |
- (CK_ULONG)item->size); |
- nssSession_ExitMonitor(session); |
- return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-nssToken_FinishDigest ( |
- NSSToken *tok, |
- nssSession *sessionOpt, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- CK_RV ckrv; |
- CK_ULONG digestLen; |
- CK_BYTE_PTR digest; |
- NSSItem *rvItem = NULL; |
- void *epv = nssToken_GetCryptokiEPV(tok); |
- nssSession *session = (sessionOpt) ? sessionOpt : tok->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 NULL; |
- } |
- |
- nssSession_EnterMonitor(session); |
- ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen); |
- if (ckrv != CKR_OK || digestLen == 0) { |
- nssSession_ExitMonitor(session); |
- return NULL; |
- } |
- digest = NULL; |
- if (rvOpt) { |
- if (rvOpt->size > 0 && rvOpt->size < digestLen) { |
- nssSession_ExitMonitor(session); |
- /* the error should be bad args */ |
- return NULL; |
- } |
- if (rvOpt->data) { |
- digest = rvOpt->data; |
- } |
- digestLen = rvOpt->size; |
- } |
- if (!digest) { |
- digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); |
- if (!digest) { |
- nssSession_ExitMonitor(session); |
- return NULL; |
- } |
- } |
- ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen); |
- nssSession_ExitMonitor(session); |
- if (ckrv != CKR_OK) { |
- nss_ZFreeIf(digest); |
- return NULL; |
- } |
- if (!rvOpt) { |
- rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); |
- } |
- return rvItem; |
-} |
- |
-NSS_IMPLEMENT PRBool |
-nssToken_IsPresent ( |
- NSSToken *token |
-) |
-{ |
- return nssSlot_IsTokenPresent(token->slot); |
-} |
- |
-/* 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 PRBool |
-nssToken_IsPrivateKeyAvailable ( |
- NSSToken *token, |
- NSSCertificate *c, |
- nssCryptokiObject *instance |
-) |
-{ |
- CK_OBJECT_CLASS theClass; |
- |
- if (token == NULL) return PR_FALSE; |
- if (c == NULL) return PR_FALSE; |
- |
- theClass = CKO_PRIVATE_KEY; |
- if (!nssSlot_IsLoggedIn(token->slot)) { |
- theClass = CKO_PUBLIC_KEY; |
- } |
- if (PK11_MatchItem(token->pk11slot, instance->handle, theClass) |
- != CK_INVALID_HANDLE) { |
- return PR_TRUE; |
- } |
- return PR_FALSE; |
-} |