DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
crypto.c File Reference
#include "quakedef.h"
#include "crypto.h"
#include "common.h"
#include "thread.h"
#include "hmac.h"
#include "libcurl.h"
+ Include dependency graph for crypto.c:

Go to the source code of this file.

Data Structures

struct  crypto_data_t
 
struct  crypto_storedhostkey_t
 
struct  server_cryptoconnect_t
 

Macros

#define CDATA   ((crypto_data_t *) crypto->data)
 
#define CLEAR_CDATA   if(crypto->data) { if(CDATA->id) qd0_blind_id_free(CDATA->id); Z_Free(crypto->data); } crypto->data = NULL
 
#define CRYPTOCONNECT_CONNECT   2
 
#define CRYPTOCONNECT_DUPLICATE   4
 
#define CRYPTOCONNECT_NONE   0
 
#define CRYPTOCONNECT_PRECONNECT   1
 
#define CRYPTOCONNECT_RECONNECT   3
 
#define D0_BOOL   int
 
#define D0_EXPORT
 
#define D0_RIJNDAEL_KEYLENGTH(keybits)
 
#define D0_RIJNDAEL_NROUNDS(keybits)
 
#define D0_RIJNDAEL_RKLENGTH(keybits)
 
#define D0_WARN_UNUSED_RESULT
 
#define FOURCC_D0ER   (('d' << 0) | ('0' << 8) | ('e' << 16) | ('r' << 24))
 
#define FOURCC_D0IC   (('d' << 0) | ('0' << 8) | ('i' << 16) | ('c' << 24))
 
#define FOURCC_D0IQ   (('d' << 0) | ('0' << 8) | ('i' << 16) | ('q' << 24))
 
#define FOURCC_D0IR   (('d' << 0) | ('0' << 8) | ('i' << 16) | ('r' << 24))
 
#define FOURCC_D0PI   (('d' << 0) | ('0' << 8) | ('p' << 16) | ('i' << 24))
 
#define FOURCC_D0PK   (('d' << 0) | ('0' << 8) | ('p' << 16) | ('k' << 24))
 
#define FOURCC_D0SI   (('d' << 0) | ('0' << 8) | ('s' << 16) | ('i' << 24))
 
#define FOURCC_D0SK   (('d' << 0) | ('0' << 8) | ('s' << 16) | ('k' << 24))
 
#define MAKE_CDATA   if(!crypto->data) crypto->data = Z_Malloc(sizeof(crypto_data_t))
 
#define MAX_CRYPTOCONNECTS   16
 
#define MAX_PUBKEYS   16
 
#define PROTOCOL_D0_BLIND_ID   FOURCC_D0PK
 
#define PROTOCOL_VLEN   (('v' << 0) | ('l' << 8) | ('e' << 16) | ('n' << 24))
 
#define USE_AES
 

Typedefs

typedef struct d0_blind_id_s d0_blind_id_t
 
typedef voidd0_createmutex_t(void)
 
typedef void d0_destroymutex_t(void *)
 
typedef D0_BOOL(* d0_fastreject_function) (const d0_blind_id_t *ctx, void *pass)
 
typedef void d0_free_t(void *p)
 
typedef int d0_lockmutex_t(void *)
 
typedef voidd0_malloc_t(size_t len)
 
typedef int d0_unlockmutex_t(void *)
 

Functions

static void aescpy (unsigned char *key, const unsigned char *iv, unsigned char *dst, const unsigned char *src, size_t len)
 
static qbool Crypto_AddPrivateKey (d0_blind_id_t *pk, char *buf, size_t len)
 
qbool Crypto_Available (void)
 
static void Crypto_BuildChallengeAppend (void)
 
static void Crypto_BuildIdString (void)
 
static qbool Crypto_ClearHostKey (lhnetaddress_t *peeraddress)
 
static void Crypto_ClearHostKeys (void)
 
static int Crypto_ClientError (char *data_out, size_t *len_out, const char *msg)
 
int Crypto_ClientParsePacket (const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress, const char *peeraddressstring)
 
static void Crypto_CloseLibrary (void)
 
static voidCrypto_d0_createmutex (void)
 
static void Crypto_d0_destroymutex (void *m)
 
static void Crypto_d0_free (void *p)
 
static int Crypto_d0_lockmutex (void *m)
 
static voidCrypto_d0_malloc (size_t len)
 
static int Crypto_d0_unlockmutex (void *m)
 
const voidCrypto_DecryptPacket (crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len)
 
const voidCrypto_EncryptPacket (crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len)
 
qbool Crypto_FinishInstance (crypto_t *out, crypto_t *crypto)
 
const char * Crypto_GetInfoResponseDataString (void)
 
static void Crypto_HostKey_Clear_f (cmd_state_t *cmd)
 
static void Crypto_HostKeys_f (cmd_state_t *cmd)
 
void Crypto_Init (void)
 
void Crypto_Init_Commands (void)
 
static void Crypto_InitHostKeys (void)
 
static void Crypto_KeyGen_f (cmd_state_t *cmd)
 
static void Crypto_KeyGen_Finished (int code, size_t length_received, unsigned char *buffer, void *cbdata)
 
static void Crypto_Keys_f (cmd_state_t *cmd)
 
static unsigned long Crypto_LittleLong (const char *data)
 
static size_t Crypto_LoadFile (const char *path, char *buf, size_t nmax, qbool inuserdir)
 
void Crypto_LoadKeys (void)
 
static qbool Crypto_OpenLibrary (void)
 
static size_t Crypto_ParsePack (const char *buf, size_t len, unsigned long header, const char **lumps, size_t *lumpsize, size_t nlumps)
 
static d0_blind_id_tCrypto_ReadPublicKey (char *buf, size_t len)
 
static void Crypto_Reload_f (cmd_state_t *cmd)
 
qbool Crypto_RetrieveHostKey (lhnetaddress_t *peeraddress, int *keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen, int *aeslevel, qbool *issigned)
 
int Crypto_RetrieveLocalKey (int keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen, qbool *issigned)
 
static void Crypto_Rijndael_CloseLibrary (void)
 
static qbool Crypto_Rijndael_OpenLibrary (void)
 
static qbool Crypto_SavePubKeyTextFile (int i)
 
qbool Crypto_ServerAppendToChallenge (const char *data_in, size_t len_in, char *data_out, size_t *len_out, size_t maxlen_out)
 
static int Crypto_ServerError (char *data_out, size_t *len_out, const char *msg, const char *msg_client)
 
static crypto_tCrypto_ServerFindInstance (lhnetaddress_t *peeraddress, qbool allow_create)
 
crypto_tCrypto_ServerGetInstance (lhnetaddress_t *peeraddress)
 
int Crypto_ServerParsePacket (const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress)
 
static int Crypto_ServerParsePacket_Internal (const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress)
 
void Crypto_Shutdown (void)
 
size_t Crypto_SignData (const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size)
 
size_t Crypto_SignDataDetached (const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size)
 
static int Crypto_SoftClientError (char *data_out, size_t *len_out, const char *msg)
 
static int Crypto_SoftServerError (char *data_out, size_t *len_out, const char *msg)
 
static void Crypto_StoreHostKey (lhnetaddress_t *peeraddress, const char *keystring, qbool complain)
 
static void Crypto_UnLittleLong (char *data, unsigned long l)
 
static void Crypto_UnloadKeys (void)
 
static size_t Crypto_UnParsePack (char *buf, size_t len, unsigned long header, const char *const *lumps, const size_t *lumpsize, size_t nlumps)
 
static const char * GetUntilNul (const char **data, size_t *len)
 
static qbool PutWithNul (char **data, size_t *len, const char *str)
 
static void seacpy (unsigned char *key, const unsigned char *iv, unsigned char *dst, const unsigned char *src, size_t len)
 
void sha256 (unsigned char *out, const unsigned char *in, int n)
 

Variables

static int cdata_id = 0
 
static char challenge_append [1400]
 
static size_t challenge_append_length
 
cvar_t crypto_aeslevel = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_aeslevel", "1", "whether to support AES encryption in authenticated connections (0 = no, 1 = supported, 2 = requested, 3 = required)"}
 
cvar_t crypto_developer = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_developer", "0", "print extra info about crypto handshake"}
 
static const char * crypto_idstring = NULL
 
static char crypto_idstring_buf [512]
 
int crypto_keyfp_recommended_length
 
static double crypto_servercpu_accumulator = 0
 
static double crypto_servercpu_lastrealtime = 0
 
cvar_t crypto_servercpudebug = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpudebug", "0", "print statistics about time usage by crypto"}
 
cvar_t crypto_servercpumaxtime = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpumaxtime", "0.01", "maximum allowed crypto CPU time per frame (0 = no limit)"}
 
cvar_t crypto_servercpupercent = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpupercent", "10", "allowed crypto CPU load in percent for server operation (0 = no limit, faster)"}
 
static crypto_storedhostkey_tcrypto_storedhostkey_hashtable [CRYPTO_HOSTKEY_HASHSIZE]
 
static server_cryptoconnect_t cryptoconnects [MAX_CRYPTOCONNECTS]
 
static mempool_tcryptomempool
 
static dllhandle_t d0_blind_id_dll = NULL
 
static dllfunction_t d0_blind_id_funcs []
 
static dllhandle_t d0_rijndael_dll = NULL
 
static dllfunction_t d0_rijndael_funcs []
 
static char keygen_buf [8192]
 
static int keygen_i = -1
 
cvar_t net_sourceaddresscheck
 
static d0_blind_id_tpubkeys [MAX_PUBKEYS]
 
static char pubkeys_fp64 [MAX_PUBKEYS][FP64_SIZE+1]
 
static qbool pubkeys_havepriv [MAX_PUBKEYS]
 
static qbool pubkeys_havesig [MAX_PUBKEYS]
 
static char pubkeys_priv_fp64 [MAX_PUBKEYS][FP64_SIZE+1]
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_challenge )(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL recv_modulus, const char *inbuf, size_t inbuflen, char *outbuf, size_t *outbuflen, D0_BOOL *status)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_response )(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_start )(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_verify )(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen, char *msg, size_t *msglen, D0_BOOL *status)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_copy )(d0_blind_id_t *ctx, const d0_blind_id_t *src)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_fingerprint64_public_id )(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_fingerprint64_public_key )(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_finish_private_id_request )(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
 
static D0_EXPORT void(* qd0_blind_id_free )(d0_blind_id_t *a)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_generate_private_id_request )(d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_generate_private_id_start )(d0_blind_id_t *ctx)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_INITIALIZE )(void)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT d0_blind_id_t *(* qd0_blind_id_new )(void)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_private_id )(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_private_id_modulus )(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_public_key )(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sessionkey_public_id )(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT void(* qd0_blind_id_setmallocfuncs )(d0_malloc_t *m, d0_free_t *f)
 
static D0_EXPORT void(* qd0_blind_id_setmutexfuncs )(d0_createmutex_t *c, d0_destroymutex_t *d, d0_lockmutex_t *l, d0_unlockmutex_t *u)
 
static D0_EXPORT void(* qd0_blind_id_SHUTDOWN )(void)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sign_with_private_id_sign )(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sign_with_private_id_sign_detached )(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen)
 
static D0_EXPORT void(* qd0_blind_id_util_sha256 )(char *out, const char *in, size_t n)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_verify_private_id )(const d0_blind_id_t *ctx)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_verify_public_id )(const d0_blind_id_t *ctx, D0_BOOL *status)
 
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_write_private_id )(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
 
D0_EXPORT void(* qd0_rijndael_decrypt )(const unsigned long *rk, int nrounds, const unsigned char ciphertext[16], unsigned char plaintext[16])
 
D0_EXPORT void(* qd0_rijndael_encrypt )(const unsigned long *rk, int nrounds, const unsigned char plaintext[16], unsigned char ciphertext[16])
 
D0_EXPORT int(* qd0_rijndael_setup_decrypt )(unsigned long *rk, const unsigned char *key, int keybits)
 
D0_EXPORT int(* qd0_rijndael_setup_encrypt )(unsigned long *rk, const unsigned char *key, int keybits)
 

Macro Definition Documentation

◆ CDATA

#define CDATA   ((crypto_data_t *) crypto->data)

Definition at line 524 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ CLEAR_CDATA

#define CLEAR_CDATA   if(crypto->data) { if(CDATA->id) qd0_blind_id_free(CDATA->id); Z_Free(crypto->data); } crypto->data = NULL

◆ CRYPTOCONNECT_CONNECT

#define CRYPTOCONNECT_CONNECT   2

Definition at line 496 of file crypto.c.

◆ CRYPTOCONNECT_DUPLICATE

#define CRYPTOCONNECT_DUPLICATE   4

Definition at line 498 of file crypto.c.

◆ CRYPTOCONNECT_NONE

#define CRYPTOCONNECT_NONE   0

Definition at line 494 of file crypto.c.

◆ CRYPTOCONNECT_PRECONNECT

#define CRYPTOCONNECT_PRECONNECT   1

Definition at line 495 of file crypto.c.

◆ CRYPTOCONNECT_RECONNECT

#define CRYPTOCONNECT_RECONNECT   3

Definition at line 497 of file crypto.c.

◆ D0_BOOL

◆ D0_EXPORT

#define D0_EXPORT

Definition at line 181 of file crypto.c.

◆ D0_RIJNDAEL_KEYLENGTH

#define D0_RIJNDAEL_KEYLENGTH ( keybits)
Value:
((keybits)/8)

Definition at line 338 of file crypto.c.

◆ D0_RIJNDAEL_NROUNDS

#define D0_RIJNDAEL_NROUNDS ( keybits)
Value:
((keybits)/32+6)

Definition at line 340 of file crypto.c.

Referenced by aescpy(), and seacpy().

◆ D0_RIJNDAEL_RKLENGTH

#define D0_RIJNDAEL_RKLENGTH ( keybits)
Value:
((keybits)/8+28)

Definition at line 339 of file crypto.c.

Referenced by aescpy(), and seacpy().

◆ D0_WARN_UNUSED_RESULT

#define D0_WARN_UNUSED_RESULT

Definition at line 185 of file crypto.c.

◆ FOURCC_D0ER

#define FOURCC_D0ER   (('d' << 0) | ('0' << 8) | ('e' << 16) | ('r' << 24))

Definition at line 56 of file crypto.c.

Referenced by Crypto_KeyGen_Finished().

◆ FOURCC_D0IC

#define FOURCC_D0IC   (('d' << 0) | ('0' << 8) | ('i' << 16) | ('c' << 24))

Definition at line 57 of file crypto.c.

◆ FOURCC_D0IQ

#define FOURCC_D0IQ   (('d' << 0) | ('0' << 8) | ('i' << 16) | ('q' << 24))

Definition at line 54 of file crypto.c.

Referenced by Crypto_KeyGen_f().

◆ FOURCC_D0IR

#define FOURCC_D0IR   (('d' << 0) | ('0' << 8) | ('i' << 16) | ('r' << 24))

Definition at line 55 of file crypto.c.

Referenced by Crypto_KeyGen_Finished().

◆ FOURCC_D0PI

#define FOURCC_D0PI   (('d' << 0) | ('0' << 8) | ('p' << 16) | ('i' << 24))

Definition at line 52 of file crypto.c.

◆ FOURCC_D0PK

#define FOURCC_D0PK   (('d' << 0) | ('0' << 8) | ('p' << 16) | ('k' << 24))

Definition at line 50 of file crypto.c.

Referenced by Crypto_ReadPublicKey().

◆ FOURCC_D0SI

#define FOURCC_D0SI   (('d' << 0) | ('0' << 8) | ('s' << 16) | ('i' << 24))

Definition at line 53 of file crypto.c.

Referenced by Crypto_AddPrivateKey(), Crypto_KeyGen_f(), and Crypto_KeyGen_Finished().

◆ FOURCC_D0SK

#define FOURCC_D0SK   (('d' << 0) | ('0' << 8) | ('s' << 16) | ('k' << 24))

Definition at line 51 of file crypto.c.

◆ MAKE_CDATA

#define MAKE_CDATA   if(!crypto->data) crypto->data = Z_Malloc(sizeof(crypto_data_t))

Definition at line 525 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ MAX_CRYPTOCONNECTS

#define MAX_CRYPTOCONNECTS   16

Definition at line 493 of file crypto.c.

Referenced by Crypto_ServerFindInstance(), and Crypto_Shutdown().

◆ MAX_PUBKEYS

◆ PROTOCOL_D0_BLIND_ID

#define PROTOCOL_D0_BLIND_ID   FOURCC_D0PK

Definition at line 46 of file crypto.c.

Referenced by Crypto_BuildChallengeAppend(), and Crypto_ClientParsePacket().

◆ PROTOCOL_VLEN

#define PROTOCOL_VLEN   (('v' << 0) | ('l' << 8) | ('e' << 16) | ('n' << 24))

Definition at line 47 of file crypto.c.

Referenced by Crypto_BuildChallengeAppend(), and Crypto_ClientParsePacket().

◆ USE_AES

#define USE_AES

Definition at line 128 of file crypto.c.

Typedef Documentation

◆ d0_blind_id_t

typedef struct d0_blind_id_s d0_blind_id_t

Definition at line 196 of file crypto.c.

◆ d0_createmutex_t

typedef void * d0_createmutex_t(void)

Definition at line 191 of file crypto.c.

◆ d0_destroymutex_t

typedef void d0_destroymutex_t(void *)

Definition at line 192 of file crypto.c.

◆ d0_fastreject_function

typedef D0_BOOL(* d0_fastreject_function) (const d0_blind_id_t *ctx, void *pass)

Definition at line 197 of file crypto.c.

◆ d0_free_t

typedef void d0_free_t(void *p)

Definition at line 190 of file crypto.c.

◆ d0_lockmutex_t

typedef int d0_lockmutex_t(void *)

Definition at line 193 of file crypto.c.

◆ d0_malloc_t

typedef void * d0_malloc_t(size_t len)

Definition at line 189 of file crypto.c.

◆ d0_unlockmutex_t

typedef int d0_unlockmutex_t(void *)

Definition at line 194 of file crypto.c.

Function Documentation

◆ aescpy()

static void aescpy ( unsigned char * key,
const unsigned char * iv,
unsigned char * dst,
const unsigned char * src,
size_t len )
static

Definition at line 1472 of file crypto.c.

1473{
1474 const unsigned char *xorpos = iv;
1475 unsigned char xorbuf[16];
1476 unsigned long rk[D0_RIJNDAEL_RKLENGTH(DHKEY_SIZE * 8)];
1477 size_t i;
1479 while(len > 16)
1480 {
1481 for(i = 0; i < 16; ++i)
1482 xorbuf[i] = src[i] ^ xorpos[i];
1484 xorpos = dst;
1485 len -= 16;
1486 src += 16;
1487 dst += 16;
1488 }
1489 if(len > 0)
1490 {
1491 for(i = 0; i < len; ++i)
1492 xorbuf[i] = src[i] ^ xorpos[i];
1493 for(; i < 16; ++i)
1494 xorbuf[i] = xorpos[i];
1496 }
1497}
D0_EXPORT int(* qd0_rijndael_setup_encrypt)(unsigned long *rk, const unsigned char *key, int keybits)
Definition crypto.c:330
D0_EXPORT void(* qd0_rijndael_encrypt)(const unsigned long *rk, int nrounds, const unsigned char plaintext[16], unsigned char ciphertext[16])
Definition crypto.c:334
#define D0_RIJNDAEL_NROUNDS(keybits)
Definition crypto.c:340
#define D0_RIJNDAEL_RKLENGTH(keybits)
Definition crypto.c:339
#define DHKEY_SIZE
Definition crypto.h:39
prvm_eval_t * src
int i

References D0_RIJNDAEL_NROUNDS, D0_RIJNDAEL_RKLENGTH, DHKEY_SIZE, i, qd0_rijndael_encrypt, qd0_rijndael_setup_encrypt, and src.

Referenced by Crypto_EncryptPacket().

◆ Crypto_AddPrivateKey()

static qbool Crypto_AddPrivateKey ( d0_blind_id_t * pk,
char * buf,
size_t len )
static

Definition at line 469 of file crypto.c.

470{
471 const char *p[1];
472 size_t l[1];
473 if(Crypto_ParsePack(buf, len, FOURCC_D0SI, p, l, 1))
474 {
475 if(qd0_blind_id_read_private_id(pk, p[0], l[0]))
476 return true;
477 }
478 return false;
479}
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_private_id)(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
Definition crypto.c:218
#define FOURCC_D0SI
Definition crypto.c:53
static size_t Crypto_ParsePack(const char *buf, size_t len, unsigned long header, const char **lumps, size_t *lumpsize, size_t nlumps)
Definition crypto.c:76
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657

References buf, Crypto_ParsePack(), FOURCC_D0SI, and qd0_blind_id_read_private_id.

Referenced by Crypto_LoadKeys().

◆ Crypto_Available()

qbool Crypto_Available ( void )

Definition at line 1097 of file crypto.c.

1098{
1099 if(!d0_blind_id_dll)
1100 return false;
1101 return true;
1102}
static dllhandle_t d0_blind_id_dll
Definition crypto.c:282

References d0_blind_id_dll.

Referenced by checkextension(), and VM_digest_hex().

◆ Crypto_BuildChallengeAppend()

static void Crypto_BuildChallengeAppend ( void )
static

Definition at line 785 of file crypto.c.

786{
787 char *p, *lengthptr, *startptr;
788 size_t n;
789 int i;
791 n = sizeof(challenge_append);
793 p += 4;
794 n -= 4;
795 lengthptr = p;
797 p += 4;
798 n -= 4;
800 p += 4;
801 n -= 4;
802 startptr = p;
803 for(i = 0; i < MAX_PUBKEYS; ++i)
805 PutWithNul(&p, &n, pubkeys_fp64[i]);
806 PutWithNul(&p, &n, "");
807 for(i = 0; i < MAX_PUBKEYS; ++i)
808 if(!pubkeys_havepriv[i] && pubkeys[i])
809 PutWithNul(&p, &n, pubkeys_fp64[i]);
810 Crypto_UnLittleLong(lengthptr, p - startptr);
812}
static char challenge_append[1400]
Definition crypto.c:487
#define PROTOCOL_VLEN
Definition crypto.c:47
#define PROTOCOL_D0_BLIND_ID
Definition crypto.c:46
static qbool PutWithNul(char **data, size_t *len, const char *str)
Definition crypto.c:406
static size_t challenge_append_length
Definition crypto.c:488
#define MAX_PUBKEYS
Definition crypto.c:481
static qbool pubkeys_havepriv[MAX_PUBKEYS]
Definition crypto.c:484
static char pubkeys_fp64[MAX_PUBKEYS][FP64_SIZE+1]
Definition crypto.c:483
static d0_blind_id_t * pubkeys[MAX_PUBKEYS]
Definition crypto.c:482
static void Crypto_UnLittleLong(char *data, unsigned long l)
Definition crypto.c:68
#define n(x, y)

References challenge_append, challenge_append_length, Crypto_UnLittleLong(), i, MAX_PUBKEYS, n, PROTOCOL_D0_BLIND_ID, PROTOCOL_VLEN, pubkeys, pubkeys_fp64, pubkeys_havepriv, and PutWithNul().

Referenced by Crypto_KeyGen_f(), and Crypto_LoadKeys().

◆ Crypto_BuildIdString()

static void Crypto_BuildIdString ( void )
static

Definition at line 842 of file crypto.c.

843{
844 int i;
845 char vabuf[1024];
846
849 for (i = 0; i < MAX_PUBKEYS; ++i)
850 if (pubkeys[i])
851 dp_strlcat(crypto_idstring_buf, va(vabuf, sizeof(vabuf), " %s@%s%s", pubkeys_priv_fp64[i], pubkeys_havesig[i] ? "" : "~", pubkeys_fp64[i]), sizeof(crypto_idstring_buf));
853}
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
#define dp_strlcat(dst, src, dsize)
Definition common.h:304
static char pubkeys_priv_fp64[MAX_PUBKEYS][FP64_SIZE+1]
Definition crypto.c:486
static char crypto_idstring_buf[512]
Definition crypto.c:43
static qbool pubkeys_havesig[MAX_PUBKEYS]
Definition crypto.c:485
static const char * crypto_idstring
Definition crypto.c:42
cvar_t crypto_aeslevel
Definition crypto.c:31
static dllhandle_t d0_rijndael_dll
Definition crypto.c:351
#define NULL
Definition qtypes.h:12
int integer
Definition cvar.h:73

References crypto_aeslevel, crypto_idstring, crypto_idstring_buf, d0_rijndael_dll, dp_strlcat, dpsnprintf(), i, cvar_t::integer, MAX_PUBKEYS, NULL, pubkeys, pubkeys_fp64, pubkeys_havesig, pubkeys_priv_fp64, and va().

Referenced by Crypto_KeyGen_Finished(), and Crypto_LoadKeys().

◆ Crypto_ClearHostKey()

static qbool Crypto_ClearHostKey ( lhnetaddress_t * peeraddress)
static

Definition at line 613 of file crypto.c.

614{
615 char buf[128];
616 int hashindex;
618 qbool found = false;
619
620 LHNETADDRESS_ToString(peeraddress, buf, sizeof(buf), 1);
621 hashindex = CRC_Block((const unsigned char *) buf, strlen(buf)) % CRYPTO_HOSTKEY_HASHSIZE;
622 for(hkp = &crypto_storedhostkey_hashtable[hashindex]; *hkp && LHNETADDRESS_Compare(&((*hkp)->addr), peeraddress); hkp = &((*hkp)->next));
623
624 if(*hkp)
625 {
626 crypto_storedhostkey_t *hk = *hkp;
627 *hkp = hk->next;
628 Z_Free(hk);
629 found = true;
630 }
631
632 return found;
633}
unsigned short CRC_Block(const unsigned char *data, size_t size)
Definition com_crc16.c:75
static crypto_storedhostkey_t * crypto_storedhostkey_hashtable[CRYPTO_HOSTKEY_HASHSIZE]
Definition crypto.c:589
int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stringbuffersize, int includeport)
Returns the number of bytes written to *string excluding the \0 terminator.
Definition lhnet.c:540
int LHNETADDRESS_Compare(const lhnetaddress_t *vaddress1, const lhnetaddress_t *vaddress2)
Definition lhnet.c:665
float strlen(string s)
#define CRYPTO_HOSTKEY_HASHSIZE
number of hash buckets for accelerating host key lookups
Definition qdefs.h:126
bool qbool
Definition qtypes.h:9
struct crypto_storedhostkey_s * next
Definition crypto.c:581
#define Z_Free(data)
Definition zone.h:164

