session.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,963 行 · 第 1/3 页

C
1,963
字号
    return CKR_GENERAL_ERROR;  }#endif /* NSSDEBUG */  if( (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) {    nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject);  }  return CKR_OK;}/* * nssCKFWSession_GetDeviceError * */NSS_IMPLEMENT CK_ULONGnssCKFWSession_GetDeviceError(  NSSCKFWSession *fwSession){#ifdef NSSDEBUG  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {    return (CK_ULONG)0;  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    return (CK_ULONG)0;  }#endif /* NSSDEBUG */  if( (void *)NULL == (void *)fwSession->mdSession->GetDeviceError ) {    return (CK_ULONG)0;  }  return fwSession->mdSession->GetDeviceError(fwSession->mdSession,     fwSession, fwSession->mdToken, fwSession->fwToken,     fwSession->mdInstance, fwSession->fwInstance);}/* * nssCKFWSession_Login * */NSS_IMPLEMENT CK_RVnssCKFWSession_Login(  NSSCKFWSession *fwSession,  CK_USER_TYPE userType,  NSSItem *pin){  CK_RV error = CKR_OK;  CK_STATE oldState;  CK_STATE newState;#ifdef NSSDEBUG  error = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != error ) {    return error;  }  switch( userType ) {  case CKU_SO:  case CKU_USER:    break;  default:    return CKR_USER_TYPE_INVALID;  }  if( (NSSItem *)NULL == pin ) {    if( CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken) ) {      return CKR_ARGUMENTS_BAD;    }  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    return CKR_GENERAL_ERROR;  }#endif /* NSSDEBUG */  oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);  /*   * It's not clear what happens when you're already logged in.   * I'll just fail; but if we decide to change, the logic is   * all right here.   */  if( CKU_SO == userType ) {    switch( oldState ) {    case CKS_RO_PUBLIC_SESSION:            /*       * There's no such thing as a read-only security officer       * session, so fail.  The error should be CKR_SESSION_READ_ONLY,       * except that C_Login isn't defined to return that.  So we'll       * do CKR_SESSION_READ_ONLY_EXISTS, which is what is documented.       */      return CKR_SESSION_READ_ONLY_EXISTS;    case CKS_RO_USER_FUNCTIONS:      return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;    case CKS_RW_PUBLIC_SESSION:      newState = CKS_RW_SO_FUNCTIONS;      break;    case CKS_RW_USER_FUNCTIONS:      return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;    case CKS_RW_SO_FUNCTIONS:      return CKR_USER_ALREADY_LOGGED_IN;    default:      return CKR_GENERAL_ERROR;    }  } else /* CKU_USER == userType */ {    switch( oldState ) {    case CKS_RO_PUBLIC_SESSION:            newState = CKS_RO_USER_FUNCTIONS;      break;    case CKS_RO_USER_FUNCTIONS:      return CKR_USER_ALREADY_LOGGED_IN;    case CKS_RW_PUBLIC_SESSION:      newState = CKS_RW_USER_FUNCTIONS;      break;    case CKS_RW_USER_FUNCTIONS:      return CKR_USER_ALREADY_LOGGED_IN;    case CKS_RW_SO_FUNCTIONS:      return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;    default:      return CKR_GENERAL_ERROR;    }  }  /*   * So now we're in one of three cases:   *   * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_SO_FUNCTIONS;   * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_USER_FUNCTIONS;   * Old == CKS_RO_PUBLIC_SESSION, New == CKS_RO_USER_FUNCTIONS;   */  if( (void *)NULL == (void *)fwSession->mdSession->Login ) {    /*     * The Module doesn't want to be informed (or check the pin)     * it'll just rely on the Framework as needed.     */    ;  } else {    error = fwSession->mdSession->Login(fwSession->mdSession, fwSession,      fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,      fwSession->fwInstance, userType, pin, oldState, newState);    if( CKR_OK != error ) {      return error;    }  }  (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);  return CKR_OK;}/* * nssCKFWSession_Logout * */NSS_IMPLEMENT CK_RVnssCKFWSession_Logout(  NSSCKFWSession *fwSession){  CK_RV error = CKR_OK;  CK_STATE oldState;  CK_STATE newState;#ifdef NSSDEBUG  error = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != error ) {    return error;  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    return CKR_GENERAL_ERROR;  }#endif /* NSSDEBUG */  oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);  switch( oldState ) {  case CKS_RO_PUBLIC_SESSION:    return CKR_USER_NOT_LOGGED_IN;  case CKS_RO_USER_FUNCTIONS:    newState = CKS_RO_PUBLIC_SESSION;    break;  case CKS_RW_PUBLIC_SESSION:    return CKR_USER_NOT_LOGGED_IN;  case CKS_RW_USER_FUNCTIONS:    newState = CKS_RW_PUBLIC_SESSION;    break;  case CKS_RW_SO_FUNCTIONS:    newState = CKS_RW_PUBLIC_SESSION;    break;  default:    return CKR_GENERAL_ERROR;  }  /*   * So now we're in one of three cases:   *   * Old == CKS_RW_SO_FUNCTIONS,   New == CKS_RW_PUBLIC_SESSION;   * Old == CKS_RW_USER_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;   * Old == CKS_RO_USER_FUNCTIONS, New == CKS_RO_PUBLIC_SESSION;   */  if( (void *)NULL == (void *)fwSession->mdSession->Logout ) {    /*     * The Module doesn't want to be informed.  Okay.     */    ;  } else {    error = fwSession->mdSession->Logout(fwSession->mdSession, fwSession,      fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,      fwSession->fwInstance, oldState, newState);    if( CKR_OK != error ) {      /*       * Now what?!  A failure really should end up with the Framework       * considering it logged out, right?       */      ;    }  }  (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);  return error;}/* * nssCKFWSession_InitPIN * */NSS_IMPLEMENT CK_RVnssCKFWSession_InitPIN(  NSSCKFWSession *fwSession,  NSSItem *pin){  CK_RV error = CKR_OK;  CK_STATE state;#ifdef NSSDEBUG  error = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != error ) {    return error;  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    return CKR_GENERAL_ERROR;  }#endif /* NSSDEBUG */  state = nssCKFWToken_GetSessionState(fwSession->fwToken);  if( CKS_RW_SO_FUNCTIONS != state ) {    return CKR_USER_NOT_LOGGED_IN;  }  if( (NSSItem *)NULL == pin ) {    CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);    if( CK_TRUE != has ) {      return CKR_ARGUMENTS_BAD;    }  }  if( (void *)NULL == (void *)fwSession->mdSession->InitPIN ) {    return CKR_TOKEN_WRITE_PROTECTED;  }  error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession,    fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,    fwSession->fwInstance, pin);  return error;}/* * nssCKFWSession_SetPIN * */NSS_IMPLEMENT CK_RVnssCKFWSession_SetPIN(  NSSCKFWSession *fwSession,  NSSItem *newPin,  NSSItem *oldPin){  CK_RV error = CKR_OK;  CK_STATE state;#ifdef NSSDEBUG  error = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != error ) {    return error;  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    return CKR_GENERAL_ERROR;  }#endif /* NSSDEBUG */  state = nssCKFWToken_GetSessionState(fwSession->fwToken);  if( (CKS_RW_SO_FUNCTIONS != state) &&      (CKS_RW_USER_FUNCTIONS != state) ) {    return CKR_USER_NOT_LOGGED_IN;  }  if( (NSSItem *)NULL == newPin ) {    CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);    if( CK_TRUE != has ) {      return CKR_ARGUMENTS_BAD;    }  }  if( (NSSItem *)NULL == oldPin ) {    CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);    if( CK_TRUE != has ) {      return CKR_ARGUMENTS_BAD;    }  }  if( (void *)NULL == (void *)fwSession->mdSession->SetPIN ) {    return CKR_TOKEN_WRITE_PROTECTED;  }  error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession,    fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,    fwSession->fwInstance, newPin, oldPin);  return error;}/* * nssCKFWSession_GetOperationStateLen * */NSS_IMPLEMENT CK_ULONGnssCKFWSession_GetOperationStateLen(  NSSCKFWSession *fwSession,  CK_RV *pError){  CK_ULONG mdAmt;  CK_ULONG fwAmt;#ifdef NSSDEBUG  if( (CK_RV *)NULL == pError ) {    return (CK_ULONG)0;  }  *pError = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != *pError ) {    return (CK_ULONG)0;  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    *pError = CKR_GENERAL_ERROR;    return (CK_ULONG)0;  }#endif /* NSSDEBUG */  if( (void *)NULL == (void *)fwSession->mdSession->GetOperationStateLen ) {    *pError = CKR_STATE_UNSAVEABLE;  }  /*   * We could check that the session is actually in some state..   */  mdAmt = fwSession->mdSession->GetOperationStateLen(fwSession->mdSession,    fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,    fwSession->fwInstance, pError);  if( ((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError) ) {    return (CK_ULONG)0;  }  /*   * Add a bit of sanity-checking   */  fwAmt = mdAmt + 2*sizeof(CK_ULONG);  return fwAmt;}/* * nssCKFWSession_GetOperationState * */NSS_IMPLEMENT CK_RVnssCKFWSession_GetOperationState(  NSSCKFWSession *fwSession,  NSSItem *buffer){  CK_RV error = CKR_OK;  CK_ULONG fwAmt;  CK_ULONG *ulBuffer;  NSSItem i2;  CK_ULONG n, i;#ifdef NSSDEBUG  error = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != error ) {    return error;  }  if( (NSSItem *)NULL == buffer ) {    return CKR_ARGUMENTS_BAD;  }  if( (void *)NULL == buffer->data ) {    return CKR_ARGUMENTS_BAD;  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    return CKR_GENERAL_ERROR;  }#endif /* NSSDEBUG */  if( (void *)NULL == (void *)fwSession->mdSession->GetOperationState ) {    return CKR_STATE_UNSAVEABLE;  }  /*   * Sanity-check the caller's buffer.   */  error = CKR_OK;  fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error);  if( ((CK_ULONG)0 == fwAmt) && (CKR_OK != error) ) {    return error;  }  if( buffer->size < fwAmt ) {    return CKR_BUFFER_TOO_SMALL;  }  ulBuffer = (CK_ULONG *)buffer->data;  i2.size = buffer->size - 2*sizeof(CK_ULONG);  i2.data = (void *)&ulBuffer[2];  error = fwSession->mdSession->GetOperationState(fwSession->mdSession,    fwSession, fwSession->mdToken, fwSession->fwToken,     fwSession->mdInstance, fwSession->fwInstance, &i2);  if( CKR_OK != error ) {    return error;  }  /*   * Add a little integrety/identity check.     * NOTE: right now, it's pretty stupid.     * A CRC or something would be better.   */  ulBuffer[0] = 0x434b4657; /* CKFW */  ulBuffer[1] = 0;  n = i2.size/sizeof(CK_ULONG);  for( i = 0; i < n; i++ ) {    ulBuffer[1] ^= ulBuffer[2+i];  }  return CKR_OK;}/* * nssCKFWSession_SetOperationState * */NSS_IMPLEMENT CK_RVnssCKFWSession_SetOperationState(  NSSCKFWSession *fwSession,  NSSItem *state,  NSSCKFWObject *encryptionKey,  NSSCKFWObject *authenticationKey){  CK_RV error = CKR_OK;  CK_ULONG *ulBuffer;  CK_ULONG n, i;  CK_ULONG x;  NSSItem s;  NSSCKMDObject *mdek;  NSSCKMDObject *mdak;#ifdef NSSDEBUG  error = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != error ) {    return error;  }  if( (NSSItem *)NULL == state ) {    return CKR_ARGUMENTS_BAD;  }  if( (void *)NULL == state->data ) {    return CKR_ARGUMENTS_BAD;  }  if( (NSSCKFWObject *)NULL != encryptionKey ) {    error = nssCKFWObject_verifyPointer(encryptionKey);    if( CKR_OK != error ) {      return error;    }  }  if( (NSSCKFWObject *)NULL != authenticationKey ) {    error = nssCKFWObject_verifyPointer(authenticationKey);    if( CKR_OK != error ) {      return error;    }  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    return CKR_GENERAL_ERROR;  }#endif /* NSSDEBUG */  ulBuffer = (CK_ULONG *)state->data;  if( 0x43b4657 != ulBuffer[0] ) {    return CKR_SAVED_STATE_INVALID;  }  n = (state->size / sizeof(CK_ULONG)) - 2;  x = (CK_ULONG)0;  for( i = 0; i < n; i++ ) {    x ^= ulBuffer[2+i];  }  if( x != ulBuffer[1] ) {    return CKR_SAVED_STATE_INVALID;  }  if( (void *)NULL == (void *)fwSession->mdSession->SetOperationState ) {    return CKR_GENERAL_ERROR;  }  s.size = state->size - 2*sizeof(CK_ULONG);  s.data = (void *)&ulBuffer[2];  if( (NSSCKFWObject *)NULL != encryptionKey ) {    mdek = nssCKFWObject_GetMDObject(encryptionKey);  } else {    mdek = (NSSCKMDObject *)NULL;  }  if( (NSSCKFWObject *)NULL != authenticationKey ) {    mdak = nssCKFWObject_GetMDObject(authenticationKey);  } else {    mdak = (NSSCKMDObject *)NULL;  }  error = fwSession->mdSession->SetOperationState(fwSession->mdSession,     fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,    fwSession->fwInstance, &s, mdek, encryptionKey, mdak, authenticationKey);  if( CKR_OK != error ) {    return error;  }  /*   * Here'd we restore any session data   */    return CKR_OK;}static CK_BBOOLnss_attributes_form_token_object(  CK_ATTRIBUTE_PTR pTemplate,  CK_ULONG ulAttributeCount){  CK_ULONG i;  CK_BBOOL rv;  for( i = 0; i < ulAttributeCount; i++ ) {    if( CKA_TOKEN == pTemplate[i].type ) {      /* If we sanity-check, we can remove this sizeof check */      if( sizeof(CK_BBOOL) == pTemplate[i].ulValueLen ) {        (void)nsslibc_memcpy(&rv, pTemplate[i].pValue, sizeof(CK_BBOOL));        return rv;      } else {        return CK_FALSE;      }    }  }  return CK_FALSE;}/* * nssCKFWSession_CreateObject * */NSS_IMPLEMENT NSSCKFWObject *nssCKFWSession_CreateObject(  NSSCKFWSession *fwSession,  CK_ATTRIBUTE_PTR pTemplate,  CK_ULONG ulAttributeCount,  CK_RV *pError){  NSSArena *arena;  NSSCKMDObject *mdObject;  NSSCKFWObject *fwObject;  CK_BBOOL isTokenObject;#ifdef NSSDEBUG  if( (CK_RV *)NULL == pError ) {    return (NSSCKFWObject *)NULL;  }  *pError = nssCKFWSession_verifyPointer(fwSession);  if( CKR_OK != pError ) {    return (NSSCKFWObject *)NULL;  }  if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {    *pError = CKR_ARGUMENTS_BAD;    return (NSSCKFWObject *)NULL;  }  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {    *pError = CKR_GENERAL_ERROR;    return (NSSCKFWObject *)NULL;  }#endif /* NSSDEBUG */  /*   * Here would be an excellent place to sanity-check the object.   */  isTokenObject = nss_attributes_form_token_object(pTemplate, ulAttributeCount);  if( CK_TRUE == isTokenObject ) {    /* === TOKEN OBJECT === */    if( (void *)NULL == (void *)fwSession->mdSession->CreateObject ) {      *pError = CKR_TOKEN_WRITE_PROTECTED;      return (NSSCKFWObject *)NULL;    }    arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);    if( (NSSArena *)NULL == arena ) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?