security/nss/lib/ckfw/token.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/ckfw/token.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1892 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +/*
     1.9 + * token.c
    1.10 + *
    1.11 + * This file implements the NSSCKFWToken type and methods.
    1.12 + */
    1.13 +
    1.14 +#ifndef CK_T
    1.15 +#include "ck.h"
    1.16 +#endif /* CK_T */
    1.17 +
    1.18 +/*
    1.19 + * NSSCKFWToken
    1.20 + *
    1.21 + *  -- create/destroy --
    1.22 + *  nssCKFWToken_Create
    1.23 + *  nssCKFWToken_Destroy
    1.24 + *
    1.25 + *  -- public accessors --
    1.26 + *  NSSCKFWToken_GetMDToken
    1.27 + *  NSSCKFWToken_GetFWSlot
    1.28 + *  NSSCKFWToken_GetMDSlot
    1.29 + *  NSSCKFWToken_GetSessionState
    1.30 + *
    1.31 + *  -- implement public accessors --
    1.32 + *  nssCKFWToken_GetMDToken
    1.33 + *  nssCKFWToken_GetFWSlot
    1.34 + *  nssCKFWToken_GetMDSlot
    1.35 + *  nssCKFWToken_GetSessionState
    1.36 + *  nssCKFWToken_SetSessionState
    1.37 + *
    1.38 + *  -- private accessors --
    1.39 + *  nssCKFWToken_SetSessionState
    1.40 + *  nssCKFWToken_RemoveSession
    1.41 + *  nssCKFWToken_CloseAllSessions
    1.42 + *  nssCKFWToken_GetSessionCount
    1.43 + *  nssCKFWToken_GetRwSessionCount
    1.44 + *  nssCKFWToken_GetRoSessionCount
    1.45 + *  nssCKFWToken_GetSessionObjectHash
    1.46 + *  nssCKFWToken_GetMDObjectHash
    1.47 + *  nssCKFWToken_GetObjectHandleHash
    1.48 + *
    1.49 + *  -- module fronts --
    1.50 + *  nssCKFWToken_InitToken
    1.51 + *  nssCKFWToken_GetLabel
    1.52 + *  nssCKFWToken_GetManufacturerID
    1.53 + *  nssCKFWToken_GetModel
    1.54 + *  nssCKFWToken_GetSerialNumber
    1.55 + *  nssCKFWToken_GetHasRNG
    1.56 + *  nssCKFWToken_GetIsWriteProtected
    1.57 + *  nssCKFWToken_GetLoginRequired
    1.58 + *  nssCKFWToken_GetUserPinInitialized
    1.59 + *  nssCKFWToken_GetRestoreKeyNotNeeded
    1.60 + *  nssCKFWToken_GetHasClockOnToken
    1.61 + *  nssCKFWToken_GetHasProtectedAuthenticationPath
    1.62 + *  nssCKFWToken_GetSupportsDualCryptoOperations
    1.63 + *  nssCKFWToken_GetMaxSessionCount
    1.64 + *  nssCKFWToken_GetMaxRwSessionCount
    1.65 + *  nssCKFWToken_GetMaxPinLen
    1.66 + *  nssCKFWToken_GetMinPinLen
    1.67 + *  nssCKFWToken_GetTotalPublicMemory
    1.68 + *  nssCKFWToken_GetFreePublicMemory
    1.69 + *  nssCKFWToken_GetTotalPrivateMemory
    1.70 + *  nssCKFWToken_GetFreePrivateMemory
    1.71 + *  nssCKFWToken_GetHardwareVersion
    1.72 + *  nssCKFWToken_GetFirmwareVersion
    1.73 + *  nssCKFWToken_GetUTCTime
    1.74 + *  nssCKFWToken_OpenSession
    1.75 + *  nssCKFWToken_GetMechanismCount
    1.76 + *  nssCKFWToken_GetMechanismTypes
    1.77 + *  nssCKFWToken_GetMechanism
    1.78 + */
    1.79 +
    1.80 +struct NSSCKFWTokenStr {
    1.81 +  NSSCKFWMutex *mutex;
    1.82 +  NSSArena *arena;
    1.83 +  NSSCKMDToken *mdToken;
    1.84 +  NSSCKFWSlot *fwSlot;
    1.85 +  NSSCKMDSlot *mdSlot;
    1.86 +  NSSCKFWInstance *fwInstance;
    1.87 +  NSSCKMDInstance *mdInstance;
    1.88 +
    1.89 +  /*
    1.90 +   * Everything above is set at creation time, and then not modified.
    1.91 +   * The invariants the mutex protects are:
    1.92 +   *
    1.93 +   * 1) Each of the cached descriptions (versions, etc.) are in an
    1.94 +   *    internally consistant state.
    1.95 +   *
    1.96 +   * 2) The session counts and hashes are consistant.
    1.97 +   *
    1.98 +   * 3) The object hashes are consistant.
    1.99 +   *
   1.100 +   * Note that the calls accessing the cached descriptions will call
   1.101 +   * the NSSCKMDToken methods with the mutex locked.  Those methods
   1.102 +   * may then call the public NSSCKFWToken routines.  Those public
   1.103 +   * routines only access the constant data above and the atomic
   1.104 +   * CK_STATE session state variable below, so there's no problem.
   1.105 +   * But be careful if you add to this object; mutexes are in
   1.106 +   * general not reentrant, so don't create deadlock situations.
   1.107 +   */
   1.108 +
   1.109 +  NSSUTF8 *label;
   1.110 +  NSSUTF8 *manufacturerID;
   1.111 +  NSSUTF8 *model;
   1.112 +  NSSUTF8 *serialNumber;
   1.113 +  CK_VERSION hardwareVersion;
   1.114 +  CK_VERSION firmwareVersion;
   1.115 +
   1.116 +  CK_ULONG sessionCount;
   1.117 +  CK_ULONG rwSessionCount;
   1.118 +  nssCKFWHash *sessions;
   1.119 +  nssCKFWHash *sessionObjectHash;
   1.120 +  nssCKFWHash *mdObjectHash;
   1.121 +  nssCKFWHash *mdMechanismHash;
   1.122 +
   1.123 +  CK_STATE state;
   1.124 +};
   1.125 +
   1.126 +#ifdef DEBUG
   1.127 +/*
   1.128 + * But first, the pointer-tracking stuff.
   1.129 + *
   1.130 + * NOTE: the pointer-tracking support in NSS/base currently relies
   1.131 + * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
   1.132 + * locking, which is tied into the runtime.  We need a pointer-tracker
   1.133 + * implementation that uses the locks supplied through C_Initialize.
   1.134 + * That support, however, can be filled in later.  So for now, I'll
   1.135 + * just do this routines as no-ops.
   1.136 + */
   1.137 +
   1.138 +static CK_RV
   1.139 +token_add_pointer
   1.140 +(
   1.141 +  const NSSCKFWToken *fwToken
   1.142 +)
   1.143 +{
   1.144 +  return CKR_OK;
   1.145 +}
   1.146 +
   1.147 +static CK_RV
   1.148 +token_remove_pointer
   1.149 +(
   1.150 +  const NSSCKFWToken *fwToken
   1.151 +)
   1.152 +{
   1.153 +  return CKR_OK;
   1.154 +}
   1.155 +
   1.156 +NSS_IMPLEMENT CK_RV
   1.157 +nssCKFWToken_verifyPointer
   1.158 +(
   1.159 +  const NSSCKFWToken *fwToken
   1.160 +)
   1.161 +{
   1.162 +  return CKR_OK;
   1.163 +}
   1.164 +
   1.165 +#endif /* DEBUG */
   1.166 +
   1.167 +/*
   1.168 + * nssCKFWToken_Create
   1.169 + *
   1.170 + */
   1.171 +NSS_IMPLEMENT NSSCKFWToken *
   1.172 +nssCKFWToken_Create
   1.173 +(
   1.174 +  NSSCKFWSlot *fwSlot,
   1.175 +  NSSCKMDToken *mdToken,
   1.176 +  CK_RV *pError
   1.177 +)
   1.178 +{
   1.179 +  NSSArena *arena = (NSSArena *)NULL;
   1.180 +  NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
   1.181 +  CK_BBOOL called_setup = CK_FALSE;
   1.182 +
   1.183 +  /*
   1.184 +   * We have already verified the arguments in nssCKFWSlot_GetToken.
   1.185 +   */
   1.186 +
   1.187 +  arena = NSSArena_Create();
   1.188 +  if (!arena) {
   1.189 +    *pError = CKR_HOST_MEMORY;
   1.190 +    goto loser;
   1.191 +  }
   1.192 +
   1.193 +  fwToken = nss_ZNEW(arena, NSSCKFWToken);
   1.194 +  if (!fwToken) {
   1.195 +    *pError = CKR_HOST_MEMORY;
   1.196 +    goto loser;
   1.197 +  }    
   1.198 +
   1.199 +  fwToken->arena = arena;
   1.200 +  fwToken->mdToken = mdToken;
   1.201 +  fwToken->fwSlot = fwSlot;
   1.202 +  fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
   1.203 +  fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
   1.204 +  fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
   1.205 +  fwToken->sessionCount = 0;
   1.206 +  fwToken->rwSessionCount = 0;
   1.207 +
   1.208 +  fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);
   1.209 +  if (!fwToken->mutex) {
   1.210 +    if( CKR_OK == *pError ) {
   1.211 +      *pError = CKR_GENERAL_ERROR;
   1.212 +    }
   1.213 +    goto loser;
   1.214 +  }
   1.215 +
   1.216 +  fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);
   1.217 +  if (!fwToken->sessions) {
   1.218 +    if( CKR_OK == *pError ) {
   1.219 +      *pError = CKR_GENERAL_ERROR;
   1.220 +    }
   1.221 +    goto loser;
   1.222 +  }
   1.223 +
   1.224 +  if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
   1.225 +                   fwToken->fwInstance) ) {
   1.226 +    fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 
   1.227 +                                   arena, pError);
   1.228 +    if (!fwToken->sessionObjectHash) {
   1.229 +      if( CKR_OK == *pError ) {
   1.230 +        *pError = CKR_GENERAL_ERROR;
   1.231 +      }
   1.232 +      goto loser;
   1.233 +    }
   1.234 +  }
   1.235 +
   1.236 +  fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 
   1.237 +                            arena, pError);
   1.238 +  if (!fwToken->mdObjectHash) {
   1.239 +    if( CKR_OK == *pError ) {
   1.240 +      *pError = CKR_GENERAL_ERROR;
   1.241 +    }
   1.242 +    goto loser;
   1.243 +  }
   1.244 +
   1.245 +  fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance, 
   1.246 +                            arena, pError);
   1.247 +  if (!fwToken->mdMechanismHash) {
   1.248 +    if( CKR_OK == *pError ) {
   1.249 +      *pError = CKR_GENERAL_ERROR;
   1.250 +    }
   1.251 +    goto loser;
   1.252 +  }
   1.253 +
   1.254 +  /* More here */
   1.255 +
   1.256 +  if (mdToken->Setup) {
   1.257 +    *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
   1.258 +    if( CKR_OK != *pError ) {
   1.259 +      goto loser;
   1.260 +    }
   1.261 +  }
   1.262 +
   1.263 +  called_setup = CK_TRUE;
   1.264 +
   1.265 +#ifdef DEBUG
   1.266 +  *pError = token_add_pointer(fwToken);
   1.267 +  if( CKR_OK != *pError ) {
   1.268 +    goto loser;
   1.269 +  }
   1.270 +#endif /* DEBUG */
   1.271 +
   1.272 +  *pError = CKR_OK;
   1.273 +  return fwToken;
   1.274 +
   1.275 + loser:
   1.276 +
   1.277 +  if( CK_TRUE == called_setup ) {
   1.278 +    if (mdToken->Invalidate) {
   1.279 +      mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
   1.280 +    }
   1.281 +  }
   1.282 +
   1.283 +  if (arena) {
   1.284 +    (void)NSSArena_Destroy(arena);
   1.285 +  }
   1.286 +
   1.287 +  return (NSSCKFWToken *)NULL;
   1.288 +}
   1.289 +
   1.290 +static void
   1.291 +nss_ckfwtoken_session_iterator
   1.292 +(
   1.293 +  const void *key,
   1.294 +  void *value,
   1.295 +  void *closure
   1.296 +)
   1.297 +{
   1.298 +  /*
   1.299 +   * Remember that the fwToken->mutex is locked
   1.300 +   */
   1.301 +  NSSCKFWSession *fwSession = (NSSCKFWSession *)value;
   1.302 +  (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
   1.303 +  return;
   1.304 +}
   1.305 +
   1.306 +static void
   1.307 +nss_ckfwtoken_object_iterator
   1.308 +(
   1.309 +  const void *key,
   1.310 +  void *value,
   1.311 +  void *closure
   1.312 +)
   1.313 +{
   1.314 +  /*
   1.315 +   * Remember that the fwToken->mutex is locked
   1.316 +   */
   1.317 +  NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
   1.318 +  (void)nssCKFWObject_Finalize(fwObject, CK_FALSE);
   1.319 +  return;
   1.320 +}
   1.321 +
   1.322 +/*
   1.323 + * nssCKFWToken_Destroy
   1.324 + *
   1.325 + */
   1.326 +NSS_IMPLEMENT CK_RV
   1.327 +nssCKFWToken_Destroy
   1.328 +(
   1.329 +  NSSCKFWToken *fwToken
   1.330 +)
   1.331 +{
   1.332 +  CK_RV error = CKR_OK;
   1.333 +
   1.334 +#ifdef NSSDEBUG
   1.335 +  error = nssCKFWToken_verifyPointer(fwToken);
   1.336 +  if( CKR_OK != error ) {
   1.337 +    return error;
   1.338 +  }
   1.339 +#endif /* NSSDEBUG */
   1.340 +
   1.341 +  (void)nssCKFWMutex_Destroy(fwToken->mutex);
   1.342 +  
   1.343 +  if (fwToken->mdToken->Invalidate) {
   1.344 +    fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,
   1.345 +      fwToken->mdInstance, fwToken->fwInstance);
   1.346 +  }
   1.347 +  /* we can destroy the list without locking now because no one else is 
   1.348 +   * referencing us (or _Destroy was invalidly called!)
   1.349 +   */
   1.350 +  nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, 
   1.351 +                                                                (void *)NULL);
   1.352 +  nssCKFWHash_Destroy(fwToken->sessions);
   1.353 +
   1.354 +  /* session objects go away when their sessions are removed */
   1.355 +  if (fwToken->sessionObjectHash) {
   1.356 +    nssCKFWHash_Destroy(fwToken->sessionObjectHash);
   1.357 +  }
   1.358 +
   1.359 +  /* free up the token objects */
   1.360 +  if (fwToken->mdObjectHash) {
   1.361 +    nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator, 
   1.362 +                                                                (void *)NULL);
   1.363 +    nssCKFWHash_Destroy(fwToken->mdObjectHash);
   1.364 +  }
   1.365 +  if (fwToken->mdMechanismHash) {
   1.366 +    nssCKFWHash_Destroy(fwToken->mdMechanismHash);
   1.367 +  }
   1.368 +
   1.369 +  nssCKFWSlot_ClearToken(fwToken->fwSlot);
   1.370 +  
   1.371 +#ifdef DEBUG
   1.372 +  error = token_remove_pointer(fwToken);
   1.373 +#endif /* DEBUG */
   1.374 +
   1.375 +  (void)NSSArena_Destroy(fwToken->arena);
   1.376 +  return error;
   1.377 +}
   1.378 +
   1.379 +/*
   1.380 + * nssCKFWToken_GetMDToken
   1.381 + *
   1.382 + */
   1.383 +NSS_IMPLEMENT NSSCKMDToken *
   1.384 +nssCKFWToken_GetMDToken
   1.385 +(
   1.386 +  NSSCKFWToken *fwToken
   1.387 +)
   1.388 +{
   1.389 +#ifdef NSSDEBUG
   1.390 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.391 +    return (NSSCKMDToken *)NULL;
   1.392 +  }
   1.393 +#endif /* NSSDEBUG */
   1.394 +
   1.395 +  return fwToken->mdToken;
   1.396 +}
   1.397 +
   1.398 +/*
   1.399 + * nssCKFWToken_GetArena
   1.400 + *
   1.401 + */
   1.402 +NSS_IMPLEMENT NSSArena *
   1.403 +nssCKFWToken_GetArena
   1.404 +(
   1.405 +  NSSCKFWToken *fwToken,
   1.406 +  CK_RV *pError
   1.407 +)
   1.408 +{
   1.409 +#ifdef NSSDEBUG
   1.410 +  if (!pError) {
   1.411 +    return (NSSArena *)NULL;
   1.412 +  }
   1.413 +
   1.414 +  *pError = nssCKFWToken_verifyPointer(fwToken);
   1.415 +  if( CKR_OK != *pError ) {
   1.416 +    return (NSSArena *)NULL;
   1.417 +  }
   1.418 +#endif /* NSSDEBUG */
   1.419 +
   1.420 +  return fwToken->arena;
   1.421 +}
   1.422 +
   1.423 +/*
   1.424 + * nssCKFWToken_GetFWSlot
   1.425 + *
   1.426 + */
   1.427 +NSS_IMPLEMENT NSSCKFWSlot *
   1.428 +nssCKFWToken_GetFWSlot
   1.429 +(
   1.430 +  NSSCKFWToken *fwToken
   1.431 +)
   1.432 +{
   1.433 +#ifdef NSSDEBUG
   1.434 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.435 +    return (NSSCKFWSlot *)NULL;
   1.436 +  }
   1.437 +#endif /* NSSDEBUG */
   1.438 +
   1.439 +  return fwToken->fwSlot;
   1.440 +}
   1.441 +
   1.442 +/*
   1.443 + * nssCKFWToken_GetMDSlot
   1.444 + *
   1.445 + */
   1.446 +NSS_IMPLEMENT NSSCKMDSlot *
   1.447 +nssCKFWToken_GetMDSlot
   1.448 +(
   1.449 +  NSSCKFWToken *fwToken
   1.450 +)
   1.451 +{
   1.452 +#ifdef NSSDEBUG
   1.453 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.454 +    return (NSSCKMDSlot *)NULL;
   1.455 +  }
   1.456 +#endif /* NSSDEBUG */
   1.457 +
   1.458 +  return fwToken->mdSlot;
   1.459 +}
   1.460 +
   1.461 +/*
   1.462 + * nssCKFWToken_GetSessionState
   1.463 + *
   1.464 + */
   1.465 +NSS_IMPLEMENT CK_STATE
   1.466 +nssCKFWToken_GetSessionState
   1.467 +(
   1.468 +  NSSCKFWToken *fwToken
   1.469 +)
   1.470 +{
   1.471 +#ifdef NSSDEBUG
   1.472 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.473 +    return CKS_RO_PUBLIC_SESSION; /* whatever */
   1.474 +  }
   1.475 +#endif /* NSSDEBUG */
   1.476 +
   1.477 +  /*
   1.478 +   * BTW, do not lock the token in this method.
   1.479 +   */
   1.480 +
   1.481 +  /*
   1.482 +   * Theoretically, there is no state if there aren't any
   1.483 +   * sessions open.  But then we'd need to worry about
   1.484 +   * reporting an error, etc.  What the heck-- let's just
   1.485 +   * revert to CKR_RO_PUBLIC_SESSION as the "default."
   1.486 +   */
   1.487 +
   1.488 +  return fwToken->state;
   1.489 +}
   1.490 +
   1.491 +/*
   1.492 + * nssCKFWToken_InitToken
   1.493 + *
   1.494 + */
   1.495 +NSS_IMPLEMENT CK_RV
   1.496 +nssCKFWToken_InitToken
   1.497 +(
   1.498 +  NSSCKFWToken *fwToken,
   1.499 +  NSSItem *pin,
   1.500 +  NSSUTF8 *label
   1.501 +)
   1.502 +{
   1.503 +  CK_RV error;
   1.504 +
   1.505 +#ifdef NSSDEBUG
   1.506 +  error = nssCKFWToken_verifyPointer(fwToken);
   1.507 +  if( CKR_OK != error ) {
   1.508 +    return CKR_ARGUMENTS_BAD;
   1.509 +  }
   1.510 +#endif /* NSSDEBUG */
   1.511 +
   1.512 +  error = nssCKFWMutex_Lock(fwToken->mutex);
   1.513 +  if( CKR_OK != error ) {
   1.514 +    return error;
   1.515 +  }
   1.516 +
   1.517 +  if( fwToken->sessionCount > 0 ) {
   1.518 +    error = CKR_SESSION_EXISTS;
   1.519 +    goto done;
   1.520 +  }
   1.521 +
   1.522 +  if (!fwToken->mdToken->InitToken) {
   1.523 +    error = CKR_DEVICE_ERROR;
   1.524 +    goto done;
   1.525 +  }
   1.526 +
   1.527 +  if (!pin) {
   1.528 +    if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
   1.529 +      ; /* okay */
   1.530 +    } else {
   1.531 +      error = CKR_PIN_INCORRECT;
   1.532 +      goto done;
   1.533 +    }
   1.534 +  }
   1.535 +
   1.536 +  if (!label) {
   1.537 +    label = (NSSUTF8 *) "";
   1.538 +  }
   1.539 +
   1.540 +  error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
   1.541 +            fwToken->mdInstance, fwToken->fwInstance, pin, label);
   1.542 +
   1.543 + done:
   1.544 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
   1.545 +  return error;
   1.546 +}
   1.547 +
   1.548 +/*
   1.549 + * nssCKFWToken_GetLabel
   1.550 + *
   1.551 + */
   1.552 +NSS_IMPLEMENT CK_RV
   1.553 +nssCKFWToken_GetLabel
   1.554 +(
   1.555 +  NSSCKFWToken *fwToken,
   1.556 +  CK_CHAR label[32]
   1.557 +)
   1.558 +{
   1.559 +  CK_RV error = CKR_OK;
   1.560 +
   1.561 +#ifdef NSSDEBUG
   1.562 +  if( (CK_CHAR_PTR)NULL == label ) {
   1.563 +    return CKR_ARGUMENTS_BAD;
   1.564 +  }
   1.565 +
   1.566 +  error = nssCKFWToken_verifyPointer(fwToken);
   1.567 +  if( CKR_OK != error ) {
   1.568 +    return error;
   1.569 +  }
   1.570 +#endif /* NSSDEBUG */
   1.571 +
   1.572 +  error = nssCKFWMutex_Lock(fwToken->mutex);
   1.573 +  if( CKR_OK != error ) {
   1.574 +    return error;
   1.575 +  }
   1.576 +
   1.577 +  if (!fwToken->label) {
   1.578 +    if (fwToken->mdToken->GetLabel) {
   1.579 +      fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,
   1.580 +        fwToken->mdInstance, fwToken->fwInstance, &error);
   1.581 +      if ((!fwToken->label) && (CKR_OK != error)) {
   1.582 +        goto done;
   1.583 +      }
   1.584 +    } else {
   1.585 +      fwToken->label = (NSSUTF8 *) "";
   1.586 +    }
   1.587 +  }
   1.588 +
   1.589 +  (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');
   1.590 +  error = CKR_OK;
   1.591 +
   1.592 + done:
   1.593 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
   1.594 +  return error;
   1.595 +}
   1.596 +
   1.597 +/*
   1.598 + * nssCKFWToken_GetManufacturerID
   1.599 + *
   1.600 + */
   1.601 +NSS_IMPLEMENT CK_RV
   1.602 +nssCKFWToken_GetManufacturerID
   1.603 +(
   1.604 +  NSSCKFWToken *fwToken,
   1.605 +  CK_CHAR manufacturerID[32]
   1.606 +)
   1.607 +{
   1.608 +  CK_RV error = CKR_OK;
   1.609 +
   1.610 +#ifdef NSSDEBUG
   1.611 +  if( (CK_CHAR_PTR)NULL == manufacturerID ) {
   1.612 +    return CKR_ARGUMENTS_BAD;
   1.613 +  }
   1.614 +
   1.615 +  error = nssCKFWToken_verifyPointer(fwToken);
   1.616 +  if( CKR_OK != error ) {
   1.617 +    return error;
   1.618 +  }
   1.619 +#endif /* NSSDEBUG */
   1.620 +
   1.621 +  error = nssCKFWMutex_Lock(fwToken->mutex);
   1.622 +  if( CKR_OK != error ) {
   1.623 +    return error;
   1.624 +  }
   1.625 +
   1.626 +  if (!fwToken->manufacturerID) {
   1.627 +    if (fwToken->mdToken->GetManufacturerID) {
   1.628 +      fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,
   1.629 +        fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
   1.630 +      if ((!fwToken->manufacturerID) && (CKR_OK != error)) {
   1.631 +        goto done;
   1.632 +      }
   1.633 +    } else {
   1.634 +      fwToken->manufacturerID = (NSSUTF8 *)"";
   1.635 +    }
   1.636 +  }
   1.637 +
   1.638 +  (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');
   1.639 +  error = CKR_OK;
   1.640 +
   1.641 + done:
   1.642 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
   1.643 +  return error;
   1.644 +}
   1.645 +
   1.646 +/*
   1.647 + * nssCKFWToken_GetModel
   1.648 + *
   1.649 + */
   1.650 +NSS_IMPLEMENT CK_RV
   1.651 +nssCKFWToken_GetModel
   1.652 +(
   1.653 +  NSSCKFWToken *fwToken,
   1.654 +  CK_CHAR model[16]
   1.655 +)
   1.656 +{
   1.657 +  CK_RV error = CKR_OK;
   1.658 +
   1.659 +#ifdef NSSDEBUG
   1.660 +  if( (CK_CHAR_PTR)NULL == model ) {
   1.661 +    return CKR_ARGUMENTS_BAD;
   1.662 +  }
   1.663 +
   1.664 +  error = nssCKFWToken_verifyPointer(fwToken);
   1.665 +  if( CKR_OK != error ) {
   1.666 +    return error;
   1.667 +  }
   1.668 +#endif /* NSSDEBUG */
   1.669 +
   1.670 +  error = nssCKFWMutex_Lock(fwToken->mutex);
   1.671 +  if( CKR_OK != error ) {
   1.672 +    return error;
   1.673 +  }
   1.674 +
   1.675 +  if (!fwToken->model) {
   1.676 +    if (fwToken->mdToken->GetModel) {
   1.677 +      fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken,
   1.678 +        fwToken->mdInstance, fwToken->fwInstance, &error);
   1.679 +      if ((!fwToken->model) && (CKR_OK != error)) {
   1.680 +        goto done;
   1.681 +      }
   1.682 +    } else {
   1.683 +      fwToken->model = (NSSUTF8 *)"";
   1.684 +    }
   1.685 +  }
   1.686 +
   1.687 +  (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' ');
   1.688 +  error = CKR_OK;
   1.689 +
   1.690 + done:
   1.691 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
   1.692 +  return error;
   1.693 +}
   1.694 +
   1.695 +/*
   1.696 + * nssCKFWToken_GetSerialNumber
   1.697 + *
   1.698 + */
   1.699 +NSS_IMPLEMENT CK_RV
   1.700 +nssCKFWToken_GetSerialNumber
   1.701 +(
   1.702 +  NSSCKFWToken *fwToken,
   1.703 +  CK_CHAR serialNumber[16]
   1.704 +)
   1.705 +{
   1.706 +  CK_RV error = CKR_OK;
   1.707 +
   1.708 +#ifdef NSSDEBUG
   1.709 +  if( (CK_CHAR_PTR)NULL == serialNumber ) {
   1.710 +    return CKR_ARGUMENTS_BAD;
   1.711 +  }
   1.712 +
   1.713 +  error = nssCKFWToken_verifyPointer(fwToken);
   1.714 +  if( CKR_OK != error ) {
   1.715 +    return error;
   1.716 +  }
   1.717 +#endif /* NSSDEBUG */
   1.718 +
   1.719 +  error = nssCKFWMutex_Lock(fwToken->mutex);
   1.720 +  if( CKR_OK != error ) {
   1.721 +    return error;
   1.722 +  }
   1.723 +
   1.724 +  if (!fwToken->serialNumber) {
   1.725 +    if (fwToken->mdToken->GetSerialNumber) {
   1.726 +      fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken, 
   1.727 +        fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
   1.728 +      if ((!fwToken->serialNumber) && (CKR_OK != error)) {
   1.729 +        goto done;
   1.730 +      }
   1.731 +    } else {
   1.732 +      fwToken->serialNumber = (NSSUTF8 *)"";
   1.733 +    }
   1.734 +  }
   1.735 +
   1.736 +  (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' ');
   1.737 +  error = CKR_OK;
   1.738 +
   1.739 + done:
   1.740 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
   1.741 +  return error;
   1.742 +}
   1.743 +
   1.744 +
   1.745 +/*
   1.746 + * nssCKFWToken_GetHasRNG
   1.747 + *
   1.748 + */
   1.749 +NSS_IMPLEMENT CK_BBOOL
   1.750 +nssCKFWToken_GetHasRNG
   1.751 +(
   1.752 +  NSSCKFWToken *fwToken
   1.753 +)
   1.754 +{
   1.755 +#ifdef NSSDEBUG
   1.756 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.757 +    return CK_FALSE;
   1.758 +  }
   1.759 +#endif /* NSSDEBUG */
   1.760 +
   1.761 +  if (!fwToken->mdToken->GetHasRNG) {
   1.762 +    return CK_FALSE;
   1.763 +  }
   1.764 +
   1.765 +  return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken, 
   1.766 +    fwToken->mdInstance, fwToken->fwInstance);
   1.767 +}
   1.768 +
   1.769 +/*
   1.770 + * nssCKFWToken_GetIsWriteProtected
   1.771 + *
   1.772 + */
   1.773 +NSS_IMPLEMENT CK_BBOOL
   1.774 +nssCKFWToken_GetIsWriteProtected
   1.775 +(
   1.776 +  NSSCKFWToken *fwToken
   1.777 +)
   1.778 +{
   1.779 +#ifdef NSSDEBUG
   1.780 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.781 +    return CK_FALSE;
   1.782 +  }
   1.783 +#endif /* NSSDEBUG */
   1.784 +
   1.785 +  if (!fwToken->mdToken->GetIsWriteProtected) {
   1.786 +    return CK_FALSE;
   1.787 +  }
   1.788 +
   1.789 +  return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken, 
   1.790 +    fwToken->mdInstance, fwToken->fwInstance);
   1.791 +}
   1.792 +
   1.793 +/*
   1.794 + * nssCKFWToken_GetLoginRequired
   1.795 + *
   1.796 + */
   1.797 +NSS_IMPLEMENT CK_BBOOL
   1.798 +nssCKFWToken_GetLoginRequired
   1.799 +(
   1.800 +  NSSCKFWToken *fwToken
   1.801 +)
   1.802 +{
   1.803 +#ifdef NSSDEBUG
   1.804 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.805 +    return CK_FALSE;
   1.806 +  }
   1.807 +#endif /* NSSDEBUG */
   1.808 +
   1.809 +  if (!fwToken->mdToken->GetLoginRequired) {
   1.810 +    return CK_FALSE;
   1.811 +  }
   1.812 +
   1.813 +  return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken, 
   1.814 +    fwToken->mdInstance, fwToken->fwInstance);
   1.815 +}
   1.816 +
   1.817 +/*
   1.818 + * nssCKFWToken_GetUserPinInitialized
   1.819 + *
   1.820 + */
   1.821 +NSS_IMPLEMENT CK_BBOOL
   1.822 +nssCKFWToken_GetUserPinInitialized
   1.823 +(
   1.824 +  NSSCKFWToken *fwToken
   1.825 +)
   1.826 +{
   1.827 +#ifdef NSSDEBUG
   1.828 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.829 +    return CK_FALSE;
   1.830 +  }
   1.831 +#endif /* NSSDEBUG */
   1.832 +
   1.833 +  if (!fwToken->mdToken->GetUserPinInitialized) {
   1.834 +    return CK_FALSE;
   1.835 +  }
   1.836 +
   1.837 +  return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken, 
   1.838 +    fwToken->mdInstance, fwToken->fwInstance);
   1.839 +}
   1.840 +
   1.841 +/*
   1.842 + * nssCKFWToken_GetRestoreKeyNotNeeded
   1.843 + *
   1.844 + */
   1.845 +NSS_IMPLEMENT CK_BBOOL
   1.846 +nssCKFWToken_GetRestoreKeyNotNeeded
   1.847 +(
   1.848 +  NSSCKFWToken *fwToken
   1.849 +)
   1.850 +{
   1.851 +#ifdef NSSDEBUG
   1.852 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.853 +    return CK_FALSE;
   1.854 +  }
   1.855 +#endif /* NSSDEBUG */
   1.856 +
   1.857 +  if (!fwToken->mdToken->GetRestoreKeyNotNeeded) {
   1.858 +    return CK_FALSE;
   1.859 +  }
   1.860 +
   1.861 +  return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken, 
   1.862 +    fwToken->mdInstance, fwToken->fwInstance);
   1.863 +}
   1.864 +
   1.865 +/*
   1.866 + * nssCKFWToken_GetHasClockOnToken
   1.867 + *
   1.868 + */
   1.869 +NSS_IMPLEMENT CK_BBOOL
   1.870 +nssCKFWToken_GetHasClockOnToken
   1.871 +(
   1.872 +  NSSCKFWToken *fwToken
   1.873 +)
   1.874 +{
   1.875 +#ifdef NSSDEBUG
   1.876 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.877 +    return CK_FALSE;
   1.878 +  }
   1.879 +#endif /* NSSDEBUG */
   1.880 +
   1.881 +  if (!fwToken->mdToken->GetHasClockOnToken) {
   1.882 +    return CK_FALSE;
   1.883 +  }
   1.884 +
   1.885 +  return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken, 
   1.886 +    fwToken->mdInstance, fwToken->fwInstance);
   1.887 +}
   1.888 +
   1.889 +/*
   1.890 + * nssCKFWToken_GetHasProtectedAuthenticationPath
   1.891 + *
   1.892 + */
   1.893 +NSS_IMPLEMENT CK_BBOOL
   1.894 +nssCKFWToken_GetHasProtectedAuthenticationPath
   1.895 +(
   1.896 +  NSSCKFWToken *fwToken
   1.897 +)
   1.898 +{
   1.899 +#ifdef NSSDEBUG
   1.900 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.901 +    return CK_FALSE;
   1.902 +  }
   1.903 +#endif /* NSSDEBUG */
   1.904 +
   1.905 +  if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) {
   1.906 +    return CK_FALSE;
   1.907 +  }
   1.908 +
   1.909 +  return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken, 
   1.910 +    fwToken, fwToken->mdInstance, fwToken->fwInstance);
   1.911 +}
   1.912 +
   1.913 +/*
   1.914 + * nssCKFWToken_GetSupportsDualCryptoOperations
   1.915 + *
   1.916 + */
   1.917 +NSS_IMPLEMENT CK_BBOOL
   1.918 +nssCKFWToken_GetSupportsDualCryptoOperations
   1.919 +(
   1.920 +  NSSCKFWToken *fwToken
   1.921 +)
   1.922 +{
   1.923 +#ifdef NSSDEBUG
   1.924 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.925 +    return CK_FALSE;
   1.926 +  }
   1.927 +#endif /* NSSDEBUG */
   1.928 +
   1.929 +  if (!fwToken->mdToken->GetSupportsDualCryptoOperations) {
   1.930 +    return CK_FALSE;
   1.931 +  }
   1.932 +
   1.933 +  return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken, 
   1.934 +    fwToken, fwToken->mdInstance, fwToken->fwInstance);
   1.935 +}
   1.936 +
   1.937 +/*
   1.938 + * nssCKFWToken_GetMaxSessionCount
   1.939 + *
   1.940 + */
   1.941 +NSS_IMPLEMENT CK_ULONG
   1.942 +nssCKFWToken_GetMaxSessionCount
   1.943 +(
   1.944 +  NSSCKFWToken *fwToken
   1.945 +)
   1.946 +{
   1.947 +#ifdef NSSDEBUG
   1.948 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.949 +    return CK_UNAVAILABLE_INFORMATION;
   1.950 +  }
   1.951 +#endif /* NSSDEBUG */
   1.952 +
   1.953 +  if (!fwToken->mdToken->GetMaxSessionCount) {
   1.954 +    return CK_UNAVAILABLE_INFORMATION;
   1.955 +  }
   1.956 +
   1.957 +  return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken, 
   1.958 +    fwToken->mdInstance, fwToken->fwInstance);
   1.959 +}
   1.960 +
   1.961 +/*
   1.962 + * nssCKFWToken_GetMaxRwSessionCount
   1.963 + *
   1.964 + */
   1.965 +NSS_IMPLEMENT CK_ULONG
   1.966 +nssCKFWToken_GetMaxRwSessionCount
   1.967 +(
   1.968 +  NSSCKFWToken *fwToken
   1.969 +)
   1.970 +{
   1.971 +#ifdef NSSDEBUG
   1.972 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.973 +    return CK_UNAVAILABLE_INFORMATION;
   1.974 +  }
   1.975 +#endif /* NSSDEBUG */
   1.976 +
   1.977 +  if (!fwToken->mdToken->GetMaxRwSessionCount) {
   1.978 +    return CK_UNAVAILABLE_INFORMATION;
   1.979 +  }
   1.980 +
   1.981 +  return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken, 
   1.982 +    fwToken->mdInstance, fwToken->fwInstance);
   1.983 +}
   1.984 +
   1.985 +/*
   1.986 + * nssCKFWToken_GetMaxPinLen
   1.987 + *
   1.988 + */
   1.989 +NSS_IMPLEMENT CK_ULONG
   1.990 +nssCKFWToken_GetMaxPinLen
   1.991 +(
   1.992 +  NSSCKFWToken *fwToken
   1.993 +)
   1.994 +{
   1.995 +#ifdef NSSDEBUG
   1.996 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   1.997 +    return CK_UNAVAILABLE_INFORMATION;
   1.998 +  }
   1.999 +#endif /* NSSDEBUG */
  1.1000 +
  1.1001 +  if (!fwToken->mdToken->GetMaxPinLen) {
  1.1002 +    return CK_UNAVAILABLE_INFORMATION;
  1.1003 +  }
  1.1004 +
  1.1005 +  return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken, 
  1.1006 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1007 +}
  1.1008 +
  1.1009 +/*
  1.1010 + * nssCKFWToken_GetMinPinLen
  1.1011 + *
  1.1012 + */
  1.1013 +NSS_IMPLEMENT CK_ULONG
  1.1014 +nssCKFWToken_GetMinPinLen
  1.1015 +(
  1.1016 +  NSSCKFWToken *fwToken
  1.1017 +)
  1.1018 +{
  1.1019 +#ifdef NSSDEBUG
  1.1020 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1021 +    return CK_UNAVAILABLE_INFORMATION;
  1.1022 +  }
  1.1023 +#endif /* NSSDEBUG */
  1.1024 +
  1.1025 +  if (!fwToken->mdToken->GetMinPinLen) {
  1.1026 +    return CK_UNAVAILABLE_INFORMATION;
  1.1027 +  }
  1.1028 +
  1.1029 +  return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken, 
  1.1030 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1031 +}
  1.1032 +
  1.1033 +/*
  1.1034 + * nssCKFWToken_GetTotalPublicMemory
  1.1035 + *
  1.1036 + */
  1.1037 +NSS_IMPLEMENT CK_ULONG
  1.1038 +nssCKFWToken_GetTotalPublicMemory
  1.1039 +(
  1.1040 +  NSSCKFWToken *fwToken
  1.1041 +)
  1.1042 +{
  1.1043 +#ifdef NSSDEBUG
  1.1044 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1045 +    return CK_UNAVAILABLE_INFORMATION;
  1.1046 +  }
  1.1047 +#endif /* NSSDEBUG */
  1.1048 +
  1.1049 +  if (!fwToken->mdToken->GetTotalPublicMemory) {
  1.1050 +    return CK_UNAVAILABLE_INFORMATION;
  1.1051 +  }
  1.1052 +
  1.1053 +  return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken, 
  1.1054 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1055 +}
  1.1056 +
  1.1057 +/*
  1.1058 + * nssCKFWToken_GetFreePublicMemory
  1.1059 + *
  1.1060 + */
  1.1061 +NSS_IMPLEMENT CK_ULONG
  1.1062 +nssCKFWToken_GetFreePublicMemory
  1.1063 +(
  1.1064 +  NSSCKFWToken *fwToken
  1.1065 +)
  1.1066 +{
  1.1067 +#ifdef NSSDEBUG
  1.1068 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1069 +    return CK_UNAVAILABLE_INFORMATION;
  1.1070 +  }
  1.1071 +#endif /* NSSDEBUG */
  1.1072 +
  1.1073 +  if (!fwToken->mdToken->GetFreePublicMemory) {
  1.1074 +    return CK_UNAVAILABLE_INFORMATION;
  1.1075 +  }
  1.1076 +
  1.1077 +  return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken, 
  1.1078 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1079 +}
  1.1080 +
  1.1081 +/*
  1.1082 + * nssCKFWToken_GetTotalPrivateMemory
  1.1083 + *
  1.1084 + */
  1.1085 +NSS_IMPLEMENT CK_ULONG
  1.1086 +nssCKFWToken_GetTotalPrivateMemory
  1.1087 +(
  1.1088 +  NSSCKFWToken *fwToken
  1.1089 +)
  1.1090 +{
  1.1091 +#ifdef NSSDEBUG
  1.1092 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1093 +    return CK_UNAVAILABLE_INFORMATION;
  1.1094 +  }
  1.1095 +#endif /* NSSDEBUG */
  1.1096 +
  1.1097 +  if (!fwToken->mdToken->GetTotalPrivateMemory) {
  1.1098 +    return CK_UNAVAILABLE_INFORMATION;
  1.1099 +  }
  1.1100 +
  1.1101 +  return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken, 
  1.1102 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1103 +}
  1.1104 +
  1.1105 +/*
  1.1106 + * nssCKFWToken_GetFreePrivateMemory
  1.1107 + *
  1.1108 + */
  1.1109 +NSS_IMPLEMENT CK_ULONG
  1.1110 +nssCKFWToken_GetFreePrivateMemory
  1.1111 +(
  1.1112 +  NSSCKFWToken *fwToken
  1.1113 +)
  1.1114 +{
  1.1115 +#ifdef NSSDEBUG
  1.1116 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1117 +    return CK_UNAVAILABLE_INFORMATION;
  1.1118 +  }
  1.1119 +#endif /* NSSDEBUG */
  1.1120 +
  1.1121 +  if (!fwToken->mdToken->GetFreePrivateMemory) {
  1.1122 +    return CK_UNAVAILABLE_INFORMATION;
  1.1123 +  }
  1.1124 +
  1.1125 +  return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken, 
  1.1126 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1127 +}
  1.1128 +
  1.1129 +/*
  1.1130 + * nssCKFWToken_GetHardwareVersion
  1.1131 + *
  1.1132 + */
  1.1133 +NSS_IMPLEMENT CK_VERSION
  1.1134 +nssCKFWToken_GetHardwareVersion
  1.1135 +(
  1.1136 +  NSSCKFWToken *fwToken
  1.1137 +)
  1.1138 +{
  1.1139 +  CK_VERSION rv;
  1.1140 +
  1.1141 +#ifdef NSSDEBUG
  1.1142 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1143 +    rv.major = rv.minor = 0;
  1.1144 +    return rv;
  1.1145 +  }
  1.1146 +#endif /* NSSDEBUG */
  1.1147 +
  1.1148 +  if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1.1149 +    rv.major = rv.minor = 0;
  1.1150 +    return rv;
  1.1151 +  }
  1.1152 +
  1.1153 +  if( (0 != fwToken->hardwareVersion.major) ||
  1.1154 +      (0 != fwToken->hardwareVersion.minor) ) {
  1.1155 +    rv = fwToken->hardwareVersion;
  1.1156 +    goto done;
  1.1157 +  }
  1.1158 +
  1.1159 +  if (fwToken->mdToken->GetHardwareVersion) {
  1.1160 +    fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion(
  1.1161 +      fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  1.1162 +  } else {
  1.1163 +    fwToken->hardwareVersion.major = 0;
  1.1164 +    fwToken->hardwareVersion.minor = 1;
  1.1165 +  }
  1.1166 +
  1.1167 +  rv = fwToken->hardwareVersion;
  1.1168 +
  1.1169 + done:
  1.1170 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1171 +  return rv;
  1.1172 +}
  1.1173 +
  1.1174 +/*
  1.1175 + * nssCKFWToken_GetFirmwareVersion
  1.1176 + *
  1.1177 + */
  1.1178 +NSS_IMPLEMENT CK_VERSION
  1.1179 +nssCKFWToken_GetFirmwareVersion
  1.1180 +(
  1.1181 +  NSSCKFWToken *fwToken
  1.1182 +)
  1.1183 +{
  1.1184 +  CK_VERSION rv;
  1.1185 +
  1.1186 +#ifdef NSSDEBUG
  1.1187 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1188 +    rv.major = rv.minor = 0;
  1.1189 +    return rv;
  1.1190 +  }
  1.1191 +#endif /* NSSDEBUG */
  1.1192 +
  1.1193 +  if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1.1194 +    rv.major = rv.minor = 0;
  1.1195 +    return rv;
  1.1196 +  }
  1.1197 +
  1.1198 +  if( (0 != fwToken->firmwareVersion.major) ||
  1.1199 +      (0 != fwToken->firmwareVersion.minor) ) {
  1.1200 +    rv = fwToken->firmwareVersion;
  1.1201 +    goto done;
  1.1202 +  }
  1.1203 +
  1.1204 +  if (fwToken->mdToken->GetFirmwareVersion) {
  1.1205 +    fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion(
  1.1206 +      fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  1.1207 +  } else {
  1.1208 +    fwToken->firmwareVersion.major = 0;
  1.1209 +    fwToken->firmwareVersion.minor = 1;
  1.1210 +  }
  1.1211 +
  1.1212 +  rv = fwToken->firmwareVersion;
  1.1213 +
  1.1214 + done:
  1.1215 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1216 +  return rv;
  1.1217 +}
  1.1218 +
  1.1219 +/*
  1.1220 + * nssCKFWToken_GetUTCTime
  1.1221 + *
  1.1222 + */
  1.1223 +NSS_IMPLEMENT CK_RV
  1.1224 +nssCKFWToken_GetUTCTime
  1.1225 +(
  1.1226 +  NSSCKFWToken *fwToken,
  1.1227 +  CK_CHAR utcTime[16]
  1.1228 +)
  1.1229 +{
  1.1230 +  CK_RV error = CKR_OK;
  1.1231 +
  1.1232 +#ifdef NSSDEBUG
  1.1233 +  error = nssCKFWToken_verifyPointer(fwToken);
  1.1234 +  if( CKR_OK != error ) {
  1.1235 +    return error;
  1.1236 +  }
  1.1237 +
  1.1238 +  if( (CK_CHAR_PTR)NULL == utcTime ) {
  1.1239 +    return CKR_ARGUMENTS_BAD;
  1.1240 +  }
  1.1241 +#endif /* DEBUG */
  1.1242 +
  1.1243 +  if( CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken) ) {
  1.1244 +    /* return CKR_DEVICE_ERROR; */
  1.1245 +    (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ');
  1.1246 +    return CKR_OK;
  1.1247 +  }
  1.1248 +
  1.1249 +  if (!fwToken->mdToken->GetUTCTime) {
  1.1250 +    /* It said it had one! */
  1.1251 +    return CKR_GENERAL_ERROR;
  1.1252 +  }
  1.1253 +
  1.1254 +  error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken, 
  1.1255 +            fwToken->mdInstance, fwToken->fwInstance, utcTime);
  1.1256 +  if( CKR_OK != error ) {
  1.1257 +    return error;
  1.1258 +  }
  1.1259 +
  1.1260 +  /* Sanity-check the data */
  1.1261 +  {
  1.1262 +    /* Format is YYYYMMDDhhmmss00 */
  1.1263 +    int i;
  1.1264 +    int Y, M, D, h, m, s, z;
  1.1265 +    static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  1.1266 +
  1.1267 +    for( i = 0; i < 16; i++ ) {
  1.1268 +      if( (utcTime[i] < '0') || (utcTime[i] > '9') ) {
  1.1269 +        goto badtime;
  1.1270 +      }
  1.1271 +    }
  1.1272 +
  1.1273 +    Y = ((utcTime[ 0] - '0') * 1000) + ((utcTime[1] - '0') * 100) +
  1.1274 +        ((utcTime[ 2] - '0') * 10) + (utcTime[ 3] - '0');
  1.1275 +    M = ((utcTime[ 4] - '0') * 10) + (utcTime[ 5] - '0');
  1.1276 +    D = ((utcTime[ 6] - '0') * 10) + (utcTime[ 7] - '0');
  1.1277 +    h = ((utcTime[ 8] - '0') * 10) + (utcTime[ 9] - '0');
  1.1278 +    m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0');
  1.1279 +    s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0');
  1.1280 +    z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '0');
  1.1281 +
  1.1282 +    if( (Y < 1990) || (Y > 3000) ) goto badtime; /* Y3K problem.  heh heh heh */
  1.1283 +    if( (M < 1) || (M > 12) ) goto badtime;
  1.1284 +    if( (D < 1) || (D > 31) ) goto badtime;
  1.1285 +
  1.1286 +    if( D > dims[M-1] ) goto badtime; /* per-month check */
  1.1287 +    if( (2 == M) && (((Y%4)||!(Y%100))&&(Y%400)) && (D > 28) ) goto badtime; /* leap years */
  1.1288 +
  1.1289 +    if( (h < 0) || (h > 23) ) goto badtime;
  1.1290 +    if( (m < 0) || (m > 60) ) goto badtime;
  1.1291 +    if( (s < 0) || (s > 61) ) goto badtime;
  1.1292 +
  1.1293 +    /* 60m and 60 or 61s is only allowed for leap seconds. */
  1.1294 +    if( (60 == m) || (s >= 60) ) {
  1.1295 +      if( (23 != h) || (60 != m) || (s < 60) ) goto badtime;
  1.1296 +      /* leap seconds can only happen on June 30 or Dec 31.. I think */
  1.1297 +      /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */
  1.1298 +    }
  1.1299 +  }
  1.1300 +
  1.1301 +  return CKR_OK;
  1.1302 +
  1.1303 + badtime:
  1.1304 +  return CKR_GENERAL_ERROR;
  1.1305 +}
  1.1306 +
  1.1307 +/*
  1.1308 + * nssCKFWToken_OpenSession
  1.1309 + *
  1.1310 + */
  1.1311 +NSS_IMPLEMENT NSSCKFWSession *
  1.1312 +nssCKFWToken_OpenSession
  1.1313 +(
  1.1314 +  NSSCKFWToken *fwToken,
  1.1315 +  CK_BBOOL rw,
  1.1316 +  CK_VOID_PTR pApplication,
  1.1317 +  CK_NOTIFY Notify,
  1.1318 +  CK_RV *pError
  1.1319 +)
  1.1320 +{
  1.1321 +  NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
  1.1322 +  NSSCKMDSession *mdSession;
  1.1323 +
  1.1324 +#ifdef NSSDEBUG
  1.1325 +  if (!pError) {
  1.1326 +    return (NSSCKFWSession *)NULL;
  1.1327 +  }
  1.1328 +
  1.1329 +  *pError = nssCKFWToken_verifyPointer(fwToken);
  1.1330 +  if( CKR_OK != *pError ) {
  1.1331 +    return (NSSCKFWSession *)NULL;
  1.1332 +  }
  1.1333 +
  1.1334 +  switch( rw ) {
  1.1335 +  case CK_TRUE:
  1.1336 +  case CK_FALSE:
  1.1337 +    break;
  1.1338 +  default:
  1.1339 +    *pError = CKR_ARGUMENTS_BAD;
  1.1340 +    return (NSSCKFWSession *)NULL;
  1.1341 +  }
  1.1342 +#endif /* NSSDEBUG */
  1.1343 +
  1.1344 +  *pError = nssCKFWMutex_Lock(fwToken->mutex);
  1.1345 +  if( CKR_OK != *pError ) {
  1.1346 +    return (NSSCKFWSession *)NULL;
  1.1347 +  }
  1.1348 +
  1.1349 +  if( CK_TRUE == rw ) {
  1.1350 +    /* Read-write session desired */
  1.1351 +    if( CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken) ) {
  1.1352 +      *pError = CKR_TOKEN_WRITE_PROTECTED;
  1.1353 +      goto done;
  1.1354 +    }
  1.1355 +  } else {
  1.1356 +    /* Read-only session desired */
  1.1357 +    if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) {
  1.1358 +      *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;
  1.1359 +      goto done;
  1.1360 +    }
  1.1361 +  }
  1.1362 +
  1.1363 +  /* We could compare sesion counts to any limits we know of, I guess.. */
  1.1364 +
  1.1365 +  if (!fwToken->mdToken->OpenSession) {
  1.1366 +    /*
  1.1367 +     * I'm not sure that the Module actually needs to implement
  1.1368 +     * mdSessions -- the Framework can keep track of everything 
  1.1369 +     * needed, really.  But I'll sort out that detail later..
  1.1370 +     */
  1.1371 +    *pError = CKR_GENERAL_ERROR;
  1.1372 +    goto done;
  1.1373 +  }
  1.1374 +
  1.1375 +  fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);
  1.1376 +  if (!fwSession) {
  1.1377 +    if( CKR_OK == *pError ) {
  1.1378 +      *pError = CKR_GENERAL_ERROR;
  1.1379 +    }
  1.1380 +    goto done;
  1.1381 +  }
  1.1382 +
  1.1383 +  mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,
  1.1384 +                fwToken->mdInstance, fwToken->fwInstance, fwSession,
  1.1385 +                rw, pError);
  1.1386 +  if (!mdSession) {
  1.1387 +    (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1.1388 +    if( CKR_OK == *pError ) {
  1.1389 +      *pError = CKR_GENERAL_ERROR;
  1.1390 +    }
  1.1391 +    goto done;
  1.1392 +  }
  1.1393 +
  1.1394 +  *pError = nssCKFWSession_SetMDSession(fwSession, mdSession);
  1.1395 +  if( CKR_OK != *pError ) {
  1.1396 +    if (mdSession->Close) {
  1.1397 +      mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,
  1.1398 +      fwToken->mdInstance, fwToken->fwInstance);
  1.1399 +    }
  1.1400 +    (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1.1401 +    goto done;
  1.1402 +  }
  1.1403 +
  1.1404 +  *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);
  1.1405 +  if( CKR_OK != *pError ) {
  1.1406 +    (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1.1407 +    fwSession = (NSSCKFWSession *)NULL;
  1.1408 +    goto done;
  1.1409 +  }
  1.1410 +
  1.1411 + done:
  1.1412 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1413 +  return fwSession;
  1.1414 +}
  1.1415 +
  1.1416 +/*
  1.1417 + * nssCKFWToken_GetMechanismCount
  1.1418 + *
  1.1419 + */
  1.1420 +NSS_IMPLEMENT CK_ULONG
  1.1421 +nssCKFWToken_GetMechanismCount
  1.1422 +(
  1.1423 +  NSSCKFWToken *fwToken
  1.1424 +)
  1.1425 +{
  1.1426 +#ifdef NSSDEBUG
  1.1427 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1428 +    return 0;
  1.1429 +  }
  1.1430 +#endif /* NSSDEBUG */
  1.1431 +
  1.1432 +  if (!fwToken->mdToken->GetMechanismCount) {
  1.1433 +    return 0;
  1.1434 +  }
  1.1435 +
  1.1436 +  return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
  1.1437 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1438 +}
  1.1439 +
  1.1440 +/*
  1.1441 + * nssCKFWToken_GetMechanismTypes
  1.1442 + *
  1.1443 + */
  1.1444 +NSS_IMPLEMENT CK_RV
  1.1445 +nssCKFWToken_GetMechanismTypes
  1.1446 +(
  1.1447 +  NSSCKFWToken *fwToken,
  1.1448 +  CK_MECHANISM_TYPE types[]
  1.1449 +)
  1.1450 +{
  1.1451 +#ifdef NSSDEBUG
  1.1452 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1453 +    return CKR_ARGUMENTS_BAD;
  1.1454 +  }
  1.1455 +
  1.1456 +  if (!types) {
  1.1457 +    return CKR_ARGUMENTS_BAD;
  1.1458 +  }
  1.1459 +#endif /* NSSDEBUG */
  1.1460 +
  1.1461 +  if (!fwToken->mdToken->GetMechanismTypes) {
  1.1462 +    /*
  1.1463 +     * This should only be called with a sufficiently-large
  1.1464 +     * "types" array, which can only be done if GetMechanismCount
  1.1465 +     * is implemented.  If that's implemented (and returns nonzero),
  1.1466 +     * then this should be too.  So return an error.
  1.1467 +     */
  1.1468 +    return CKR_GENERAL_ERROR;
  1.1469 +  }
  1.1470 +
  1.1471 +  return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken,
  1.1472 +    fwToken->mdInstance, fwToken->fwInstance, types);
  1.1473 +}
  1.1474 +
  1.1475 +
  1.1476 +/*
  1.1477 + * nssCKFWToken_GetMechanism
  1.1478 + *
  1.1479 + */
  1.1480 +NSS_IMPLEMENT NSSCKFWMechanism *
  1.1481 +nssCKFWToken_GetMechanism
  1.1482 +(
  1.1483 +  NSSCKFWToken *fwToken,
  1.1484 +  CK_MECHANISM_TYPE which,
  1.1485 +  CK_RV *pError
  1.1486 +)
  1.1487 +{
  1.1488 +  NSSCKMDMechanism *mdMechanism;
  1.1489 +  if (!fwToken->mdMechanismHash) {
  1.1490 +    *pError = CKR_GENERAL_ERROR;
  1.1491 +    return (NSSCKFWMechanism *)NULL;
  1.1492 +  }
  1.1493 +  
  1.1494 +  if (!fwToken->mdToken->GetMechanism) {
  1.1495 +    /*
  1.1496 +     * If we don't implement any GetMechanism function, then we must
  1.1497 +     * not support any.
  1.1498 +     */
  1.1499 +    *pError = CKR_MECHANISM_INVALID;
  1.1500 +    return (NSSCKFWMechanism *)NULL;
  1.1501 +  }
  1.1502 +
  1.1503 +  /* lookup in hash table */
  1.1504 +  mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken,
  1.1505 +    fwToken->mdInstance, fwToken->fwInstance, which, pError);
  1.1506 +  if (!mdMechanism) {
  1.1507 +    return (NSSCKFWMechanism *) NULL;
  1.1508 +  }
  1.1509 +  /* store in hash table */
  1.1510 +  return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken,
  1.1511 +    fwToken->mdInstance, fwToken->fwInstance);
  1.1512 +}
  1.1513 +
  1.1514 +NSS_IMPLEMENT CK_RV
  1.1515 +nssCKFWToken_SetSessionState
  1.1516 +(
  1.1517 +  NSSCKFWToken *fwToken,
  1.1518 +  CK_STATE newState
  1.1519 +)
  1.1520 +{
  1.1521 +  CK_RV error = CKR_OK;
  1.1522 +
  1.1523 +#ifdef NSSDEBUG
  1.1524 +  error = nssCKFWToken_verifyPointer(fwToken);
  1.1525 +  if( CKR_OK != error ) {
  1.1526 +    return error;
  1.1527 +  }
  1.1528 +
  1.1529 +  switch( newState ) {
  1.1530 +  case CKS_RO_PUBLIC_SESSION:
  1.1531 +  case CKS_RO_USER_FUNCTIONS:
  1.1532 +  case CKS_RW_PUBLIC_SESSION:
  1.1533 +  case CKS_RW_USER_FUNCTIONS:
  1.1534 +  case CKS_RW_SO_FUNCTIONS:
  1.1535 +    break;
  1.1536 +  default:
  1.1537 +    return CKR_ARGUMENTS_BAD;
  1.1538 +  }
  1.1539 +#endif /* NSSDEBUG */
  1.1540 +
  1.1541 +  error = nssCKFWMutex_Lock(fwToken->mutex);
  1.1542 +  if( CKR_OK != error ) {
  1.1543 +    return error;
  1.1544 +  }
  1.1545 +
  1.1546 +  fwToken->state = newState;
  1.1547 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1548 +  return CKR_OK;
  1.1549 +}
  1.1550 +
  1.1551 +/*
  1.1552 + * nssCKFWToken_RemoveSession
  1.1553 + *
  1.1554 + */
  1.1555 +NSS_IMPLEMENT CK_RV
  1.1556 +nssCKFWToken_RemoveSession
  1.1557 +(
  1.1558 +  NSSCKFWToken *fwToken,
  1.1559 +  NSSCKFWSession *fwSession
  1.1560 +)
  1.1561 +{
  1.1562 +  CK_RV error = CKR_OK;
  1.1563 +
  1.1564 +#ifdef NSSDEBUG
  1.1565 +  error = nssCKFWToken_verifyPointer(fwToken);
  1.1566 +  if( CKR_OK != error ) {
  1.1567 +    return error;
  1.1568 +  }
  1.1569 +
  1.1570 +  error = nssCKFWSession_verifyPointer(fwSession);
  1.1571 +  if( CKR_OK != error ) {
  1.1572 +    return error;
  1.1573 +  }
  1.1574 +#endif /* NSSDEBUG */
  1.1575 +
  1.1576 +  error = nssCKFWMutex_Lock(fwToken->mutex);
  1.1577 +  if( CKR_OK != error ) {
  1.1578 +    return error;
  1.1579 +  }
  1.1580 +
  1.1581 +  if( CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession) ) {
  1.1582 +    error = CKR_SESSION_HANDLE_INVALID;
  1.1583 +    goto done;
  1.1584 +  }
  1.1585 +
  1.1586 +  nssCKFWHash_Remove(fwToken->sessions, fwSession);
  1.1587 +  fwToken->sessionCount--;
  1.1588 +
  1.1589 +  if( nssCKFWSession_IsRWSession(fwSession) ) {
  1.1590 +    fwToken->rwSessionCount--;
  1.1591 +  }
  1.1592 +
  1.1593 +  if( 0 == fwToken->sessionCount ) {
  1.1594 +    fwToken->rwSessionCount = 0; /* sanity */
  1.1595 +    fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1.1596 +  }
  1.1597 +
  1.1598 +  error = CKR_OK;
  1.1599 +
  1.1600 + done:
  1.1601 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1602 +  return error;
  1.1603 +}
  1.1604 +
  1.1605 +
  1.1606 +/*
  1.1607 + * nssCKFWToken_CloseAllSessions
  1.1608 + *
  1.1609 + */
  1.1610 +NSS_IMPLEMENT CK_RV
  1.1611 +nssCKFWToken_CloseAllSessions
  1.1612 +(
  1.1613 +  NSSCKFWToken *fwToken
  1.1614 +)
  1.1615 +{
  1.1616 +  CK_RV error = CKR_OK;
  1.1617 +
  1.1618 +#ifdef NSSDEBUG
  1.1619 +  error = nssCKFWToken_verifyPointer(fwToken);
  1.1620 +  if( CKR_OK != error ) {
  1.1621 +    return error;
  1.1622 +  }
  1.1623 +#endif /* NSSDEBUG */
  1.1624 +
  1.1625 +  error = nssCKFWMutex_Lock(fwToken->mutex);
  1.1626 +  if( CKR_OK != error ) {
  1.1627 +    return error;
  1.1628 +  }
  1.1629 +
  1.1630 +  nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
  1.1631 +
  1.1632 +  nssCKFWHash_Destroy(fwToken->sessions);
  1.1633 +
  1.1634 +  fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
  1.1635 +  if (!fwToken->sessions) {
  1.1636 +    if( CKR_OK == error ) {
  1.1637 +      error = CKR_GENERAL_ERROR;
  1.1638 +    }
  1.1639 +    goto done;
  1.1640 +  }
  1.1641 +
  1.1642 +  fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1.1643 +  fwToken->sessionCount = 0;
  1.1644 +  fwToken->rwSessionCount = 0;
  1.1645 +
  1.1646 +  error = CKR_OK;
  1.1647 +
  1.1648 + done:
  1.1649 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1650 +  return error;
  1.1651 +}
  1.1652 +
  1.1653 +/*
  1.1654 + * nssCKFWToken_GetSessionCount
  1.1655 + *
  1.1656 + */
  1.1657 +NSS_IMPLEMENT CK_ULONG
  1.1658 +nssCKFWToken_GetSessionCount
  1.1659 +(
  1.1660 +  NSSCKFWToken *fwToken
  1.1661 +)
  1.1662 +{
  1.1663 +  CK_ULONG rv;
  1.1664 +
  1.1665 +#ifdef NSSDEBUG
  1.1666 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1667 +    return (CK_ULONG)0;
  1.1668 +  }
  1.1669 +#endif /* NSSDEBUG */
  1.1670 +
  1.1671 +  if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1.1672 +    return (CK_ULONG)0;
  1.1673 +  }
  1.1674 +
  1.1675 +  rv = fwToken->sessionCount;
  1.1676 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1677 +  return rv;
  1.1678 +}
  1.1679 +
  1.1680 +/*
  1.1681 + * nssCKFWToken_GetRwSessionCount
  1.1682 + *
  1.1683 + */
  1.1684 +NSS_IMPLEMENT CK_ULONG
  1.1685 +nssCKFWToken_GetRwSessionCount
  1.1686 +(
  1.1687 +  NSSCKFWToken *fwToken
  1.1688 +)
  1.1689 +{
  1.1690 +  CK_ULONG rv;
  1.1691 +
  1.1692 +#ifdef NSSDEBUG
  1.1693 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1694 +    return (CK_ULONG)0;
  1.1695 +  }
  1.1696 +#endif /* NSSDEBUG */
  1.1697 +
  1.1698 +  if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1.1699 +    return (CK_ULONG)0;
  1.1700 +  }
  1.1701 +
  1.1702 +  rv = fwToken->rwSessionCount;
  1.1703 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1704 +  return rv;
  1.1705 +}
  1.1706 +
  1.1707 +/*
  1.1708 + * nssCKFWToken_GetRoSessionCount
  1.1709 + *
  1.1710 + */
  1.1711 +NSS_IMPLEMENT CK_ULONG
  1.1712 +nssCKFWToken_GetRoSessionCount
  1.1713 +(
  1.1714 +  NSSCKFWToken *fwToken
  1.1715 +)
  1.1716 +{
  1.1717 +  CK_ULONG rv;
  1.1718 +
  1.1719 +#ifdef NSSDEBUG
  1.1720 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1721 +    return (CK_ULONG)0;
  1.1722 +  }
  1.1723 +#endif /* NSSDEBUG */
  1.1724 +
  1.1725 +  if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1.1726 +    return (CK_ULONG)0;
  1.1727 +  }
  1.1728 +
  1.1729 +  rv = fwToken->sessionCount - fwToken->rwSessionCount;
  1.1730 +  (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1.1731 +  return rv;
  1.1732 +}
  1.1733 +
  1.1734 +/*
  1.1735 + * nssCKFWToken_GetSessionObjectHash
  1.1736 + *
  1.1737 + */
  1.1738 +NSS_IMPLEMENT nssCKFWHash *
  1.1739 +nssCKFWToken_GetSessionObjectHash
  1.1740 +(
  1.1741 +  NSSCKFWToken *fwToken
  1.1742 +)
  1.1743 +{
  1.1744 +#ifdef NSSDEBUG
  1.1745 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1746 +    return (nssCKFWHash *)NULL;
  1.1747 +  }
  1.1748 +#endif /* NSSDEBUG */
  1.1749 +
  1.1750 +  return fwToken->sessionObjectHash;
  1.1751 +}
  1.1752 +
  1.1753 +/*
  1.1754 + * nssCKFWToken_GetMDObjectHash
  1.1755 + *
  1.1756 + */
  1.1757 +NSS_IMPLEMENT nssCKFWHash *
  1.1758 +nssCKFWToken_GetMDObjectHash
  1.1759 +(
  1.1760 +  NSSCKFWToken *fwToken
  1.1761 +)
  1.1762 +{
  1.1763 +#ifdef NSSDEBUG
  1.1764 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1765 +    return (nssCKFWHash *)NULL;
  1.1766 +  }
  1.1767 +#endif /* NSSDEBUG */
  1.1768 +
  1.1769 +  return fwToken->mdObjectHash;
  1.1770 +}
  1.1771 +
  1.1772 +/*
  1.1773 + * nssCKFWToken_GetObjectHandleHash
  1.1774 + *
  1.1775 + */
  1.1776 +NSS_IMPLEMENT nssCKFWHash *
  1.1777 +nssCKFWToken_GetObjectHandleHash
  1.1778 +(
  1.1779 +  NSSCKFWToken *fwToken
  1.1780 +)
  1.1781 +{
  1.1782 +#ifdef NSSDEBUG
  1.1783 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1784 +    return (nssCKFWHash *)NULL;
  1.1785 +  }
  1.1786 +#endif /* NSSDEBUG */
  1.1787 +
  1.1788 +  return fwToken->mdObjectHash;
  1.1789 +}
  1.1790 +
  1.1791 +/*
  1.1792 + * NSSCKFWToken_GetMDToken
  1.1793 + *
  1.1794 + */
  1.1795 +
  1.1796 +NSS_IMPLEMENT NSSCKMDToken *
  1.1797 +NSSCKFWToken_GetMDToken
  1.1798 +(
  1.1799 +  NSSCKFWToken *fwToken
  1.1800 +)
  1.1801 +{
  1.1802 +#ifdef DEBUG
  1.1803 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1804 +    return (NSSCKMDToken *)NULL;
  1.1805 +  }
  1.1806 +#endif /* DEBUG */
  1.1807 +
  1.1808 +  return nssCKFWToken_GetMDToken(fwToken);
  1.1809 +}
  1.1810 +
  1.1811 +/*
  1.1812 + * NSSCKFWToken_GetArena
  1.1813 + *
  1.1814 + */
  1.1815 +
  1.1816 +NSS_IMPLEMENT NSSArena *
  1.1817 +NSSCKFWToken_GetArena
  1.1818 +(
  1.1819 +  NSSCKFWToken *fwToken,
  1.1820 +  CK_RV *pError
  1.1821 +)
  1.1822 +{
  1.1823 +#ifdef DEBUG
  1.1824 +  if (!pError) {
  1.1825 +    return (NSSArena *)NULL;
  1.1826 +  }
  1.1827 +
  1.1828 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1829 +    *pError = CKR_ARGUMENTS_BAD;
  1.1830 +    return (NSSArena *)NULL;
  1.1831 +  }
  1.1832 +#endif /* DEBUG */
  1.1833 +
  1.1834 +  return nssCKFWToken_GetArena(fwToken, pError);
  1.1835 +}
  1.1836 +
  1.1837 +/*
  1.1838 + * NSSCKFWToken_GetFWSlot
  1.1839 + *
  1.1840 + */
  1.1841 +
  1.1842 +NSS_IMPLEMENT NSSCKFWSlot *
  1.1843 +NSSCKFWToken_GetFWSlot
  1.1844 +(
  1.1845 +  NSSCKFWToken *fwToken
  1.1846 +)
  1.1847 +{
  1.1848 +#ifdef DEBUG
  1.1849 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1850 +    return (NSSCKFWSlot *)NULL;
  1.1851 +  }
  1.1852 +#endif /* DEBUG */
  1.1853 +
  1.1854 +  return nssCKFWToken_GetFWSlot(fwToken);
  1.1855 +}
  1.1856 +
  1.1857 +/*
  1.1858 + * NSSCKFWToken_GetMDSlot
  1.1859 + *
  1.1860 + */
  1.1861 +
  1.1862 +NSS_IMPLEMENT NSSCKMDSlot *
  1.1863 +NSSCKFWToken_GetMDSlot
  1.1864 +(
  1.1865 +  NSSCKFWToken *fwToken
  1.1866 +)
  1.1867 +{
  1.1868 +#ifdef DEBUG
  1.1869 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1870 +    return (NSSCKMDSlot *)NULL;
  1.1871 +  }
  1.1872 +#endif /* DEBUG */
  1.1873 +
  1.1874 +  return nssCKFWToken_GetMDSlot(fwToken);
  1.1875 +}
  1.1876 +
  1.1877 +/*
  1.1878 + * NSSCKFWToken_GetSessionState
  1.1879 + *
  1.1880 + */
  1.1881 +
  1.1882 +NSS_IMPLEMENT CK_STATE
  1.1883 +NSSCKFWSession_GetSessionState
  1.1884 +(
  1.1885 +  NSSCKFWToken *fwToken
  1.1886 +)
  1.1887 +{
  1.1888 +#ifdef DEBUG
  1.1889 +  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1.1890 +    return CKS_RO_PUBLIC_SESSION;
  1.1891 +  }
  1.1892 +#endif /* DEBUG */
  1.1893 +
  1.1894 +  return nssCKFWToken_GetSessionState(fwToken);
  1.1895 +}

mercurial