References buf, CRC_Block(), CRYPTO_HOSTKEY_HASHSIZE, crypto_storedhostkey_hashtable, LHNETADDRESS_Compare(), LHNETADDRESS_ToString(), crypto_storedhostkey_t::next, strlen(), and Z_Free.

Referenced by Crypto_HostKey_Clear_f().

◆ Crypto_ClearHostKeys()

static void Crypto_ClearHostKeys ( void )
static

Definition at line 598 of file crypto.c.

599{
600 int i;
601 crypto_storedhostkey_t *hk, *hkn;
602 for(i = 0; i < CRYPTO_HOSTKEY_HASHSIZE; ++i)
603 {
604 for(hk = crypto_storedhostkey_hashtable[i]; hk; hk = hkn)
605 {
606 hkn = hk->next;
607 Z_Free(hk);
608 }
610 }
611}

References CRYPTO_HOSTKEY_HASHSIZE, crypto_storedhostkey_hashtable, i, crypto_storedhostkey_t::next, NULL, and Z_Free.

Referenced by Crypto_Reload_f().

◆ Crypto_ClientError()

static int Crypto_ClientError ( char * data_out,
size_t * len_out,
const char * msg )
static

Definition at line 2093 of file crypto.c.

2094{
2095 dpsnprintf(data_out, *len_out, "reject %s", msg);
2096 *len_out = strlen(data_out);
2097 return CRYPTO_REPLACE;
2098}
#define CRYPTO_REPLACE
Definition crypto.h:67

References CRYPTO_REPLACE, dpsnprintf(), and strlen().

Referenced by Crypto_ClientParsePacket().

◆ Crypto_ClientParsePacket()

int Crypto_ClientParsePacket ( const char * data_in,
size_t len_in,
char * data_out,
size_t * len_out,
lhnetaddress_t * peeraddress,
const char * peeraddressstring )

Definition at line 2107 of file crypto.c.

