// Call lower level SRP code to generate a verifier with the // given pointers. Contains the preparations, call parameters // and error checking common to all srp verifier generation code. // See docs of srp_create_salted_verification_key for more info. static inline void gen_srp_v(const std::string &name, const std::string &password, char **salt, size_t *salt_len, char **bytes_v, size_t *len_v) { std::string n_name = lowercase(name); SRP_Result res = srp_create_salted_verification_key(SRP_SHA256, SRP_NG_2048, n_name.c_str(), (const unsigned char *)password.c_str(), password.size(), (unsigned char **)salt, salt_len, (unsigned char **)bytes_v, len_v, NULL, NULL); FATAL_ERROR_IF(res != SRP_OK, "Couldn't create salted SRP verifier"); }
//***************************************************************************** // bool SERVER_ProcessSRPClientCommand( LONG lCommand, BYTESTREAM_s *pByteStream ) { switch ( lCommand ) { case CLC_SRP_USER_REQUEST_LOGIN: { CLIENT_s *pClient = SERVER_GetClient(SERVER_GetCurrentClient()); pClient->username = NETWORK_ReadString( pByteStream ); pClient->clientSessionID = M_Random.GenRand32(); #if EMULATE_AUTH_SERVER SERVERCOMMANDS_SRPUserStartAuthentication ( SERVER_GetCurrentClient() ); #else // [BB] The client wants to log in, so start negotiating with the auth server. SERVER_AUTH_Negotiate ( pClient->username.GetChars(), pClient->clientSessionID ); #endif } break; case CLC_SRP_USER_START_AUTHENTICATION: { CLIENT_s *pClient = SERVER_GetClient(SERVER_GetCurrentClient()); const int lenA = NETWORK_ReadShort( pByteStream ); if ( lenA > 0 ) { pClient->bytesA.Resize ( lenA ); for ( int i = 0; i < lenA; ++i ) pClient->bytesA[i] = NETWORK_ReadByte( pByteStream ); } else Printf ( "CLC_SRP_USER_START_AUTHENTICATION: Invalid length\n" ); #if EMULATE_AUTH_SERVER const unsigned char * bytesS = NULL; const unsigned char * bytesV = NULL; int lenS = 0; int lenV = 0; const char *password = "******"; srp_create_salted_verification_key( SRP_SHA256, SRP_NG_2048, pClient->username.GetChars(), reinterpret_cast<const unsigned char *>(password), strlen(password), &bytesS, &lenS, &bytesV, &lenV, NULL, NULL ); pClient->salt.Resize ( lenS ); for ( int i = 0; i < lenS; ++i ) pClient->salt[i] = bytesS[i]; const unsigned char * bytesB = NULL; int lenB = 0; if ( g_ver != NULL ) srp_verifier_delete( g_ver ); g_ver = srp_verifier_new( SRP_SHA256, SRP_NG_2048, pClient->username.GetChars(), bytesS, lenS, bytesV, lenV, &(pClient->bytesA[0]), lenA, &bytesB, &lenB, NULL, NULL, 1 ); if ( ( bytesB == NULL ) || ( lenB == 0 ) ) { Printf ( "Verifier SRP-6a safety check violated!\n" ); pClient->bytesB.Clear(); } else { Printf ( "Verifier SRP-6a safety check passed.\n" ); pClient->bytesB.Resize ( lenB ); for ( int i = 0; i < lenB; ++i ) pClient->bytesB[i] = bytesB[i]; SERVERCOMMANDS_SRPUserProcessChallenge ( SERVER_GetCurrentClient() ); } free( (char *)bytesS ); free( (char *)bytesV ); #else SERVER_AUTH_SRPMessage ( SERVER_AUTH_SRP_STEP_ONE, pClient->SRPsessionID, pClient->bytesA ); #endif return ( false ); } break; case CLC_SRP_USER_PROCESS_CHALLENGE: { CLIENT_s *pClient = SERVER_GetClient(SERVER_GetCurrentClient()); const int lenM = NETWORK_ReadShort( pByteStream ); if ( lenM > 0 ) { pClient->bytesM.Resize ( lenM ); for ( int i = 0; i < lenM; ++i ) pClient->bytesM[i] = NETWORK_ReadByte( pByteStream ); } else Printf ( "CLC_SRP_USER_PROCESS_CHALLENGE: Invalid length\n" ); #if EMULATE_AUTH_SERVER unsigned char bytesM[SHA512_DIGEST_LENGTH]; for ( int i = 0; i < lenM; ++i ) bytesM[i] = pClient->bytesM[i]; if ( g_ver == NULL ) Printf ( "Error: Verifier pointer is NULL.\n" ); else { const unsigned char * bytesHAMK = NULL; srp_verifier_verify_session( g_ver, bytesM, &bytesHAMK ); if ( bytesHAMK == NULL ) { SERVER_InitClientSRPData ( SERVER_GetCurrentClient() ); Printf ( "User authentication failed!\n" ); SERVER_PrintfPlayer( PRINT_HIGH, SERVER_GetCurrentClient(), "User authentication failed!\n" ); } else { Printf ( "User authentication successfully.\n" ); // [BB] The user has logged in in successfully. SERVER_GetClient(SERVER_GetCurrentClient())->loggedIn = true; pClient->bytesHAMK.Resize ( srp_verifier_get_session_key_length( g_ver ) ); for ( unsigned int i = 0; i < pClient->bytesHAMK.Size(); ++i ) pClient->bytesHAMK[i] = bytesHAMK[i]; SERVERCOMMANDS_SRPUserVerifySession ( SERVER_GetCurrentClient() ); } } #else if ( pClient->SRPsessionID != -1 ) SERVER_AUTH_SRPMessage ( SERVER_AUTH_SRP_STEP_THREE, pClient->SRPsessionID, pClient->bytesM ); #endif return ( false ); } break; default: Printf ( "Error: Received unknown SRP command '%d' from client %d.\n", static_cast<int>(lCommand), static_cast<int>(SERVER_GetCurrentClient()) ); break; } return ( false ); }