| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 #include "pkcs11.h" | 5 #include "pkcs11.h" |
| 6 | 6 |
| 7 #ifndef DEVM_H | 7 #ifndef DEVM_H |
| 8 #include "devm.h" | 8 #include "devm.h" |
| 9 #endif /* DEVM_H */ | 9 #endif /* DEVM_H */ |
| 10 | 10 |
| 11 #ifndef CKHELPER_H | 11 #ifndef CKHELPER_H |
| 12 #include "ckhelper.h" | 12 #include "ckhelper.h" |
| 13 #endif /* CKHELPER_H */ | 13 #endif /* CKHELPER_H */ |
| 14 | 14 |
| 15 #include "pk11func.h" | 15 #include "pk11func.h" |
| 16 #include "dev3hack.h" | 16 #include "dev3hack.h" |
| 17 #include "secerr.h" | 17 #include "secerr.h" |
| 18 | 18 |
| 19 extern const NSSError NSS_ERROR_NOT_FOUND; | 19 extern const NSSError NSS_ERROR_NOT_FOUND; |
| 20 extern const NSSError NSS_ERROR_INVALID_ARGUMENT; | 20 extern const NSSError NSS_ERROR_INVALID_ARGUMENT; |
| 21 extern const NSSError NSS_ERROR_PKCS11; | 21 extern const NSSError NSS_ERROR_PKCS11; |
| 22 | 22 |
| 23 /* The number of object handles to grab during each call to C_FindObjects */ | 23 /* The number of object handles to grab during each call to C_FindObjects */ |
| 24 #define OBJECT_STACK_SIZE 16 | 24 #define OBJECT_STACK_SIZE 16 |
| 25 | 25 |
| 26 NSS_IMPLEMENT PRStatus | 26 NSS_IMPLEMENT PRStatus |
| 27 nssToken_Destroy ( | 27 nssToken_Destroy( |
| 28 NSSToken *tok | 28 NSSToken *tok) |
| 29 ) | |
| 30 { | 29 { |
| 31 if (tok) { | 30 if (tok) { |
| 32 » if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) { | 31 if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) { |
| 33 » PZ_DestroyLock(tok->base.lock); | 32 PZ_DestroyLock(tok->base.lock); |
| 34 » nssTokenObjectCache_Destroy(tok->cache); | 33 nssTokenObjectCache_Destroy(tok->cache); |
| 35 » /* The token holds the first/last reference to the slot. | 34 /* The token holds the first/last reference to the slot. |
| 36 » * When the token is actually destroyed, that ref must go too. | 35 * When the token is actually destroyed, that ref must go too. |
| 37 » */ | 36 */ |
| 38 » (void)nssSlot_Destroy(tok->slot); | 37 (void)nssSlot_Destroy(tok->slot); |
| 39 » return nssArena_Destroy(tok->base.arena); | 38 return nssArena_Destroy(tok->base.arena); |
| 40 » } | 39 } |
| 41 } | 40 } |
| 42 return PR_SUCCESS; | 41 return PR_SUCCESS; |
| 43 } | 42 } |
| 44 | 43 |
| 45 NSS_IMPLEMENT void | 44 NSS_IMPLEMENT void |
| 46 nssToken_Remove ( | 45 nssToken_Remove( |
| 47 NSSToken *tok | 46 NSSToken *tok) |
| 48 ) | |
| 49 { | 47 { |
| 50 nssTokenObjectCache_Clear(tok->cache); | 48 nssTokenObjectCache_Clear(tok->cache); |
| 51 } | 49 } |
| 52 | 50 |
| 53 NSS_IMPLEMENT void | 51 NSS_IMPLEMENT void |
| 54 NSSToken_Destroy ( | 52 NSSToken_Destroy( |
| 55 NSSToken *tok | 53 NSSToken *tok) |
| 56 ) | |
| 57 { | 54 { |
| 58 (void)nssToken_Destroy(tok); | 55 (void)nssToken_Destroy(tok); |
| 59 } | 56 } |
| 60 | 57 |
| 61 NSS_IMPLEMENT NSSToken * | 58 NSS_IMPLEMENT NSSToken * |
| 62 nssToken_AddRef ( | 59 nssToken_AddRef( |
| 63 NSSToken *tok | 60 NSSToken *tok) |
| 64 ) | |
| 65 { | 61 { |
| 66 PR_ATOMIC_INCREMENT(&tok->base.refCount); | 62 PR_ATOMIC_INCREMENT(&tok->base.refCount); |
| 67 return tok; | 63 return tok; |
| 68 } | 64 } |
| 69 | 65 |
| 70 NSS_IMPLEMENT NSSSlot * | 66 NSS_IMPLEMENT NSSSlot * |
| 71 nssToken_GetSlot ( | 67 nssToken_GetSlot( |
| 72 NSSToken *tok | 68 NSSToken *tok) |
| 73 ) | |
| 74 { | 69 { |
| 75 return nssSlot_AddRef(tok->slot); | 70 return nssSlot_AddRef(tok->slot); |
| 76 } | 71 } |
| 77 | 72 |
| 78 NSS_IMPLEMENT void * | 73 NSS_IMPLEMENT void * |
| 79 nssToken_GetCryptokiEPV ( | 74 nssToken_GetCryptokiEPV( |
| 80 NSSToken *token | 75 NSSToken *token) |
| 81 ) | |
| 82 { | 76 { |
| 83 return nssSlot_GetCryptokiEPV(token->slot); | 77 return nssSlot_GetCryptokiEPV(token->slot); |
| 84 } | 78 } |
| 85 | 79 |
| 86 NSS_IMPLEMENT nssSession * | 80 NSS_IMPLEMENT nssSession * |
| 87 nssToken_GetDefaultSession ( | 81 nssToken_GetDefaultSession( |
| 88 NSSToken *token | 82 NSSToken *token) |
| 89 ) | |
| 90 { | 83 { |
| 91 return token->defaultSession; | 84 return token->defaultSession; |
| 92 } | 85 } |
| 93 | 86 |
| 94 NSS_IMPLEMENT NSSUTF8 * | 87 NSS_IMPLEMENT NSSUTF8 * |
| 95 nssToken_GetName ( | 88 nssToken_GetName( |
| 96 NSSToken *tok | 89 NSSToken *tok) |
| 97 ) | |
| 98 { | 90 { |
| 99 if (tok == NULL) { | 91 if (tok == NULL) { |
| 100 » return ""; | 92 return ""; |
| 101 } | 93 } |
| 102 if (tok->base.name[0] == 0) { | 94 if (tok->base.name[0] == 0) { |
| 103 » (void) nssSlot_IsTokenPresent(tok->slot); | 95 (void)nssSlot_IsTokenPresent(tok->slot); |
| 104 } | 96 } |
| 105 return tok->base.name; | 97 return tok->base.name; |
| 106 } | 98 } |
| 107 | 99 |
| 108 NSS_IMPLEMENT NSSUTF8 * | 100 NSS_IMPLEMENT NSSUTF8 * |
| 109 NSSToken_GetName ( | 101 NSSToken_GetName( |
| 110 NSSToken *token | 102 NSSToken *token) |
| 111 ) | |
| 112 { | 103 { |
| 113 return nssToken_GetName(token); | 104 return nssToken_GetName(token); |
| 114 } | 105 } |
| 115 | 106 |
| 116 NSS_IMPLEMENT PRBool | 107 NSS_IMPLEMENT PRBool |
| 117 nssToken_IsLoginRequired ( | 108 nssToken_IsLoginRequired( |
| 118 NSSToken *token | 109 NSSToken *token) |
| 119 ) | |
| 120 { | 110 { |
| 121 return (token->ckFlags & CKF_LOGIN_REQUIRED); | 111 return (token->ckFlags & CKF_LOGIN_REQUIRED); |
| 122 } | 112 } |
| 123 | 113 |
| 124 NSS_IMPLEMENT PRBool | 114 NSS_IMPLEMENT PRBool |
| 125 nssToken_NeedsPINInitialization ( | 115 nssToken_NeedsPINInitialization( |
| 126 NSSToken *token | 116 NSSToken *token) |
| 127 ) | |
| 128 { | 117 { |
| 129 return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED)); | 118 return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED)); |
| 130 } | 119 } |
| 131 | 120 |
| 132 NSS_IMPLEMENT PRStatus | 121 NSS_IMPLEMENT PRStatus |
| 133 nssToken_DeleteStoredObject ( | 122 nssToken_DeleteStoredObject( |
| 134 nssCryptokiObject *instance | 123 nssCryptokiObject *instance) |
| 135 ) | |
| 136 { | 124 { |
| 137 CK_RV ckrv; | 125 CK_RV ckrv; |
| 138 PRStatus status; | 126 PRStatus status; |
| 139 PRBool createdSession = PR_FALSE; | 127 PRBool createdSession = PR_FALSE; |
| 140 NSSToken *token = instance->token; | 128 NSSToken *token = instance->token; |
| 141 nssSession *session = NULL; | 129 nssSession *session = NULL; |
| 142 void *epv = nssToken_GetCryptokiEPV(instance->token); | 130 void *epv = nssToken_GetCryptokiEPV(instance->token); |
| 143 if (token->cache) { | 131 if (token->cache) { |
| 144 » nssTokenObjectCache_RemoveObject(token->cache, instance); | 132 nssTokenObjectCache_RemoveObject(token->cache, instance); |
| 145 } | 133 } |
| 146 if (instance->isTokenObject) { | 134 if (instance->isTokenObject) { |
| 147 if (token->defaultSession && | 135 if (token->defaultSession && |
| 148 nssSession_IsReadWrite(token->defaultSession)) { | 136 nssSession_IsReadWrite(token->defaultSession)) { |
| 149 » session = token->defaultSession; | 137 session = token->defaultSession; |
| 150 } else { | 138 } else { |
| 151 » session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); | 139 session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); |
| 152 » createdSession = PR_TRUE; | 140 createdSession = PR_TRUE; |
| 153 } | 141 } |
| 154 } | 142 } |
| 155 if (session == NULL) { | 143 if (session == NULL) { |
| 156 » return PR_FAILURE; | 144 return PR_FAILURE; |
| 157 } | 145 } |
| 158 nssSession_EnterMonitor(session); | 146 nssSession_EnterMonitor(session); |
| 159 ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle); | 147 ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle); |
| 160 nssSession_ExitMonitor(session); | 148 nssSession_ExitMonitor(session); |
| 161 if (createdSession) { | 149 if (createdSession) { |
| 162 » nssSession_Destroy(session); | 150 nssSession_Destroy(session); |
| 163 } | 151 } |
| 164 status = PR_SUCCESS; | 152 status = PR_SUCCESS; |
| 165 if (ckrv != CKR_OK) { | 153 if (ckrv != CKR_OK) { |
| 166 » status = PR_FAILURE; | 154 status = PR_FAILURE; |
| 167 » /* use the error stack to pass the PKCS #11 error out */ | 155 /* use the error stack to pass the PKCS #11 error out */ |
| 168 » nss_SetError(ckrv); | 156 nss_SetError(ckrv); |
| 169 » nss_SetError(NSS_ERROR_PKCS11); | 157 nss_SetError(NSS_ERROR_PKCS11); |
| 170 } | 158 } |
| 171 return status; | 159 return status; |
| 172 } | 160 } |
| 173 | 161 |
| 174 static nssCryptokiObject * | 162 static nssCryptokiObject * |
| 175 import_object ( | 163 import_object( |
| 176 NSSToken *tok, | 164 NSSToken *tok, |
| 177 nssSession *sessionOpt, | 165 nssSession *sessionOpt, |
| 178 CK_ATTRIBUTE_PTR objectTemplate, | 166 CK_ATTRIBUTE_PTR objectTemplate, |
| 179 CK_ULONG otsize | 167 CK_ULONG otsize) |
| 180 ) | |
| 181 { | 168 { |
| 182 nssSession *session = NULL; | 169 nssSession *session = NULL; |
| 183 PRBool createdSession = PR_FALSE; | 170 PRBool createdSession = PR_FALSE; |
| 184 nssCryptokiObject *object = NULL; | 171 nssCryptokiObject *object = NULL; |
| 185 CK_OBJECT_HANDLE handle; | 172 CK_OBJECT_HANDLE handle; |
| 186 CK_RV ckrv; | 173 CK_RV ckrv; |
| 187 void *epv = nssToken_GetCryptokiEPV(tok); | 174 void *epv = nssToken_GetCryptokiEPV(tok); |
| 188 if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) { | 175 if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) { |
| 189 » if (sessionOpt) { | 176 if (sessionOpt) { |
| 190 » if (!nssSession_IsReadWrite(sessionOpt)) { | 177 if (!nssSession_IsReadWrite(sessionOpt)) { |
| 191 » » nss_SetError(NSS_ERROR_INVALID_ARGUMENT); | 178 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
| 192 » » return NULL; | 179 return NULL; |
| 193 » } | 180 } |
| 194 » session = sessionOpt; | 181 session = sessionOpt; |
| 195 » } else if (tok->defaultSession && | 182 } else if (tok->defaultSession && |
| 196 » nssSession_IsReadWrite(tok->defaultSession)) { | 183 nssSession_IsReadWrite(tok->defaultSession)) { |
| 197 » session = tok->defaultSession; | 184 session = tok->defaultSession; |
| 198 » } else { | 185 } else { |
| 199 » session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE); | 186 session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE); |
| 200 » createdSession = PR_TRUE; | 187 createdSession = PR_TRUE; |
| 201 » } | 188 } |
| 202 } else { | 189 } else { |
| 203 » session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 190 session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
| 204 } | 191 } |
| 205 if (session == NULL) { | 192 if (session == NULL) { |
| 206 » nss_SetError(NSS_ERROR_INVALID_ARGUMENT); | 193 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
| 207 » return NULL; | 194 return NULL; |
| 208 } | 195 } |
| 209 nssSession_EnterMonitor(session); | 196 nssSession_EnterMonitor(session); |
| 210 ckrv = CKAPI(epv)->C_CreateObject(session->handle, | 197 ckrv = CKAPI(epv)->C_CreateObject(session->handle, |
| 211 objectTemplate, otsize, | 198 objectTemplate, otsize, |
| 212 &handle); | 199 &handle); |
| 213 nssSession_ExitMonitor(session); | 200 nssSession_ExitMonitor(session); |
| 214 if (ckrv == CKR_OK) { | 201 if (ckrv == CKR_OK) { |
| 215 » object = nssCryptokiObject_Create(tok, session, handle); | 202 object = nssCryptokiObject_Create(tok, session, handle); |
| 216 } else { | 203 } else { |
| 217 » nss_SetError(ckrv); | 204 nss_SetError(ckrv); |
| 218 » nss_SetError(NSS_ERROR_PKCS11); | 205 nss_SetError(NSS_ERROR_PKCS11); |
| 219 } | 206 } |
| 220 if (createdSession) { | 207 if (createdSession) { |
| 221 » nssSession_Destroy(session); | 208 nssSession_Destroy(session); |
| 222 } | 209 } |
| 223 return object; | 210 return object; |
| 224 } | 211 } |
| 225 | 212 |
| 226 static nssCryptokiObject ** | 213 static nssCryptokiObject ** |
| 227 create_objects_from_handles ( | 214 create_objects_from_handles( |
| 228 NSSToken *tok, | 215 NSSToken *tok, |
| 229 nssSession *session, | 216 nssSession *session, |
| 230 CK_OBJECT_HANDLE *handles, | 217 CK_OBJECT_HANDLE *handles, |
| 231 PRUint32 numH | 218 PRUint32 numH) |
| 232 ) | |
| 233 { | 219 { |
| 234 nssCryptokiObject **objects; | 220 nssCryptokiObject **objects; |
| 235 objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1); | 221 objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1); |
| 236 if (objects) { | 222 if (objects) { |
| 237 » PRInt32 i; | 223 PRInt32 i; |
| 238 » for (i=0; i<(PRInt32)numH; i++) { | 224 for (i = 0; i < (PRInt32)numH; i++) { |
| 239 » objects[i] = nssCryptokiObject_Create(tok, session, handles[i]); | 225 objects[i] = nssCryptokiObject_Create(tok, session, handles[i]); |
| 240 » if (!objects[i]) { | 226 if (!objects[i]) { |
| 241 » » for (--i; i>0; --i) { | 227 for (--i; i > 0; --i) { |
| 242 » » nssCryptokiObject_Destroy(objects[i]); | 228 nssCryptokiObject_Destroy(objects[i]); |
| 243 » » } | 229 } |
| 244 » » nss_ZFreeIf(objects); | 230 nss_ZFreeIf(objects); |
| 245 » » objects = NULL; | 231 objects = NULL; |
| 246 » » break; | 232 break; |
| 247 » } | 233 } |
| 248 » } | 234 } |
| 249 } | 235 } |
| 250 return objects; | 236 return objects; |
| 251 } | 237 } |
| 252 | 238 |
| 253 static nssCryptokiObject ** | 239 static nssCryptokiObject ** |
| 254 find_objects ( | 240 find_objects( |
| 255 NSSToken *tok, | 241 NSSToken *tok, |
| 256 nssSession *sessionOpt, | 242 nssSession *sessionOpt, |
| 257 CK_ATTRIBUTE_PTR obj_template, | 243 CK_ATTRIBUTE_PTR obj_template, |
| 258 CK_ULONG otsize, | 244 CK_ULONG otsize, |
| 259 PRUint32 maximumOpt, | 245 PRUint32 maximumOpt, |
| 260 PRStatus *statusOpt | 246 PRStatus *statusOpt) |
| 261 ) | |
| 262 { | 247 { |
| 263 CK_RV ckrv = CKR_OK; | 248 CK_RV ckrv = CKR_OK; |
| 264 CK_ULONG count; | 249 CK_ULONG count; |
| 265 CK_OBJECT_HANDLE *objectHandles = NULL; | 250 CK_OBJECT_HANDLE *objectHandles = NULL; |
| 266 CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE]; | 251 CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE]; |
| 267 PRUint32 arraySize, numHandles; | 252 PRUint32 arraySize, numHandles; |
| 268 void *epv = nssToken_GetCryptokiEPV(tok); | 253 void *epv = nssToken_GetCryptokiEPV(tok); |
| 269 nssCryptokiObject **objects; | 254 nssCryptokiObject **objects; |
| 270 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 255 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
| 271 | 256 |
| 272 /* Don't ask the module to use an invalid session handle. */ | 257 /* Don't ask the module to use an invalid session handle. */ |
| 273 if (!session || session->handle == CK_INVALID_SESSION) { | 258 if (!session || session->handle == CK_INVALID_SESSION) { |
| 274 » ckrv = CKR_SESSION_HANDLE_INVALID; | 259 ckrv = CKR_SESSION_HANDLE_INVALID; |
| 275 » goto loser; | 260 goto loser; |
| 276 } | 261 } |
| 277 | 262 |
| 278 /* the arena is only for the array of object handles */ | 263 /* the arena is only for the array of object handles */ |
| 279 if (maximumOpt > 0) { | 264 if (maximumOpt > 0) { |
| 280 » arraySize = maximumOpt; | 265 arraySize = maximumOpt; |
| 281 } else { | 266 } else { |
| 282 » arraySize = OBJECT_STACK_SIZE; | 267 arraySize = OBJECT_STACK_SIZE; |
| 283 } | 268 } |
| 284 numHandles = 0; | 269 numHandles = 0; |
| 285 if (arraySize <= OBJECT_STACK_SIZE) { | 270 if (arraySize <= OBJECT_STACK_SIZE) { |
| 286 » objectHandles = staticObjects; | 271 objectHandles = staticObjects; |
| 287 } else { | 272 } else { |
| 288 » objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize); | 273 objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize); |
| 289 } | 274 } |
| 290 if (!objectHandles) { | 275 if (!objectHandles) { |
| 291 » ckrv = CKR_HOST_MEMORY; | 276 ckrv = CKR_HOST_MEMORY; |
| 292 » goto loser; | 277 goto loser; |
| 293 } | 278 } |
| 294 nssSession_EnterMonitor(session); /* ==== session lock === */ | 279 nssSession_EnterMonitor(session); /* ==== session lock === */ |
| 295 /* Initialize the find with the template */ | 280 /* Initialize the find with the template */ |
| 296 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, | 281 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, |
| 297 obj_template, otsize); | 282 obj_template, otsize); |
| 298 if (ckrv != CKR_OK) { | 283 if (ckrv != CKR_OK) { |
| 299 » nssSession_ExitMonitor(session); | 284 nssSession_ExitMonitor(session); |
| 300 » goto loser; | 285 goto loser; |
| 301 } | 286 } |
| 302 while (PR_TRUE) { | 287 while (PR_TRUE) { |
| 303 » /* Issue the find for up to arraySize - numHandles objects */ | 288 /* Issue the find for up to arraySize - numHandles objects */ |
| 304 » ckrv = CKAPI(epv)->C_FindObjects(session->handle, | 289 ckrv = CKAPI(epv)->C_FindObjects(session->handle, |
| 305 » objectHandles + numHandles, | 290 objectHandles + numHandles, |
| 306 » arraySize - numHandles, | 291 arraySize - numHandles, |
| 307 » &count); | 292 &count); |
| 308 » if (ckrv != CKR_OK) { | 293 if (ckrv != CKR_OK) { |
| 309 » nssSession_ExitMonitor(session); | 294 nssSession_ExitMonitor(session); |
| 310 » goto loser; | 295 goto loser; |
| 311 » } | 296 } |
| 312 » /* bump the number of found objects */ | 297 /* bump the number of found objects */ |
| 313 » numHandles += count; | 298 numHandles += count; |
| 314 » if (maximumOpt > 0 || numHandles < arraySize) { | 299 if (maximumOpt > 0 || numHandles < arraySize) { |
| 315 » /* When a maximum is provided, the search is done all at once, | 300 /* When a maximum is provided, the search is done all at once, |
| 316 » * so the search is finished. If the number returned was less | 301 * so the search is finished. If the number returned was less |
| 317 » * than the number sought, the search is finished. | 302 * than the number sought, the search is finished. |
| 318 » */ | 303 */ |
| 319 » break; | 304 break; |
| 320 » } | 305 } |
| 321 » /* the array is filled, double it and continue */ | 306 /* the array is filled, double it and continue */ |
| 322 » arraySize *= 2; | 307 arraySize *= 2; |
| 323 » if (objectHandles == staticObjects) { | 308 if (objectHandles == staticObjects) { |
| 324 » objectHandles = nss_ZNEWARRAY(NULL,CK_OBJECT_HANDLE, arraySize); | 309 objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize); |
| 325 » if (objectHandles) { | 310 if (objectHandles) { |
| 326 » » PORT_Memcpy(objectHandles, staticObjects, | 311 PORT_Memcpy(objectHandles, staticObjects, |
| 327 » » » OBJECT_STACK_SIZE * sizeof(objectHandles[1])); | 312 OBJECT_STACK_SIZE * sizeof(objectHandles[1])); |
| 328 » } | 313 } |
| 329 » } else { | 314 } else { |
| 330 » objectHandles = nss_ZREALLOCARRAY(objectHandles, | 315 objectHandles = nss_ZREALLOCARRAY(objectHandles, |
| 331 » CK_OBJECT_HANDLE, | 316 CK_OBJECT_HANDLE, |
| 332 » arraySize); | 317 arraySize); |
| 333 » } | 318 } |
| 334 » if (!objectHandles) { | 319 if (!objectHandles) { |
| 335 » nssSession_ExitMonitor(session); | 320 nssSession_ExitMonitor(session); |
| 336 » ckrv = CKR_HOST_MEMORY; | 321 ckrv = CKR_HOST_MEMORY; |
| 337 » goto loser; | 322 goto loser; |
| 338 » } | 323 } |
| 339 } | 324 } |
| 340 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); | 325 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); |
| 341 nssSession_ExitMonitor(session); /* ==== end session lock === */ | 326 nssSession_ExitMonitor(session); /* ==== end session lock === */ |
| 342 if (ckrv != CKR_OK) { | 327 if (ckrv != CKR_OK) { |
| 343 » goto loser; | 328 goto loser; |
| 344 } | 329 } |
| 345 if (numHandles > 0) { | 330 if (numHandles > 0) { |
| 346 » objects = create_objects_from_handles(tok, session, | 331 objects = create_objects_from_handles(tok, session, |
| 347 » objectHandles, numHandles); | 332 objectHandles, numHandles); |
| 348 } else { | 333 } else { |
| 349 » nss_SetError(NSS_ERROR_NOT_FOUND); | 334 nss_SetError(NSS_ERROR_NOT_FOUND); |
| 350 » objects = NULL; | 335 objects = NULL; |
| 351 } | 336 } |
| 352 if (objectHandles && objectHandles != staticObjects) { | 337 if (objectHandles && objectHandles != staticObjects) { |
| 353 » nss_ZFreeIf(objectHandles); | 338 nss_ZFreeIf(objectHandles); |
| 354 } | 339 } |
| 355 if (statusOpt) *statusOpt = PR_SUCCESS; | 340 if (statusOpt) |
| 341 *statusOpt = PR_SUCCESS; |
| 356 return objects; | 342 return objects; |
| 357 loser: | 343 loser: |
| 358 if (objectHandles && objectHandles != staticObjects) { | 344 if (objectHandles && objectHandles != staticObjects) { |
| 359 » nss_ZFreeIf(objectHandles); | 345 nss_ZFreeIf(objectHandles); |
| 360 } | 346 } |
| 361 /* | 347 /* |
| 362 * These errors should be treated the same as if the objects just weren't | 348 * These errors should be treated the same as if the objects just weren't |
| 363 * found.. | 349 * found.. |
| 364 */ | 350 */ |
| 365 if ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || | 351 if ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || |
| 366 » (ckrv == CKR_ATTRIBUTE_VALUE_INVALID) || | 352 (ckrv == CKR_ATTRIBUTE_VALUE_INVALID) || |
| 367 » (ckrv == CKR_DATA_INVALID) || | 353 (ckrv == CKR_DATA_INVALID) || |
| 368 » (ckrv == CKR_DATA_LEN_RANGE) || | 354 (ckrv == CKR_DATA_LEN_RANGE) || |
| 369 » (ckrv == CKR_FUNCTION_NOT_SUPPORTED) || | 355 (ckrv == CKR_FUNCTION_NOT_SUPPORTED) || |
| 370 » (ckrv == CKR_TEMPLATE_INCOMPLETE) || | 356 (ckrv == CKR_TEMPLATE_INCOMPLETE) || |
| 371 » (ckrv == CKR_TEMPLATE_INCONSISTENT)) { | 357 (ckrv == CKR_TEMPLATE_INCONSISTENT)) { |
| 372 | 358 |
| 373 » nss_SetError(NSS_ERROR_NOT_FOUND); | 359 nss_SetError(NSS_ERROR_NOT_FOUND); |
| 374 » if (statusOpt) *statusOpt = PR_SUCCESS; | 360 if (statusOpt) |
| 361 *statusOpt = PR_SUCCESS; |
| 375 } else { | 362 } else { |
| 376 » nss_SetError(ckrv); | 363 nss_SetError(ckrv); |
| 377 » nss_SetError(NSS_ERROR_PKCS11); | 364 nss_SetError(NSS_ERROR_PKCS11); |
| 378 » if (statusOpt) *statusOpt = PR_FAILURE; | 365 if (statusOpt) |
| 366 *statusOpt = PR_FAILURE; |
| 379 } | 367 } |
| 380 return (nssCryptokiObject **)NULL; | 368 return (nssCryptokiObject **)NULL; |
| 381 } | 369 } |
| 382 | 370 |
| 383 static nssCryptokiObject ** | 371 static nssCryptokiObject ** |
| 384 find_objects_by_template ( | 372 find_objects_by_template( |
| 385 NSSToken *token, | 373 NSSToken *token, |
| 386 nssSession *sessionOpt, | 374 nssSession *sessionOpt, |
| 387 CK_ATTRIBUTE_PTR obj_template, | 375 CK_ATTRIBUTE_PTR obj_template, |
| 388 CK_ULONG otsize, | 376 CK_ULONG otsize, |
| 389 PRUint32 maximumOpt, | 377 PRUint32 maximumOpt, |
| 390 PRStatus *statusOpt | 378 PRStatus *statusOpt) |
| 391 ) | |
| 392 { | 379 { |
| 393 CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1; | 380 CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1; |
| 394 nssCryptokiObject **objects = NULL; | 381 nssCryptokiObject **objects = NULL; |
| 395 PRUint32 i; | 382 PRUint32 i; |
| 396 | 383 |
| 397 if (!token) { | 384 if (!token) { |
| 398 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 385 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 399 » if (statusOpt) | 386 if (statusOpt) |
| 400 » *statusOpt = PR_FAILURE; | 387 *statusOpt = PR_FAILURE; |
| 401 » return NULL; | 388 return NULL; |
| 402 } | 389 } |
| 403 for (i=0; i<otsize; i++) { | 390 for (i = 0; i < otsize; i++) { |
| 404 » if (obj_template[i].type == CKA_CLASS) { | 391 if (obj_template[i].type == CKA_CLASS) { |
| 405 » objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; | 392 objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; |
| 406 » break; | 393 break; |
| 407 » } | 394 } |
| 408 } | 395 } |
| 409 PR_ASSERT(i < otsize); | 396 PR_ASSERT(i < otsize); |
| 410 if (i == otsize) { | 397 if (i == otsize) { |
| 411 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 398 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| 412 » if (statusOpt) *statusOpt = PR_FAILURE; | 399 if (statusOpt) |
| 413 » return NULL; | 400 *statusOpt = PR_FAILURE; |
| 401 return NULL; |
| 414 } | 402 } |
| 415 /* If these objects are being cached, try looking there first */ | 403 /* If these objects are being cached, try looking there first */ |
| 416 if (token->cache && | 404 if (token->cache && |
| 417 nssTokenObjectCache_HaveObjectClass(token->cache, objclass)) | 405 nssTokenObjectCache_HaveObjectClass(token->cache, objclass)) { |
| 418 { | 406 PRStatus status; |
| 419 » PRStatus status; | 407 objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache, |
| 420 » objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache, | 408 objclass, |
| 421 » objclass, | 409 obj_template, |
| 422 » obj_template, | 410 otsize, |
| 423 » otsize, | 411 maximumOpt, |
| 424 » maximumOpt, | 412 &status); |
| 425 » &status); | 413 if (status == PR_SUCCESS) { |
| 426 » if (status == PR_SUCCESS) { | 414 if (statusOpt) |
| 427 » if (statusOpt) *statusOpt = status; | 415 *statusOpt = status; |
| 428 » return objects; | 416 return objects; |
| 429 » } | 417 } |
| 430 } | 418 } |
| 431 /* Either they are not cached, or cache failed; look on token. */ | 419 /* Either they are not cached, or cache failed; look on token. */ |
| 432 objects = find_objects(token, sessionOpt, | 420 objects = find_objects(token, sessionOpt, |
| 433 obj_template, otsize, | 421 obj_template, otsize, |
| 434 maximumOpt, statusOpt); | 422 maximumOpt, statusOpt); |
| 435 return objects; | 423 return objects; |
| 436 } | 424 } |
| 437 | 425 |
| 438 extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; | 426 extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; |
| 439 | 427 |
| 440 NSS_IMPLEMENT nssCryptokiObject * | 428 NSS_IMPLEMENT nssCryptokiObject * |
| 441 nssToken_ImportCertificate ( | 429 nssToken_ImportCertificate( |
| 442 NSSToken *tok, | 430 NSSToken *tok, |
| 443 nssSession *sessionOpt, | 431 nssSession *sessionOpt, |
| 444 NSSCertificateType certType, | 432 NSSCertificateType certType, |
| 445 NSSItem *id, | 433 NSSItem *id, |
| 446 const NSSUTF8 *nickname, | 434 const NSSUTF8 *nickname, |
| 447 NSSDER *encoding, | 435 NSSDER *encoding, |
| 448 NSSDER *issuer, | 436 NSSDER *issuer, |
| 449 NSSDER *subject, | 437 NSSDER *subject, |
| 450 NSSDER *serial, | 438 NSSDER *serial, |
| 451 NSSASCII7 *email, | 439 NSSASCII7 *email, |
| 452 PRBool asTokenObject | 440 PRBool asTokenObject) |
| 453 ) | |
| 454 { | 441 { |
| 455 PRStatus status; | 442 PRStatus status; |
| 456 CK_CERTIFICATE_TYPE cert_type; | 443 CK_CERTIFICATE_TYPE cert_type; |
| 457 CK_ATTRIBUTE_PTR attr; | 444 CK_ATTRIBUTE_PTR attr; |
| 458 CK_ATTRIBUTE cert_tmpl[10]; | 445 CK_ATTRIBUTE cert_tmpl[10]; |
| 459 CK_ULONG ctsize; | 446 CK_ULONG ctsize; |
| 460 nssTokenSearchType searchType; | 447 nssTokenSearchType searchType; |
| 461 nssCryptokiObject *rvObject = NULL; | 448 nssCryptokiObject *rvObject = NULL; |
| 462 | 449 |
| 463 if (!tok) { | 450 if (!tok) { |
| 464 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 451 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 465 » return NULL; | 452 return NULL; |
| 466 } | 453 } |
| 467 if (certType == NSSCertificateType_PKIX) { | 454 if (certType == NSSCertificateType_PKIX) { |
| 468 » cert_type = CKC_X_509; | 455 cert_type = CKC_X_509; |
| 469 } else { | 456 } else { |
| 470 » return (nssCryptokiObject *)NULL; | 457 return (nssCryptokiObject *)NULL; |
| 471 } | 458 } |
| 472 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); | 459 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); |
| 473 if (asTokenObject) { | 460 if (asTokenObject) { |
| 474 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 461 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 475 » searchType = nssTokenSearchType_TokenOnly; | 462 searchType = nssTokenSearchType_TokenOnly; |
| 476 } else { | 463 } else { |
| 477 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 464 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 478 » searchType = nssTokenSearchType_SessionOnly; | 465 searchType = nssTokenSearchType_SessionOnly; |
| 479 } | 466 } |
| 480 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 467 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 481 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type); | 468 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CERTIFICATE_TYPE, cert_type); |
| 482 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); | 469 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
| 483 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); | 470 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); |
| 484 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); | 471 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); |
| 485 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); | 472 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); |
| 486 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 473 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
| 487 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); | 474 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); |
| 488 if (email) { | 475 if (email) { |
| 489 » NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); | 476 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); |
| 490 } | 477 } |
| 491 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); | 478 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); |
| 492 /* see if the cert is already there */ | 479 /* see if the cert is already there */ |
| 493 rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok, | 480 rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok, |
| 494 sessionOpt, | 481 sessionOpt, |
| 495 issuer, | 482 issuer, |
| 496 serial, | 483 serial, |
| 497 searchType, | 484 searchType, |
| 498 NULL); | 485 NULL); |
| 499 if (rvObject) { | 486 if (rvObject) { |
| 500 » NSSItem existingDER; | 487 NSSItem existingDER; |
| 501 » NSSSlot *slot = nssToken_GetSlot(tok); | 488 NSSSlot *slot = nssToken_GetSlot(tok); |
| 502 » nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE); | 489 nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE); |
| 503 » if (!session) { | 490 if (!session) { |
| 504 » nssCryptokiObject_Destroy(rvObject); | 491 nssCryptokiObject_Destroy(rvObject); |
| 505 » nssSlot_Destroy(slot); | 492 nssSlot_Destroy(slot); |
| 506 » return (nssCryptokiObject *)NULL; | 493 return (nssCryptokiObject *)NULL; |
| 507 » } | 494 } |
| 508 » /* Reject any attempt to import a new cert that has the same | 495 /* Reject any attempt to import a new cert that has the same |
| 509 » * issuer/serial as an existing cert, but does not have the | 496 * issuer/serial as an existing cert, but does not have the |
| 510 » * same encoding | 497 * same encoding |
| 511 » */ | 498 */ |
| 512 » NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); | 499 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); |
| 513 » NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); | 500 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); |
| 514 » NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); | 501 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); |
| 515 » status = nssCKObject_GetAttributes(rvObject->handle, | 502 status = nssCKObject_GetAttributes(rvObject->handle, |
| 516 » cert_tmpl, ctsize, NULL, | 503 cert_tmpl, ctsize, NULL, |
| 517 » session, slot); | 504 session, slot); |
| 518 » NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); | 505 NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); |
| 519 » if (status == PR_SUCCESS) { | 506 if (status == PR_SUCCESS) { |
| 520 » if (!nssItem_Equal(encoding, &existingDER, NULL)) { | 507 if (!nssItem_Equal(encoding, &existingDER, NULL)) { |
| 521 » » nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); | 508 nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); |
| 522 » » status = PR_FAILURE; | 509 status = PR_FAILURE; |
| 523 » } | 510 } |
| 524 » nss_ZFreeIf(existingDER.data); | 511 nss_ZFreeIf(existingDER.data); |
| 525 » } | 512 } |
| 526 » if (status == PR_FAILURE) { | 513 if (status == PR_FAILURE) { |
| 527 » nssCryptokiObject_Destroy(rvObject); | 514 nssCryptokiObject_Destroy(rvObject); |
| 528 » nssSession_Destroy(session); | 515 nssSession_Destroy(session); |
| 529 » nssSlot_Destroy(slot); | 516 nssSlot_Destroy(slot); |
| 530 » return (nssCryptokiObject *)NULL; | 517 return (nssCryptokiObject *)NULL; |
| 531 » } | 518 } |
| 532 » /* according to PKCS#11, label, ID, issuer, and serial number | 519 /* according to PKCS#11, label, ID, issuer, and serial number |
| 533 » * may change after the object has been created. For PKIX, the | 520 * may change after the object has been created. For PKIX, the |
| 534 » * last two attributes can't change, so for now we'll only worry | 521 * last two attributes can't change, so for now we'll only worry |
| 535 » * about the first two. | 522 * about the first two. |
| 536 » */ | 523 */ |
| 537 » NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); | 524 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); |
| 538 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); | 525 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
| 539 » NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); | 526 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); |
| 540 » NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); | 527 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); |
| 541 » /* reset the mutable attributes on the token */ | 528 /* reset the mutable attributes on the token */ |
| 542 » nssCKObject_SetAttributes(rvObject->handle, | 529 nssCKObject_SetAttributes(rvObject->handle, |
| 543 » cert_tmpl, ctsize, | 530 cert_tmpl, ctsize, |
| 544 » session, slot); | 531 session, slot); |
| 545 » if (!rvObject->label && nickname) { | 532 if (!rvObject->label && nickname) { |
| 546 » rvObject->label = nssUTF8_Duplicate(nickname, NULL); | 533 rvObject->label = nssUTF8_Duplicate(nickname, NULL); |
| 547 » } | 534 } |
| 548 » nssSession_Destroy(session); | 535 nssSession_Destroy(session); |
| 549 » nssSlot_Destroy(slot); | 536 nssSlot_Destroy(slot); |
| 550 } else { | 537 } else { |
| 551 » /* Import the certificate onto the token */ | 538 /* Import the certificate onto the token */ |
| 552 » rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize); | 539 rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize); |
| 553 } | 540 } |
| 554 if (rvObject && tok->cache) { | 541 if (rvObject && tok->cache) { |
| 555 » /* The cache will overwrite the attributes if the object already | 542 /* The cache will overwrite the attributes if the object already |
| 556 » * exists. | 543 * exists. |
| 557 » */ | 544 */ |
| 558 » nssTokenObjectCache_ImportObject(tok->cache, rvObject, | 545 nssTokenObjectCache_ImportObject(tok->cache, rvObject, |
| 559 » CKO_CERTIFICATE, | 546 CKO_CERTIFICATE, |
| 560 » cert_tmpl, ctsize); | 547 cert_tmpl, ctsize); |
| 561 } | 548 } |
| 562 return rvObject; | 549 return rvObject; |
| 563 } | 550 } |
| 564 | 551 |
| 565 /* traverse all objects of the given class - this should only happen | 552 /* traverse all objects of the given class - this should only happen |
| 566 * if the token has been marked as "traversable" | 553 * if the token has been marked as "traversable" |
| 567 */ | 554 */ |
| 568 NSS_IMPLEMENT nssCryptokiObject ** | 555 NSS_IMPLEMENT nssCryptokiObject ** |
| 569 nssToken_FindObjects ( | 556 nssToken_FindObjects( |
| 570 NSSToken *token, | 557 NSSToken *token, |
| 571 nssSession *sessionOpt, | 558 nssSession *sessionOpt, |
| 572 CK_OBJECT_CLASS objclass, | 559 CK_OBJECT_CLASS objclass, |
| 573 nssTokenSearchType searchType, | 560 nssTokenSearchType searchType, |
| 574 PRUint32 maximumOpt, | 561 PRUint32 maximumOpt, |
| 575 PRStatus *statusOpt | 562 PRStatus *statusOpt) |
| 576 ) | |
| 577 { | 563 { |
| 578 CK_ATTRIBUTE_PTR attr; | 564 CK_ATTRIBUTE_PTR attr; |
| 579 CK_ATTRIBUTE obj_template[2]; | 565 CK_ATTRIBUTE obj_template[2]; |
| 580 CK_ULONG obj_size; | 566 CK_ULONG obj_size; |
| 581 nssCryptokiObject **objects; | 567 nssCryptokiObject **objects; |
| 582 NSS_CK_TEMPLATE_START(obj_template, attr, obj_size); | 568 NSS_CK_TEMPLATE_START(obj_template, attr, obj_size); |
| 583 /* Set the search to token/session only if provided */ | 569 /* Set the search to token/session only if provided */ |
| 584 if (searchType == nssTokenSearchType_SessionOnly) { | 570 if (searchType == nssTokenSearchType_SessionOnly) { |
| 585 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 571 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 586 } else if (searchType == nssTokenSearchType_TokenOnly || | 572 } else if (searchType == nssTokenSearchType_TokenOnly || |
| 587 searchType == nssTokenSearchType_TokenForced) { | 573 searchType == nssTokenSearchType_TokenForced) { |
| 588 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 574 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 589 } | 575 } |
| 590 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, objclass); | 576 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, objclass); |
| 591 NSS_CK_TEMPLATE_FINISH(obj_template, attr, obj_size); | 577 NSS_CK_TEMPLATE_FINISH(obj_template, attr, obj_size); |
| 592 | 578 |
| 593 if (searchType == nssTokenSearchType_TokenForced) { | 579 if (searchType == nssTokenSearchType_TokenForced) { |
| 594 » objects = find_objects(token, sessionOpt, | 580 objects = find_objects(token, sessionOpt, |
| 595 » obj_template, obj_size, | 581 obj_template, obj_size, |
| 596 » maximumOpt, statusOpt); | 582 maximumOpt, statusOpt); |
| 597 } else { | 583 } else { |
| 598 » objects = find_objects_by_template(token, sessionOpt, | 584 objects = find_objects_by_template(token, sessionOpt, |
| 599 » obj_template, obj_size, | 585 obj_template, obj_size, |
| 600 » maximumOpt, statusOpt); | 586 maximumOpt, statusOpt); |
| 601 } | 587 } |
| 602 return objects; | 588 return objects; |
| 603 } | 589 } |
| 604 | 590 |
| 605 NSS_IMPLEMENT nssCryptokiObject ** | 591 NSS_IMPLEMENT nssCryptokiObject ** |
| 606 nssToken_FindCertificatesBySubject ( | 592 nssToken_FindCertificatesBySubject( |
| 607 NSSToken *token, | 593 NSSToken *token, |
| 608 nssSession *sessionOpt, | 594 nssSession *sessionOpt, |
| 609 NSSDER *subject, | 595 NSSDER *subject, |
| 610 nssTokenSearchType searchType, | 596 nssTokenSearchType searchType, |
| 611 PRUint32 maximumOpt, | 597 PRUint32 maximumOpt, |
| 612 PRStatus *statusOpt | 598 PRStatus *statusOpt) |
| 613 ) | |
| 614 { | 599 { |
| 615 CK_ATTRIBUTE_PTR attr; | 600 CK_ATTRIBUTE_PTR attr; |
| 616 CK_ATTRIBUTE subj_template[3]; | 601 CK_ATTRIBUTE subj_template[3]; |
| 617 CK_ULONG stsize; | 602 CK_ULONG stsize; |
| 618 nssCryptokiObject **objects; | 603 nssCryptokiObject **objects; |
| 619 NSS_CK_TEMPLATE_START(subj_template, attr, stsize); | 604 NSS_CK_TEMPLATE_START(subj_template, attr, stsize); |
| 620 /* Set the search to token/session only if provided */ | 605 /* Set the search to token/session only if provided */ |
| 621 if (searchType == nssTokenSearchType_SessionOnly) { | 606 if (searchType == nssTokenSearchType_SessionOnly) { |
| 622 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 607 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 623 } else if (searchType == nssTokenSearchType_TokenOnly) { | 608 } else if (searchType == nssTokenSearchType_TokenOnly) { |
| 624 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 609 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 625 } | 610 } |
| 626 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 611 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 627 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 612 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
| 628 NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); | 613 NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); |
| 629 /* now locate the token certs matching this template */ | 614 /* now locate the token certs matching this template */ |
| 630 objects = find_objects_by_template(token, sessionOpt, | 615 objects = find_objects_by_template(token, sessionOpt, |
| 631 subj_template, stsize, | 616 subj_template, stsize, |
| 632 maximumOpt, statusOpt); | 617 maximumOpt, statusOpt); |
| 633 return objects; | 618 return objects; |
| 634 } | 619 } |
| 635 | 620 |
| 636 NSS_IMPLEMENT nssCryptokiObject ** | 621 NSS_IMPLEMENT nssCryptokiObject ** |
| 637 nssToken_FindCertificatesByNickname ( | 622 nssToken_FindCertificatesByNickname( |
| 638 NSSToken *token, | 623 NSSToken *token, |
| 639 nssSession *sessionOpt, | 624 nssSession *sessionOpt, |
| 640 const NSSUTF8 *name, | 625 const NSSUTF8 *name, |
| 641 nssTokenSearchType searchType, | 626 nssTokenSearchType searchType, |
| 642 PRUint32 maximumOpt, | 627 PRUint32 maximumOpt, |
| 643 PRStatus *statusOpt | 628 PRStatus *statusOpt) |
| 644 ) | |
| 645 { | 629 { |
| 646 CK_ATTRIBUTE_PTR attr; | 630 CK_ATTRIBUTE_PTR attr; |
| 647 CK_ATTRIBUTE nick_template[3]; | 631 CK_ATTRIBUTE nick_template[3]; |
| 648 CK_ULONG ntsize; | 632 CK_ULONG ntsize; |
| 649 nssCryptokiObject **objects; | 633 nssCryptokiObject **objects; |
| 650 NSS_CK_TEMPLATE_START(nick_template, attr, ntsize); | 634 NSS_CK_TEMPLATE_START(nick_template, attr, ntsize); |
| 651 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name); | 635 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name); |
| 652 /* Set the search to token/session only if provided */ | 636 /* Set the search to token/session only if provided */ |
| 653 if (searchType == nssTokenSearchType_SessionOnly) { | 637 if (searchType == nssTokenSearchType_SessionOnly) { |
| 654 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 638 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 655 } else if (searchType == nssTokenSearchType_TokenOnly) { | 639 } else if (searchType == nssTokenSearchType_TokenOnly) { |
| 656 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 640 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 657 } | 641 } |
| 658 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 642 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 659 NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize); | 643 NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize); |
| 660 /* now locate the token certs matching this template */ | 644 /* now locate the token certs matching this template */ |
| 661 objects = find_objects_by_template(token, sessionOpt, | 645 objects = find_objects_by_template(token, sessionOpt, |
| 662 nick_template, ntsize, | 646 nick_template, ntsize, |
| 663 maximumOpt, statusOpt); | 647 maximumOpt, statusOpt); |
| 664 if (!objects) { | 648 if (!objects) { |
| 665 » /* This is to workaround the fact that PKCS#11 doesn't specify | 649 /* This is to workaround the fact that PKCS#11 doesn't specify |
| 666 » * whether the '\0' should be included. XXX Is that still true? | 650 * whether the '\0' should be included. XXX Is that still true? |
| 667 » * im - this is not needed by the current softoken. However, I'm | 651 * im - this is not needed by the current softoken. However, I'm |
| 668 » * leaving it in until I have surveyed more tokens to see if it needed. | 652 * leaving it in until I have surveyed more tokens to see if it needed. |
| 669 » * well, its needed by the builtin token... | 653 * well, its needed by the builtin token... |
| 670 » */ | 654 */ |
| 671 » nick_template[0].ulValueLen++; | 655 nick_template[0].ulValueLen++; |
| 672 » objects = find_objects_by_template(token, sessionOpt, | 656 objects = find_objects_by_template(token, sessionOpt, |
| 673 » nick_template, ntsize, | 657 nick_template, ntsize, |
| 674 » maximumOpt, statusOpt); | 658 maximumOpt, statusOpt); |
| 675 } | 659 } |
| 676 return objects; | 660 return objects; |
| 677 } | 661 } |
| 678 | 662 |
| 679 /* XXX | 663 /* XXX |
| 680 * This function *does not* use the token object cache, because not even | 664 * This function *does not* use the token object cache, because not even |
| 681 * the softoken will return a value for CKA_NSS_EMAIL from a call | 665 * the softoken will return a value for CKA_NSS_EMAIL from a call |
| 682 * to GetAttributes. The softoken does allow searches with that attribute, | 666 * to GetAttributes. The softoken does allow searches with that attribute, |
| 683 * it just won't return a value for it. | 667 * it just won't return a value for it. |
| 684 */ | 668 */ |
| 685 NSS_IMPLEMENT nssCryptokiObject ** | 669 NSS_IMPLEMENT nssCryptokiObject ** |
| 686 nssToken_FindCertificatesByEmail ( | 670 nssToken_FindCertificatesByEmail( |
| 687 NSSToken *token, | 671 NSSToken *token, |
| 688 nssSession *sessionOpt, | 672 nssSession *sessionOpt, |
| 689 NSSASCII7 *email, | 673 NSSASCII7 *email, |
| 690 nssTokenSearchType searchType, | 674 nssTokenSearchType searchType, |
| 691 PRUint32 maximumOpt, | 675 PRUint32 maximumOpt, |
| 692 PRStatus *statusOpt | 676 PRStatus *statusOpt) |
| 693 ) | |
| 694 { | 677 { |
| 695 CK_ATTRIBUTE_PTR attr; | 678 CK_ATTRIBUTE_PTR attr; |
| 696 CK_ATTRIBUTE email_template[3]; | 679 CK_ATTRIBUTE email_template[3]; |
| 697 CK_ULONG etsize; | 680 CK_ULONG etsize; |
| 698 nssCryptokiObject **objects; | 681 nssCryptokiObject **objects; |
| 699 NSS_CK_TEMPLATE_START(email_template, attr, etsize); | 682 NSS_CK_TEMPLATE_START(email_template, attr, etsize); |
| 700 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); | 683 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); |
| 701 /* Set the search to token/session only if provided */ | 684 /* Set the search to token/session only if provided */ |
| 702 if (searchType == nssTokenSearchType_SessionOnly) { | 685 if (searchType == nssTokenSearchType_SessionOnly) { |
| 703 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 686 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 704 } else if (searchType == nssTokenSearchType_TokenOnly) { | 687 } else if (searchType == nssTokenSearchType_TokenOnly) { |
| 705 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 688 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 706 } | 689 } |
| 707 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 690 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 708 NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize); | 691 NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize); |
| 709 /* now locate the token certs matching this template */ | 692 /* now locate the token certs matching this template */ |
| 710 objects = find_objects(token, sessionOpt, | 693 objects = find_objects(token, sessionOpt, |
| 711 email_template, etsize, | 694 email_template, etsize, |
| 712 maximumOpt, statusOpt); | 695 maximumOpt, statusOpt); |
| 713 if (!objects) { | 696 if (!objects) { |
| 714 » /* This is to workaround the fact that PKCS#11 doesn't specify | 697 /* This is to workaround the fact that PKCS#11 doesn't specify |
| 715 » * whether the '\0' should be included. XXX Is that still true? | 698 * whether the '\0' should be included. XXX Is that still true? |
| 716 » * im - this is not needed by the current softoken. However, I'm | 699 * im - this is not needed by the current softoken. However, I'm |
| 717 » * leaving it in until I have surveyed more tokens to see if it needed. | 700 * leaving it in until I have surveyed more tokens to see if it needed. |
| 718 » * well, its needed by the builtin token... | 701 * well, its needed by the builtin token... |
| 719 » */ | 702 */ |
| 720 » email_template[0].ulValueLen++; | 703 email_template[0].ulValueLen++; |
| 721 » objects = find_objects(token, sessionOpt, | 704 objects = find_objects(token, sessionOpt, |
| 722 » email_template, etsize, | 705 email_template, etsize, |
| 723 » maximumOpt, statusOpt); | 706 maximumOpt, statusOpt); |
| 724 } | 707 } |
| 725 return objects; | 708 return objects; |
| 726 } | 709 } |
| 727 | 710 |
| 728 NSS_IMPLEMENT nssCryptokiObject ** | 711 NSS_IMPLEMENT nssCryptokiObject ** |
| 729 nssToken_FindCertificatesByID ( | 712 nssToken_FindCertificatesByID( |
| 730 NSSToken *token, | 713 NSSToken *token, |
| 731 nssSession *sessionOpt, | 714 nssSession *sessionOpt, |
| 732 NSSItem *id, | 715 NSSItem *id, |
| 733 nssTokenSearchType searchType, | 716 nssTokenSearchType searchType, |
| 734 PRUint32 maximumOpt, | 717 PRUint32 maximumOpt, |
| 735 PRStatus *statusOpt | 718 PRStatus *statusOpt) |
| 736 ) | |
| 737 { | 719 { |
| 738 CK_ATTRIBUTE_PTR attr; | 720 CK_ATTRIBUTE_PTR attr; |
| 739 CK_ATTRIBUTE id_template[3]; | 721 CK_ATTRIBUTE id_template[3]; |
| 740 CK_ULONG idtsize; | 722 CK_ULONG idtsize; |
| 741 nssCryptokiObject **objects; | 723 nssCryptokiObject **objects; |
| 742 NSS_CK_TEMPLATE_START(id_template, attr, idtsize); | 724 NSS_CK_TEMPLATE_START(id_template, attr, idtsize); |
| 743 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); | 725 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
| 744 /* Set the search to token/session only if provided */ | 726 /* Set the search to token/session only if provided */ |
| 745 if (searchType == nssTokenSearchType_SessionOnly) { | 727 if (searchType == nssTokenSearchType_SessionOnly) { |
| 746 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 728 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 747 } else if (searchType == nssTokenSearchType_TokenOnly) { | 729 } else if (searchType == nssTokenSearchType_TokenOnly) { |
| 748 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 730 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 749 } | 731 } |
| 750 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 732 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 751 NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize); | 733 NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize); |
| 752 /* now locate the token certs matching this template */ | 734 /* now locate the token certs matching this template */ |
| 753 objects = find_objects_by_template(token, sessionOpt, | 735 objects = find_objects_by_template(token, sessionOpt, |
| 754 id_template, idtsize, | 736 id_template, idtsize, |
| 755 maximumOpt, statusOpt); | 737 maximumOpt, statusOpt); |
| 756 return objects; | 738 return objects; |
| 757 } | 739 } |
| 758 | 740 |
| 759 /* | 741 /* |
| 760 * decode the serial item and return our result. | 742 * decode the serial item and return our result. |
| 761 * NOTE serialDecode's data is really stored in serial. Don't free it. | 743 * NOTE serialDecode's data is really stored in serial. Don't free it. |
| 762 */ | 744 */ |
| 763 static PRStatus | 745 static PRStatus |
| 764 nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode) | 746 nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode) |
| 765 { | 747 { |
| 766 unsigned char *data = (unsigned char *)serial->data; | 748 unsigned char *data = (unsigned char *)serial->data; |
| 767 int data_left, data_len, index; | 749 int data_left, data_len, index; |
| 768 | 750 |
| 769 if ((serial->size >= 3) && (data[0] == 0x2)) { | 751 if ((serial->size >= 3) && (data[0] == 0x2)) { |
| 770 » /* remove the der encoding of the serial number before generating the | 752 /* remove the der encoding of the serial number before generating the |
| 771 » * key.. */ | 753 * key.. */ |
| 772 » data_left = serial->size-2; | 754 data_left = serial->size - 2; |
| 773 » data_len = data[1]; | 755 data_len = data[1]; |
| 774 » index = 2; | 756 index = 2; |
| 775 | 757 |
| 776 » /* extended length ? (not very likely for a serial number) */ | 758 /* extended length ? (not very likely for a serial number) */ |
| 777 » if (data_len & 0x80) { | 759 if (data_len & 0x80) { |
| 778 » int len_count = data_len & 0x7f; | 760 int len_count = data_len & 0x7f; |
| 779 | 761 |
| 780 » data_len = 0; | 762 data_len = 0; |
| 781 » data_left -= len_count; | 763 data_left -= len_count; |
| 782 » if (data_left > 0) { | 764 if (data_left > 0) { |
| 783 » » while (len_count --) { | 765 while (len_count--) { |
| 784 » » data_len = (data_len << 8) | data[index++]; | 766 data_len = (data_len << 8) | data[index++]; |
| 785 » » } | 767 } |
| 786 » } | 768 } |
| 787 » } | 769 } |
| 788 » /* XXX leaving any leading zeros on the serial number for backwards | 770 /* XXX leaving any leading zeros on the serial number for backwards |
| 789 » * compatibility | 771 * compatibility |
| 790 » */ | 772 */ |
| 791 » /* not a valid der, must be just an unlucky serial number value */ | 773 /* not a valid der, must be just an unlucky serial number value */ |
| 792 » if (data_len == data_left) { | 774 if (data_len == data_left) { |
| 793 » serialDecode->size = data_len; | 775 serialDecode->size = data_len; |
| 794 » serialDecode->data = &data[index]; | 776 serialDecode->data = &data[index]; |
| 795 » return PR_SUCCESS; | 777 return PR_SUCCESS; |
| 796 » } | 778 } |
| 797 } | 779 } |
| 798 return PR_FAILURE; | 780 return PR_FAILURE; |
| 799 } | 781 } |
| 800 | 782 |
| 801 NSS_IMPLEMENT nssCryptokiObject * | 783 NSS_IMPLEMENT nssCryptokiObject * |
| 802 nssToken_FindCertificateByIssuerAndSerialNumber ( | 784 nssToken_FindCertificateByIssuerAndSerialNumber( |
| 803 NSSToken *token, | 785 NSSToken *token, |
| 804 nssSession *sessionOpt, | 786 nssSession *sessionOpt, |
| 805 NSSDER *issuer, | 787 NSSDER *issuer, |
| 806 NSSDER *serial, | 788 NSSDER *serial, |
| 807 nssTokenSearchType searchType, | 789 nssTokenSearchType searchType, |
| 808 PRStatus *statusOpt | 790 PRStatus *statusOpt) |
| 809 ) | |
| 810 { | 791 { |
| 811 CK_ATTRIBUTE_PTR attr; | 792 CK_ATTRIBUTE_PTR attr; |
| 812 CK_ATTRIBUTE_PTR serialAttr; | 793 CK_ATTRIBUTE_PTR serialAttr; |
| 813 CK_ATTRIBUTE cert_template[4]; | 794 CK_ATTRIBUTE cert_template[4]; |
| 814 CK_ULONG ctsize; | 795 CK_ULONG ctsize; |
| 815 nssCryptokiObject **objects; | 796 nssCryptokiObject **objects; |
| 816 nssCryptokiObject *rvObject = NULL; | 797 nssCryptokiObject *rvObject = NULL; |
| 817 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); | 798 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); |
| 818 | 799 |
| 819 if (!token) { | 800 if (!token) { |
| 820 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 801 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 821 » if (statusOpt) | 802 if (statusOpt) |
| 822 » *statusOpt = PR_FAILURE; | 803 *statusOpt = PR_FAILURE; |
| 823 » return NULL; | 804 return NULL; |
| 824 } | 805 } |
| 825 /* Set the search to token/session only if provided */ | 806 /* Set the search to token/session only if provided */ |
| 826 if (searchType == nssTokenSearchType_SessionOnly) { | 807 if (searchType == nssTokenSearchType_SessionOnly) { |
| 827 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 808 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 828 } else if ((searchType == nssTokenSearchType_TokenOnly) || | 809 } else if ((searchType == nssTokenSearchType_TokenOnly) || |
| 829 (searchType == nssTokenSearchType_TokenForced)) { | 810 (searchType == nssTokenSearchType_TokenForced)) { |
| 830 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 811 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 831 } | 812 } |
| 832 /* Set the unique id */ | 813 /* Set the unique id */ |
| 833 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 814 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 834 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); | 815 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); |
| 835 serialAttr = attr; | 816 serialAttr = attr; |
| 836 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); | 817 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); |
| 837 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); | 818 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); |
| 838 /* get the object handle */ | 819 /* get the object handle */ |
| 839 if (searchType == nssTokenSearchType_TokenForced) { | 820 if (searchType == nssTokenSearchType_TokenForced) { |
| 840 » objects = find_objects(token, sessionOpt, | 821 objects = find_objects(token, sessionOpt, |
| 841 » cert_template, ctsize, | 822 cert_template, ctsize, |
| 842 » 1, statusOpt); | 823 1, statusOpt); |
| 843 } else { | 824 } else { |
| 844 » objects = find_objects_by_template(token, sessionOpt, | 825 objects = find_objects_by_template(token, sessionOpt, |
| 845 cert_template, ctsize, | 826 cert_template, ctsize, |
| 846 1, statusOpt); | 827 1, statusOpt); |
| 847 } | 828 } |
| 848 if (objects) { | 829 if (objects) { |
| 849 » rvObject = objects[0]; | 830 rvObject = objects[0]; |
| 850 » nss_ZFreeIf(objects); | 831 nss_ZFreeIf(objects); |
| 851 } | 832 } |
| 852 | 833 |
| 853 /* | 834 /* |
| 854 * NSS used to incorrectly store serial numbers in their decoded form. | 835 * NSS used to incorrectly store serial numbers in their decoded form. |
| 855 * because of this old tokens have decoded serial numbers. | 836 * because of this old tokens have decoded serial numbers. |
| 856 */ | 837 */ |
| 857 if (!objects) { | 838 if (!objects) { |
| 858 » NSSItem serialDecode; | 839 NSSItem serialDecode; |
| 859 » PRStatus status; | 840 PRStatus status; |
| 860 | 841 |
| 861 » status = nssToken_decodeSerialItem(serial, &serialDecode); | 842 status = nssToken_decodeSerialItem(serial, &serialDecode); |
| 862 » if (status != PR_SUCCESS) { | 843 if (status != PR_SUCCESS) { |
| 863 » return NULL; | 844 return NULL; |
| 864 » } | 845 } |
| 865 » NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr,CKA_SERIAL_NUMBER,&serialDecode); | 846 NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr, CKA_SERIAL_NUMBER, &serialDecode); |
| 866 » if (searchType == nssTokenSearchType_TokenForced) { | 847 if (searchType == nssTokenSearchType_TokenForced) { |
| 867 » objects = find_objects(token, sessionOpt, | 848 objects = find_objects(token, sessionOpt, |
| 868 » cert_template, ctsize, | 849 cert_template, ctsize, |
| 869 » 1, statusOpt); | 850 1, statusOpt); |
| 870 » } else { | 851 } else { |
| 871 » objects = find_objects_by_template(token, sessionOpt, | 852 objects = find_objects_by_template(token, sessionOpt, |
| 872 cert_template, ctsize, | 853 cert_template, ctsize, |
| 873 1, statusOpt); | 854 1, statusOpt); |
| 874 » } | 855 } |
| 875 » if (objects) { | 856 if (objects) { |
| 876 » rvObject = objects[0]; | 857 rvObject = objects[0]; |
| 877 » nss_ZFreeIf(objects); | 858 nss_ZFreeIf(objects); |
| 878 » } | 859 } |
| 879 } | 860 } |
| 880 return rvObject; | 861 return rvObject; |
| 881 } | 862 } |
| 882 | 863 |
| 883 NSS_IMPLEMENT nssCryptokiObject * | 864 NSS_IMPLEMENT nssCryptokiObject * |
| 884 nssToken_FindCertificateByEncodedCertificate ( | 865 nssToken_FindCertificateByEncodedCertificate( |
| 885 NSSToken *token, | 866 NSSToken *token, |
| 886 nssSession *sessionOpt, | 867 nssSession *sessionOpt, |
| 887 NSSBER *encodedCertificate, | 868 NSSBER *encodedCertificate, |
| 888 nssTokenSearchType searchType, | 869 nssTokenSearchType searchType, |
| 889 PRStatus *statusOpt | 870 PRStatus *statusOpt) |
| 890 ) | |
| 891 { | 871 { |
| 892 CK_ATTRIBUTE_PTR attr; | 872 CK_ATTRIBUTE_PTR attr; |
| 893 CK_ATTRIBUTE cert_template[3]; | 873 CK_ATTRIBUTE cert_template[3]; |
| 894 CK_ULONG ctsize; | 874 CK_ULONG ctsize; |
| 895 nssCryptokiObject **objects; | 875 nssCryptokiObject **objects; |
| 896 nssCryptokiObject *rvObject = NULL; | 876 nssCryptokiObject *rvObject = NULL; |
| 897 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); | 877 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); |
| 898 /* Set the search to token/session only if provided */ | 878 /* Set the search to token/session only if provided */ |
| 899 if (searchType == nssTokenSearchType_SessionOnly) { | 879 if (searchType == nssTokenSearchType_SessionOnly) { |
| 900 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 880 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 901 } else if (searchType == nssTokenSearchType_TokenOnly) { | 881 } else if (searchType == nssTokenSearchType_TokenOnly) { |
| 902 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 882 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 903 } | 883 } |
| 904 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 884 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 905 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); | 885 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); |
| 906 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); | 886 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); |
| 907 /* get the object handle */ | 887 /* get the object handle */ |
| 908 objects = find_objects_by_template(token, sessionOpt, | 888 objects = find_objects_by_template(token, sessionOpt, |
| 909 cert_template, ctsize, | 889 cert_template, ctsize, |
| 910 1, statusOpt); | 890 1, statusOpt); |
| 911 if (objects) { | 891 if (objects) { |
| 912 » rvObject = objects[0]; | 892 rvObject = objects[0]; |
| 913 » nss_ZFreeIf(objects); | 893 nss_ZFreeIf(objects); |
| 914 } | 894 } |
| 915 return rvObject; | 895 return rvObject; |
| 916 } | 896 } |
| 917 | 897 |
| 918 NSS_IMPLEMENT nssCryptokiObject ** | 898 NSS_IMPLEMENT nssCryptokiObject ** |
| 919 nssToken_FindPrivateKeys ( | 899 nssToken_FindPrivateKeys( |
| 920 NSSToken *token, | 900 NSSToken *token, |
| 921 nssSession *sessionOpt, | 901 nssSession *sessionOpt, |
| 922 nssTokenSearchType searchType, | 902 nssTokenSearchType searchType, |
| 923 PRUint32 maximumOpt, | 903 PRUint32 maximumOpt, |
| 924 PRStatus *statusOpt | 904 PRStatus *statusOpt) |
| 925 ) | |
| 926 { | 905 { |
| 927 CK_ATTRIBUTE_PTR attr; | 906 CK_ATTRIBUTE_PTR attr; |
| 928 CK_ATTRIBUTE key_template[2]; | 907 CK_ATTRIBUTE key_template[2]; |
| 929 CK_ULONG ktsize; | 908 CK_ULONG ktsize; |
| 930 nssCryptokiObject **objects; | 909 nssCryptokiObject **objects; |
| 931 | 910 |
| 932 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); | 911 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); |
| 933 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); | 912 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); |
| 934 if (searchType == nssTokenSearchType_SessionOnly) { | 913 if (searchType == nssTokenSearchType_SessionOnly) { |
| 935 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 914 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 936 } else if (searchType == nssTokenSearchType_TokenOnly) { | 915 } else if (searchType == nssTokenSearchType_TokenOnly) { |
| 937 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 916 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 938 } | 917 } |
| 939 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); | 918 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); |
| 940 | 919 |
| 941 objects = find_objects_by_template(token, sessionOpt, | 920 objects = find_objects_by_template(token, sessionOpt, |
| 942 key_template, ktsize, | 921 key_template, ktsize, |
| 943 maximumOpt, statusOpt); | 922 maximumOpt, statusOpt); |
| 944 return objects; | 923 return objects; |
| 945 } | 924 } |
| 946 | 925 |
| 947 /* XXX ?there are no session cert objects, so only search token objects */ | 926 /* XXX ?there are no session cert objects, so only search token objects */ |
| 948 NSS_IMPLEMENT nssCryptokiObject * | 927 NSS_IMPLEMENT nssCryptokiObject * |
| 949 nssToken_FindPrivateKeyByID ( | 928 nssToken_FindPrivateKeyByID( |
| 950 NSSToken *token, | 929 NSSToken *token, |
| 951 nssSession *sessionOpt, | 930 nssSession *sessionOpt, |
| 952 NSSItem *keyID | 931 NSSItem *keyID) |
| 953 ) | |
| 954 { | 932 { |
| 955 CK_ATTRIBUTE_PTR attr; | 933 CK_ATTRIBUTE_PTR attr; |
| 956 CK_ATTRIBUTE key_template[3]; | 934 CK_ATTRIBUTE key_template[3]; |
| 957 CK_ULONG ktsize; | 935 CK_ULONG ktsize; |
| 958 nssCryptokiObject **objects; | 936 nssCryptokiObject **objects; |
| 959 nssCryptokiObject *rvKey = NULL; | 937 nssCryptokiObject *rvKey = NULL; |
| 960 | 938 |
| 961 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); | 939 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); |
| 962 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); | 940 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); |
| 963 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 941 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 964 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); | 942 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); |
| 965 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); | 943 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); |
| 966 | 944 |
| 967 objects = find_objects_by_template(token, sessionOpt, | 945 objects = find_objects_by_template(token, sessionOpt, |
| 968 key_template, ktsize, | 946 key_template, ktsize, |
| 969 1, NULL); | 947 1, NULL); |
| 970 if (objects) { | 948 if (objects) { |
| 971 » rvKey = objects[0]; | 949 rvKey = objects[0]; |
| 972 » nss_ZFreeIf(objects); | 950 nss_ZFreeIf(objects); |
| 973 } | 951 } |
| 974 return rvKey; | 952 return rvKey; |
| 975 } | 953 } |
| 976 | 954 |
| 977 /* XXX ?there are no session cert objects, so only search token objects */ | 955 /* XXX ?there are no session cert objects, so only search token objects */ |
| 978 NSS_IMPLEMENT nssCryptokiObject * | 956 NSS_IMPLEMENT nssCryptokiObject * |
| 979 nssToken_FindPublicKeyByID ( | 957 nssToken_FindPublicKeyByID( |
| 980 NSSToken *token, | 958 NSSToken *token, |
| 981 nssSession *sessionOpt, | 959 nssSession *sessionOpt, |
| 982 NSSItem *keyID | 960 NSSItem *keyID) |
| 983 ) | |
| 984 { | 961 { |
| 985 CK_ATTRIBUTE_PTR attr; | 962 CK_ATTRIBUTE_PTR attr; |
| 986 CK_ATTRIBUTE key_template[3]; | 963 CK_ATTRIBUTE key_template[3]; |
| 987 CK_ULONG ktsize; | 964 CK_ULONG ktsize; |
| 988 nssCryptokiObject **objects; | 965 nssCryptokiObject **objects; |
| 989 nssCryptokiObject *rvKey = NULL; | 966 nssCryptokiObject *rvKey = NULL; |
| 990 | 967 |
| 991 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); | 968 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); |
| 992 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey); | 969 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey); |
| 993 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 970 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 994 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); | 971 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); |
| 995 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); | 972 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); |
| 996 | 973 |
| 997 objects = find_objects_by_template(token, sessionOpt, | 974 objects = find_objects_by_template(token, sessionOpt, |
| 998 key_template, ktsize, | 975 key_template, ktsize, |
| 999 1, NULL); | 976 1, NULL); |
| 1000 if (objects) { | 977 if (objects) { |
| 1001 » rvKey = objects[0]; | 978 rvKey = objects[0]; |
| 1002 » nss_ZFreeIf(objects); | 979 nss_ZFreeIf(objects); |
| 1003 } | 980 } |
| 1004 return rvKey; | 981 return rvKey; |
| 1005 } | 982 } |
| 1006 | 983 |
| 1007 static void | 984 static void |
| 1008 sha1_hash(NSSItem *input, NSSItem *output) | 985 sha1_hash(NSSItem *input, NSSItem *output) |
| 1009 { | 986 { |
| 1010 NSSAlgorithmAndParameters *ap; | 987 NSSAlgorithmAndParameters *ap; |
| 1011 PK11SlotInfo *internal = PK11_GetInternalSlot(); | 988 PK11SlotInfo *internal = PK11_GetInternalSlot(); |
| 1012 NSSToken *token = PK11Slot_GetNSSToken(internal); | 989 NSSToken *token = PK11Slot_GetNSSToken(internal); |
| 1013 ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL); | 990 ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL); |
| 1014 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); | 991 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); |
| 1015 PK11_FreeSlot(token->pk11slot); | 992 PK11_FreeSlot(token->pk11slot); |
| 1016 nss_ZFreeIf(ap); | 993 nss_ZFreeIf(ap); |
| 1017 } | 994 } |
| 1018 | 995 |
| 1019 static void | 996 static void |
| 1020 md5_hash(NSSItem *input, NSSItem *output) | 997 md5_hash(NSSItem *input, NSSItem *output) |
| 1021 { | 998 { |
| 1022 NSSAlgorithmAndParameters *ap; | 999 NSSAlgorithmAndParameters *ap; |
| 1023 PK11SlotInfo *internal = PK11_GetInternalSlot(); | 1000 PK11SlotInfo *internal = PK11_GetInternalSlot(); |
| 1024 NSSToken *token = PK11Slot_GetNSSToken(internal); | 1001 NSSToken *token = PK11Slot_GetNSSToken(internal); |
| 1025 ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); | 1002 ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); |
| 1026 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); | 1003 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); |
| 1027 PK11_FreeSlot(token->pk11slot); | 1004 PK11_FreeSlot(token->pk11slot); |
| 1028 nss_ZFreeIf(ap); | 1005 nss_ZFreeIf(ap); |
| 1029 } | 1006 } |
| 1030 | 1007 |
| 1031 static CK_TRUST | 1008 static CK_TRUST |
| 1032 get_ck_trust ( | 1009 get_ck_trust( |
| 1033 nssTrustLevel nssTrust | 1010 nssTrustLevel nssTrust) |
| 1034 ) | |
| 1035 { | 1011 { |
| 1036 CK_TRUST t; | 1012 CK_TRUST t; |
| 1037 switch (nssTrust) { | 1013 switch (nssTrust) { |
| 1038 case nssTrustLevel_NotTrusted: t = CKT_NSS_NOT_TRUSTED; break; | 1014 case nssTrustLevel_NotTrusted: |
| 1039 case nssTrustLevel_TrustedDelegator: t = CKT_NSS_TRUSTED_DELEGATOR; | 1015 t = CKT_NSS_NOT_TRUSTED; |
| 1040 » break; | 1016 break; |
| 1041 case nssTrustLevel_ValidDelegator: t = CKT_NSS_VALID_DELEGATOR; break; | 1017 case nssTrustLevel_TrustedDelegator: |
| 1042 case nssTrustLevel_Trusted: t = CKT_NSS_TRUSTED; break; | 1018 t = CKT_NSS_TRUSTED_DELEGATOR; |
| 1043 case nssTrustLevel_MustVerify: t = CKT_NSS_MUST_VERIFY_TRUST; break; | 1019 break; |
| 1044 case nssTrustLevel_Unknown: | 1020 case nssTrustLevel_ValidDelegator: |
| 1045 default: t = CKT_NSS_TRUST_UNKNOWN; break; | 1021 t = CKT_NSS_VALID_DELEGATOR; |
| 1022 break; |
| 1023 case nssTrustLevel_Trusted: |
| 1024 t = CKT_NSS_TRUSTED; |
| 1025 break; |
| 1026 case nssTrustLevel_MustVerify: |
| 1027 t = CKT_NSS_MUST_VERIFY_TRUST; |
| 1028 break; |
| 1029 case nssTrustLevel_Unknown: |
| 1030 default: |
| 1031 t = CKT_NSS_TRUST_UNKNOWN; |
| 1032 break; |
| 1046 } | 1033 } |
| 1047 return t; | 1034 return t; |
| 1048 } | 1035 } |
| 1049 | 1036 |
| 1050 NSS_IMPLEMENT nssCryptokiObject * | 1037 NSS_IMPLEMENT nssCryptokiObject * |
| 1051 nssToken_ImportTrust ( | 1038 nssToken_ImportTrust( |
| 1052 NSSToken *tok, | 1039 NSSToken *tok, |
| 1053 nssSession *sessionOpt, | 1040 nssSession *sessionOpt, |
| 1054 NSSDER *certEncoding, | 1041 NSSDER *certEncoding, |
| 1055 NSSDER *certIssuer, | 1042 NSSDER *certIssuer, |
| 1056 NSSDER *certSerial, | 1043 NSSDER *certSerial, |
| 1057 nssTrustLevel serverAuth, | 1044 nssTrustLevel serverAuth, |
| 1058 nssTrustLevel clientAuth, | 1045 nssTrustLevel clientAuth, |
| 1059 nssTrustLevel codeSigning, | 1046 nssTrustLevel codeSigning, |
| 1060 nssTrustLevel emailProtection, | 1047 nssTrustLevel emailProtection, |
| 1061 PRBool stepUpApproved, | 1048 PRBool stepUpApproved, |
| 1062 PRBool asTokenObject | 1049 PRBool asTokenObject) |
| 1063 ) | |
| 1064 { | 1050 { |
| 1065 nssCryptokiObject *object; | 1051 nssCryptokiObject *object; |
| 1066 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; | 1052 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; |
| 1067 CK_TRUST ckSA, ckCA, ckCS, ckEP; | 1053 CK_TRUST ckSA, ckCA, ckCS, ckEP; |
| 1068 CK_ATTRIBUTE_PTR attr; | 1054 CK_ATTRIBUTE_PTR attr; |
| 1069 CK_ATTRIBUTE trust_tmpl[11]; | 1055 CK_ATTRIBUTE trust_tmpl[11]; |
| 1070 CK_ULONG tsize; | 1056 CK_ULONG tsize; |
| 1071 PRUint8 sha1[20]; /* this is cheating... */ | 1057 PRUint8 sha1[20]; /* this is cheating... */ |
| 1072 PRUint8 md5[16]; | 1058 PRUint8 md5[16]; |
| 1073 NSSItem sha1_result, md5_result; | 1059 NSSItem sha1_result, md5_result; |
| 1074 sha1_result.data = sha1; sha1_result.size = sizeof sha1; | 1060 sha1_result.data = sha1; |
| 1075 md5_result.data = md5; md5_result.size = sizeof md5; | 1061 sha1_result.size = sizeof sha1; |
| 1062 md5_result.data = md5; |
| 1063 md5_result.size = sizeof md5; |
| 1076 sha1_hash(certEncoding, &sha1_result); | 1064 sha1_hash(certEncoding, &sha1_result); |
| 1077 md5_hash(certEncoding, &md5_result); | 1065 md5_hash(certEncoding, &md5_result); |
| 1078 ckSA = get_ck_trust(serverAuth); | 1066 ckSA = get_ck_trust(serverAuth); |
| 1079 ckCA = get_ck_trust(clientAuth); | 1067 ckCA = get_ck_trust(clientAuth); |
| 1080 ckCS = get_ck_trust(codeSigning); | 1068 ckCS = get_ck_trust(codeSigning); |
| 1081 ckEP = get_ck_trust(emailProtection); | 1069 ckEP = get_ck_trust(emailProtection); |
| 1082 NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize); | 1070 NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize); |
| 1083 if (asTokenObject) { | 1071 if (asTokenObject) { |
| 1084 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1072 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 1085 } else { | 1073 } else { |
| 1086 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1074 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 1087 } | 1075 } |
| 1088 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); | 1076 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, tobjc); |
| 1089 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); | 1077 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); |
| 1090 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); | 1078 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); |
| 1091 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); | 1079 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); |
| 1092 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result); | 1080 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result); |
| 1093 /* now set the trust values */ | 1081 /* now set the trust values */ |
| 1094 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA); | 1082 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA); |
| 1095 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA); | 1083 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA); |
| 1096 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS); | 1084 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS); |
| 1097 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP); | 1085 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP); |
| 1098 if (stepUpApproved) { | 1086 if (stepUpApproved) { |
| 1099 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, | 1087 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, |
| 1100 » &g_ck_true); | 1088 &g_ck_true); |
| 1101 } else { | 1089 } else { |
| 1102 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, | 1090 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, |
| 1103 » &g_ck_false); | 1091 &g_ck_false); |
| 1104 } | 1092 } |
| 1105 NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); | 1093 NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); |
| 1106 /* import the trust object onto the token */ | 1094 /* import the trust object onto the token */ |
| 1107 object = import_object(tok, sessionOpt, trust_tmpl, tsize); | 1095 object = import_object(tok, sessionOpt, trust_tmpl, tsize); |
| 1108 if (object && tok->cache) { | 1096 if (object && tok->cache) { |
| 1109 » nssTokenObjectCache_ImportObject(tok->cache, object, tobjc, | 1097 nssTokenObjectCache_ImportObject(tok->cache, object, tobjc, |
| 1110 » trust_tmpl, tsize); | 1098 trust_tmpl, tsize); |
| 1111 } | 1099 } |
| 1112 return object; | 1100 return object; |
| 1113 } | 1101 } |
| 1114 | 1102 |
| 1115 NSS_IMPLEMENT nssCryptokiObject * | 1103 NSS_IMPLEMENT nssCryptokiObject * |
| 1116 nssToken_FindTrustForCertificate ( | 1104 nssToken_FindTrustForCertificate( |
| 1117 NSSToken *token, | 1105 NSSToken *token, |
| 1118 nssSession *sessionOpt, | 1106 nssSession *sessionOpt, |
| 1119 NSSDER *certEncoding, | 1107 NSSDER *certEncoding, |
| 1120 NSSDER *certIssuer, | 1108 NSSDER *certIssuer, |
| 1121 NSSDER *certSerial, | 1109 NSSDER *certSerial, |
| 1122 nssTokenSearchType searchType | 1110 nssTokenSearchType searchType) |
| 1123 ) | |
| 1124 { | 1111 { |
| 1125 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; | 1112 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; |
| 1126 CK_ATTRIBUTE_PTR attr; | 1113 CK_ATTRIBUTE_PTR attr; |
| 1127 CK_ATTRIBUTE tobj_template[5]; | 1114 CK_ATTRIBUTE tobj_template[5]; |
| 1128 CK_ULONG tobj_size; | 1115 CK_ULONG tobj_size; |
| 1129 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; | 1116 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; |
| 1130 nssCryptokiObject *object = NULL, **objects; | 1117 nssCryptokiObject *object = NULL, **objects; |
| 1131 | 1118 |
| 1132 /* Don't ask the module to use an invalid session handle. */ | 1119 /* Don't ask the module to use an invalid session handle. */ |
| 1133 if (!session || session->handle == CK_INVALID_SESSION) { | 1120 if (!session || session->handle == CK_INVALID_SESSION) { |
| 1134 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1121 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 1135 » return object; | 1122 return object; |
| 1136 } | 1123 } |
| 1137 | 1124 |
| 1138 NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); | 1125 NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); |
| 1139 if (searchType == nssTokenSearchType_TokenOnly) { | 1126 if (searchType == nssTokenSearchType_TokenOnly) { |
| 1140 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1127 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 1141 } | 1128 } |
| 1142 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); | 1129 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, tobjc); |
| 1143 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); | 1130 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); |
| 1144 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , certSerial); | 1131 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); |
| 1145 NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); | 1132 NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); |
| 1146 objects = find_objects_by_template(token, session, | 1133 objects = find_objects_by_template(token, session, |
| 1147 tobj_template, tobj_size, | 1134 tobj_template, tobj_size, |
| 1148 1, NULL); | 1135 1, NULL); |
| 1149 if (objects) { | 1136 if (objects) { |
| 1150 » object = objects[0]; | 1137 object = objects[0]; |
| 1151 » nss_ZFreeIf(objects); | 1138 nss_ZFreeIf(objects); |
| 1152 } | 1139 } |
| 1153 return object; | 1140 return object; |
| 1154 } | 1141 } |
| 1155 | 1142 |
| 1156 NSS_IMPLEMENT nssCryptokiObject * | 1143 NSS_IMPLEMENT nssCryptokiObject * |
| 1157 nssToken_ImportCRL ( | 1144 nssToken_ImportCRL( |
| 1158 NSSToken *token, | 1145 NSSToken *token, |
| 1159 nssSession *sessionOpt, | 1146 nssSession *sessionOpt, |
| 1160 NSSDER *subject, | 1147 NSSDER *subject, |
| 1161 NSSDER *encoding, | 1148 NSSDER *encoding, |
| 1162 PRBool isKRL, | 1149 PRBool isKRL, |
| 1163 NSSUTF8 *url, | 1150 NSSUTF8 *url, |
| 1164 PRBool asTokenObject | 1151 PRBool asTokenObject) |
| 1165 ) | |
| 1166 { | 1152 { |
| 1167 nssCryptokiObject *object; | 1153 nssCryptokiObject *object; |
| 1168 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; | 1154 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; |
| 1169 CK_ATTRIBUTE_PTR attr; | 1155 CK_ATTRIBUTE_PTR attr; |
| 1170 CK_ATTRIBUTE crl_tmpl[6]; | 1156 CK_ATTRIBUTE crl_tmpl[6]; |
| 1171 CK_ULONG crlsize; | 1157 CK_ULONG crlsize; |
| 1172 | 1158 |
| 1173 NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize); | 1159 NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize); |
| 1174 if (asTokenObject) { | 1160 if (asTokenObject) { |
| 1175 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1161 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 1176 } else { | 1162 } else { |
| 1177 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1163 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 1178 } | 1164 } |
| 1179 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc); | 1165 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, crlobjc); |
| 1180 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 1166 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
| 1181 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); | 1167 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); |
| 1182 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url); | 1168 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url); |
| 1183 if (isKRL) { | 1169 if (isKRL) { |
| 1184 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true); | 1170 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true); |
| 1185 } else { | 1171 } else { |
| 1186 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false); | 1172 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false); |
| 1187 } | 1173 } |
| 1188 NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize); | 1174 NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize); |
| 1189 | 1175 |
| 1190 /* import the crl object onto the token */ | 1176 /* import the crl object onto the token */ |
| 1191 object = import_object(token, sessionOpt, crl_tmpl, crlsize); | 1177 object = import_object(token, sessionOpt, crl_tmpl, crlsize); |
| 1192 if (object && token->cache) { | 1178 if (object && token->cache) { |
| 1193 » nssTokenObjectCache_ImportObject(token->cache, object, crlobjc, | 1179 nssTokenObjectCache_ImportObject(token->cache, object, crlobjc, |
| 1194 » crl_tmpl, crlsize); | 1180 crl_tmpl, crlsize); |
| 1195 } | 1181 } |
| 1196 return object; | 1182 return object; |
| 1197 } | 1183 } |
| 1198 | 1184 |
| 1199 NSS_IMPLEMENT nssCryptokiObject ** | 1185 NSS_IMPLEMENT nssCryptokiObject ** |
| 1200 nssToken_FindCRLsBySubject ( | 1186 nssToken_FindCRLsBySubject( |
| 1201 NSSToken *token, | 1187 NSSToken *token, |
| 1202 nssSession *sessionOpt, | 1188 nssSession *sessionOpt, |
| 1203 NSSDER *subject, | 1189 NSSDER *subject, |
| 1204 nssTokenSearchType searchType, | 1190 nssTokenSearchType searchType, |
| 1205 PRUint32 maximumOpt, | 1191 PRUint32 maximumOpt, |
| 1206 PRStatus *statusOpt | 1192 PRStatus *statusOpt) |
| 1207 ) | |
| 1208 { | 1193 { |
| 1209 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; | 1194 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; |
| 1210 CK_ATTRIBUTE_PTR attr; | 1195 CK_ATTRIBUTE_PTR attr; |
| 1211 CK_ATTRIBUTE crlobj_template[3]; | 1196 CK_ATTRIBUTE crlobj_template[3]; |
| 1212 CK_ULONG crlobj_size; | 1197 CK_ULONG crlobj_size; |
| 1213 nssCryptokiObject **objects = NULL; | 1198 nssCryptokiObject **objects = NULL; |
| 1214 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; | 1199 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; |
| 1215 | 1200 |
| 1216 /* Don't ask the module to use an invalid session handle. */ | 1201 /* Don't ask the module to use an invalid session handle. */ |
| 1217 if (!session || session->handle == CK_INVALID_SESSION) { | 1202 if (!session || session->handle == CK_INVALID_SESSION) { |
| 1218 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1203 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 1219 » return objects; | 1204 return objects; |
| 1220 } | 1205 } |
| 1221 | 1206 |
| 1222 NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size); | 1207 NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size); |
| 1223 if (searchType == nssTokenSearchType_SessionOnly) { | 1208 if (searchType == nssTokenSearchType_SessionOnly) { |
| 1224 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1209 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 1225 } else if (searchType == nssTokenSearchType_TokenOnly || | 1210 } else if (searchType == nssTokenSearchType_TokenOnly || |
| 1226 searchType == nssTokenSearchType_TokenForced) { | 1211 searchType == nssTokenSearchType_TokenForced) { |
| 1227 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1212 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 1228 } | 1213 } |
| 1229 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc); | 1214 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, crlobjc); |
| 1230 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 1215 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
| 1231 NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); | 1216 NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); |
| 1232 | 1217 |
| 1233 objects = find_objects_by_template(token, session, | 1218 objects = find_objects_by_template(token, session, |
| 1234 crlobj_template, crlobj_size, | 1219 crlobj_template, crlobj_size, |
| 1235 maximumOpt, statusOpt); | 1220 maximumOpt, statusOpt); |
| 1236 return objects; | 1221 return objects; |
| 1237 } | 1222 } |
| 1238 | 1223 |
| 1239 NSS_IMPLEMENT PRStatus | 1224 NSS_IMPLEMENT PRStatus |
| 1240 nssToken_GetCachedObjectAttributes ( | 1225 nssToken_GetCachedObjectAttributes( |
| 1241 NSSToken *token, | 1226 NSSToken *token, |
| 1242 NSSArena *arenaOpt, | 1227 NSSArena *arenaOpt, |
| 1243 nssCryptokiObject *object, | 1228 nssCryptokiObject *object, |
| 1244 CK_OBJECT_CLASS objclass, | 1229 CK_OBJECT_CLASS objclass, |
| 1245 CK_ATTRIBUTE_PTR atemplate, | 1230 CK_ATTRIBUTE_PTR atemplate, |
| 1246 CK_ULONG atlen | 1231 CK_ULONG atlen) |
| 1247 ) | |
| 1248 { | 1232 { |
| 1249 if (!token->cache) { | 1233 if (!token->cache) { |
| 1250 » return PR_FAILURE; | 1234 return PR_FAILURE; |
| 1251 } | 1235 } |
| 1252 return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt, | 1236 return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt, |
| 1253 object, objclass, | 1237 object, objclass, |
| 1254 atemplate, atlen); | 1238 atemplate, atlen); |
| 1255 } | 1239 } |
| 1256 | 1240 |
| 1257 NSS_IMPLEMENT NSSItem * | 1241 NSS_IMPLEMENT NSSItem * |
| 1258 nssToken_Digest ( | 1242 nssToken_Digest( |
| 1259 NSSToken *tok, | 1243 NSSToken *tok, |
| 1260 nssSession *sessionOpt, | 1244 nssSession *sessionOpt, |
| 1261 NSSAlgorithmAndParameters *ap, | 1245 NSSAlgorithmAndParameters *ap, |
| 1262 NSSItem *data, | 1246 NSSItem *data, |
| 1263 NSSItem *rvOpt, | 1247 NSSItem *rvOpt, |
| 1264 NSSArena *arenaOpt | 1248 NSSArena *arenaOpt) |
| 1265 ) | |
| 1266 { | 1249 { |
| 1267 CK_RV ckrv; | 1250 CK_RV ckrv; |
| 1268 CK_ULONG digestLen; | 1251 CK_ULONG digestLen; |
| 1269 CK_BYTE_PTR digest; | 1252 CK_BYTE_PTR digest; |
| 1270 NSSItem *rvItem = NULL; | 1253 NSSItem *rvItem = NULL; |
| 1271 void *epv = nssToken_GetCryptokiEPV(tok); | 1254 void *epv = nssToken_GetCryptokiEPV(tok); |
| 1272 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1255 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
| 1273 | 1256 |
| 1274 /* Don't ask the module to use an invalid session handle. */ | 1257 /* Don't ask the module to use an invalid session handle. */ |
| 1275 if (!session || session->handle == CK_INVALID_SESSION) { | 1258 if (!session || session->handle == CK_INVALID_SESSION) { |
| 1276 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1259 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 1277 » return rvItem; | 1260 return rvItem; |
| 1278 } | 1261 } |
| 1279 | 1262 |
| 1280 nssSession_EnterMonitor(session); | 1263 nssSession_EnterMonitor(session); |
| 1281 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); | 1264 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); |
| 1282 if (ckrv != CKR_OK) { | 1265 if (ckrv != CKR_OK) { |
| 1283 » nssSession_ExitMonitor(session); | 1266 nssSession_ExitMonitor(session); |
| 1284 » return NULL; | 1267 return NULL; |
| 1285 } | 1268 } |
| 1286 #if 0 | 1269 #if 0 |
| 1287 /* XXX the standard says this should work, but it doesn't */ | 1270 /* XXX the standard says this should work, but it doesn't */ |
| 1288 ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen); | 1271 ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen); |
| 1289 if (ckrv != CKR_OK) { | 1272 if (ckrv != CKR_OK) { |
| 1290 nssSession_ExitMonitor(session); | 1273 nssSession_ExitMonitor(session); |
| 1291 return NULL; | 1274 return NULL; |
| 1292 } | 1275 } |
| 1293 #endif | 1276 #endif |
| 1294 digestLen = 0; /* XXX for now */ | 1277 digestLen = 0; /* XXX for now */ |
| 1295 digest = NULL; | 1278 digest = NULL; |
| 1296 if (rvOpt) { | 1279 if (rvOpt) { |
| 1297 » if (rvOpt->size > 0 && rvOpt->size < digestLen) { | 1280 if (rvOpt->size > 0 && rvOpt->size < digestLen) { |
| 1298 » nssSession_ExitMonitor(session); | 1281 nssSession_ExitMonitor(session); |
| 1299 » /* the error should be bad args */ | 1282 /* the error should be bad args */ |
| 1300 » return NULL; | 1283 return NULL; |
| 1301 » } | 1284 } |
| 1302 » if (rvOpt->data) { | 1285 if (rvOpt->data) { |
| 1303 » digest = rvOpt->data; | 1286 digest = rvOpt->data; |
| 1304 » } | 1287 } |
| 1305 » digestLen = rvOpt->size; | 1288 digestLen = rvOpt->size; |
| 1306 } | 1289 } |
| 1307 if (!digest) { | 1290 if (!digest) { |
| 1308 » digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); | 1291 digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); |
| 1309 » if (!digest) { | 1292 if (!digest) { |
| 1310 » nssSession_ExitMonitor(session); | 1293 nssSession_ExitMonitor(session); |
| 1311 » return NULL; | 1294 return NULL; |
| 1312 » } | 1295 } |
| 1313 } | 1296 } |
| 1314 ckrv = CKAPI(epv)->C_Digest(session->handle, | 1297 ckrv = CKAPI(epv)->C_Digest(session->handle, |
| 1315 (CK_BYTE_PTR)data->data, | 1298 (CK_BYTE_PTR)data->data, |
| 1316 (CK_ULONG)data->size, | 1299 (CK_ULONG)data->size, |
| 1317 (CK_BYTE_PTR)digest, | 1300 (CK_BYTE_PTR)digest, |
| 1318 &digestLen); | 1301 &digestLen); |
| 1319 nssSession_ExitMonitor(session); | 1302 nssSession_ExitMonitor(session); |
| 1320 if (ckrv != CKR_OK) { | 1303 if (ckrv != CKR_OK) { |
| 1321 » nss_ZFreeIf(digest); | 1304 nss_ZFreeIf(digest); |
| 1322 » return NULL; | 1305 return NULL; |
| 1323 } | 1306 } |
| 1324 if (!rvOpt) { | 1307 if (!rvOpt) { |
| 1325 » rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); | 1308 rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); |
| 1326 } | 1309 } |
| 1327 return rvItem; | 1310 return rvItem; |
| 1328 } | 1311 } |
| 1329 | 1312 |
| 1330 NSS_IMPLEMENT PRStatus | 1313 NSS_IMPLEMENT PRStatus |
| 1331 nssToken_BeginDigest ( | 1314 nssToken_BeginDigest( |
| 1332 NSSToken *tok, | 1315 NSSToken *tok, |
| 1333 nssSession *sessionOpt, | 1316 nssSession *sessionOpt, |
| 1334 NSSAlgorithmAndParameters *ap | 1317 NSSAlgorithmAndParameters *ap) |
| 1335 ) | |
| 1336 { | 1318 { |
| 1337 CK_RV ckrv; | 1319 CK_RV ckrv; |
| 1338 void *epv = nssToken_GetCryptokiEPV(tok); | 1320 void *epv = nssToken_GetCryptokiEPV(tok); |
| 1339 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1321 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
| 1340 | 1322 |
| 1341 /* Don't ask the module to use an invalid session handle. */ | 1323 /* Don't ask the module to use an invalid session handle. */ |
| 1342 if (!session || session->handle == CK_INVALID_SESSION) { | 1324 if (!session || session->handle == CK_INVALID_SESSION) { |
| 1343 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1325 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 1344 » return PR_FAILURE; | 1326 return PR_FAILURE; |
| 1345 } | 1327 } |
| 1346 | 1328 |
| 1347 nssSession_EnterMonitor(session); | 1329 nssSession_EnterMonitor(session); |
| 1348 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); | 1330 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); |
| 1349 nssSession_ExitMonitor(session); | 1331 nssSession_ExitMonitor(session); |
| 1350 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; | 1332 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; |
| 1351 } | 1333 } |
| 1352 | 1334 |
| 1353 NSS_IMPLEMENT PRStatus | 1335 NSS_IMPLEMENT PRStatus |
| 1354 nssToken_ContinueDigest ( | 1336 nssToken_ContinueDigest( |
| 1355 NSSToken *tok, | 1337 NSSToken *tok, |
| 1356 nssSession *sessionOpt, | 1338 nssSession *sessionOpt, |
| 1357 NSSItem *item | 1339 NSSItem *item) |
| 1358 ) | |
| 1359 { | 1340 { |
| 1360 CK_RV ckrv; | 1341 CK_RV ckrv; |
| 1361 void *epv = nssToken_GetCryptokiEPV(tok); | 1342 void *epv = nssToken_GetCryptokiEPV(tok); |
| 1362 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1343 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
| 1363 | 1344 |
| 1364 /* Don't ask the module to use an invalid session handle. */ | 1345 /* Don't ask the module to use an invalid session handle. */ |
| 1365 if (!session || session->handle == CK_INVALID_SESSION) { | 1346 if (!session || session->handle == CK_INVALID_SESSION) { |
| 1366 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1347 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 1367 » return PR_FAILURE; | 1348 return PR_FAILURE; |
| 1368 } | 1349 } |
| 1369 | 1350 |
| 1370 nssSession_EnterMonitor(session); | 1351 nssSession_EnterMonitor(session); |
| 1371 ckrv = CKAPI(epv)->C_DigestUpdate(session->handle, | 1352 ckrv = CKAPI(epv)->C_DigestUpdate(session->handle, |
| 1372 (CK_BYTE_PTR)item->data, | 1353 (CK_BYTE_PTR)item->data, |
| 1373 (CK_ULONG)item->size); | 1354 (CK_ULONG)item->size); |
| 1374 nssSession_ExitMonitor(session); | 1355 nssSession_ExitMonitor(session); |
| 1375 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; | 1356 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; |
| 1376 } | 1357 } |
| 1377 | 1358 |
| 1378 NSS_IMPLEMENT NSSItem * | 1359 NSS_IMPLEMENT NSSItem * |
| 1379 nssToken_FinishDigest ( | 1360 nssToken_FinishDigest( |
| 1380 NSSToken *tok, | 1361 NSSToken *tok, |
| 1381 nssSession *sessionOpt, | 1362 nssSession *sessionOpt, |
| 1382 NSSItem *rvOpt, | 1363 NSSItem *rvOpt, |
| 1383 NSSArena *arenaOpt | 1364 NSSArena *arenaOpt) |
| 1384 ) | |
| 1385 { | 1365 { |
| 1386 CK_RV ckrv; | 1366 CK_RV ckrv; |
| 1387 CK_ULONG digestLen; | 1367 CK_ULONG digestLen; |
| 1388 CK_BYTE_PTR digest; | 1368 CK_BYTE_PTR digest; |
| 1389 NSSItem *rvItem = NULL; | 1369 NSSItem *rvItem = NULL; |
| 1390 void *epv = nssToken_GetCryptokiEPV(tok); | 1370 void *epv = nssToken_GetCryptokiEPV(tok); |
| 1391 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1371 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
| 1392 | 1372 |
| 1393 /* Don't ask the module to use an invalid session handle. */ | 1373 /* Don't ask the module to use an invalid session handle. */ |
| 1394 if (!session || session->handle == CK_INVALID_SESSION) { | 1374 if (!session || session->handle == CK_INVALID_SESSION) { |
| 1395 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1375 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 1396 » return NULL; | 1376 return NULL; |
| 1397 } | 1377 } |
| 1398 | 1378 |
| 1399 nssSession_EnterMonitor(session); | 1379 nssSession_EnterMonitor(session); |
| 1400 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen); | 1380 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen); |
| 1401 if (ckrv != CKR_OK || digestLen == 0) { | 1381 if (ckrv != CKR_OK || digestLen == 0) { |
| 1402 » nssSession_ExitMonitor(session); | 1382 nssSession_ExitMonitor(session); |
| 1403 » return NULL; | 1383 return NULL; |
| 1404 } | 1384 } |
| 1405 digest = NULL; | 1385 digest = NULL; |
| 1406 if (rvOpt) { | 1386 if (rvOpt) { |
| 1407 » if (rvOpt->size > 0 && rvOpt->size < digestLen) { | 1387 if (rvOpt->size > 0 && rvOpt->size < digestLen) { |
| 1408 » nssSession_ExitMonitor(session); | 1388 nssSession_ExitMonitor(session); |
| 1409 » /* the error should be bad args */ | 1389 /* the error should be bad args */ |
| 1410 » return NULL; | 1390 return NULL; |
| 1411 » } | 1391 } |
| 1412 » if (rvOpt->data) { | 1392 if (rvOpt->data) { |
| 1413 » digest = rvOpt->data; | 1393 digest = rvOpt->data; |
| 1414 » } | 1394 } |
| 1415 » digestLen = rvOpt->size; | 1395 digestLen = rvOpt->size; |
| 1416 } | 1396 } |
| 1417 if (!digest) { | 1397 if (!digest) { |
| 1418 » digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); | 1398 digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); |
| 1419 » if (!digest) { | 1399 if (!digest) { |
| 1420 » nssSession_ExitMonitor(session); | 1400 nssSession_ExitMonitor(session); |
| 1421 » return NULL; | 1401 return NULL; |
| 1422 » } | 1402 } |
| 1423 } | 1403 } |
| 1424 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen); | 1404 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen); |
| 1425 nssSession_ExitMonitor(session); | 1405 nssSession_ExitMonitor(session); |
| 1426 if (ckrv != CKR_OK) { | 1406 if (ckrv != CKR_OK) { |
| 1427 » nss_ZFreeIf(digest); | 1407 nss_ZFreeIf(digest); |
| 1428 » return NULL; | 1408 return NULL; |
| 1429 } | 1409 } |
| 1430 if (!rvOpt) { | 1410 if (!rvOpt) { |
| 1431 » rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); | 1411 rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); |
| 1432 } | 1412 } |
| 1433 return rvItem; | 1413 return rvItem; |
| 1434 } | 1414 } |
| 1435 | 1415 |
| 1436 NSS_IMPLEMENT PRBool | 1416 NSS_IMPLEMENT PRBool |
| 1437 nssToken_IsPresent ( | 1417 nssToken_IsPresent( |
| 1438 NSSToken *token | 1418 NSSToken *token) |
| 1439 ) | |
| 1440 { | 1419 { |
| 1441 return nssSlot_IsTokenPresent(token->slot); | 1420 return nssSlot_IsTokenPresent(token->slot); |
| 1442 } | 1421 } |
| 1443 | 1422 |
| 1444 /* Sigh. The methods to find objects declared above cause problems with | 1423 /* Sigh. The methods to find objects declared above cause problems with |
| 1445 * the low-level object cache in the softoken -- the objects are found in | 1424 * the low-level object cache in the softoken -- the objects are found in |
| 1446 * toto, then one wave of GetAttributes is done, then another. Having a | 1425 * toto, then one wave of GetAttributes is done, then another. Having a |
| 1447 * large number of objects causes the cache to be thrashed, as the objects | 1426 * large number of objects causes the cache to be thrashed, as the objects |
| 1448 * are gone before there's any chance to ask for their attributes. | 1427 * are gone before there's any chance to ask for their attributes. |
| 1449 * So, for now, bringing back traversal methods for certs. This way all of | 1428 * So, for now, bringing back traversal methods for certs. This way all of |
| 1450 * the cert's attributes can be grabbed immediately after finding it, | 1429 * the cert's attributes can be grabbed immediately after finding it, |
| 1451 * increasing the likelihood that the cache takes care of it. | 1430 * increasing the likelihood that the cache takes care of it. |
| 1452 */ | 1431 */ |
| 1453 NSS_IMPLEMENT PRStatus | 1432 NSS_IMPLEMENT PRStatus |
| 1454 nssToken_TraverseCertificates ( | 1433 nssToken_TraverseCertificates( |
| 1455 NSSToken *token, | 1434 NSSToken *token, |
| 1456 nssSession *sessionOpt, | 1435 nssSession *sessionOpt, |
| 1457 nssTokenSearchType searchType, | 1436 nssTokenSearchType searchType, |
| 1458 PRStatus (* callback)(nssCryptokiObject *instance, void *arg), | 1437 PRStatus (*callback)(nssCryptokiObject *instance, void *arg), |
| 1459 void *arg | 1438 void *arg) |
| 1460 ) | |
| 1461 { | 1439 { |
| 1462 CK_RV ckrv; | 1440 CK_RV ckrv; |
| 1463 CK_ULONG count; | 1441 CK_ULONG count; |
| 1464 CK_OBJECT_HANDLE *objectHandles; | 1442 CK_OBJECT_HANDLE *objectHandles; |
| 1465 CK_ATTRIBUTE_PTR attr; | 1443 CK_ATTRIBUTE_PTR attr; |
| 1466 CK_ATTRIBUTE cert_template[2]; | 1444 CK_ATTRIBUTE cert_template[2]; |
| 1467 CK_ULONG ctsize; | 1445 CK_ULONG ctsize; |
| 1468 NSSArena *arena; | 1446 NSSArena *arena; |
| 1469 PRUint32 arraySize, numHandles; | 1447 PRUint32 arraySize, numHandles; |
| 1470 nssCryptokiObject **objects; | 1448 nssCryptokiObject **objects; |
| 1471 void *epv = nssToken_GetCryptokiEPV(token); | 1449 void *epv = nssToken_GetCryptokiEPV(token); |
| 1472 nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession; | 1450 nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession; |
| 1473 | 1451 |
| 1474 /* Don't ask the module to use an invalid session handle. */ | 1452 /* Don't ask the module to use an invalid session handle. */ |
| 1475 if (!session || session->handle == CK_INVALID_SESSION) { | 1453 if (!session || session->handle == CK_INVALID_SESSION) { |
| 1476 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1454 PORT_SetError(SEC_ERROR_NO_TOKEN); |
| 1477 » return PR_FAILURE; | 1455 return PR_FAILURE; |
| 1478 } | 1456 } |
| 1479 | 1457 |
| 1480 /* template for all certs */ | 1458 /* template for all certs */ |
| 1481 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); | 1459 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); |
| 1482 if (searchType == nssTokenSearchType_SessionOnly) { | 1460 if (searchType == nssTokenSearchType_SessionOnly) { |
| 1483 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1461 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
| 1484 } else if (searchType == nssTokenSearchType_TokenOnly || | 1462 } else if (searchType == nssTokenSearchType_TokenOnly || |
| 1485 searchType == nssTokenSearchType_TokenForced) { | 1463 searchType == nssTokenSearchType_TokenForced) { |
| 1486 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1464 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
| 1487 } | 1465 } |
| 1488 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 1466 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
| 1489 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); | 1467 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); |
| 1490 | 1468 |
| 1491 /* the arena is only for the array of object handles */ | 1469 /* the arena is only for the array of object handles */ |
| 1492 arena = nssArena_Create(); | 1470 arena = nssArena_Create(); |
| 1493 if (!arena) { | 1471 if (!arena) { |
| 1494 » return PR_FAILURE; | 1472 return PR_FAILURE; |
| 1495 } | 1473 } |
| 1496 arraySize = OBJECT_STACK_SIZE; | 1474 arraySize = OBJECT_STACK_SIZE; |
| 1497 numHandles = 0; | 1475 numHandles = 0; |
| 1498 objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize); | 1476 objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize); |
| 1499 if (!objectHandles) { | 1477 if (!objectHandles) { |
| 1500 » goto loser; | 1478 goto loser; |
| 1501 } | 1479 } |
| 1502 nssSession_EnterMonitor(session); /* ==== session lock === */ | 1480 nssSession_EnterMonitor(session); /* ==== session lock === */ |
| 1503 /* Initialize the find with the template */ | 1481 /* Initialize the find with the template */ |
| 1504 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, | 1482 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, |
| 1505 cert_template, ctsize); | 1483 cert_template, ctsize); |
| 1506 if (ckrv != CKR_OK) { | 1484 if (ckrv != CKR_OK) { |
| 1507 » nssSession_ExitMonitor(session); | 1485 nssSession_ExitMonitor(session); |
| 1508 » goto loser; | 1486 goto loser; |
| 1509 } | 1487 } |
| 1510 while (PR_TRUE) { | 1488 while (PR_TRUE) { |
| 1511 » /* Issue the find for up to arraySize - numHandles objects */ | 1489 /* Issue the find for up to arraySize - numHandles objects */ |
| 1512 » ckrv = CKAPI(epv)->C_FindObjects(session->handle, | 1490 ckrv = CKAPI(epv)->C_FindObjects(session->handle, |
| 1513 » objectHandles + numHandles, | 1491 objectHandles + numHandles, |
| 1514 » arraySize - numHandles, | 1492 arraySize - numHandles, |
| 1515 » &count); | 1493 &count); |
| 1516 » if (ckrv != CKR_OK) { | 1494 if (ckrv != CKR_OK) { |
| 1517 » nssSession_ExitMonitor(session); | 1495 nssSession_ExitMonitor(session); |
| 1518 » goto loser; | 1496 goto loser; |
| 1519 » } | 1497 } |
| 1520 » /* bump the number of found objects */ | 1498 /* bump the number of found objects */ |
| 1521 » numHandles += count; | 1499 numHandles += count; |
| 1522 » if (numHandles < arraySize) { | 1500 if (numHandles < arraySize) { |
| 1523 » break; | 1501 break; |
| 1524 » } | 1502 } |
| 1525 » /* the array is filled, double it and continue */ | 1503 /* the array is filled, double it and continue */ |
| 1526 » arraySize *= 2; | 1504 arraySize *= 2; |
| 1527 » objectHandles = nss_ZREALLOCARRAY(objectHandles, | 1505 objectHandles = nss_ZREALLOCARRAY(objectHandles, |
| 1528 » CK_OBJECT_HANDLE, | 1506 CK_OBJECT_HANDLE, |
| 1529 » arraySize); | 1507 arraySize); |
| 1530 » if (!objectHandles) { | 1508 if (!objectHandles) { |
| 1531 » nssSession_ExitMonitor(session); | 1509 nssSession_ExitMonitor(session); |
| 1532 » goto loser; | 1510 goto loser; |
| 1533 » } | 1511 } |
| 1534 } | 1512 } |
| 1535 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); | 1513 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); |
| 1536 nssSession_ExitMonitor(session); /* ==== end session lock === */ | 1514 nssSession_ExitMonitor(session); /* ==== end session lock === */ |
| 1537 if (ckrv != CKR_OK) { | 1515 if (ckrv != CKR_OK) { |
| 1538 » goto loser; | 1516 goto loser; |
| 1539 } | 1517 } |
| 1540 if (numHandles > 0) { | 1518 if (numHandles > 0) { |
| 1541 » objects = create_objects_from_handles(token, session, | 1519 objects = create_objects_from_handles(token, session, |
| 1542 » objectHandles, numHandles); | 1520 objectHandles, numHandles); |
| 1543 » if (objects) { | 1521 if (objects) { |
| 1544 » nssCryptokiObject **op; | 1522 nssCryptokiObject **op; |
| 1545 » for (op = objects; *op; op++) { | 1523 for (op = objects; *op; op++) { |
| 1546 » » (void)(*callback)(*op, arg); | 1524 (void)(*callback)(*op, arg); |
| 1547 » } | 1525 } |
| 1548 » nss_ZFreeIf(objects); | 1526 nss_ZFreeIf(objects); |
| 1549 » } | 1527 } |
| 1550 } | 1528 } |
| 1551 nssArena_Destroy(arena); | 1529 nssArena_Destroy(arena); |
| 1552 return PR_SUCCESS; | 1530 return PR_SUCCESS; |
| 1553 loser: | 1531 loser: |
| 1554 nssArena_Destroy(arena); | 1532 nssArena_Destroy(arena); |
| 1555 return PR_FAILURE; | 1533 return PR_FAILURE; |
| 1556 } | 1534 } |
| 1557 | 1535 |
| 1558 NSS_IMPLEMENT PRBool | 1536 NSS_IMPLEMENT PRBool |
| 1559 nssToken_IsPrivateKeyAvailable ( | 1537 nssToken_IsPrivateKeyAvailable( |
| 1560 NSSToken *token, | 1538 NSSToken *token, |
| 1561 NSSCertificate *c, | 1539 NSSCertificate *c, |
| 1562 nssCryptokiObject *instance | 1540 nssCryptokiObject *instance) |
| 1563 ) | |
| 1564 { | 1541 { |
| 1565 CK_OBJECT_CLASS theClass; | 1542 CK_OBJECT_CLASS theClass; |
| 1566 | 1543 |
| 1567 if (token == NULL) return PR_FALSE; | 1544 if (token == NULL) |
| 1568 if (c == NULL) return PR_FALSE; | 1545 return PR_FALSE; |
| 1546 if (c == NULL) |
| 1547 return PR_FALSE; |
| 1569 | 1548 |
| 1570 theClass = CKO_PRIVATE_KEY; | 1549 theClass = CKO_PRIVATE_KEY; |
| 1571 if (!nssSlot_IsLoggedIn(token->slot)) { | 1550 if (!nssSlot_IsLoggedIn(token->slot)) { |
| 1572 » theClass = CKO_PUBLIC_KEY; | 1551 theClass = CKO_PUBLIC_KEY; |
| 1573 } | 1552 } |
| 1574 if (PK11_MatchItem(token->pk11slot, instance->handle, theClass) | 1553 if (PK11_MatchItem(token->pk11slot, instance->handle, theClass) != |
| 1575 » » » » » » != CK_INVALID_HANDLE) { | 1554 CK_INVALID_HANDLE) { |
| 1576 » return PR_TRUE; | 1555 return PR_TRUE; |
| 1577 } | 1556 } |
| 1578 return PR_FALSE; | 1557 return PR_FALSE; |
| 1579 } | 1558 } |
| OLD | NEW |