2108{
2109 crypto_t *crypto = &cls.crypto;
2110 const char *string = data_in;
2111 D0_BOOL aes;
2112 char *data_out_p = data_out;
2113 D0_BOOL status;
2114 char infostringvalue[MAX_INPUTLINE];
2115 char vabuf[1024];
2116
2117 if(!d0_blind_id_dll)
2118 return CRYPTO_NOMATCH; // no support
2119
2120 // if "challenge": verify challenge, and discard message, send next crypto protocol message instead
2121 // otherwise, just handle actual protocol messages
2122
2123 if (len_in == 6 && !memcmp(string, "accept", 6) && cls.connect_trying && d0_rijndael_dll)
2124 {
2125 int wantserverid = -1;
2126 Crypto_RetrieveHostKey(&cls.connect_address, &wantserverid, NULL, 0, NULL, 0, NULL, NULL);
2127 if(!crypto || !crypto->authenticated) // we ALSO get here if we are using an encrypted connection, so let's rule this out
2128 {
2129 if(wantserverid >= 0)
2130 return Crypto_ClientError(data_out, len_out, "Server tried an unauthenticated connection even though a host key is present");
2131 if(crypto_aeslevel.integer >= 3)
2132 return Crypto_ClientError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)");
2133 }
2134 return CRYPTO_NOMATCH;
2135 }
2136 else if (len_in >= 1 && string[0] == 'j' && cls.connect_trying && d0_rijndael_dll)
2137 {
2138 int wantserverid = -1;
2139 Crypto_RetrieveHostKey(&cls.connect_address, &wantserverid, NULL, 0, NULL, 0, NULL, NULL);
2140 //if(!crypto || !crypto->authenticated)
2141 {
2142 if(wantserverid >= 0)
2143 return Crypto_ClientError(data_out, len_out, "Server tried an unauthenticated connection even though a host key is present");
2144 if(crypto_aeslevel.integer >= 3)
2145 return Crypto_ClientError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)");
2146 }
2147 return CRYPTO_NOMATCH;
2148 }
2149 else if (len_in >= 5 && BuffLittleLong((unsigned char *) string) == ((int)NETFLAG_CTL | (int)len_in))
2150 {
2151 int wantserverid = -1;
2152
2153 // these three are harmless
2154 if((unsigned char) string[4] == CCREP_SERVER_INFO)
2155 return CRYPTO_NOMATCH;
2156 if((unsigned char) string[4] == CCREP_PLAYER_INFO)
2157 return CRYPTO_NOMATCH;
2158 if((unsigned char) string[4] == CCREP_RULE_INFO)
2159 return CRYPTO_NOMATCH;
2160
2161 Crypto_RetrieveHostKey(&cls.connect_address, &wantserverid, NULL, 0, NULL, 0, NULL, NULL);
2162 //if(!crypto || !crypto->authenticated)
2163 {
2164 if(wantserverid >= 0)
2165 return Crypto_ClientError(data_out, len_out, "Server tried an unauthenticated connection even though a host key is present");
2166 if(crypto_aeslevel.integer >= 3)
2167 return Crypto_ClientError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)");
2168 }
2169 return CRYPTO_NOMATCH;
2170 }
2171 else if (len_in >= 13 && !memcmp(string, "infoResponse\x0A", 13))
2172 {
2173 if(InfoString_GetValue(string + 13, "d0_blind_id", infostringvalue, sizeof(infostringvalue)))
2174 Crypto_StoreHostKey(peeraddress, infostringvalue, true);
2175 return CRYPTO_NOMATCH;
2176 }
2177 else if (len_in >= 15 && !memcmp(string, "statusResponse\x0A", 15))
2178 {
2179 char save = 0;
2180 const char *p;
2181 p = strchr(string + 15, '\n');
2182 if(p)
2183 {
2184 save = *p;
2185 * (char *) p = 0; // cut off the string there
2186 }
2187 if(InfoString_GetValue(string + 15, "d0_blind_id", infostringvalue, sizeof(infostringvalue)))
2188 Crypto_StoreHostKey(peeraddress, infostringvalue, true);
2189 if(p)
2190 {
2191 * (char *) p = save;
2192 // invoking those nasal demons again (do not run this on the DS9k)
2193 }
2194 return CRYPTO_NOMATCH;
2195 }
2196 else if(len_in > 10 && !memcmp(string, "challenge ", 10) && cls.connect_trying)
2197 {
2198 const char *vlen_blind_id_ptr = NULL;
2199 size_t len_blind_id_ptr = 0;
2200 unsigned long k, v;
2201 const char *challenge = data_in + 10;
2202 const char *p;
2203 int i;
2204 int clientid = -1, serverid = -1, wantserverid = -1;
2205 qbool server_can_auth = true;
2206 char wantserver_idfp[FP64_SIZE+1];
2207 int wantserver_aeslevel = 0;
2208 qbool wantserver_issigned = false;
2209
2210 // Must check the source IP here, if we want to prevent other servers' replies from falsely advancing the crypto state, preventing successful connect to the real server.
2212 {
2213 char warn_msg[128];
2214
2215 dpsnprintf(warn_msg, sizeof(warn_msg), "ignoring challenge message from wrong server %s", peeraddressstring);
2216 return Crypto_SoftClientError(data_out, len_out, warn_msg);
2217 }
2218
2219 // if we have a stored host key for the server, assume serverid to already be selected!
2220 // (the loop will refuse to overwrite this one then)
2221 wantserver_idfp[0] = 0;
2222 Crypto_RetrieveHostKey(&cls.connect_address, &wantserverid, NULL, 0, wantserver_idfp, sizeof(wantserver_idfp), &wantserver_aeslevel, &wantserver_issigned);
2223 // requirement: wantserver_idfp is a full ID if wantserverid set
2224
2225 // if we leave, we have to consider the connection
2226 // unauthenticated; NOTE: this may be faked by a clever
2227 // attacker to force an unauthenticated connection; so we have
2228 // a safeguard check in place when encryption is required too
2229 // in place, or when authentication is required by the server
2230 crypto->authenticated = false;
2231
2232 GetUntilNul(&data_in, &len_in);
2233 if(!data_in)
2234 return (wantserverid >= 0) ? Crypto_ClientError(data_out, len_out, "Server tried an unauthenticated connection even though a host key is present") :
2235 (d0_rijndael_dll && crypto_aeslevel.integer >= 3) ? Crypto_ClientError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)") :
2237
2238 // FTEQW extension protocol
2239 while(len_in >= 8)
2240 {
2241 k = Crypto_LittleLong(data_in);
2242 v = Crypto_LittleLong(data_in + 4);
2243 data_in += 8;
2244 len_in -= 8;
2245 switch(k)
2246 {
2247 case PROTOCOL_VLEN:
2248 if(len_in >= 4 + v)
2249 {
2250 k = Crypto_LittleLong(data_in);
2251 data_in += 4;
2252 len_in -= 4;
2253 switch(k)
2254 {
2256 vlen_blind_id_ptr = data_in;
2257 len_blind_id_ptr = v;
2258 break;
2259 }
2260 data_in += v;
2261 len_in -= v;
2262 }
2263 break;
2264 default:
2265 break;
2266 }
2267 }
2268
2269 if(!vlen_blind_id_ptr)
2270 return (wantserverid >= 0) ? Crypto_ClientError(data_out, len_out, "Server tried an unauthenticated connection even though authentication is required") :
2271 (d0_rijndael_dll && crypto_aeslevel.integer >= 3) ? Crypto_ClientError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)") :
2273
2274 data_in = vlen_blind_id_ptr;
2275 len_in = len_blind_id_ptr;
2276
2277 // parse fingerprints
2278 // once we found a fingerprint we can auth to (ANY), select it as clientfp
2279 // once we found a fingerprint in the first list that we know, select it as serverfp
2280
2281 for(;;)
2282 {
2283 p = GetUntilNul(&data_in, &len_in);
2284 if(!p)
2285 break;
2286 if(!*p)
2287 {
2288 if(!server_can_auth)
2289 break; // other protocol message may follow
2290 server_can_auth = false;
2291 if(clientid >= 0)
2292 break;
2293 continue;
2294 }
2295 // Find the highest numbered matching key for p.
2296 for(i = 0; i < MAX_PUBKEYS; ++i)
2297 {
2298 if(pubkeys[i])
2299 if(!strcmp(p, pubkeys_fp64[i]))
2300 {
2301 if(pubkeys_havepriv[i])
2302 clientid = i;
2303 if(server_can_auth)
2304 if(wantserverid < 0 || i == wantserverid)
2305 serverid = i;
2306 }
2307 }
2308 // Not breaking, as higher keys in the list always have priority.
2309 }
2310
2311 // if stored host key is not found:
2312 if(wantserverid >= 0 && serverid < 0)
2313 return Crypto_ClientError(data_out, len_out, "Server CA does not match stored host key, refusing to connect");
2314
2315 if(serverid >= 0 || clientid >= 0)
2316 {
2317 MAKE_CDATA;
2318 CDATA->cdata_id = ++cdata_id;
2319 CDATA->s = serverid;
2320 CDATA->c = clientid;
2321 memset(crypto->dhkey, 0, sizeof(crypto->dhkey));
2322 dp_strlcpy(CDATA->challenge, challenge, sizeof(CDATA->challenge));
2323 crypto->client_keyfp[0] = 0;
2324 crypto->client_idfp[0] = 0;
2325 crypto->server_keyfp[0] = 0;
2326 crypto->server_idfp[0] = 0;
2327 memcpy(CDATA->wantserver_idfp, wantserver_idfp, sizeof(crypto->server_idfp));
2328 CDATA->wantserver_issigned = wantserver_issigned;
2329
2330 if(CDATA->wantserver_idfp[0]) // if we know a host key, honor its encryption setting
2331 switch(bound(0, d0_rijndael_dll ? crypto_aeslevel.integer : 0, 3))
2332 {
2333 default: // dummy, never happens, but to make gcc happy...
2334 case 0:
2335 if(wantserver_aeslevel >= 3)
2336 return Crypto_ClientError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)");
2337 CDATA->wantserver_aes = false;
2338 break;
2339 case 1:
2340 CDATA->wantserver_aes = (wantserver_aeslevel >= 2);
2341 break;
2342 case 2:
2343 CDATA->wantserver_aes = (wantserver_aeslevel >= 1);
2344 break;
2345 case 3:
2346 if(wantserver_aeslevel <= 0)
2347 return Crypto_ClientError(data_out, len_out, "This server requires encryption to be supported (crypto_aeslevel >= 1, and d0_rijndael library must be present)");
2348 CDATA->wantserver_aes = true;
2349 break;
2350 }
2351
2352 // build outgoing message
2353 // append regular stuff
2354 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\0\\id\\%d\\aeslevel\\%d\\challenge\\%s", CDATA->cdata_id, d0_rijndael_dll ? crypto_aeslevel.integer : 0, challenge));
2355 PutWithNul(&data_out_p, len_out, serverid >= 0 ? pubkeys_fp64[serverid] : "");
2356 PutWithNul(&data_out_p, len_out, clientid >= 0 ? pubkeys_fp64[clientid] : "");
2357
2358 if(clientid >= 0)
2359 {
2360 // I am the client, and my key is ok... so let's set client_keyfp and client_idfp
2361 dp_strlcpy(crypto->client_keyfp, pubkeys_fp64[CDATA->c], sizeof(crypto->client_keyfp));
2362 dp_strlcpy(crypto->client_idfp, pubkeys_priv_fp64[CDATA->c], sizeof(crypto->client_idfp));
2364 }
2365
2366 if(serverid >= 0)
2367 {
2368 if(!CDATA->id)
2369 CDATA->id = qd0_blind_id_new();
2370 if(!CDATA->id)
2371 {
2373 return Crypto_ClientError(data_out, len_out, "d0_blind_id_new failed");
2374 }
2375 if(!qd0_blind_id_copy(CDATA->id, pubkeys[CDATA->s]))
2376 {
2378 return Crypto_ClientError(data_out, len_out, "d0_blind_id_copy failed");
2379 }
2380 CDATA->next_step = 1;
2381 *len_out = data_out_p - data_out;
2382 }
2383 else // if(clientid >= 0) // guaranteed by condition one level outside
2384 {
2385 // skip over server auth, perform client auth only
2386 if(!CDATA->id)
2387 CDATA->id = qd0_blind_id_new();
2388 if(!CDATA->id)
2389 {
2391 return Crypto_ClientError(data_out, len_out, "d0_blind_id_new failed");
2392 }
2393 if(!qd0_blind_id_copy(CDATA->id, pubkeys[CDATA->c]))
2394 {
2396 return Crypto_ClientError(data_out, len_out, "d0_blind_id_copy failed");
2397 }
2398 if(!qd0_blind_id_authenticate_with_private_id_start(CDATA->id, true, false, "XONOTIC", 8, data_out_p, len_out)) // len_out receives used size by this op
2399 {
2401 return Crypto_ClientError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_start failed");
2402 }
2403 CDATA->next_step = 5;
2404 data_out_p += *len_out;
2405 *len_out = data_out_p - data_out;
2406 }
2407 return CRYPTO_DISCARD;
2408 }
2409 else
2410 {
2411 if(wantserver_idfp[0]) // if we know a host key, honor its encryption setting
2412 if(wantserver_aeslevel >= 3)
2413 return Crypto_ClientError(data_out, len_out, "Server insists on encryption, but neither can authenticate to the other");
2414 return (d0_rijndael_dll && crypto_aeslevel.integer >= 3) ? Crypto_ClientError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)") :
2416 }
2417 }
2418 else if(len_in > 5 && !memcmp(string, "d0pk\\", 5) && cls.connect_trying)
2419 {
2420 const char *cnt;
2421 int id;
2422
2423 // Must check the source IP here, if we want to prevent other servers' replies from falsely advancing the crypto state, preventing successful connect to the real server.
2425 {
2426 char warn_msg[128];
2427
2428 dpsnprintf(warn_msg, sizeof(warn_msg), "ignoring d0pk\\ message from wrong server %s", peeraddressstring);
2429 return Crypto_SoftClientError(data_out, len_out, warn_msg);
2430 }
2431
2432 id = (InfoString_GetValue(string + 4, "id", infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : -1);
2433 cnt = (InfoString_GetValue(string + 4, "cnt", infostringvalue, sizeof(infostringvalue)) ? infostringvalue : NULL);
2434 if(!cnt)
2435 return Crypto_ClientError(data_out, len_out, "d0pk\\ message without cnt");
2436 GetUntilNul(&data_in, &len_in);
2437 if(!data_in)
2438 return Crypto_ClientError(data_out, len_out, "d0pk\\ message without attachment");
2439
2440 if(!strcmp(cnt, "1"))
2441 {
2442 if(id >= 0)
2443 if(CDATA->cdata_id != id)
2444 return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
2445 if(CDATA->next_step != 1)
2446 return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
2447
2448 cls.connect_nextsendtime = max(cls.connect_nextsendtime, host.realtime + 1); // prevent "hammering"
2449
2450 if(InfoString_GetValue(string + 4, "aes", infostringvalue, sizeof(infostringvalue)))
2451 aes = atoi(infostringvalue);
2452 else
2453 aes = false;
2454 // we CANNOT toggle the AES status any more!
2455 // as the server already decided
2456 if(CDATA->wantserver_idfp[0]) // if we know a host key, honor its encryption setting
2457 if(!aes && CDATA->wantserver_aes)
2458 {
2460 return Crypto_ClientError(data_out, len_out, "Stored host key requires encryption, but server did not enable encryption");
2461 }
2462 if(aes && (!d0_rijndael_dll || crypto_aeslevel.integer <= 0))
2463 {
2465 return Crypto_ClientError(data_out, len_out, "Server insists on encryption too hard");
2466 }
2467 if(!aes && (d0_rijndael_dll && crypto_aeslevel.integer >= 3))
2468 {
2470 return Crypto_ClientError(data_out, len_out, "Server insists on plaintext too hard");
2471 }
2472 crypto->use_aes = aes != 0;
2473
2474 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\2\\id\\%d", CDATA->cdata_id));
2475 if(!qd0_blind_id_authenticate_with_private_id_challenge(CDATA->id, true, false, data_in, len_in, data_out_p, len_out, &status))
2476 {
2478 return Crypto_ClientError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_challenge failed");
2479 }
2480 CDATA->next_step = 3;
2481 data_out_p += *len_out;
2482 *len_out = data_out_p - data_out;
2483 return CRYPTO_DISCARD;
2484 }
2485 else if(!strcmp(cnt, "3"))
2486 {
2487 static char msgbuf[32];
2488 size_t msgbuflen = sizeof(msgbuf);
2489 size_t fpbuflen;
2490
2491 if(id >= 0)
2492 if(CDATA->cdata_id != id)
2493 return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
2494 if(CDATA->next_step != 3)
2495 return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
2496
2497 cls.connect_nextsendtime = max(cls.connect_nextsendtime, host.realtime + 1); // prevent "hammering"
2498
2499 if(!qd0_blind_id_authenticate_with_private_id_verify(CDATA->id, data_in, len_in, msgbuf, &msgbuflen, &status))
2500 {
2502 return Crypto_ClientError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_verify failed (server authentication error)");
2503 }
2504
2505 dp_strlcpy(crypto->server_keyfp, pubkeys_fp64[CDATA->s], sizeof(crypto->server_keyfp));
2506 if (!status && CDATA->wantserver_issigned)
2507 {
2509 return Crypto_ClientError(data_out, len_out, "Stored host key requires a valid signature, but server did not provide any");
2510 }
2511 crypto->server_issigned = status;
2512
2513 memset(crypto->server_idfp, 0, sizeof(crypto->server_idfp));
2514 fpbuflen = FP64_SIZE;
2515 if(!qd0_blind_id_fingerprint64_public_id(CDATA->id, crypto->server_idfp, &fpbuflen))
2516 {
2518 return Crypto_ClientError(data_out, len_out, "d0_blind_id_fingerprint64_public_id failed");
2519 }
2520 if(CDATA->wantserver_idfp[0])
2521 if(memcmp(CDATA->wantserver_idfp, crypto->server_idfp, sizeof(crypto->server_idfp)))
2522 {
2524 return Crypto_ClientError(data_out, len_out, "Server ID does not match stored host key, refusing to connect");
2525 }
2526 fpbuflen = DHKEY_SIZE;
2527 if(!qd0_blind_id_sessionkey_public_id(CDATA->id, (char *) crypto->dhkey, &fpbuflen))
2528 {
2530 return Crypto_ClientError(data_out, len_out, "d0_blind_id_sessionkey_public_id failed");
2531 }
2532
2533 // cache the server key
2534 Crypto_StoreHostKey(&cls.connect_address, va(vabuf, sizeof(vabuf), "%d %s@%s%s", crypto->use_aes ? 1 : 0, crypto->server_idfp, crypto->server_issigned ? "" : "~", pubkeys_fp64[CDATA->s]), false);
2535
2536 if(CDATA->c >= 0)
2537 {
2538 // client will auth next
2539 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\4\\id\\%d", CDATA->cdata_id));
2540 if(!qd0_blind_id_copy(CDATA->id, pubkeys[CDATA->c]))
2541 {
2543 return Crypto_ClientError(data_out, len_out, "d0_blind_id_copy failed");
2544 }
2545 if(!qd0_blind_id_authenticate_with_private_id_start(CDATA->id, true, false, "XONOTIC", 8, data_out_p, len_out)) // len_out receives used size by this op
2546 {
2548 return Crypto_ClientError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_start failed");
2549 }
2550 CDATA->next_step = 5;
2551 data_out_p += *len_out;
2552 *len_out = data_out_p - data_out;
2553 return CRYPTO_DISCARD;
2554 }
2555 else
2556 {
2557 // session key is FINISHED (no server part is to be expected)! By this, all keys are set up
2558 crypto->authenticated = true;
2559 CDATA->next_step = 0;
2560 // assume we got the empty challenge to finish the protocol
2561 PutWithNul(&data_out_p, len_out, "challenge ");
2562 *len_out = data_out_p - data_out;
2563 --*len_out; // remove NUL terminator
2564 return CRYPTO_REPLACE;
2565 }
2566 }
2567 else if(!strcmp(cnt, "5"))
2568 {
2569 size_t fpbuflen;
2570 unsigned char dhkey[DHKEY_SIZE];
2571 int i;
2572
2573 if(id >= 0)
2574 if(CDATA->cdata_id != id)
2575 return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
2576 if(CDATA->next_step != 5)
2577 return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
2578
2579 cls.connect_nextsendtime = max(cls.connect_nextsendtime, host.realtime + 1); // prevent "hammering"
2580
2581 if(CDATA->s < 0) // only if server didn't auth
2582 {
2583 if(InfoString_GetValue(string + 4, "aes", infostringvalue, sizeof(infostringvalue)))
2584 aes = atoi(infostringvalue);
2585 else
2586 aes = false;
2587 if(CDATA->wantserver_idfp[0]) // if we know a host key, honor its encryption setting
2588 if(!aes && CDATA->wantserver_aes)
2589 {
2591 return Crypto_ClientError(data_out, len_out, "Stored host key requires encryption, but server did not enable encryption");
2592 }
2593 if(aes && (!d0_rijndael_dll || crypto_aeslevel.integer <= 0))
2594 {
2596 return Crypto_ClientError(data_out, len_out, "Server insists on encryption too hard");
2597 }
2598 if(!aes && (d0_rijndael_dll && crypto_aeslevel.integer >= 3))
2599 {
2601 return Crypto_ClientError(data_out, len_out, "Server insists on plaintext too hard");
2602 }
2603 crypto->use_aes = aes != 0;
2604 }
2605
2606 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\6\\id\\%d", CDATA->cdata_id));
2607 if(!qd0_blind_id_authenticate_with_private_id_response(CDATA->id, data_in, len_in, data_out_p, len_out))
2608 {
2610 return Crypto_ClientError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_response failed");
2611 }
2612 fpbuflen = DHKEY_SIZE;
2613 if(!qd0_blind_id_sessionkey_public_id(CDATA->id, (char *) dhkey, &fpbuflen))
2614 {
2616 return Crypto_ClientError(data_out, len_out, "d0_blind_id_sessionkey_public_id failed");
2617 }
2618 // XOR the two DH keys together to make one
2619 for(i = 0; i < DHKEY_SIZE; ++i)
2620 crypto->dhkey[i] ^= dhkey[i];
2621 // session key is FINISHED! By this, all keys are set up
2622 crypto->authenticated = true;
2623 CDATA->next_step = 0;
2624 data_out_p += *len_out;
2625 *len_out = data_out_p - data_out;
2626 return CRYPTO_DISCARD;
2627 }
2628 return Crypto_SoftClientError(data_out, len_out, "Got unknown d0_blind_id message from server");
2629 }
2630
2631 return CRYPTO_NOMATCH;
2632}
client_static_t cls
Definition cl_main.c:116
size_t InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuesize)
Returns the number of bytes written to *value excluding the \0 terminator.
int BuffLittleLong(const unsigned char *buffer)
Extract a little endian 32bit int from the given buffer.
Definition com_msg.c:71
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
static int cdata_id
Definition crypto.c:509
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_challenge)(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL recv_modulus, const char *inbuf, size_t inbuflen, char *outbuf, size_t *outbuflen, D0_BOOL *status)
Definition crypto.c:223
#define D0_BOOL
Definition crypto.c:187
static D0_EXPORT D0_WARN_UNUSED_RESULT d0_blind_id_t *(* qd0_blind_id_new)(void)
Definition crypto.c:198
qbool Crypto_RetrieveHostKey(lhnetaddress_t *peeraddress, int *keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen, int *aeslevel, qbool *issigned)
Definition crypto.c:734
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sessionkey_public_id)(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
Definition crypto.c:227
#define CDATA
Definition crypto.c:524
static int Crypto_ClientError(char *data_out, size_t *len_out, const char *msg)
Definition crypto.c:2093
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_fingerprint64_public_id)(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
Definition crypto.c:226
#define MAKE_CDATA
Definition crypto.c:525
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_start)(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen)
Definition crypto.c:222
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_response)(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen, char *outbuf, size_t *outbuflen)
Definition crypto.c:224
static void Crypto_StoreHostKey(lhnetaddress_t *peeraddress, const char *keystring, qbool complain)
Definition crypto.c:635
static unsigned long Crypto_LittleLong(const char *data)
Definition crypto.c:59
static int Crypto_SoftClientError(char *data_out, size_t *len_out, const char *msg)
Definition crypto.c:2100
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_copy)(d0_blind_id_t *ctx, const d0_blind_id_t *src)
Definition crypto.c:201
#define CLEAR_CDATA
Definition crypto.c:526
cvar_t net_sourceaddresscheck
Definition netconn.c:87
static const char * GetUntilNul(const char **data, size_t *len)
Definition crypto.c:418
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_verify)(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen, char *msg, size_t *msglen, D0_BOOL *status)
Definition crypto.c:225
#define CRYPTO_DISCARD
Definition crypto.h:66
#define FP64_SIZE
Definition crypto.h:38
#define CRYPTO_NOMATCH
Definition crypto.h:64
GLenum GLuint id
Definition glquake.h:657
const GLdouble * v
Definition glquake.h:762
host_static_t host
Definition host.c:41
#define max(A, B)
Definition mathlib.h:38
#define bound(min, num, max)
Definition mathlib.h:34
#define CCREP_SERVER_INFO
Definition netconn.h:127
#define NETFLAG_CTL
Definition netconn.h:44
#define CCREP_PLAYER_INFO
Definition netconn.h:128
#define CCREP_RULE_INFO
Definition netconn.h:129
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
Definition qdefs.h:94
qbool connect_trying
Definition client.h:609
crypto_t crypto
Definition client.h:680
double connect_nextsendtime
Definition client.h:611
lhnetaddress_t connect_address
Definition client.h:613
char server_keyfp[FP64_SIZE+1]
Definition crypto.h:48
qbool server_issigned
Definition crypto.h:49
char client_idfp[FP64_SIZE+1]
Definition crypto.h:44
unsigned char dhkey[DHKEY_SIZE]
Definition crypto.h:43
char client_keyfp[FP64_SIZE+1]
Definition crypto.h:45
qbool authenticated
Definition crypto.h:50
qbool client_issigned
Definition crypto.h:46
char server_idfp[FP64_SIZE+1]
Definition crypto.h:47
qbool use_aes
Definition crypto.h:51
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46

References crypto_t::authenticated, bound, BuffLittleLong(), CCREP_PLAYER_INFO, CCREP_RULE_INFO, CCREP_SERVER_INFO, CDATA, cdata_id, CLEAR_CDATA, crypto_t::client_idfp, crypto_t::client_issigned, crypto_t::client_keyfp, cls, client_static_t::connect_address, client_static_t::connect_nextsendtime, client_static_t::connect_trying, client_static_t::crypto, crypto_aeslevel, Crypto_ClientError(), CRYPTO_DISCARD, Crypto_LittleLong(), CRYPTO_NOMATCH, CRYPTO_REPLACE, Crypto_RetrieveHostKey(), Crypto_SoftClientError(), Crypto_StoreHostKey(), d0_blind_id_dll, D0_BOOL, d0_rijndael_dll, crypto_t::dhkey, DHKEY_SIZE, dp_strlcpy, dpsnprintf(), FP64_SIZE, GetUntilNul(), host, i, id, InfoString_GetValue(), cvar_t::integer, LHNETADDRESS_Compare(), MAKE_CDATA, max, MAX_INPUTLINE, MAX_PUBKEYS, net_sourceaddresscheck, NETFLAG_CTL, NULL, PROTOCOL_D0_BLIND_ID, PROTOCOL_VLEN, pubkeys, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, pubkeys_priv_fp64, PutWithNul(), qd0_blind_id_authenticate_with_private_id_challenge, qd0_blind_id_authenticate_with_private_id_response, qd0_blind_id_authenticate_with_private_id_start, qd0_blind_id_authenticate_with_private_id_verify, qd0_blind_id_copy, qd0_blind_id_fingerprint64_public_id, qd0_blind_id_new, qd0_blind_id_sessionkey_public_id, host_static_t::realtime, crypto_t::server_idfp, crypto_t::server_issigned, crypto_t::server_keyfp, crypto_t::use_aes, v, and va().

Referenced by NetConn_ClientParsePacket().

◆ Crypto_CloseLibrary()

static void Crypto_CloseLibrary ( void )
static

Definition at line 306 of file crypto.c.

307{
309}
void Sys_FreeLibrary(dllhandle_t *handle)
Definition sys_shared.c:245

References d0_blind_id_dll, and Sys_FreeLibrary().

Referenced by Crypto_Init(), and Crypto_Shutdown().

◆ Crypto_d0_createmutex()

static void * Crypto_d0_createmutex ( void )
static

Definition at line 1020 of file crypto.c.

1021{
1022 return Thread_CreateMutex();
1023}
#define Thread_CreateMutex()
Definition thread.h:15

References Thread_CreateMutex.

Referenced by Crypto_Init().

◆ Crypto_d0_destroymutex()

static void Crypto_d0_destroymutex ( void * m)
static

Definition at line 1025 of file crypto.c.

1026{
1028}
#define Thread_DestroyMutex(m)
Definition thread.h:16

References Thread_DestroyMutex.

Referenced by Crypto_Init().

◆ Crypto_d0_free()

static void Crypto_d0_free ( void * p)
static

Definition at line 1015 of file crypto.c.

1016{
1017 Mem_Free(p);
1018}
#define Mem_Free(mem)
Definition zone.h:96

References Mem_Free.

Referenced by Crypto_Init().

◆ Crypto_d0_lockmutex()

static int Crypto_d0_lockmutex ( void * m)
static

Definition at line 1030 of file crypto.c.

1031{
1032 return Thread_LockMutex(m);
1033}
#define Thread_LockMutex(m)
Definition thread.h:17

References Thread_LockMutex.

Referenced by Crypto_Init().

◆ Crypto_d0_malloc()

static void * Crypto_d0_malloc ( size_t len)
static

Definition at line 1010 of file crypto.c.

1011{
1012 return Mem_Alloc(cryptomempool, len);
1013}
static mempool_t * cryptomempool
Definition crypto.c:1004
#define Mem_Alloc(pool, size)
Definition zone.h:92

References cryptomempool, and Mem_Alloc.

Referenced by Crypto_Init().

◆ Crypto_d0_unlockmutex()

static int Crypto_d0_unlockmutex ( void * m)
static

Definition at line 1035 of file crypto.c.

1036{
1037 return Thread_UnlockMutex(m);
1038}
#define Thread_UnlockMutex(m)
Definition thread.h:18

References Thread_UnlockMutex.

Referenced by Crypto_Init().

◆ Crypto_DecryptPacket()

const void * Crypto_DecryptPacket ( crypto_t * crypto,
const void * data_src,
size_t len_src,
void * data_dst,
size_t * len_dst,
size_t len )

Definition at line 1584 of file crypto.c.

