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 + -
显示快捷键?