Literally, unironically, draw the rest of the owl

This commit is contained in:
AJ Martinez 2023-03-18 05:18:04 -07:00 committed by James R
parent 9b77d95357
commit 138663bf5a
6 changed files with 47 additions and 27 deletions

View file

@ -47,6 +47,7 @@
#include "lua_hook.h" #include "lua_hook.h"
#include "md5.h" #include "md5.h"
#include "m_perfstats.h" #include "m_perfstats.h"
#include "monocypher/monocypher.h"
// SRB2Kart // SRB2Kart
#include "k_kart.h" #include "k_kart.h"
@ -156,13 +157,13 @@ char connectedservername[MAXSERVERNAME];
/// \todo WORK! /// \todo WORK!
boolean acceptnewnode = true; boolean acceptnewnode = true;
char lastReceivedKey[MAXNETNODES][32]; uint8_t lastReceivedKey[MAXNETNODES][32];
char lastComputedChallenge[MAXNETNODES][32]; uint8_t lastSentChallenge[MAXNETNODES][32];
boolean serverisfull = false; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not boolean serverisfull = false; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not
tic_t firstconnectattempttime = 0; tic_t firstconnectattempttime = 0;
char awaitingChallenge[32]; uint8_t awaitingChallenge[32];
// engine // engine
@ -833,7 +834,16 @@ static boolean CL_SendJoin(void)
memcpy(&netbuffer->u.clientcfg.availabilities, R_GetSkinAvailabilities(false, false), MAXAVAILABILITY*sizeof(UINT8)); memcpy(&netbuffer->u.clientcfg.availabilities, R_GetSkinAvailabilities(false, false), MAXAVAILABILITY*sizeof(UINT8));
memcpy(&netbuffer->u.clientcfg.challengeResponse, awaitingChallenge, 32); uint8_t signature[64];
crypto_eddsa_sign(signature, secret_key, awaitingChallenge, 32);
if (crypto_eddsa_check(signature, public_key, awaitingChallenge, 32) != 0)
I_Error("Couldn't verify own key?");
// Testing
// memset(signature, 0, sizeof(signature));
memcpy(&netbuffer->u.clientcfg.challengeResponse, signature, sizeof(signature));
return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak)); return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak));
} }
@ -4059,6 +4069,11 @@ static void HandleConnect(SINT8 node)
if (playernode[i] != UINT8_MAX) // We use this to count players because it is affected by SV_AddWaitingPlayers when more than one client joins on the same tic, unlike playeringame and D_NumPlayers. UINT8_MAX denotes no node for that player if (playernode[i] != UINT8_MAX) // We use this to count players because it is affected by SV_AddWaitingPlayers when more than one client joins on the same tic, unlike playeringame and D_NumPlayers. UINT8_MAX denotes no node for that player
connectedplayers++; connectedplayers++;
// Testing
// memset(netbuffer->u.clientcfg.challengeResponse, 0, sizeof(netbuffer->u.clientcfg.challengeResponse));
int sigcheck = crypto_eddsa_check(netbuffer->u.clientcfg.challengeResponse, lastReceivedKey[node], lastSentChallenge[node], 32);
if (bannednode && bannednode[node].banid != SIZE_MAX) if (bannednode && bannednode[node].banid != SIZE_MAX)
{ {
const char *reason = NULL; const char *reason = NULL;
@ -4140,9 +4155,9 @@ static void HandleConnect(SINT8 node)
SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."), SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."),
(joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE)); (joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE));
} }
else if (netgame && node != 0 && !memcmp(netbuffer->u.clientcfg.challengeResponse, lastComputedChallenge[node], 32)) else if (netgame && node != 0 && sigcheck != 0)
{ {
SV_SendRefuse(node, M_GetText("Failed to validate key exchange.")); SV_SendRefuse(node, M_GetText("Signature verification failed."));
} }
else else
{ {
@ -4536,7 +4551,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
PT_ClientKey(node); PT_ClientKey(node);
break; break;
case PT_SERVERCHALLENGE: case PT_SERVERCHALLENGE:
memset(awaitingChallenge, 0, 32); // TODO: ACTUALLY COMPUTE CHALLENGE RESPONSE IDIOT memcpy(awaitingChallenge, netbuffer->u.serverchallenge.secret, sizeof(awaitingChallenge));
cl_mode = CL_ASKJOIN; cl_mode = CL_ASKJOIN;
break; break;
default: default:

View file

@ -256,7 +256,7 @@ struct clientconfig_pak
UINT8 mode; UINT8 mode;
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
UINT8 availabilities[MAXAVAILABILITY]; UINT8 availabilities[MAXAVAILABILITY];
char challengeResponse[32]; uint8_t challengeResponse[64];
} ATTRPACK; } ATTRPACK;
#define SV_SPEEDMASK 0x03 // used to send kartspeed #define SV_SPEEDMASK 0x03 // used to send kartspeed
@ -460,8 +460,8 @@ extern UINT16 software_MAXPACKETLENGTH;
extern boolean acceptnewnode; extern boolean acceptnewnode;
extern SINT8 servernode; extern SINT8 servernode;
extern char connectedservername[MAXSERVERNAME]; extern char connectedservername[MAXSERVERNAME];
extern char lastReceivedKey[MAXNETNODES][32]; extern uint8_t lastReceivedKey[MAXNETNODES][32];
extern char lastComputedChallenge[MAXNETNODES][32]; extern uint8_t lastSentChallenge[MAXNETNODES][32];
void Command_Ping_f(void); void Command_Ping_f(void);
extern tic_t connectiontimeout; extern tic_t connectiontimeout;