1585{
1586 unsigned char h[32];
1587 int i;
1588
1589 // silently handle non-crypto packets
1590 i = BuffBigLong((unsigned char *) data_src);
1591 if(
1592 (i == (int)0xFFFFFFFF) // avoid QW control packet
1593 ||
1594 (i == (int)0x80000000 + (int)len_src) // avoid NQ control packet
1595 )
1596 return NULL;
1597
1598 if(crypto->authenticated)
1599 {
1600 if(crypto->use_aes)
1601 {
1602 if(len_src < 16 || ((len_src - 16) % 16))
1603 {
1604 Con_Printf("Crypto_DecryptPacket failed (not enough space: %d bytes in, %d bytes out)\n", (int) len_src, (int) len);
1605 return NULL;
1606 }
1607 *len_dst = len_src - ((unsigned char *) data_src)[0];
1608 if(len < *len_dst || *len_dst > len_src - 16)
1609 {
1610 Con_Printf("Crypto_DecryptPacket failed (not enough space: %d bytes in, %d->%d bytes out)\n", (int) len_src, (int) *len_dst, (int) len);
1611 return NULL;
1612 }
1613 seacpy(crypto->dhkey, (unsigned char *) data_src, (unsigned char *) data_dst, ((const unsigned char *) data_src) + 16, *len_dst);
1614 // IV dst src len
1615 if(!HMAC_SHA256_32BYTES(h, (const unsigned char *) data_dst, (int)*len_dst, crypto->dhkey, DHKEY_SIZE))
1616 {
1617 Con_Printf("HMAC fail\n");
1618 return NULL;
1619 }
1620 if(memcmp(((const unsigned char *) data_src)+1, h, 15)) // ignore first byte, used for length
1621 {
1622 Con_Printf("HMAC mismatch\n");
1623 return NULL;
1624 }
1626 {
1627 Con_Print("Decrypted:\n");
1628 Com_HexDumpToConsole((const unsigned char *) data_dst, (int)*len_dst);
1629 }
1630 return data_dst; // no need to copy
1631 }
1632 else
1633 {
1634 if(len_src < 16)
1635 {
1636 Con_Printf("Crypto_DecryptPacket failed (not enough space: %d bytes in, %d bytes out)\n", (int) len_src, (int) len);
1637 return NULL;
1638 }
1639 *len_dst = len_src - 16;
1640 if(len < *len_dst)
1641 {
1642 Con_Printf("Crypto_DecryptPacket failed (not enough space: %d bytes in, %d->%d bytes out)\n", (int) len_src, (int) *len_dst, (int) len);
1643 return NULL;
1644 }
1645 //memcpy(data_dst, data_src + 16, *len_dst);
1646 if(!HMAC_SHA256_32BYTES(h, ((const unsigned char *) data_src) + 16, (int)*len_dst, crypto->dhkey, DHKEY_SIZE))
1647 {
1648 Con_Printf("HMAC fail\n");
1649 Com_HexDumpToConsole((const unsigned char *) data_src, (int)len_src);
1650 return NULL;
1651 }
1652
1653 if(memcmp((const unsigned char *) data_src, h, 16)) // ignore first byte, used for length
1654 {
1655 // undo the "avoid conditions"
1656 if(
1657 (i == (int)0x7FFFFFFF) // avoided QW control packet
1658 ||
1659 (i == (int)0x00000000 + (int)len_src) // avoided NQ control packet
1660 )
1661 {
1662 // do the avoidance on the hash too
1663 h[0] ^= 0x80;
1664 if(memcmp((const unsigned char *) data_src, h, 16)) // ignore first byte, used for length
1665 {
1666 Con_Printf("HMAC mismatch\n");
1667 Com_HexDumpToConsole((const unsigned char *) data_src, (int)len_src);
1668 return NULL;
1669 }
1670 }
1671 else
1672 {
1673 Con_Printf("HMAC mismatch\n");
1674 Com_HexDumpToConsole((const unsigned char *) data_src, (int)len_src);
1675 return NULL;
1676 }
1677 }
1678 return ((const unsigned char *) data_src) + 16; // no need to copy, so data_dst is not used
1679 }
1680 }
1681 else
1682 {
1683 *len_dst = len_src;
1684 return data_src;
1685 }
1686}
int BuffBigLong(const unsigned char *buffer)
Extract a big endian 32bit int from the given buffer.
Definition com_msg.c:49
void Com_HexDumpToConsole(const unsigned char *data, int size)
Definition common.c:82
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
static void seacpy(unsigned char *key, const unsigned char *iv, unsigned char *dst, const unsigned char *src, size_t len)
Definition crypto.c:1498
#define HMAC_SHA256_32BYTES(out, in, n, key, k)
Definition hmac.h:15
cvar_t developer_networking
Definition netconn.c:89

References crypto_t::authenticated, BuffBigLong(), Com_HexDumpToConsole(), Con_Print(), Con_Printf(), developer_networking, crypto_t::dhkey, DHKEY_SIZE, HMAC_SHA256_32BYTES, i, cvar_t::integer, NULL, seacpy(), and crypto_t::use_aes.

Referenced by NetConn_ReceivedMessage().

◆ Crypto_EncryptPacket()

const void * Crypto_EncryptPacket ( crypto_t * crypto,
const void * data_src,
size_t len_src,
void * data_dst,
size_t * len_dst,
size_t len )

Definition at line 1527 of file crypto.c.

1528{
1529 unsigned char h[32];
1530 int i;
1531 if(crypto->authenticated)
1532 {
1533 if(crypto->use_aes)
1534 {
1535 // AES packet = 1 byte length overhead, 15 bytes from HMAC-SHA-256, data, 0..15 bytes padding
1536 // 15 bytes HMAC-SHA-256 (112bit) suffice as the attacker can't do more than forge a random-looking packet
1537 // HMAC is needed to not leak information about packet content
1539 {
1540 Con_Print("To be encrypted:\n");
1541 Com_HexDumpToConsole((const unsigned char *) data_src, (int)len_src);
1542 }
1543 if(len_src + 32 > len || !HMAC_SHA256_32BYTES(h, (const unsigned char *) data_src, (int)len_src, crypto->dhkey, DHKEY_SIZE))
1544 {
1545 Con_Printf("Crypto_EncryptPacket failed (not enough space: %d bytes in, %d bytes out)\n", (int) len_src, (int) len);
1546 return NULL;
1547 }
1548 *len_dst = ((len_src + 15) / 16) * 16 + 16; // add 16 for HMAC, then round to 16-size for AES
1549 ((unsigned char *) data_dst)[0] = (unsigned char)(*len_dst - len_src);
1550 memcpy(((unsigned char *) data_dst)+1, h, 15);
1551 aescpy(crypto->dhkey, (const unsigned char *) data_dst, ((unsigned char *) data_dst) + 16, (const unsigned char *) data_src, len_src);
1552 // IV dst src len
1553 }
1554 else
1555 {
1556 // HMAC packet = 16 bytes HMAC-SHA-256 (truncated to 128 bits), data
1557 if(len_src + 16 > len || !HMAC_SHA256_32BYTES(h, (const unsigned char *) data_src, (int)len_src, crypto->dhkey, DHKEY_SIZE))
1558 {
1559 Con_Printf("Crypto_EncryptPacket failed (not enough space: %d bytes in, %d bytes out)\n", (int) len_src, (int) len);
1560 return NULL;
1561 }
1562 *len_dst = len_src + 16;
1563 memcpy(data_dst, h, 16);
1564 memcpy(((unsigned char *) data_dst) + 16, (unsigned char *) data_src, len_src);
1565
1566 // handle the "avoid" conditions:
1567 i = BuffBigLong((unsigned char *) data_dst);
1568 if(
1569 (i == (int)0xFFFFFFFF) // avoid QW control packet
1570 ||
1571 (i == (int)0x80000000 + (int)*len_dst) // avoid NQ control packet
1572 )
1573 *(unsigned char *)data_dst ^= 0x80; // this will ALWAYS fix it
1574 }
1575 return data_dst;
1576 }
1577 else
1578 {
1579 *len_dst = len_src;
1580 return data_src;
1581 }
1582}
static void aescpy(unsigned char *key, const unsigned char *iv, unsigned char *dst, const unsigned char *src, size_t len)
Definition crypto.c:1472

References aescpy(), crypto_t::authenticated, BuffBigLong(), Com_HexDumpToConsole(), Con_Print(), Con_Printf(), developer_networking, crypto_t::dhkey, DHKEY_SIZE, HMAC_SHA256_32BYTES, i, cvar_t::integer, NULL, and crypto_t::use_aes.

Referenced by NetConn_ReceivedMessage(), and NetConn_SendUnreliableMessage().

◆ Crypto_FinishInstance()

qbool Crypto_FinishInstance ( crypto_t * out,
crypto_t * crypto )

Definition at line 558 of file crypto.c.

559{
560 // no check needed here (returned pointers are only used in prefilled fields)
561 if(!crypto || !crypto->authenticated)
562 {
563 Con_Printf("Passed an invalid crypto connect instance\n");
564 memset(out, 0, sizeof(*out));
565 return false;
566 }
568 memcpy(out, crypto, sizeof(*out));
569 memset(crypto, 0, sizeof(*crypto));
570 return true;
571}

References crypto_t::authenticated, CLEAR_CDATA, and Con_Printf().

Referenced by NetConn_ConnectionEstablished(), and NetConn_ServerParsePacket().

◆ Crypto_GetInfoResponseDataString()

const char * Crypto_GetInfoResponseDataString ( void )

Definition at line 1689 of file crypto.c.

1690{
1692 return crypto_idstring;
1693}

References crypto_aeslevel, crypto_idstring, crypto_idstring_buf, and cvar_t::integer.

Referenced by NetConn_BuildStatusResponse().

◆ Crypto_HostKey_Clear_f()

static void Crypto_HostKey_Clear_f ( cmd_state_t * cmd)
static

Definition at line 1428 of file crypto.c.

1429{
1431 int i;
1432
1433 if(!d0_blind_id_dll)
1434 {
1435 Con_Print("libd0_blind_id DLL not found, this command is inactive.\n");
1436 return;
1437 }
1438
1439 for(i = 1; i < Cmd_Argc(cmd); ++i)
1440 {
1443 {
1444 Con_Printf("cleared host key for %s\n", Cmd_Argv(cmd, i));
1445 }
1446 }
1447}
static int Cmd_Argc(cmd_state_t *cmd)
Definition cmd.h:249
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
Definition cmd.h:254
static qbool Crypto_ClearHostKey(lhnetaddress_t *peeraddress)
Definition crypto.c:613
int LHNETADDRESS_FromString(lhnetaddress_t *vaddress, const char *string, int defaultport)
Definition lhnet.c:204
void cmd(string command,...)
prvm_uint_t addr

References addr, cmd(), Cmd_Argc(), Cmd_Argv(), Con_Print(), Con_Printf(), Crypto_ClearHostKey(), d0_blind_id_dll, i, and LHNETADDRESS_FromString().

Referenced by Crypto_Init_Commands().

◆ Crypto_HostKeys_f()

static void Crypto_HostKeys_f ( cmd_state_t * cmd)
static

Definition at line 1403 of file crypto.c.

1404{
1405 int i;
1407 char buf[128];
1408
1409 if(!d0_blind_id_dll)
1410 {
1411 Con_Print("libd0_blind_id DLL not found, this command is inactive.\n");
1412 return;
1413 }
1414 for(i = 0; i < CRYPTO_HOSTKEY_HASHSIZE; ++i)
1415 {
1416 for(hk = crypto_storedhostkey_hashtable[i]; hk; hk = hk->next)
1417 {
1418 LHNETADDRESS_ToString(&hk->addr, buf, sizeof(buf), 1);
1419 Con_Printf("%d %s@%.*s %s\n",
1420 hk->aeslevel,
1421 hk->idfp,
1423 buf);
1424 }
1425 }
1426}
int crypto_keyfp_recommended_length
Definition crypto.c:41
char idfp[FP64_SIZE+1]
Definition crypto.c:584
lhnetaddress_t addr
Definition crypto.c:582

References crypto_storedhostkey_t::addr, crypto_storedhostkey_t::aeslevel, buf, Con_Print(), Con_Printf(), CRYPTO_HOSTKEY_HASHSIZE, crypto_keyfp_recommended_length, crypto_storedhostkey_hashtable, d0_blind_id_dll, i, crypto_storedhostkey_t::idfp, crypto_storedhostkey_t::keyid, LHNETADDRESS_ToString(), crypto_storedhostkey_t::next, and pubkeys_fp64.

Referenced by Crypto_Init_Commands().

◆ Crypto_Init()

void Crypto_Init ( void )

Definition at line 1072 of file crypto.c.

1073{
1074 cryptomempool = Mem_AllocPool("crypto", 0, NULL);
1075
1076 if(!Crypto_OpenLibrary())
1077 return;
1078
1080 if (Thread_HasThreads())
1082
1084 {
1087 Con_Printf("libd0_blind_id initialization FAILED, cryptography support has been disabled\n");
1088 return;
1089 }
1090
1091 (void) Crypto_Rijndael_OpenLibrary(); // if this fails, it's uncritical
1092
1094}
static void Crypto_d0_free(void *p)
Definition crypto.c:1015
static void Crypto_d0_destroymutex(void *m)
Definition crypto.c:1025
static int Crypto_d0_lockmutex(void *m)
Definition crypto.c:1030
static void Crypto_InitHostKeys(void)
Definition crypto.c:591
static D0_EXPORT void(* qd0_blind_id_setmallocfuncs)(d0_malloc_t *m, d0_free_t *f)
Definition crypto.c:233
static qbool Crypto_OpenLibrary(void)
Definition crypto.c:283
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_INITIALIZE)(void)
Definition crypto.c:228
static qbool Crypto_Rijndael_OpenLibrary(void)
Definition crypto.c:352
static void Crypto_Rijndael_CloseLibrary(void)
Definition crypto.c:375
static int Crypto_d0_unlockmutex(void *m)
Definition crypto.c:1035
static void Crypto_CloseLibrary(void)
Definition crypto.c:306
static void * Crypto_d0_malloc(size_t len)
Definition crypto.c:1010
static void * Crypto_d0_createmutex(void)
Definition crypto.c:1020
static D0_EXPORT void(* qd0_blind_id_setmutexfuncs)(d0_createmutex_t *c, d0_destroymutex_t *d, d0_lockmutex_t *l, d0_unlockmutex_t *u)
Definition crypto.c:234
void() predraw
qbool Thread_HasThreads(void)
Definition thread_null.c:13
#define Mem_AllocPool(name, flags, parent)
Definition zone.h:104

References Con_Printf(), Crypto_CloseLibrary(), Crypto_d0_createmutex(), Crypto_d0_destroymutex(), Crypto_d0_free(), Crypto_d0_lockmutex(), Crypto_d0_malloc(), Crypto_d0_unlockmutex(), Crypto_InitHostKeys(), Crypto_OpenLibrary(), Crypto_Rijndael_CloseLibrary(), Crypto_Rijndael_OpenLibrary(), cryptomempool, Mem_AllocPool, NULL, qd0_blind_id_INITIALIZE, qd0_blind_id_setmallocfuncs, qd0_blind_id_setmutexfuncs, Thread_HasThreads(), and void().

Referenced by Host_Init().

◆ Crypto_Init_Commands()

void Crypto_Init_Commands ( void )

Definition at line 1449 of file crypto.c.

1450{
1451 if(d0_blind_id_dll)
1452 {
1453 Cmd_AddCommand(CF_SHARED, "crypto_reload", Crypto_Reload_f, "reloads cryptographic keys");
1454 Cmd_AddCommand(CF_SHARED, "crypto_keygen", Crypto_KeyGen_f, "generates and saves a cryptographic key");
1455 Cmd_AddCommand(CF_SHARED, "crypto_keys", Crypto_Keys_f, "lists the loaded keys");
1456 Cmd_AddCommand(CF_SHARED, "crypto_hostkeys", Crypto_HostKeys_f, "lists the cached host keys");
1457 Cmd_AddCommand(CF_SHARED, "crypto_hostkey_clear", Crypto_HostKey_Clear_f, "clears a cached host key");
1458
1460 if(d0_rijndael_dll)
1462 else
1463 crypto_aeslevel.integer = 0; // make sure
1467 }
1468}
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1661
#define CF_SHARED
Definition cmd.h:67
static void Crypto_Reload_f(cmd_state_t *cmd)
Definition crypto.c:1373
cvar_t crypto_servercpupercent
Definition crypto.c:33
cvar_t crypto_developer
Definition crypto.c:30
cvar_t crypto_servercpumaxtime
Definition crypto.c:34
cvar_t crypto_servercpudebug
Definition crypto.c:35
static void Crypto_HostKeys_f(cmd_state_t *cmd)
Definition crypto.c:1403
static void Crypto_KeyGen_f(cmd_state_t *cmd)
Definition crypto.c:1217
static void Crypto_HostKey_Clear_f(cmd_state_t *cmd)
Definition crypto.c:1428
static void Crypto_Keys_f(cmd_state_t *cmd)
Definition crypto.c:1380
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599

References CF_SHARED, Cmd_AddCommand(), crypto_aeslevel, crypto_developer, Crypto_HostKey_Clear_f(), Crypto_HostKeys_f(), Crypto_KeyGen_f(), Crypto_Keys_f(), Crypto_Reload_f(), crypto_servercpudebug, crypto_servercpumaxtime, crypto_servercpupercent, Cvar_RegisterVariable(), d0_blind_id_dll, d0_rijndael_dll, and cvar_t::integer.

Referenced by Host_Init().

◆ Crypto_InitHostKeys()

static void Crypto_InitHostKeys ( void )
static

Definition at line 591 of file crypto.c.

592{
593 int i;
594 for(i = 0; i < CRYPTO_HOSTKEY_HASHSIZE; ++i)
596}

References CRYPTO_HOSTKEY_HASHSIZE, crypto_storedhostkey_hashtable, i, and NULL.

Referenced by Crypto_Init().

◆ Crypto_KeyGen_f()

static void Crypto_KeyGen_f ( cmd_state_t * cmd)
static

Definition at line 1217 of file crypto.c.

1218{
1219 int i;
1220 const char *p[1];
1221 size_t l[1];
1222 static char buf[8192];
1223 static char buf2[8192];
1224 size_t buf2size;
1225 size_t buf2l, buf2pos;
1226 char vabuf[1024];
1227 size_t len2;
1228 qfile_t *f = NULL;
1229
1230 if(!d0_blind_id_dll)
1231 {
1232 Con_Print("libd0_blind_id DLL not found, this command is inactive.\n");
1233 return;
1234 }
1235 if(Cmd_Argc(cmd) != 3)
1236 {
1237 Con_Printf("usage:\n%s id url\n", Cmd_Argv(cmd, 0));
1238 return;
1239 }
1242 i = atoi(Cmd_Argv(cmd, 1));
1243 if(!pubkeys[i])
1244 {
1245 Con_Printf("there is no public key %d\n", i);
1247 return;
1248 }
1249 if(keygen_i >= 0)
1250 {
1251 Con_Printf("there is already a keygen run on the way\n");
1253 return;
1254 }
1255 keygen_i = i;
1256
1257 // how to START the keygenning...
1259 {
1261 {
1262 Con_Printf("there is already a signed private key for %d\n", i);
1263 keygen_i = -1;
1265 return;
1266 }
1267 // if we get here, we only need a signature, no new keygen run needed
1268 Con_Printf("Only need a signature for an existing key...\n");
1269 }
1270 else
1271 {
1272 // we also need a new ID itself
1274 {
1275 Con_Printf("d0_blind_id_start failed\n");
1276 keygen_i = -1;
1278 return;
1279 }
1280 // verify the key we just got (just in case)
1282 {
1283 Con_Printf("d0_blind_id_verify_private_id failed\n");
1284 keygen_i = -1;
1286 return;
1287 }
1288 // we have a valid key now!
1289 // make the rest of crypto.c know that
1290 len2 = FP64_SIZE;
1292 {
1293 Con_Printf("Generated private ID key_%d.d0pk (public key fingerprint: %s)\n", keygen_i, pubkeys_priv_fp64[keygen_i]);
1294 pubkeys_havepriv[keygen_i] = true;
1298 }
1299 // write the key to disk
1300 p[0] = buf;
1301 l[0] = sizeof(buf);
1303 {
1304 Con_Printf("d0_blind_id_write_private_id failed\n");
1305 keygen_i = -1;
1307 return;
1308 }
1309 if(!(buf2size = Crypto_UnParsePack(buf2, sizeof(buf2), FOURCC_D0SI, p, l, 1)))
1310 {
1311 Con_Printf("Crypto_UnParsePack failed\n");
1312 keygen_i = -1;
1314 return;
1315 }
1316
1317 FS_CreatePath(va(vabuf, sizeof(vabuf), "%skey_%d.d0si%s", *fs_userdir ? fs_userdir : fs_basedir, keygen_i, sessionid.string));
1318 f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%skey_%d.d0si%s", *fs_userdir ? fs_userdir : fs_basedir, keygen_i, sessionid.string), "wb", false);
1319 if(!f)
1320 {
1321 Con_Printf("Cannot open key_%d.d0si%s\n", keygen_i, sessionid.string);
1322 keygen_i = -1;
1324 return;
1325 }
1326 FS_Write(f, buf2, buf2size);
1327 FS_Close(f);
1328
1330
1331 Con_Printf("Saved unsigned key to key_%d.d0si%s\n", keygen_i, sessionid.string);
1332 }
1333 p[0] = buf;
1334 l[0] = sizeof(buf);
1336 {
1337 Con_Printf("d0_blind_id_generate_private_id_request failed\n");
1338 keygen_i = -1;
1340 return;
1341 }
1342 buf2pos = strlen(Cmd_Argv(cmd, 2));
1343 memcpy(buf2, Cmd_Argv(cmd, 2), buf2pos);
1344 if(!(buf2l = Crypto_UnParsePack(buf2 + buf2pos, sizeof(buf2) - buf2pos - 1, FOURCC_D0IQ, p, l, 1)))
1345 {
1346 Con_Printf("Crypto_UnParsePack failed\n");
1347 keygen_i = -1;
1349 return;
1350 }
1351 if(!(buf2l = base64_encode((unsigned char *) (buf2 + buf2pos), buf2l, sizeof(buf2) - buf2pos - 1)))
1352 {
1353 Con_Printf("base64_encode failed\n");
1354 keygen_i = -1;
1356 return;
1357 }
1358 buf2l += buf2pos;
1359 buf2[buf2l] = 0;
1360 if(!Curl_Begin_ToMemory(buf2, 0, (unsigned char *) keygen_buf, sizeof(keygen_buf), Crypto_KeyGen_Finished, NULL))
1361 {
1362 Con_Printf("curl failed\n");
1363 keygen_i = -1;
1365 return;
1366 }
1367 Con_Printf("Signature generation in progress...\n");
1369}
size_t base64_encode(unsigned char *buf, size_t buflen, size_t outbuflen)
Definition common.c:1502
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_generate_private_id_request)(d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
Definition crypto.c:213
void Crypto_LoadKeys(void)
Definition crypto.c:855
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_write_private_id)(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
Definition crypto.c:220
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_verify_private_id)(const d0_blind_id_t *ctx)
Definition crypto.c:236
static size_t Crypto_UnParsePack(char *buf, size_t len, unsigned long header, const char *const *lumps, const size_t *lumpsize, size_t nlumps)
Definition crypto.c:103
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_generate_private_id_start)(d0_blind_id_t *ctx)
Definition crypto.c:212
static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned char *buffer, void *cbdata)
Definition crypto.c:1105
static qbool Crypto_SavePubKeyTextFile(int i)
Definition crypto.c:814
static char keygen_buf[8192]
Definition crypto.c:491
#define FOURCC_D0IQ
Definition crypto.c:54
static int keygen_i
Definition crypto.c:490
static void Crypto_BuildChallengeAppend(void)
Definition crypto.c:785
fs_offset_t FS_Write(qfile_t *file, const void *data, size_t datasize)
Definition fs.c:3019
qfile_t * FS_SysOpen(const char *filepath, const char *mode, qbool nonblocking)
Definition fs.c:2484
int FS_Close(qfile_t *file)
Definition fs.c:2970
void FS_CreatePath(char *path)
Definition fs.c:1028
char fs_basedir[MAX_OSPATH]
Definition fs.c:444
char fs_userdir[MAX_OSPATH]
Definition fs.c:442
cvar_t sessionid
Definition host.c:58
qbool Curl_Begin_ToMemory(const char *URL, double maxspeed, unsigned char *buf, size_t bufsize, curl_callback_t callback, void *cbdata)
Definition libcurl.c:1117
#define SV_LockThreadMutex()
Definition server.h:606
#define SV_UnlockThreadMutex()
Definition server.h:607
float f
const char * string
Definition cvar.h:71

