-// TODO key loading, generating, saving
#include "quakedef.h"
#include "crypto.h"
#include "common.h"
return crypto;
}
-qboolean Crypto_ServerFinishInstance(crypto_t *out, crypto_t *crypto)
+qboolean Crypto_FinishInstance(crypto_t *out, crypto_t *crypto)
{
// no check needed here (returned pointers are only used in prefilled fields)
if(!crypto || !crypto->authenticated)
if(idend - idstart == FP64_SIZE && keyend - keystart == FP64_SIZE)
{
- for(keyid = 0; keyid < MAX_PUBKEYS; ++keyid)
+ for(keyid = MAX_PUBKEYS - 1; keyid >= 0; --keyid)
if(pubkeys[keyid])
if(!memcmp(pubkeys_fp64[keyid], keystart, FP64_SIZE))
{
idfp[FP64_SIZE] = 0;
break;
}
- if(keyid >= MAX_PUBKEYS)
- keyid = -1;
+ // If this failed, keyid will be -1.
}
}
p = GetUntilNul(&data_in, &len_in);
if(p && *p)
{
+ // Find the highest numbered matching key for p.
for(i = 0; i < MAX_PUBKEYS; ++i)
{
if(pubkeys[i])
if(!strcmp(p, pubkeys_fp64[i]))
if(pubkeys_havepriv[i])
- if(serverid < 0)
- serverid = i;
+ serverid = i;
}
if(serverid < 0)
return Crypto_ServerError(data_out, len_out, "Invalid server key", NULL);
p = GetUntilNul(&data_in, &len_in);
if(p && *p)
{
+ // Find the highest numbered matching key for p.
for(i = 0; i < MAX_PUBKEYS; ++i)
{
if(pubkeys[i])
if(!strcmp(p, pubkeys_fp64[i]))
- if(clientid < 0)
- clientid = i;
+ clientid = i;
}
if(clientid < 0)
return Crypto_ServerError(data_out, len_out, "Invalid client key", NULL);
break;
continue;
}
+ // Find the highest numbered matching key for p.
for(i = 0; i < MAX_PUBKEYS; ++i)
{
if(pubkeys[i])
if(!strcmp(p, pubkeys_fp64[i]))
{
if(pubkeys_havepriv[i])
- if(clientid < 0)
- clientid = i;
+ clientid = i;
if(server_can_auth)
- if(serverid < 0)
- if(wantserverid < 0 || i == wantserverid)
- serverid = i;
+ if(wantserverid < 0 || i == wantserverid)
+ serverid = i;
}
}
- if(clientid >= 0 && serverid >= 0)
- break;
+ // Not breaking, as higher keys in the list always have priority.
}
// if stored host key is not found:
if(serverid >= 0 || clientid >= 0)
{
- // TODO at this point, fill clientside crypto struct!
MAKE_CDATA;
CDATA->cdata_id = ++cdata_id;
CDATA->s = serverid;
qboolean Crypto_ServerAppendToChallenge(const char *data_in, size_t len_in, char *data_out, size_t *len_out, size_t maxlen);
crypto_t *Crypto_ServerGetInstance(lhnetaddress_t *peeraddress);
-qboolean Crypto_ServerFinishInstance(crypto_t *out, crypto_t *in); // also clears allocated memory
+qboolean Crypto_FinishInstance(crypto_t *out, crypto_t *in); // also clears allocated memory, and frees the instance received by ServerGetInstance
const char *Crypto_GetInfoResponseDataString(void);
// retrieves a host key for an address (can be exposed to menuqc, or used by the engine to look up stored keys e.g. for server bookmarking)
}
// allocate a net connection to keep track of things
cls.netcon = NetConn_Open(mysocket, peeraddress);
- crypto = &cls.crypto;
- if(crypto && crypto->authenticated)
+ crypto = &cls.netcon->crypto;
+ if(cls.crypto.authenticated)
{
- Crypto_ServerFinishInstance(&cls.netcon->crypto, crypto);
+ Crypto_FinishInstance(crypto, &cls.crypto);
Con_Printf("%s connection to %s has been established: server is %s@%.*s, I am %.*s@%.*s\n",
crypto->use_aes ? "Encrypted" : "Authenticated",
cls.netcon->address,
Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", addressstring2);
NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
if(crypto && crypto->authenticated)
- Crypto_ServerFinishInstance(&client->netconnection->crypto, crypto);
+ Crypto_FinishInstance(&client->netconnection->crypto, crypto);
SV_SendServerinfo(client);
}
else
if (developer_extra.integer)
Con_Printf("Datagram_ParseConnectionless: sending duplicate accept to %s.\n", addressstring2);
if(crypto && crypto->authenticated)
- Crypto_ServerFinishInstance(&client->netconnection->crypto, crypto);
+ Crypto_FinishInstance(&client->netconnection->crypto, crypto);
NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
}
return true;
NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
// now set up the client
if(crypto && crypto->authenticated)
- Crypto_ServerFinishInstance(&conn->crypto, crypto);
+ Crypto_FinishInstance(&conn->crypto, crypto);
SV_ConnectClient(clientnum, conn);
NetConn_Heartbeat(1);
return true;