View file

@ -161,7 +161,7 @@ boolean dedicated = false;
// For identity negotiation with netgame servers // For identity negotiation with netgame servers
uint8_t public_key[32]; uint8_t public_key[32];
uint8_t secret_key[32]; uint8_t secret_key[64];
// //
// D_PostEvent // D_PostEvent
@ -1715,32 +1715,36 @@ void D_SRB2Main(void)
ACS_Init(); ACS_Init();
CON_SetLoadingProgress(LOADED_ACSINIT); CON_SetLoadingProgress(LOADED_ACSINIT);
// -- IT'S HOMEGROWN CRYPTO TIME --
// TODO: This file should probably give a fuck about command line params, // TODO: This file should probably give a fuck about command line params,
// or not be stored next to the EXE in a way that allows people to unknowingly send it to others. // or not be stored next to the EXE in a way that allows people to unknowingly send it to others.
static char keyfile[16] = "rrid.dat"; static char keyfile[16] = "rrid.dat";
csprng(secret_key, 32); static uint8_t seed[32];
csprng(seed, 32);
crypto_eddsa_key_pair(secret_key, public_key, seed);
int sk_size = sizeof(secret_key);
int pk_size = sizeof(public_key);
int totalsize = sk_size + pk_size;
if (FIL_ReadFileOK(keyfile)) if (FIL_ReadFileOK(keyfile))
{ {
UINT8 *readbuffer = NULL; UINT8 *readbuffer = NULL;
UINT16 lengthRead = FIL_ReadFile(keyfile, &readbuffer); UINT16 lengthRead = FIL_ReadFile(keyfile, &readbuffer);
if (readbuffer == NULL || lengthRead != 32) if (readbuffer == NULL || lengthRead != totalsize)
I_Error("Malformed keyfile"); I_Error("Malformed keyfile");
memcpy(secret_key, readbuffer, 32); memcpy(secret_key, readbuffer, sk_size);
memcpy(public_key, readbuffer + sk_size, pk_size);
} }
else else
{ {
if (!FIL_WriteFile(keyfile, secret_key, 32)) uint8_t keybuffer[totalsize];
memcpy(keybuffer, secret_key, sk_size);
memcpy(keybuffer + sk_size, public_key, pk_size);
if (!FIL_WriteFile(keyfile, keybuffer, totalsize))
I_Error("Couldn't open keyfile"); I_Error("Couldn't open keyfile");
} }
crypto_x25519_public_key(public_key, secret_key);
// -- END HOMEGROWN CRYPTO TIME --
//------------------------------------------------ COMMAND LINE PARAMS //------------------------------------------------ COMMAND LINE PARAMS
// this must be done after loading gamedata, // this must be done after loading gamedata,

View file

@ -32,7 +32,7 @@ extern char srb2path[256]; //Alam: SRB2's Home
extern char addonsdir[MAX_WADPATH]; // Where addons are stored extern char addonsdir[MAX_WADPATH]; // Where addons are stored
extern uint8_t public_key[32]; extern uint8_t public_key[32];
extern uint8_t secret_key[32]; extern uint8_t secret_key[64];
// the infinite loop of D_SRB2Loop() called from win_main for windows version // the infinite loop of D_SRB2Loop() called from win_main for windows version
void D_SRB2Loop(void) FUNCNORETURN; void D_SRB2Loop(void) FUNCNORETURN;

View file

@ -1320,14 +1320,15 @@ void PT_ClientKey(INT32 node)
// TODO // TODO
// Stage 1: Exchange packets with no verification of their contents // Stage 1: Exchange packets with no verification of their contents
// Stage 2: Exchange packets with a check, but no crypto (YOU ARE HERE) // Stage 2: Exchange packets with a check, but no crypto
// Stage 3: The crypto part // Stage 3: The crypto part (YOU ARE HERE)
memcpy(lastReceivedKey[node], packet->key, 32); memcpy(lastReceivedKey[node], packet->key, 32);
netbuffer->packettype = PT_SERVERCHALLENGE; netbuffer->packettype = PT_SERVERCHALLENGE;
csprng(lastComputedChallenge[node], sizeof(serverchallenge_pak));
memcpy(&netbuffer->u.serverchallenge, lastComputedChallenge[node], sizeof(serverchallenge_pak)); csprng(lastSentChallenge[node], sizeof(serverchallenge_pak));
memcpy(&netbuffer->u.serverchallenge, lastSentChallenge[node], sizeof(serverchallenge_pak));
HSendPacket(node, false, 0, sizeof (serverchallenge_pak)); HSendPacket(node, false, 0, sizeof (serverchallenge_pak));
} }

View file

@ -713,7 +713,7 @@ struct player_t
mobj_t *stumbleIndicator; mobj_t *stumbleIndicator;
mobj_t *sliptideZipIndicator; mobj_t *sliptideZipIndicator;
char public_key[32]; uint8_t public_key[32];
#ifdef HWRENDER #ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering fixed_t fovadd; // adjust FOV for hw rendering