References base64_encode(), buf, cmd(), Cmd_Argc(), Cmd_Argv(), Con_Print(), Con_Printf(), Crypto_BuildChallengeAppend(), crypto_idstring, crypto_idstring_buf, Crypto_KeyGen_Finished(), Crypto_LoadKeys(), Crypto_SavePubKeyTextFile(), Crypto_UnParsePack(), Curl_Begin_ToMemory(), d0_blind_id_dll, dp_strlcat, f, FOURCC_D0IQ, FOURCC_D0SI, FP64_SIZE, fs_basedir, FS_Close(), FS_CreatePath(), FS_SysOpen(), fs_userdir, FS_Write(), i, keygen_buf, keygen_i, NULL, pubkeys, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, pubkeys_priv_fp64, qd0_blind_id_fingerprint64_public_id, qd0_blind_id_generate_private_id_request, qd0_blind_id_generate_private_id_start, qd0_blind_id_verify_private_id, qd0_blind_id_write_private_id, sessionid, cvar_t::string, strlen(), SV_LockThreadMutex, SV_UnlockThreadMutex, and va().

Referenced by Crypto_Init_Commands().

◆ Crypto_KeyGen_Finished()

static void Crypto_KeyGen_Finished ( int code,
size_t length_received,
unsigned char * buffer,
void * cbdata )
static

Definition at line 1105 of file crypto.c.

1106{
1107 const char *p[1];
1108 size_t l[1];
1109 static char buf[8192];
1110 static char buf2[8192];
1111 size_t buf2size;
1112 qfile_t *f = NULL;
1113 D0_BOOL status;
1114 char vabuf[1024];
1115
1117
1118 if(!d0_blind_id_dll)
1119 {
1120 Con_Print("libd0_blind_id DLL not found, this command is inactive.\n");
1121 keygen_i = -1;
1123 return;
1124 }
1125
1126 if(keygen_i < 0)
1127 {
1128 Con_Printf("Unexpected response from keygen server:\n");
1129 Com_HexDumpToConsole(buffer, (int)length_received);
1131 return;
1132 }
1134 {
1135 Con_Printf("overflow of keygen_i\n");
1136 keygen_i = -1;
1138 return;
1139 }
1140 if(!Crypto_ParsePack((const char *) buffer, length_received, FOURCC_D0IR, p, l, 1))
1141 {
1142 if(length_received >= 5 && Crypto_LittleLong((const char *) buffer) == FOURCC_D0ER)
1143 {
1144 Con_Printf(CON_ERROR "Error response from keygen server: %.*s\n", (int)(length_received - 5), buffer + 5);
1145 }
1146 else
1147 {
1148 Con_Printf(CON_ERROR "Invalid response from keygen server:\n");
1149 Com_HexDumpToConsole(buffer, (int)length_received);
1150 }
1151 keygen_i = -1;
1153 return;
1154 }
1156 {
1157 Con_Printf("d0_blind_id_finish_private_id_request failed\n");
1158 keygen_i = -1;
1160 return;
1161 }
1162
1163 // verify the key we just got (just in case)
1164 if(!qd0_blind_id_verify_public_id(pubkeys[keygen_i], &status) || !status)
1165 {
1166 Con_Printf("d0_blind_id_verify_public_id failed\n");
1167 keygen_i = -1;
1169 return;
1170 }
1171
1172 // we have a valid key now!
1173 // make the rest of crypto.c know that
1174 Con_Printf("Received signature for private ID key_%d.d0pk (public key fingerprint: %s)\n", keygen_i, pubkeys_priv_fp64[keygen_i]);
1175 pubkeys_havesig[keygen_i] = true;
1176
1177 // write the key to disk
1178 p[0] = buf;
1179 l[0] = sizeof(buf);
1181 {
1182 Con_Printf("d0_blind_id_write_private_id failed\n");
1183 keygen_i = -1;
1185 return;
1186 }
1187 if(!(buf2size = Crypto_UnParsePack(buf2, sizeof(buf2), FOURCC_D0SI, p, l, 1)))
1188 {
1189 Con_Printf("Crypto_UnParsePack failed\n");
1190 keygen_i = -1;
1192 return;
1193 }
1194
1195 FS_CreatePath(va(vabuf, sizeof(vabuf), "%skey_%d.d0si%s", *fs_userdir ? fs_userdir : fs_basedir, keygen_i, sessionid.string));
1196 f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%skey_%d.d0si%s", *fs_userdir ? fs_userdir : fs_basedir, keygen_i, sessionid.string), "wb", false);
1197 if(!f)
1198 {
1199 Con_Printf("Cannot open key_%d.d0si%s\n", keygen_i, sessionid.string);
1200 keygen_i = -1;
1202 return;
1203 }
1204 FS_Write(f, buf2, buf2size);
1205 FS_Close(f);
1206
1208
1209 Con_Printf("Saved to key_%d.d0si%s\n", keygen_i, sessionid.string);
1210
1212
1213 keygen_i = -1;
1215}
#define CON_ERROR
Definition console.h:102
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_verify_public_id)(const d0_blind_id_t *ctx, D0_BOOL *status)
Definition crypto.c:235
static void Crypto_BuildIdString(void)
Definition crypto.c:842
#define FOURCC_D0IR
Definition crypto.c:55
#define FOURCC_D0ER
Definition crypto.c:56
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_finish_private_id_request)(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
Definition crypto.c:215
GLuint buffer
Definition glquake.h:630

References buf, buffer, Com_HexDumpToConsole(), CON_ERROR, Con_Print(), Con_Printf(), Crypto_BuildIdString(), Crypto_LittleLong(), Crypto_ParsePack(), Crypto_SavePubKeyTextFile(), Crypto_UnParsePack(), d0_blind_id_dll, D0_BOOL, f, FOURCC_D0ER, FOURCC_D0IR, FOURCC_D0SI, fs_basedir, FS_Close(), FS_CreatePath(), FS_SysOpen(), fs_userdir, FS_Write(), keygen_i, MAX_PUBKEYS, NULL, pubkeys, pubkeys_havesig, pubkeys_priv_fp64, qd0_blind_id_finish_private_id_request, qd0_blind_id_verify_public_id, qd0_blind_id_write_private_id, sessionid, cvar_t::string, SV_LockThreadMutex, SV_UnlockThreadMutex, and va().

Referenced by Crypto_KeyGen_f().

◆ Crypto_Keys_f()

static void Crypto_Keys_f ( cmd_state_t * cmd)
static

Definition at line 1380 of file crypto.c.

1381{
1382 int i;
1383 if(!d0_blind_id_dll)
1384 {
1385 Con_Print("libd0_blind_id DLL not found, this command is inactive.\n");
1386 return;
1387 }
1388 for(i = 0; i < MAX_PUBKEYS; ++i)
1389 {
1390 if(pubkeys[i])
1391 {
1392 Con_Printf("%2d: public key key_%d.d0pk (fingerprint: %s)\n", i, i, pubkeys_fp64[i]);
1393 if(pubkeys_havepriv[i])
1394 {
1395 Con_Printf(" private ID key_%d.d0si%s (public key fingerprint: %s)\n", i, sessionid.string, pubkeys_priv_fp64[i]);
1396 if(!pubkeys_havesig[i])
1397 Con_Printf(" NOTE: this ID has not yet been signed!\n");
1398 }
1399 }
1400 }
1401}

References Con_Print(), Con_Printf(), d0_blind_id_dll, i, MAX_PUBKEYS, pubkeys, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, pubkeys_priv_fp64, sessionid, and cvar_t::string.

Referenced by Crypto_Init_Commands().

◆ Crypto_LittleLong()

static unsigned long Crypto_LittleLong ( const char * data)
static

Definition at line 59 of file crypto.c.

60{
61 return
62 ((unsigned char) data[0]) |
63 (((unsigned char) data[1]) << 8) |
64 (((unsigned char) data[2]) << 16) |
65 (((unsigned char) data[3]) << 24);
66}
GLsizeiptr const GLvoid * data
Definition glquake.h:639

References data.

Referenced by Crypto_ClientParsePacket(), Crypto_KeyGen_Finished(), and Crypto_ParsePack().

◆ Crypto_LoadFile()

static size_t Crypto_LoadFile ( const char * path,
char * buf,
size_t nmax,
qbool inuserdir )
static

Definition at line 388 of file crypto.c.

389{
390 char vabuf[1024];
391 qfile_t *f = NULL;
393 if(inuserdir)
394 f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%s%s", *fs_userdir ? fs_userdir : fs_basedir, path), "rb", false);
395 else
396 f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%s%s", fs_basedir, path), "rb", false);
397 if(!f)
398 return 0;
399 n = FS_Read(f, buf, nmax);
400 if(n < 0)
401 n = 0;
402 FS_Close(f);
403 return (size_t) n;
404}
fs_offset_t FS_Read(qfile_t *file, void *buffer, size_t buffersize)
Definition fs.c:3066
int64_t fs_offset_t
Definition fs.h:37

References buf, f, fs_basedir, FS_Close(), FS_Read(), FS_SysOpen(), fs_userdir, n, NULL, and va().

Referenced by Crypto_LoadKeys().

◆ Crypto_LoadKeys()

void Crypto_LoadKeys ( void )

Definition at line 855 of file crypto.c.

856{
857 char buf[8192];
858 size_t len, len2;
859 int i;
860 char vabuf[1024];
861
862 if(!d0_blind_id_dll) // don't if we can't
863 return;
864
865 if(crypto_idstring) // already loaded? then not
866 return;
867
868 Host_LockSession(); // we use the session ID here
869
870 // load keys
871 // note: we are just a CLIENT
872 // so we load:
873 // PUBLIC KEYS to accept (including modulus)
874 // PRIVATE KEY of user
875
876 for(i = 0; i < MAX_PUBKEYS; ++i)
877 {
878 memset(pubkeys_fp64[i], 0, sizeof(pubkeys_fp64[i]));
879 memset(pubkeys_priv_fp64[i], 0, sizeof(pubkeys_fp64[i]));
880 pubkeys_havepriv[i] = false;
881 pubkeys_havesig[i] = false;
882 len = Crypto_LoadFile(va(vabuf, sizeof(vabuf), "key_%d.d0pk", i), buf, sizeof(buf), false);
883 if((pubkeys[i] = Crypto_ReadPublicKey(buf, len)))
884 {
885 len2 = FP64_SIZE;
886 if(qd0_blind_id_fingerprint64_public_key(pubkeys[i], pubkeys_fp64[i], &len2)) // keeps final NUL
887 {
888 Con_Printf("Loaded public key key_%d.d0pk (fingerprint: %s)\n", i, pubkeys_fp64[i]);
889 len = Crypto_LoadFile(va(vabuf, sizeof(vabuf), "key_%d.d0si%s", i, sessionid.string), buf, sizeof(buf), true);
890 if(len)
891 {
893 {
894 len2 = FP64_SIZE;
895 if(qd0_blind_id_fingerprint64_public_id(pubkeys[i], pubkeys_priv_fp64[i], &len2)) // keeps final NUL
896 {
897 D0_BOOL status = 0;
898
899 Con_Printf("Loaded private ID key_%d.d0si%s for key_%d.d0pk (public key fingerprint: %s)\n", i, sessionid.string, i, pubkeys_priv_fp64[i]);
900
901 // verify the key we just loaded (just in case)
903 {
904 pubkeys_havepriv[i] = true;
905 pubkeys_havesig[i] = status;
906
907 // verify the key we just got (just in case)
908 if(!status)
909 Con_Printf("NOTE: this ID has not yet been signed!\n");
910
912 }
913 else
914 {
915 Con_Printf("d0_blind_id_verify_private_id failed, this is not a valid key!\n");
917 pubkeys[i] = NULL;
918 }
919 }
920 else
921 {
922 Con_Printf("d0_blind_id_fingerprint64_public_id failed\n");
924 pubkeys[i] = NULL;
925 }
926 }
927 }
928 }
929 else
930 {
931 // can't really happen
933 pubkeys[i] = NULL;
934 }
935 }
936 }
937
938 keygen_i = -1;
941
942 // find a good prefix length for all the keys we know (yes, algorithm is not perfect yet, may yield too long prefix length)
944 memset(buf+256, 0, MAX_PUBKEYS + MAX_PUBKEYS);
946 {
947 memset(buf, 0, 256);
948 for(i = 0; i < MAX_PUBKEYS; ++i)
949 if(pubkeys[i])
950 {
951 if(!buf[256 + i])
954 if(!buf[256 + MAX_PUBKEYS + i])
956 }
957 for(i = 0; i < MAX_PUBKEYS; ++i)
958 if(pubkeys[i])
959 {
960 if(!buf[256 + i])
961 if(buf[(unsigned char) pubkeys_fp64[i][crypto_keyfp_recommended_length]] < 2)
962 buf[256 + i] = 1;
964 if(!buf[256 + MAX_PUBKEYS + i])
965 if(buf[(unsigned char) pubkeys_priv_fp64[i][crypto_keyfp_recommended_length]] < 2)
966 buf[256 + MAX_PUBKEYS + i] = 1;
967 }
969 for(i = 0; i < MAX_PUBKEYS; ++i)
970 if(pubkeys[i])
971 {
972 if(!buf[256 + i])
973 break;
975 if(!buf[256 + MAX_PUBKEYS + i])
976 break;
977 }
978 if(i >= MAX_PUBKEYS)
979 break;
980 }
983}
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_fingerprint64_public_key)(const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen)
Definition crypto.c:208
static d0_blind_id_t * Crypto_ReadPublicKey(char *buf, size_t len)
Definition crypto.c:450
static D0_EXPORT void(* qd0_blind_id_free)(d0_blind_id_t *a)
Definition crypto.c:199
static size_t Crypto_LoadFile(const char *path, char *buf, size_t nmax, qbool inuserdir)
Definition crypto.c:388
static qbool Crypto_AddPrivateKey(d0_blind_id_t *pk, char *buf, size_t len)
Definition crypto.c:469
void Host_LockSession(void)
Definition host.c:330

References buf, Con_Printf(), Crypto_AddPrivateKey(), Crypto_BuildChallengeAppend(), Crypto_BuildIdString(), crypto_idstring, crypto_keyfp_recommended_length, Crypto_LoadFile(), Crypto_ReadPublicKey(), Crypto_SavePubKeyTextFile(), d0_blind_id_dll, D0_BOOL, FP64_SIZE, Host_LockSession(), i, keygen_i, MAX_PUBKEYS, NULL, pubkeys, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, pubkeys_priv_fp64, qd0_blind_id_fingerprint64_public_id, qd0_blind_id_fingerprint64_public_key, qd0_blind_id_free, qd0_blind_id_verify_private_id, qd0_blind_id_verify_public_id, sessionid, cvar_t::string, and va().

Referenced by Crypto_KeyGen_f(), Crypto_Reload_f(), NetConn_OpenClientPorts(), NetConn_OpenServerPorts(), and PRVM_Prog_Load().

◆ Crypto_OpenLibrary()

static qbool Crypto_OpenLibrary ( void )
static

Definition at line 283 of file crypto.c.

284{
285 const char* dllnames [] =
286 {
287#if defined(WIN32)
288 "libd0_blind_id-0.dll",
289#elif defined(MACOSX)
290 "libd0_blind_id.0.dylib",
291#else
292 "libd0_blind_id.so.0",
293 "libd0_blind_id.so", // FreeBSD
294#endif
295 NULL
296 };
297
298 // Already loaded?
299 if (d0_blind_id_dll)
300 return true;
301
302 // Load the DLL
304}
static dllfunction_t d0_blind_id_funcs[]
Definition crypto.c:237
qbool Sys_LoadDependency(const char **dllnames, dllhandle_t *handle, const dllfunction_t *fcts)
Definition sys_shared.c:131

References d0_blind_id_dll, d0_blind_id_funcs, NULL, and Sys_LoadDependency().

Referenced by Crypto_Init().

◆ Crypto_ParsePack()

static size_t Crypto_ParsePack ( const char * buf,
size_t len,
unsigned long header,
const char ** lumps,
size_t * lumpsize,
size_t nlumps )
static

Definition at line 76 of file crypto.c.

77{
78 size_t i;
79 size_t pos;
80 pos = 0;
81 if(header)
82 {
83 if(len < 4)
84 return 0;
85 if(Crypto_LittleLong(buf) != header)
86 return 0;
87 pos += 4;
88 }
89 for(i = 0; i < nlumps; ++i)
90 {
91 if(pos + 4 > len)
92 return 0;
93 lumpsize[i] = Crypto_LittleLong(&buf[pos]);
94 pos += 4;
95 if(pos + lumpsize[i] > len)
96 return 0;
97 lumps[i] = &buf[pos];
98 pos += lumpsize[i];
99 }
100 return pos;
101}

References buf, Crypto_LittleLong(), and i.

Referenced by Crypto_AddPrivateKey(), Crypto_KeyGen_Finished(), and Crypto_ReadPublicKey().

◆ Crypto_ReadPublicKey()

static d0_blind_id_t * Crypto_ReadPublicKey ( char * buf,
size_t len )
static

Definition at line 450 of file crypto.c.

451{
452 d0_blind_id_t *pk = NULL;
453 const char *p[2];
454 size_t l[2];
455 if(Crypto_ParsePack(buf, len, FOURCC_D0PK, p, l, 2))
456 {
457 pk = qd0_blind_id_new();
458 if(pk)
459 if(qd0_blind_id_read_public_key(pk, p[0], l[0]))
460 if(qd0_blind_id_read_private_id_modulus(pk, p[1], l[1]))
461 return pk;
462 }
463 if(pk)
465 return NULL;
466}
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_public_key)(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
Definition crypto.c:205
#define FOURCC_D0PK
Definition crypto.c:50
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_private_id_modulus)(d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen)
Definition crypto.c:210
struct d0_blind_id_s d0_blind_id_t
Definition crypto.c:196

References buf, Crypto_ParsePack(), FOURCC_D0PK, NULL, qd0_blind_id_free, qd0_blind_id_new, qd0_blind_id_read_private_id_modulus, and qd0_blind_id_read_public_key.

Referenced by Crypto_LoadKeys().

◆ Crypto_Reload_f()

static void Crypto_Reload_f ( cmd_state_t * cmd)
static

Definition at line 1373 of file crypto.c.

1374{
1378}
static void Crypto_ClearHostKeys(void)
Definition crypto.c:598
static void Crypto_UnloadKeys(void)
Definition crypto.c:985

References Crypto_ClearHostKeys(), Crypto_LoadKeys(), and Crypto_UnloadKeys().

Referenced by Crypto_Init_Commands().

◆ Crypto_RetrieveHostKey()

qbool Crypto_RetrieveHostKey ( lhnetaddress_t * peeraddress,
int * keyid,
char * keyfp,
size_t keyfplen,
char * idfp,
size_t idfplen,
int * aeslevel,
qbool * issigned )

Definition at line 734 of file crypto.c.

735{
736 char buf[128];
737 int hashindex;
739
740 if(!d0_blind_id_dll)
741 return false;
742
743 LHNETADDRESS_ToString(peeraddress, buf, sizeof(buf), 1);
744 hashindex = CRC_Block((const unsigned char *) buf, strlen(buf)) % CRYPTO_HOSTKEY_HASHSIZE;
745 for(hk = crypto_storedhostkey_hashtable[hashindex]; hk && LHNETADDRESS_Compare(&hk->addr, peeraddress); hk = hk->next);
746
747 if(!hk)
748 return false;
749
750 if(keyid)
751 *keyid = hk->keyid;
752 if(keyfp)
753 dp_strlcpy(keyfp, pubkeys_fp64[hk->keyid], keyfplen);
754 if(idfp)
755 dp_strlcpy(idfp, hk->idfp, idfplen);
756 if(aeslevel)
757 *aeslevel = hk->aeslevel;
758 if(issigned)
759 *issigned = hk->issigned;
760
761 return true;
762}

References crypto_storedhostkey_t::addr, crypto_storedhostkey_t::aeslevel, buf, CRC_Block(), CRYPTO_HOSTKEY_HASHSIZE, crypto_storedhostkey_hashtable, d0_blind_id_dll, dp_strlcpy, crypto_storedhostkey_t::idfp, crypto_storedhostkey_t::issigned, crypto_storedhostkey_t::keyid, LHNETADDRESS_Compare(), LHNETADDRESS_ToString(), crypto_storedhostkey_t::next, pubkeys_fp64, and strlen().

Referenced by Crypto_ClientParsePacket(), VM_M_crypto_getencryptlevel(), VM_M_crypto_getidfp(), VM_M_crypto_getidstatus(), and VM_M_crypto_getkeyfp().

◆ Crypto_RetrieveLocalKey()

int Crypto_RetrieveLocalKey ( int keyid,
char * keyfp,
size_t keyfplen,
char * idfp,
size_t idfplen,
qbool * issigned )

Definition at line 763 of file crypto.c.

764{
765 if(keyid < 0 || keyid >= MAX_PUBKEYS)
766 return 0;
767 if(keyfp)
768 *keyfp = 0;
769 if(idfp)
770 *idfp = 0;
771 if(!pubkeys[keyid])
772 return -1;
773 if(keyfp)
774 dp_strlcpy(keyfp, pubkeys_fp64[keyid], keyfplen);
775 if(idfp)
776 if(pubkeys_havepriv[keyid])
777 dp_strlcpy(idfp, pubkeys_priv_fp64[keyid], idfplen);
778 if(issigned)
779 *issigned = pubkeys_havesig[keyid];
780 return 1;
781}

References dp_strlcpy, MAX_PUBKEYS, pubkeys, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, and pubkeys_priv_fp64.

Referenced by VM_M_crypto_getmyidfp(), VM_M_crypto_getmyidstatus(), and VM_M_crypto_getmykeyfp().

◆ Crypto_Rijndael_CloseLibrary()

static void Crypto_Rijndael_CloseLibrary ( void )
static

Definition at line 375 of file crypto.c.

376{
378}

References d0_rijndael_dll, and Sys_FreeLibrary().

Referenced by Crypto_Init(), and Crypto_Shutdown().

◆ Crypto_Rijndael_OpenLibrary()

static qbool Crypto_Rijndael_OpenLibrary ( void )
static

Definition at line 352 of file crypto.c.

353{
354 const char* dllnames [] =
355 {
356#if defined(WIN32)
357 "libd0_rijndael-0.dll",
358#elif defined(MACOSX)
359 "libd0_rijndael.0.dylib",
360#else
361 "libd0_rijndael.so.0",
362 "libd0_rijndael.so", // FreeBSD
363#endif
364 NULL
365 };
366
367 // Already loaded?
368 if (d0_rijndael_dll)
369 return true;
370
371 // Load the DLL
373}
static dllfunction_t d0_rijndael_funcs[]
Definition crypto.c:341

References d0_rijndael_dll, d0_rijndael_funcs, NULL, and Sys_LoadDependency().

Referenced by Crypto_Init().

◆ Crypto_SavePubKeyTextFile()

static qbool Crypto_SavePubKeyTextFile ( int i)
static

Definition at line 814 of file crypto.c.

815{
816 qfile_t *f;
817 char vabuf[1024];
818
819 if(!pubkeys_havepriv[i])
820 return false;
821 f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%skey_%d-public-fp%s.txt", *fs_userdir ? fs_userdir : fs_basedir, i, sessionid.string), "w", false);
822 if(!f)
823 return false;
824
825 // we ignore errors for this file, as it's not necessary to have
826 FS_Printf(f, "ID-Fingerprint: %s\n", pubkeys_priv_fp64[i]);
827 FS_Printf(f, "ID-Is-Signed: %s\n", pubkeys_havesig[i] ? "yes" : "no");
828 FS_Printf(f, "ID-Is-For-Key: %s\n", pubkeys_fp64[i]);
829 FS_Printf(f, "\n");
830 FS_Printf(f, "This is a PUBLIC ID file for DarkPlaces.\n");
831 FS_Printf(f, "You are free to share this file or its contents.\n");
832 FS_Printf(f, "\n");
833 FS_Printf(f, "This file will be automatically generated again if deleted.\n");
834 FS_Printf(f, "\n");
835 FS_Printf(f, "However, NEVER share the accompanying SECRET ID file called\n");
836 FS_Printf(f, "key_%d.d0si%s, as doing so would compromise security!\n", i, sessionid.string);
837 FS_Close(f);
838
839 return true;
840}
int FS_Printf(qfile_t *file, const char *format,...)
Definition fs.c:3273

References f, fs_basedir, FS_Close(), FS_Printf(), FS_SysOpen(), fs_userdir, i, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, pubkeys_priv_fp64, sessionid, cvar_t::string, and va().

Referenced by Crypto_KeyGen_f(), Crypto_KeyGen_Finished(), and Crypto_LoadKeys().

◆ Crypto_ServerAppendToChallenge()

qbool Crypto_ServerAppendToChallenge ( const char * data_in,
size_t len_in,
char * data_out,
size_t * len_out,
size_t maxlen_out )

Definition at line 1696 of file crypto.c.

1697{
1698 // cheap op, all is precomputed
1699 if(!d0_blind_id_dll)
1700 return false; // no support
1701 // append challenge
1702 if(maxlen_out <= *len_out + challenge_append_length)
1703 return false;
1704 memcpy(data_out + *len_out, challenge_append, challenge_append_length);
1705 *len_out += challenge_append_length;
1706 return false;
1707}

References challenge_append, challenge_append_length, and d0_blind_id_dll.

Referenced by NetConn_ServerParsePacket().

◆ Crypto_ServerError()

static int Crypto_ServerError ( char * data_out,
size_t * len_out,
const char * msg,
const char * msg_client )
static

Definition at line 1709 of file crypto.c.

1710{
1711 if(!msg_client)
1712 msg_client = msg;
1713 Con_DPrintf("rejecting client: %s\n", msg);
1714 if(*msg_client)
1715 dpsnprintf(data_out, *len_out, "reject %s", msg_client);
1716 *len_out = strlen(data_out);
1717 return CRYPTO_DISCARD;
1718}
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544

References Con_DPrintf(), CRYPTO_DISCARD, dpsnprintf(), and strlen().

Referenced by Crypto_ServerParsePacket_Internal().

◆ Crypto_ServerFindInstance()

static crypto_t * Crypto_ServerFindInstance ( lhnetaddress_t * peeraddress,
qbool allow_create )
static

Definition at line 528 of file crypto.c.

529{
530 crypto_t *crypto;
531 int i, best;
532
533 if(!d0_blind_id_dll)
534 return NULL; // no support
535
536 for(i = 0; i < MAX_CRYPTOCONNECTS; ++i)
537 if(LHNETADDRESS_Compare(peeraddress, &cryptoconnects[i].address))
538 break;
539 if(i < MAX_CRYPTOCONNECTS && (allow_create || cryptoconnects[i].crypto.data))
540 {
541 crypto = &cryptoconnects[i].crypto;
543 return crypto;
544 }
545 if(!allow_create)
546 return NULL;
547 best = 0;
548 for(i = 1; i < MAX_CRYPTOCONNECTS; ++i)
549 if(cryptoconnects[i].lasttime < cryptoconnects[best].lasttime)
550 best = i;
551 crypto = &cryptoconnects[best].crypto;
553 memcpy(&cryptoconnects[best].address, peeraddress, sizeof(cryptoconnects[best].address));
555 return crypto;
556}
#define MAX_CRYPTOCONNECTS
Definition crypto.c:493
static server_cryptoconnect_t cryptoconnects[MAX_CRYPTOCONNECTS]
Definition crypto.c:507
void * data
Definition crypto.h:52

References CLEAR_CDATA, server_cryptoconnect_t::crypto, cryptoconnects, d0_blind_id_dll, crypto_t::data, host, i, server_cryptoconnect_t::lasttime, LHNETADDRESS_Compare(), MAX_CRYPTOCONNECTS, NULL, and host_static_t::realtime.

Referenced by Crypto_ServerGetInstance(), and Crypto_ServerParsePacket_Internal().

◆ Crypto_ServerGetInstance()

crypto_t * Crypto_ServerGetInstance ( lhnetaddress_t * peeraddress)

Definition at line 573 of file crypto.c.

574{
575 // no check needed here (returned pointers are only used in prefilled fields)
576 return Crypto_ServerFindInstance(peeraddress, false);
577}
static crypto_t * Crypto_ServerFindInstance(lhnetaddress_t *peeraddress, qbool allow_create)
Definition crypto.c:528

References Crypto_ServerFindInstance().

Referenced by NetConn_ServerParsePacket().

◆ Crypto_ServerParsePacket()

int Crypto_ServerParsePacket ( const char * data_in,
size_t len_in,
char * data_out,
size_t * len_out,
lhnetaddress_t * peeraddress )

Definition at line 2036 of file crypto.c.

2037{
2038 int ret;
2039 double t = 0;
2040 static double complain_time = 0;
2041 const char *cnt;
2042 qbool do_time = false;
2043 qbool do_reject = false;
2044 char infostringvalue[MAX_INPUTLINE];
2046 if(len_in > 5 && !memcmp(data_in, "d0pk\\", 5))
2047 {
2048 do_time = true;
2049 cnt = (InfoString_GetValue(data_in + 4, "cnt", infostringvalue, sizeof(infostringvalue)) ? infostringvalue : NULL);
2050 if(cnt)
2051 if(!strcmp(cnt, "0"))
2052 do_reject = true;
2053 }
2054 if(do_time)
2055 {
2056 // check if we may perform crypto...
2058 {
2063 }
2064 else
2065 {
2069 }
2071 if(do_reject && crypto_servercpu_accumulator < 0)
2072 {
2073 if(host.realtime > complain_time + 5)
2074 Con_Printf("crypto: cannot perform requested crypto operations; denial service attack or crypto_servercpupercent/crypto_servercpumaxtime are too low\n");
2075 *len_out = 0;
2076 return CRYPTO_DISCARD;
2077 }
2078 t = Sys_DirtyTime();
2079 }
2080 ret = Crypto_ServerParsePacket_Internal(data_in, len_in, data_out, len_out, peeraddress);
2081 if(do_time)
2082 {
2083 t = Sys_DirtyTime() - t;if (t < 0.0) t = 0.0; // dirtytime can step backwards
2085 Con_Printf("crypto: accumulator was %.1f ms, used %.1f ms for crypto, ", crypto_servercpu_accumulator * 1000, t * 1000);
2088 Con_Printf("is %.1f ms\n", crypto_servercpu_accumulator * 1000);
2089 }
2090 return ret;
2091}
static double crypto_servercpu_accumulator
Definition crypto.c:36
static double crypto_servercpu_lastrealtime
Definition crypto.c:37
static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress)
Definition crypto.c:1727
return ret
float value
Definition cvar.h:74
double Sys_DirtyTime(void)
Definition sys_shared.c:417

References Con_Printf(), CRYPTO_DISCARD, crypto_servercpu_accumulator, crypto_servercpu_lastrealtime, crypto_servercpudebug, crypto_servercpumaxtime, crypto_servercpupercent, Crypto_ServerParsePacket_Internal(), host, InfoString_GetValue(), cvar_t::integer, MAX_INPUTLINE, NULL, host_static_t::realtime, ret, Sys_DirtyTime(), and cvar_t::value.

Referenced by NetConn_ServerParsePacket().

◆ Crypto_ServerParsePacket_Internal()

static int Crypto_ServerParsePacket_Internal ( const char * data_in,
size_t len_in,
char * data_out,
size_t * len_out,
lhnetaddress_t * peeraddress )
static

Definition at line 1727 of file crypto.c.

1728{
1729 // if "connect": reject if in the middle of crypto handshake
1730 crypto_t *crypto = NULL;
1731 char *data_out_p = data_out;
1732 const char *string = data_in;
1733 int aeslevel;
1734 D0_BOOL aes;
1735 D0_BOOL status;
1736 char infostringvalue[MAX_INPUTLINE];
1737 char vabuf[1024];
1738
1739 if(!d0_blind_id_dll)
1740 return CRYPTO_NOMATCH; // no support
1741
1742 if (len_in > 8 && !memcmp(string, "connect\\", 8) && d0_rijndael_dll && crypto_aeslevel.integer >= 3)
1743 {
1744 int i;
1745 // sorry, we have to verify the challenge here to not reflect network spam
1746
1747 if (!InfoString_GetValue(string + 4, "challenge", infostringvalue, sizeof(infostringvalue)))
1748 return CRYPTO_NOMATCH; // will be later accepted if encryption was set up
1749 // validate the challenge
1750 for (i = 0;i < MAX_CHALLENGES;i++)
1751 if(challenges[i].time > 0)
1752 if (!LHNETADDRESS_Compare(peeraddress, &challenges[i].address) && !strcmp(challenges[i].string, infostringvalue))
1753 break;
1754 // if the challenge is not recognized, drop the packet
1755 if (i == MAX_CHALLENGES) // challenge mismatch is silent
1756 return Crypto_SoftServerError(data_out, len_out, "missing challenge in connect");
1757
1758 crypto = Crypto_ServerFindInstance(peeraddress, false);
1759 if(!crypto || !crypto->authenticated)
1760 return Crypto_ServerError(data_out, len_out, "This server requires authentication and encryption to be supported by your client", NULL);
1761 }
1762 else if(len_in > 5 && !memcmp(string, "d0pk\\", 5) && ((LHNETADDRESS_GetAddressType(peeraddress) == LHNETADDRESSTYPE_LOOP) || sv_public.integer > -3))
1763 {
1764 const char *cnt, *p;
1765 int id;
1766 int clientid = -1, serverid = -1;
1767 id = (InfoString_GetValue(string + 4, "id", infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : -1);
1768 cnt = (InfoString_GetValue(string + 4, "cnt", infostringvalue, sizeof(infostringvalue)) ? infostringvalue : NULL);
1769 if(!cnt)
1770 return Crypto_SoftServerError(data_out, len_out, "missing cnt in d0pk");
1771 GetUntilNul(&data_in, &len_in);
1772 if(!data_in)
1773 return Crypto_SoftServerError(data_out, len_out, "missing appended data in d0pk");
1774 if(!strcmp(cnt, "0"))
1775 {
1776 int i;
1777 if (!InfoString_GetValue(string + 4, "challenge", infostringvalue, sizeof(infostringvalue)))
1778 return Crypto_SoftServerError(data_out, len_out, "missing challenge in d0pk\\0");
1779 // validate the challenge
1780 for (i = 0;i < MAX_CHALLENGES;i++)
1781 if(challenges[i].time > 0)
1782 if (!LHNETADDRESS_Compare(peeraddress, &challenges[i].address) && !strcmp(challenges[i].string, infostringvalue))
1783 break;
1784 // if the challenge is not recognized, drop the packet
1785 if (i == MAX_CHALLENGES)
1786 return Crypto_SoftServerError(data_out, len_out, "invalid challenge in d0pk\\0");
1787
1788 if (!InfoString_GetValue(string + 4, "aeslevel", infostringvalue, sizeof(infostringvalue)))
1789 aeslevel = 0; // not supported
1790 else
1791 aeslevel = bound(0, atoi(infostringvalue), 3);
1792 switch(bound(0, d0_rijndael_dll ? crypto_aeslevel.integer : 0, 3))
1793 {
1794 default: // dummy, never happens, but to make gcc happy...
1795 case 0:
1796 if(aeslevel >= 3)
1797 return Crypto_ServerError(data_out, len_out, "This server requires encryption to be not required (crypto_aeslevel <= 2)", NULL);
1798 aes = false;
1799 break;
1800 case 1:
1801 aes = (aeslevel >= 2);
1802 break;
1803 case 2:
1804 aes = (aeslevel >= 1);
1805 break;
1806 case 3:
1807 if(aeslevel <= 0)
1808 return Crypto_ServerError(data_out, len_out, "This server requires encryption to be supported (crypto_aeslevel >= 1, and d0_rijndael library must be present)", NULL);
1809 aes = true;
1810 break;
1811 }
1812
1813 p = GetUntilNul(&data_in, &len_in);
1814 if(p && *p)
1815 {
1816 // Find the highest numbered matching key for p.
1817 for(i = 0; i < MAX_PUBKEYS; ++i)
1818 {
1819 if(pubkeys[i])
1820 if(!strcmp(p, pubkeys_fp64[i]))
1821 if(pubkeys_havepriv[i])
1822 serverid = i;
1823 }
1824 if(serverid < 0)
1825 return Crypto_ServerError(data_out, len_out, "Invalid server key", NULL);
1826 }
1827 p = GetUntilNul(&data_in, &len_in);
1828 if(p && *p)
1829 {
1830 // Find the highest numbered matching key for p.
1831 for(i = 0; i < MAX_PUBKEYS; ++i)
1832 {
1833 if(pubkeys[i])
1834 if(!strcmp(p, pubkeys_fp64[i]))
1835 clientid = i;
1836 }
1837 if(clientid < 0)
1838 return Crypto_ServerError(data_out, len_out, "Invalid client key", NULL);
1839 }
1840
1841 crypto = Crypto_ServerFindInstance(peeraddress, true);
1842 if(!crypto)
1843 return Crypto_ServerError(data_out, len_out, "Could not create a crypto connect instance", NULL);
1844 MAKE_CDATA;
1845 CDATA->cdata_id = id;
1846 CDATA->s = serverid;
1847 CDATA->c = clientid;
1848 memset(crypto->dhkey, 0, sizeof(crypto->dhkey));
1849 CDATA->challenge[0] = 0;
1850 crypto->client_keyfp[0] = 0;
1851 crypto->client_idfp[0] = 0;
1852 crypto->server_keyfp[0] = 0;
1853 crypto->server_idfp[0] = 0;
1854 crypto->use_aes = aes != 0;
1855
1856 if(CDATA->s >= 0)
1857 {
1858 // I am the server, and my key is ok... so let's set server_keyfp and server_idfp
1859 dp_strlcpy(crypto->server_keyfp, pubkeys_fp64[CDATA->s], sizeof(crypto->server_keyfp));
1860 dp_strlcpy(crypto->server_idfp, pubkeys_priv_fp64[CDATA->s], sizeof(crypto->server_idfp));
1862
1863 if(!CDATA->id)
1864 CDATA->id = qd0_blind_id_new();
1865 if(!CDATA->id)
1866 {
1868 return Crypto_ServerError(data_out, len_out, "d0_blind_id_new failed", "Internal error");
1869 }
1870 if(!qd0_blind_id_copy(CDATA->id, pubkeys[CDATA->s]))
1871 {
1873 return Crypto_ServerError(data_out, len_out, "d0_blind_id_copy failed", "Internal error");
1874 }
1875 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\1\\id\\%d\\aes\\%d", CDATA->cdata_id, crypto->use_aes));
1876 if(!qd0_blind_id_authenticate_with_private_id_start(CDATA->id, true, false, "XONOTIC", 8, data_out_p, len_out)) // len_out receives used size by this op
1877 {
1879 return Crypto_ServerError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_start failed", "Internal error");
1880 }
1881 CDATA->next_step = 2;
1882 data_out_p += *len_out;
1883 *len_out = data_out_p - data_out;
1884 return CRYPTO_DISCARD;
1885 }
1886 else if(CDATA->c >= 0)
1887 {
1888 if(!CDATA->id)
1889 CDATA->id = qd0_blind_id_new();
1890 if(!CDATA->id)
1891 {
1893 return Crypto_ServerError(data_out, len_out, "d0_blind_id_new failed", "Internal error");
1894 }
1895 if(!qd0_blind_id_copy(CDATA->id, pubkeys[CDATA->c]))
1896 {
1898 return Crypto_ServerError(data_out, len_out, "d0_blind_id_copy failed", "Internal error");
1899 }
1900 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\5\\id\\%d\\aes\\%d", CDATA->cdata_id, crypto->use_aes));
1901 if(!qd0_blind_id_authenticate_with_private_id_challenge(CDATA->id, true, false, data_in, len_in, data_out_p, len_out, &status))
1902 {
1904 return Crypto_ServerError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_challenge failed", "Internal error");
1905 }
1906 CDATA->next_step = 6;
1907 data_out_p += *len_out;
1908 *len_out = data_out_p - data_out;
1909 return CRYPTO_DISCARD;
1910 }
1911 else
1912 {
1914 return Crypto_ServerError(data_out, len_out, "Missing client and server key", NULL);
1915 }
1916 }
1917 else if(!strcmp(cnt, "2"))
1918 {
1919 size_t fpbuflen;
1920 crypto = Crypto_ServerFindInstance(peeraddress, false);
1921 if(!crypto)
1922 return CRYPTO_NOMATCH; // pre-challenge, rather be silent
1923 if(id >= 0)
1924 if(CDATA->cdata_id != id)
1925 return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
1926 if(CDATA->next_step != 2)
1927 return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
1928
1929 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\3\\id\\%d", CDATA->cdata_id));
1930 if(!qd0_blind_id_authenticate_with_private_id_response(CDATA->id, data_in, len_in, data_out_p, len_out))
1931 {
1933 return Crypto_ServerError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_response failed", "Internal error");
1934 }
1935 fpbuflen = DHKEY_SIZE;
1936 if(!qd0_blind_id_sessionkey_public_id(CDATA->id, (char *) crypto->dhkey, &fpbuflen))
1937 {
1939 return Crypto_ServerError(data_out, len_out, "d0_blind_id_sessionkey_public_id failed", "Internal error");
1940 }
1941 if(CDATA->c >= 0)
1942 {
1943 if(!qd0_blind_id_copy(CDATA->id, pubkeys[CDATA->c]))
1944 {
1946 return Crypto_ServerError(data_out, len_out, "d0_blind_id_copy failed", "Internal error");
1947 }
1948 CDATA->next_step = 4;
1949 }
1950 else
1951 {
1952 // session key is FINISHED (no server part is to be expected)! By this, all keys are set up
1953 crypto->authenticated = true;
1954 CDATA->next_step = 0;
1955 }
1956 data_out_p += *len_out;
1957 *len_out = data_out_p - data_out;
1958 return CRYPTO_DISCARD;
1959 }
1960 else if(!strcmp(cnt, "4"))
1961 {
1962 crypto = Crypto_ServerFindInstance(peeraddress, false);
1963 if(!crypto)
1964 return CRYPTO_NOMATCH; // pre-challenge, rather be silent
1965 if(id >= 0)
1966 if(CDATA->cdata_id != id)
1967 return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
1968 if(CDATA->next_step != 4)
1969 return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
1970 PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\5\\id\\%d", CDATA->cdata_id));
1971 if(!qd0_blind_id_authenticate_with_private_id_challenge(CDATA->id, true, false, data_in, len_in, data_out_p, len_out, &status))
1972 {
1974 return Crypto_ServerError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_challenge failed", "Internal error");
1975 }
1976 CDATA->next_step = 6;
1977 data_out_p += *len_out;
1978 *len_out = data_out_p - data_out;
1979 return CRYPTO_DISCARD;
1980 }
1981 else if(!strcmp(cnt, "6"))
1982 {
1983 static char msgbuf[32];
1984 size_t msgbuflen = sizeof(msgbuf);
1985 size_t fpbuflen;
1986 int i;
1987 unsigned char dhkey[DHKEY_SIZE];
1988 crypto = Crypto_ServerFindInstance(peeraddress, false);
1989 if(!crypto)
1990 return CRYPTO_NOMATCH; // pre-challenge, rather be silent
1991 if(id >= 0)
1992 if(CDATA->cdata_id != id)
1993 return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
1994 if(CDATA->next_step != 6)
1995 return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
1996
1997 if(!qd0_blind_id_authenticate_with_private_id_verify(CDATA->id, data_in, len_in, msgbuf, &msgbuflen, &status))
1998 {
2000 return Crypto_ServerError(data_out, len_out, "d0_blind_id_authenticate_with_private_id_verify failed (authentication error)", "Authentication error");
2001 }
2002 dp_strlcpy(crypto->client_keyfp, pubkeys_fp64[CDATA->c], sizeof(crypto->client_keyfp));
2003 crypto->client_issigned = status;
2004
2005 memset(crypto->client_idfp, 0, sizeof(crypto->client_idfp));
2006 fpbuflen = FP64_SIZE;
2007 if(!qd0_blind_id_fingerprint64_public_id(CDATA->id, crypto->client_idfp, &fpbuflen))
2008 {
2010 return Crypto_ServerError(data_out, len_out, "d0_blind_id_fingerprint64_public_id failed", "Internal error");
2011 }
2012 fpbuflen = DHKEY_SIZE;
2013 if(!qd0_blind_id_sessionkey_public_id(CDATA->id, (char *) dhkey, &fpbuflen))
2014 {
2016 return Crypto_ServerError(data_out, len_out, "d0_blind_id_sessionkey_public_id failed", "Internal error");
2017 }
2018 // XOR the two DH keys together to make one
2019 for(i = 0; i < DHKEY_SIZE; ++i)
2020 crypto->dhkey[i] ^= dhkey[i];
2021
2022 // session key is FINISHED (no server part is to be expected)! By this, all keys are set up
2023 crypto->authenticated = true;
2024 CDATA->next_step = 0;
2025 // send a challenge-less challenge
2026 PutWithNul(&data_out_p, len_out, "challenge ");
2027 *len_out = data_out_p - data_out;
2028 --*len_out; // remove NUL terminator
2029 return CRYPTO_MATCH;
2030 }
2031 return CRYPTO_NOMATCH; // pre-challenge, rather be silent
2032 }
2033 return CRYPTO_NOMATCH;
2034}
static int Crypto_ServerError(char *data_out, size_t *len_out, const char *msg, const char *msg_client)
Definition crypto.c:1709
static int Crypto_SoftServerError(char *data_out, size_t *len_out, const char *msg)
Definition crypto.c:1720
#define CRYPTO_MATCH
Definition crypto.h:65
float time
@ LHNETADDRESSTYPE_LOOP
Definition lhnet.h:13
static lhnetaddresstype_t LHNETADDRESS_GetAddressType(const lhnetaddress_t *address)
Definition lhnet.h:31
cvar_t sv_public
Definition netconn.c:36
challenge_t challenges[MAX_CHALLENGES]
Definition netconn.c:123
#define MAX_CHALLENGES
Definition netconn.h:476

References crypto_t::authenticated, bound, CDATA, challenges, CLEAR_CDATA, crypto_t::client_idfp, crypto_t::client_issigned, crypto_t::client_keyfp, crypto_aeslevel, CRYPTO_DISCARD, CRYPTO_MATCH, CRYPTO_NOMATCH, Crypto_ServerError(), Crypto_ServerFindInstance(), Crypto_SoftServerError(), d0_blind_id_dll, D0_BOOL, d0_rijndael_dll, crypto_t::dhkey, DHKEY_SIZE, dp_strlcpy, FP64_SIZE, GetUntilNul(), i, id, InfoString_GetValue(), cvar_t::integer, LHNETADDRESS_Compare(), LHNETADDRESS_GetAddressType(), LHNETADDRESSTYPE_LOOP, MAKE_CDATA, MAX_CHALLENGES, MAX_INPUTLINE, MAX_PUBKEYS, NULL, pubkeys, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, pubkeys_priv_fp64, PutWithNul(), qd0_blind_id_authenticate_with_private_id_challenge, qd0_blind_id_authenticate_with_private_id_response, qd0_blind_id_authenticate_with_private_id_start, qd0_blind_id_authenticate_with_private_id_verify, qd0_blind_id_copy, qd0_blind_id_fingerprint64_public_id, qd0_blind_id_new, qd0_blind_id_sessionkey_public_id, crypto_t::server_idfp, crypto_t::server_issigned, crypto_t::server_keyfp, sv_public, time, crypto_t::use_aes, and va().

Referenced by Crypto_ServerParsePacket().

◆ Crypto_Shutdown()

void Crypto_Shutdown ( void )

Definition at line 1043 of file crypto.c.

1044{
1045 crypto_t *crypto;
1046 int i;
1047
1049
1050 if(d0_blind_id_dll)
1051 {
1052 // free memory
1053 for(i = 0; i < MAX_CRYPTOCONNECTS; ++i)
1054 {
1055 crypto = &cryptoconnects[i].crypto;
1057 }
1058 memset(cryptoconnects, 0, sizeof(cryptoconnects));
1059 crypto = &cls.crypto;
1061
1063
1065
1067 }
1068
1070}
static D0_EXPORT void(* qd0_blind_id_SHUTDOWN)(void)
Definition crypto.c:229
#define Mem_FreePool(pool)
Definition zone.h:105

References CLEAR_CDATA, cls, client_static_t::crypto, server_cryptoconnect_t::crypto, Crypto_CloseLibrary(), Crypto_Rijndael_CloseLibrary(), Crypto_UnloadKeys(), cryptoconnects, cryptomempool, d0_blind_id_dll, i, MAX_CRYPTOCONNECTS, Mem_FreePool, and qd0_blind_id_SHUTDOWN.

Referenced by Host_Shutdown().

◆ Crypto_SignData()

size_t Crypto_SignData ( const void * data,
size_t datasize,
int keyid,
void * signed_data,
size_t signed_size )

Definition at line 2634 of file crypto.c.

2635{
2636 if(keyid < 0 || keyid >= MAX_PUBKEYS)
2637 return 0;
2638 if(!pubkeys_havepriv[keyid])
2639 return 0;
2640 if(qd0_blind_id_sign_with_private_id_sign(pubkeys[keyid], true, false, (const char *)data, datasize, (char *)signed_data, &signed_size))
2641 return signed_size;
2642 return 0;
2643}
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sign_with_private_id_sign)(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen)
Definition crypto.c:231

References data, MAX_PUBKEYS, pubkeys, pubkeys_havepriv, and qd0_blind_id_sign_with_private_id_sign.

◆ Crypto_SignDataDetached()

size_t Crypto_SignDataDetached ( const void * data,
size_t datasize,
int keyid,
void * signed_data,
size_t signed_size )

Definition at line 2645 of file crypto.c.

2646{
2647 if(keyid < 0 || keyid >= MAX_PUBKEYS)
2648 return 0;
2649 if(!pubkeys_havepriv[keyid])
2650 return 0;
2651 if(qd0_blind_id_sign_with_private_id_sign_detached(pubkeys[keyid], true, false, (const char *)data, datasize, (char *)signed_data, &signed_size))
2652 return signed_size;
2653 return 0;
2654}
static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sign_with_private_id_sign_detached)(d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen)
Definition crypto.c:232

References data, MAX_PUBKEYS, pubkeys, pubkeys_havepriv, and qd0_blind_id_sign_with_private_id_sign_detached.

Referenced by VM_uri_get().

◆ Crypto_SoftClientError()

static int Crypto_SoftClientError ( char * data_out,
size_t * len_out,
const char * msg )
static

Definition at line 2100 of file crypto.c.

2101{
2102 *len_out = 0;
2103 Con_DPrintf("%s\n", msg);
2104 return CRYPTO_DISCARD;
2105}

References Con_DPrintf(), and CRYPTO_DISCARD.

Referenced by Crypto_ClientParsePacket().

◆ Crypto_SoftServerError()

static int Crypto_SoftServerError ( char * data_out,
size_t * len_out,
const char * msg )
static

Definition at line 1720 of file crypto.c.

1721{
1722 *len_out = 0;
1723 Con_DPrintf("%s\n", msg);
1724 return CRYPTO_DISCARD;
1725}

References Con_DPrintf(), and CRYPTO_DISCARD.

Referenced by Crypto_ServerParsePacket_Internal().

◆ Crypto_StoreHostKey()

static void Crypto_StoreHostKey ( lhnetaddress_t * peeraddress,
const char * keystring,
qbool complain )
static

Definition at line 635 of file crypto.c.

636{
637 char buf[128];
638 int hashindex;
640 int keyid;
641 char idfp[FP64_SIZE+1];
642 int aeslevel;
643 qbool issigned;
644
645 if(!d0_blind_id_dll)
646 return;
647
648 // syntax of keystring:
649 // aeslevel id@key id@key ...
650
651 if(!*keystring)
652 return;
653 aeslevel = bound(0, *keystring - '0', 3);
654 while(*keystring && *keystring != ' ')
655 ++keystring;
656
657 keyid = -1;
658 issigned = false;
659 while(*keystring && keyid < 0)
660 {
661 // id@key
662 const char *idstart, *idend, *keystart, *keyend;
663 qbool thisissigned = true;
664 ++keystring; // skip the space
665 idstart = keystring;
666 while(*keystring && *keystring != ' ' && *keystring != '@')
667 ++keystring;
668 idend = keystring;
669 if(!*keystring)
670 break;
671 ++keystring;
672 keystart = keystring;
673 while(*keystring && *keystring != ' ')
674 ++keystring;
675 keyend = keystring;
676
677 if (keystart[0] == '~')
678 {
679 thisissigned = false;
680 ++keystart;
681 }
682
683 if(idend - idstart == FP64_SIZE && keyend - keystart == FP64_SIZE)
684 {
685 int thiskeyid;
686 for(thiskeyid = MAX_PUBKEYS - 1; thiskeyid >= 0; --thiskeyid)
687 if(pubkeys[thiskeyid])
688 if(!memcmp(pubkeys_fp64[thiskeyid], keystart, FP64_SIZE))
689 {
690 memcpy(idfp, idstart, FP64_SIZE);
691 idfp[FP64_SIZE] = 0;
692 keyid = thiskeyid;
693 issigned = thisissigned;
694 break;
695 }
696 // If this failed, keyid will be -1.
697 }
698 }
699
700 if(keyid < 0)
701 return;
702
703 LHNETADDRESS_ToString(peeraddress, buf, sizeof(buf), 1);
704 hashindex = CRC_Block((const unsigned char *) buf, strlen(buf)) % CRYPTO_HOSTKEY_HASHSIZE;
705 for(hk = crypto_storedhostkey_hashtable[hashindex]; hk && LHNETADDRESS_Compare(&hk->addr, peeraddress); hk = hk->next);
706
707 if(hk)
708 {
709 if(complain)
710 {
711 if(hk->keyid != keyid || memcmp(hk->idfp, idfp, FP64_SIZE+1))
712 Con_Printf("Server %s tried to change the host key to a value not in the host cache. Connecting to it will fail. To accept the new host key, do crypto_hostkey_clear %s\n", buf, buf);
713 if(hk->aeslevel > aeslevel)
714 Con_Printf("Server %s tried to reduce encryption status, not accepted. Connecting to it will fail. To accept, do crypto_hostkey_clear %s\n", buf, buf);
715 if(hk->issigned > issigned)
716 Con_Printf("Server %s tried to reduce signature status, not accepted. Connecting to it will fail. To accept, do crypto_hostkey_clear %s\n", buf, buf);
717 }
718 hk->aeslevel = max(aeslevel, hk->aeslevel);
719 hk->issigned = issigned;
720 return;
721 }
722
723 // great, we did NOT have it yet
724 hk = (crypto_storedhostkey_t *) Z_Malloc(sizeof(*hk));
725 memcpy(&hk->addr, peeraddress, sizeof(hk->addr));
726 hk->keyid = keyid;
727 memcpy(hk->idfp, idfp, FP64_SIZE+1);
728 hk->next = crypto_storedhostkey_hashtable[hashindex];
729 hk->aeslevel = aeslevel;
730 hk->issigned = issigned;
731 crypto_storedhostkey_hashtable[hashindex] = hk;
732}
#define Z_Malloc(size)
Definition zone.h:161

References crypto_storedhostkey_t::addr, crypto_storedhostkey_t::aeslevel, bound, buf, Con_Printf(), CRC_Block(), CRYPTO_HOSTKEY_HASHSIZE, crypto_storedhostkey_hashtable, d0_blind_id_dll, FP64_SIZE, crypto_storedhostkey_t::idfp, crypto_storedhostkey_t::issigned, crypto_storedhostkey_t::keyid, LHNETADDRESS_Compare(), LHNETADDRESS_ToString(), max, MAX_PUBKEYS, crypto_storedhostkey_t::next, pubkeys, pubkeys_fp64, strlen(), and Z_Malloc.

Referenced by Crypto_ClientParsePacket().

◆ Crypto_UnLittleLong()

static void Crypto_UnLittleLong ( char * data,
unsigned long l )
static

Definition at line 68 of file crypto.c.

69{
70 data[0] = l & 0xFF;
71 data[1] = (l >> 8) & 0xFF;
72 data[2] = (l >> 16) & 0xFF;
73 data[3] = (l >> 24) & 0xFF;
74}

References data.

Referenced by Crypto_BuildChallengeAppend(), and Crypto_UnParsePack().

◆ Crypto_UnloadKeys()

static void Crypto_UnloadKeys ( void )
static

Definition at line 985 of file crypto.c.

986{
987 int i;
988
989 keygen_i = -1;
990 for(i = 0; i < MAX_PUBKEYS; ++i)
991 {
992 if(pubkeys[i])
994 pubkeys[i] = NULL;
995 pubkeys_havepriv[i] = false;
996 pubkeys_havesig[i] = false;
997 memset(pubkeys_fp64[i], 0, sizeof(pubkeys_fp64[i]));
998 memset(pubkeys_priv_fp64[i], 0, sizeof(pubkeys_fp64[i]));
1000 }
1002}

References challenge_append_length, crypto_idstring, i, keygen_i, MAX_PUBKEYS, NULL, pubkeys, pubkeys_fp64, pubkeys_havepriv, pubkeys_havesig, pubkeys_priv_fp64, and qd0_blind_id_free.

Referenced by Crypto_Reload_f(), and Crypto_Shutdown().

◆ Crypto_UnParsePack()

static size_t Crypto_UnParsePack ( char * buf,
size_t len,
unsigned long header,
const char *const * lumps,
const size_t * lumpsize,
size_t nlumps )
static

Definition at line 103 of file crypto.c.

104{
105 size_t i;
106 size_t pos;
107 pos = 0;
108 if(header)
109 {
110 if(len < 4)
111 return 0;
112 Crypto_UnLittleLong(buf, header);
113 pos += 4;
114 }
115 for(i = 0; i < nlumps; ++i)
116 {
117 if(pos + 4 + lumpsize[i] > len)
118 return 0;
119 Crypto_UnLittleLong(&buf[pos], (unsigned long)lumpsize[i]);
120 pos += 4;
121 memcpy(&buf[pos], lumps[i], lumpsize[i]);
122 pos += lumpsize[i];
123 }
124 return pos;
125}

References buf, Crypto_UnLittleLong(), and i.

Referenced by Crypto_KeyGen_f(), and Crypto_KeyGen_Finished().

◆ GetUntilNul()

static const char * GetUntilNul ( const char ** data,
size_t * len )
static

Definition at line 418 of file crypto.c.

419{
420 // invariant: data points to next character to take
421 const char *data_save = *data;
422 size_t n;
423 const char *p;
424
425 if(!*data)
426 return NULL;
427
428 if(!*len)
429 {
430 *data = NULL;
431 return NULL;
432 }
433
434 p = (const char *) memchr(*data, 0, *len);
435 if(!p) // no terminating NUL
436 {
437 *data = NULL;
438 *len = 0;
439 return NULL;
440 }
441 n = (p - *data) + 1;
442 *len -= n;
443 *data += n;
444 if(*len == 0)
445 *data = NULL;
446 return (const char *) data_save;
447}

References data, n, and NULL.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ PutWithNul()

static qbool PutWithNul ( char ** data,
size_t * len,
const char * str )
static

Definition at line 406 of file crypto.c.

407{
408 // invariant: data points to insertion point
409 size_t l = strlen(str);
410 if(l >= *len)
411 return false;
412 memcpy(*data, str, l+1);
413 *data += l+1;
414 *len -= l+1;
415 return true;
416}

References data, and strlen().

Referenced by Crypto_BuildChallengeAppend(), Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ seacpy()

static void seacpy ( unsigned char * key,
const unsigned char * iv,
unsigned char * dst,
const unsigned char * src,
size_t len )
static

Definition at line 1498 of file crypto.c.

1499{
1500 const unsigned char *xorpos = iv;
1501 unsigned char xorbuf[16];
1502 unsigned long rk[D0_RIJNDAEL_RKLENGTH(DHKEY_SIZE * 8)];
1503 size_t i;
1505 while(len > 16)
1506 {
1508 for(i = 0; i < 16; ++i)
1509 dst[i] = xorbuf[i] ^ xorpos[i];
1510 xorpos = src;
1511 len -= 16;
1512 src += 16;
1513 dst += 16;
1514 }
1515 if(len > 0)
1516 {
1518 for(i = 0; i < len; ++i)
1519 dst[i] = xorbuf[i] ^ xorpos[i];
1520 }
1521}
D0_EXPORT int(* qd0_rijndael_setup_decrypt)(unsigned long *rk, const unsigned char *key, int keybits)
Definition crypto.c:332
D0_EXPORT void(* qd0_rijndael_decrypt)(const unsigned long *rk, int nrounds, const unsigned char ciphertext[16], unsigned char plaintext[16])
Definition crypto.c:336

References D0_RIJNDAEL_NROUNDS, D0_RIJNDAEL_RKLENGTH, DHKEY_SIZE, i, qd0_rijndael_decrypt, qd0_rijndael_setup_decrypt, and src.

Referenced by Crypto_DecryptPacket().

◆ sha256()

void sha256 ( unsigned char * out,
const unsigned char * in,
int n )

Definition at line 383 of file crypto.c.

384{
385 qd0_blind_id_util_sha256((char *) out, (const char *) in, n);
386}
static D0_EXPORT void(* qd0_blind_id_util_sha256)(char *out, const char *in, size_t n)
Definition crypto.c:230

References n, and qd0_blind_id_util_sha256.

Referenced by VM_digest_hex().

Variable Documentation

◆ cdata_id

int cdata_id = 0
static

Definition at line 509 of file crypto.c.

Referenced by Crypto_ClientParsePacket().

◆ challenge_append

char challenge_append[1400]
static

Definition at line 487 of file crypto.c.

Referenced by Crypto_BuildChallengeAppend(), and Crypto_ServerAppendToChallenge().

◆ challenge_append_length

size_t challenge_append_length
static

◆ crypto_aeslevel

cvar_t crypto_aeslevel = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_aeslevel", "1", "whether to support AES encryption in authenticated connections (0 = no, 1 = supported, 2 = requested, 3 = required)"}

Definition at line 31 of file crypto.c.

31{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_aeslevel", "1", "whether to support AES encryption in authenticated connections (0 = no, 1 = supported, 2 = requested, 3 = required)"};
#define CF_SERVER
cvar/command that only the server can change/execute
Definition cmd.h:49
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53

Referenced by Crypto_BuildIdString(), Crypto_ClientParsePacket(), Crypto_GetInfoResponseDataString(), Crypto_Init_Commands(), and Crypto_ServerParsePacket_Internal().

◆ crypto_developer

cvar_t crypto_developer = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_developer", "0", "print extra info about crypto handshake"}

Definition at line 30 of file crypto.c.

30{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_developer", "0", "print extra info about crypto handshake"};

Referenced by Crypto_Init_Commands(), and NetConn_ServerParsePacket().

◆ crypto_idstring

◆ crypto_idstring_buf

char crypto_idstring_buf[512]
static

◆ crypto_keyfp_recommended_length

int crypto_keyfp_recommended_length

◆ crypto_servercpu_accumulator

double crypto_servercpu_accumulator = 0
static

Definition at line 36 of file crypto.c.

Referenced by Crypto_ServerParsePacket().

◆ crypto_servercpu_lastrealtime

double crypto_servercpu_lastrealtime = 0
static

Definition at line 37 of file crypto.c.

Referenced by Crypto_ServerParsePacket().

◆ crypto_servercpudebug

cvar_t crypto_servercpudebug = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpudebug", "0", "print statistics about time usage by crypto"}

Definition at line 35 of file crypto.c.

35{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpudebug", "0", "print statistics about time usage by crypto"};

Referenced by Crypto_Init_Commands(), and Crypto_ServerParsePacket().

◆ crypto_servercpumaxtime

cvar_t crypto_servercpumaxtime = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpumaxtime", "0.01", "maximum allowed crypto CPU time per frame (0 = no limit)"}

Definition at line 34 of file crypto.c.

34{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpumaxtime", "0.01", "maximum allowed crypto CPU time per frame (0 = no limit)"};

Referenced by Crypto_Init_Commands(), and Crypto_ServerParsePacket().

◆ crypto_servercpupercent

cvar_t crypto_servercpupercent = {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpupercent", "10", "allowed crypto CPU load in percent for server operation (0 = no limit, faster)"}

Definition at line 33 of file crypto.c.

33{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "crypto_servercpupercent", "10", "allowed crypto CPU load in percent for server operation (0 = no limit, faster)"};

Referenced by Crypto_Init_Commands(), and Crypto_ServerParsePacket().

◆ crypto_storedhostkey_hashtable

◆ cryptoconnects

Definition at line 507 of file crypto.c.

Referenced by Crypto_ServerFindInstance(), and Crypto_Shutdown().

◆ cryptomempool

mempool_t* cryptomempool
static

Definition at line 1004 of file crypto.c.

Referenced by Crypto_d0_malloc(), Crypto_Init(), and Crypto_Shutdown().

◆ d0_blind_id_dll

◆ d0_blind_id_funcs

dllfunction_t d0_blind_id_funcs[]
static

Definition at line 237 of file crypto.c.

238{
239 {"d0_blind_id_new", (void **) &qd0_blind_id_new},
240 {"d0_blind_id_free", (void **) &qd0_blind_id_free},
241 //{"d0_blind_id_clear", (void **) &qd0_blind_id_clear},
242 {"d0_blind_id_copy", (void **) &qd0_blind_id_copy},
243 //{"d0_blind_id_generate_private_key", (void **) &qd0_blind_id_generate_private_key},
244 //{"d0_blind_id_generate_private_key_fastreject", (void **) &qd0_blind_id_generate_private_key_fastreject},
245 //{"d0_blind_id_read_private_key", (void **) &qd0_blind_id_read_private_key},
246 {"d0_blind_id_read_public_key", (void **) &qd0_blind_id_read_public_key},
247 //{"d0_blind_id_write_private_key", (void **) &qd0_blind_id_write_private_key},
248 //{"d0_blind_id_write_public_key", (void **) &qd0_blind_id_write_public_key},
249 {"d0_blind_id_fingerprint64_public_key", (void **) &qd0_blind_id_fingerprint64_public_key},
250 //{"d0_blind_id_generate_private_id_modulus", (void **) &qd0_blind_id_generate_private_id_modulus},
251 {"d0_blind_id_read_private_id_modulus", (void **) &qd0_blind_id_read_private_id_modulus},
252 //{"d0_blind_id_write_private_id_modulus", (void **) &qd0_blind_id_write_private_id_modulus},
253 {"d0_blind_id_generate_private_id_start", (void **) &qd0_blind_id_generate_private_id_start},
254 {"d0_blind_id_generate_private_id_request", (void **) &qd0_blind_id_generate_private_id_request},
255 //{"d0_blind_id_answer_private_id_request", (void **) &qd0_blind_id_answer_private_id_request},
256 {"d0_blind_id_finish_private_id_request", (void **) &qd0_blind_id_finish_private_id_request},
257 //{"d0_blind_id_read_private_id_request_camouflage", (void **) &qd0_blind_id_read_private_id_request_camouflage},
258 //{"d0_blind_id_write_private_id_request_camouflage", (void **) &qd0_blind_id_write_private_id_request_camouflage},
259 {"d0_blind_id_read_private_id", (void **) &qd0_blind_id_read_private_id},
260 //{"d0_blind_id_read_public_id", (void **) &qd0_blind_id_read_public_id},
261 {"d0_blind_id_write_private_id", (void **) &qd0_blind_id_write_private_id},
262 //{"d0_blind_id_write_public_id", (void **) &qd0_blind_id_write_public_id},
263 {"d0_blind_id_authenticate_with_private_id_start", (void **) &qd0_blind_id_authenticate_with_private_id_start},
264 {"d0_blind_id_authenticate_with_private_id_challenge", (void **) &qd0_blind_id_authenticate_with_private_id_challenge},
265 {"d0_blind_id_authenticate_with_private_id_response", (void **) &qd0_blind_id_authenticate_with_private_id_response},
266 {"d0_blind_id_authenticate_with_private_id_verify", (void **) &qd0_blind_id_authenticate_with_private_id_verify},
267 {"d0_blind_id_fingerprint64_public_id", (void **) &qd0_blind_id_fingerprint64_public_id},
268 {"d0_blind_id_sessionkey_public_id", (void **) &qd0_blind_id_sessionkey_public_id},
269 {"d0_blind_id_INITIALIZE", (void **) &qd0_blind_id_INITIALIZE},
270 {"d0_blind_id_SHUTDOWN", (void **) &qd0_blind_id_SHUTDOWN},
271 {"d0_blind_id_util_sha256", (void **) &qd0_blind_id_util_sha256},
272 {"d0_blind_id_sign_with_private_id_sign", (void **) &qd0_blind_id_sign_with_private_id_sign},
273 {"d0_blind_id_sign_with_private_id_sign_detached", (void **) &qd0_blind_id_sign_with_private_id_sign_detached},
274 {"d0_blind_id_setmallocfuncs", (void **) &qd0_blind_id_setmallocfuncs},
275 {"d0_blind_id_setmutexfuncs", (void **) &qd0_blind_id_setmutexfuncs},
276 {"d0_blind_id_verify_public_id", (void **) &qd0_blind_id_verify_public_id},
277 {"d0_blind_id_verify_private_id", (void **) &qd0_blind_id_verify_private_id},
278 {NULL, NULL}
279};

Referenced by Crypto_OpenLibrary().

◆ d0_rijndael_dll

◆ d0_rijndael_funcs

dllfunction_t d0_rijndael_funcs[]
static
Initial value:
=
{
{"d0_rijndael_setup_decrypt", (void **) &qd0_rijndael_setup_decrypt},
{"d0_rijndael_setup_encrypt", (void **) &qd0_rijndael_setup_encrypt},
{"d0_rijndael_decrypt", (void **) &qd0_rijndael_decrypt},
{"d0_rijndael_encrypt", (void **) &qd0_rijndael_encrypt},
}

Definition at line 341 of file crypto.c.

342{
343 {"d0_rijndael_setup_decrypt", (void **) &qd0_rijndael_setup_decrypt},
344 {"d0_rijndael_setup_encrypt", (void **) &qd0_rijndael_setup_encrypt},
345 {"d0_rijndael_decrypt", (void **) &qd0_rijndael_decrypt},
346 {"d0_rijndael_encrypt", (void **) &qd0_rijndael_encrypt},
347 {NULL, NULL}
348};

Referenced by Crypto_Rijndael_OpenLibrary().

◆ keygen_buf

char keygen_buf[8192]
static

Definition at line 491 of file crypto.c.

Referenced by Crypto_KeyGen_f().

◆ keygen_i

int keygen_i = -1
static

◆ net_sourceaddresscheck

cvar_t net_sourceaddresscheck
extern

Definition at line 87 of file netconn.c.

87{CF_CLIENT, "net_sourceaddresscheck", "1", "compare the source IP address for replies (more secure, may break some bad multihoming setups"};

Referenced by Crypto_ClientParsePacket(), NetConn_ClientParsePacket(), and NetConn_Init().

◆ pubkeys

◆ pubkeys_fp64

◆ pubkeys_havepriv

◆ pubkeys_havesig

◆ pubkeys_priv_fp64

◆ qd0_blind_id_authenticate_with_private_id_challenge

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_challenge) (d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL recv_modulus, const char *inbuf, size_t inbuflen, char *outbuf, size_t *outbuflen, D0_BOOL *status) ( d0_blind_id_t * ctx,
D0_BOOL is_first,
D0_BOOL recv_modulus,
const char * inbuf,
size_t inbuflen,
char * outbuf,
size_t * outbuflen,
D0_BOOL * status )
static

Definition at line 223 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ qd0_blind_id_authenticate_with_private_id_response

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_response) (d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen, char *outbuf, size_t *outbuflen) ( d0_blind_id_t * ctx,
const char * inbuf,
size_t inbuflen,
char * outbuf,
size_t * outbuflen )
static

Definition at line 224 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ qd0_blind_id_authenticate_with_private_id_start

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_start) (d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen) ( d0_blind_id_t * ctx,
D0_BOOL is_first,
D0_BOOL send_modulus,
const char * message,
size_t msglen,
char * outbuf,
size_t * outbuflen )
static

Definition at line 222 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ qd0_blind_id_authenticate_with_private_id_verify

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_authenticate_with_private_id_verify) (d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen, char *msg, size_t *msglen, D0_BOOL *status) ( d0_blind_id_t * ctx,
const char * inbuf,
size_t inbuflen,
char * msg,
size_t * msglen,
D0_BOOL * status )
static

Definition at line 225 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ qd0_blind_id_copy

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_copy) (d0_blind_id_t *ctx, const d0_blind_id_t *src) ( d0_blind_id_t * ctx,
const d0_blind_id_t * src )
static

Definition at line 201 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ qd0_blind_id_fingerprint64_public_id

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_fingerprint64_public_id) (const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen) ( const d0_blind_id_t * ctx,
char * outbuf,
size_t * outbuflen )
static

◆ qd0_blind_id_fingerprint64_public_key

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_fingerprint64_public_key) (const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen) ( const d0_blind_id_t * ctx,
char * outbuf,
size_t * outbuflen )
static

Definition at line 208 of file crypto.c.

Referenced by Crypto_LoadKeys().

◆ qd0_blind_id_finish_private_id_request

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_finish_private_id_request) (d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen) ( d0_blind_id_t * ctx,
const char * inbuf,
size_t inbuflen )
static

Definition at line 215 of file crypto.c.

Referenced by Crypto_KeyGen_Finished().

◆ qd0_blind_id_free

D0_EXPORT void(* qd0_blind_id_free) (d0_blind_id_t *a) ( d0_blind_id_t * a)
static

Definition at line 199 of file crypto.c.

Referenced by Crypto_LoadKeys(), Crypto_ReadPublicKey(), and Crypto_UnloadKeys().

◆ qd0_blind_id_generate_private_id_request

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_generate_private_id_request) (d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen) ( d0_blind_id_t * ctx,
char * outbuf,
size_t * outbuflen )
static

Definition at line 213 of file crypto.c.

Referenced by Crypto_KeyGen_f().

◆ qd0_blind_id_generate_private_id_start

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_generate_private_id_start) (d0_blind_id_t *ctx) ( d0_blind_id_t * ctx)
static

Definition at line 212 of file crypto.c.

Referenced by Crypto_KeyGen_f().

◆ qd0_blind_id_INITIALIZE

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_INITIALIZE) (void) ( void )
static

Definition at line 228 of file crypto.c.

Referenced by Crypto_Init().

◆ qd0_blind_id_new

◆ qd0_blind_id_read_private_id

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_private_id) (d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen) ( d0_blind_id_t * ctx,
const char * inbuf,
size_t inbuflen )
static

Definition at line 218 of file crypto.c.

Referenced by Crypto_AddPrivateKey().

◆ qd0_blind_id_read_private_id_modulus

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_private_id_modulus) (d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen) ( d0_blind_id_t * ctx,
const char * inbuf,
size_t inbuflen )
static

Definition at line 210 of file crypto.c.

Referenced by Crypto_ReadPublicKey().

◆ qd0_blind_id_read_public_key

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_read_public_key) (d0_blind_id_t *ctx, const char *inbuf, size_t inbuflen) ( d0_blind_id_t * ctx,
const char * inbuf,
size_t inbuflen )
static

Definition at line 205 of file crypto.c.

Referenced by Crypto_ReadPublicKey().

◆ qd0_blind_id_sessionkey_public_id

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sessionkey_public_id) (const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen) ( const d0_blind_id_t * ctx,
char * outbuf,
size_t * outbuflen )
static

Definition at line 227 of file crypto.c.

Referenced by Crypto_ClientParsePacket(), and Crypto_ServerParsePacket_Internal().

◆ qd0_blind_id_setmallocfuncs

D0_EXPORT void(* qd0_blind_id_setmallocfuncs) (d0_malloc_t *m, d0_free_t *f) ( d0_malloc_t * m,
d0_free_t * f )
static

Definition at line 233 of file crypto.c.

Referenced by Crypto_Init().

◆ qd0_blind_id_setmutexfuncs

Definition at line 234 of file crypto.c.

Referenced by Crypto_Init().

◆ qd0_blind_id_SHUTDOWN

D0_EXPORT void(* qd0_blind_id_SHUTDOWN) (void) ( void )
static

Definition at line 229 of file crypto.c.

Referenced by Crypto_Shutdown().

◆ qd0_blind_id_sign_with_private_id_sign

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sign_with_private_id_sign) (d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen) ( d0_blind_id_t * ctx,
D0_BOOL is_first,
D0_BOOL send_modulus,
const char * message,
size_t msglen,
char * outbuf,
size_t * outbuflen )
static

Definition at line 231 of file crypto.c.

Referenced by Crypto_SignData().

◆ qd0_blind_id_sign_with_private_id_sign_detached

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_sign_with_private_id_sign_detached) (d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen) ( d0_blind_id_t * ctx,
D0_BOOL is_first,
D0_BOOL send_modulus,
const char * message,
size_t msglen,
char * outbuf,
size_t * outbuflen )
static

Definition at line 232 of file crypto.c.

Referenced by Crypto_SignDataDetached().

◆ qd0_blind_id_util_sha256

D0_EXPORT void(* qd0_blind_id_util_sha256) (char *out, const char *in, size_t n) ( char * out,
const char * in,
size_t n )
static

Definition at line 230 of file crypto.c.

Referenced by sha256().

◆ qd0_blind_id_verify_private_id

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_verify_private_id) (const d0_blind_id_t *ctx) ( const d0_blind_id_t * ctx)
static

Definition at line 236 of file crypto.c.

Referenced by Crypto_KeyGen_f(), and Crypto_LoadKeys().

◆ qd0_blind_id_verify_public_id

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_verify_public_id) (const d0_blind_id_t *ctx, D0_BOOL *status) ( const d0_blind_id_t * ctx,
D0_BOOL * status )
static

Definition at line 235 of file crypto.c.

Referenced by Crypto_KeyGen_Finished(), and Crypto_LoadKeys().

◆ qd0_blind_id_write_private_id

D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL(* qd0_blind_id_write_private_id) (const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen) ( const d0_blind_id_t * ctx,
char * outbuf,
size_t * outbuflen )
static

Definition at line 220 of file crypto.c.

Referenced by Crypto_KeyGen_f(), and Crypto_KeyGen_Finished().

◆ qd0_rijndael_decrypt

D0_EXPORT void(* qd0_rijndael_decrypt) (const unsigned long *rk, int nrounds, const unsigned char ciphertext[16], unsigned char plaintext[16]) ( const unsigned long * rk,
int nrounds,
const unsigned char ciphertext[16],
unsigned char plaintext[16] )

Definition at line 336 of file crypto.c.

Referenced by seacpy().

◆ qd0_rijndael_encrypt

D0_EXPORT void(* qd0_rijndael_encrypt) (const unsigned long *rk, int nrounds, const unsigned char plaintext[16], unsigned char ciphertext[16]) ( const unsigned long * rk,
int nrounds,
const unsigned char plaintext[16],
unsigned char ciphertext[16] )

Definition at line 334 of file crypto.c.

Referenced by aescpy().

◆ qd0_rijndael_setup_decrypt

D0_EXPORT int(* qd0_rijndael_setup_decrypt) (unsigned long *rk, const unsigned char *key, int keybits) ( unsigned long * rk,
const unsigned char * key,
int keybits )

Definition at line 332 of file crypto.c.

Referenced by seacpy().

◆ qd0_rijndael_setup_encrypt

D0_EXPORT int(* qd0_rijndael_setup_encrypt) (unsigned long *rk, const unsigned char *key, int keybits) ( unsigned long * rk,
const unsigned char * key,
int keybits )

Definition at line 330 of file crypto.c.

Referenced by aescpy().