From: divverent Date: Sat, 1 Oct 2011 13:29:16 +0000 (+0000) Subject: implement digest_hex() X-Git-Tag: xonotic-v0.6.0~297 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=279b12081e3cfad0b0c0f1f11c2a567977e7c842;p=xonotic%2Fdarkplaces.git implement digest_hex() git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11382 d7cf8633-e32d-0410-b094-e92efae38249 ::stable-branch::merge=853f7fe77fd4e7a79e682cf964e4ad863a1a60e7 --- diff --git a/clvm_cmds.c b/clvm_cmds.c index 289d071c..965b64eb 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -4779,7 +4779,8 @@ NULL, // #635 NULL, // #636 NULL, // #637 VM_CL_RotateMoves, // #638 -NULL, // #639 +VM_digest_hex, // #639 +NULL, // #640 }; const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t); diff --git a/crypto.c b/crypto.c index ef281462..7bd36d12 100644 --- a/crypto.c +++ b/crypto.c @@ -914,6 +914,13 @@ void Crypto_Init(void) } // end +qboolean Crypto_Available(void) +{ + if(!d0_blind_id_dll) + return false; + return true; +} + // keygen code static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned char *buffer, void *cbdata) { diff --git a/crypto.h b/crypto.h index 507c0a06..2cff5c2d 100644 --- a/crypto.h +++ b/crypto.h @@ -32,6 +32,8 @@ crypto_t; void Crypto_Init(void); void Crypto_Init_Commands(void); void Crypto_Shutdown(void); +qboolean Crypto_Available(void); +void sha256(unsigned char *out, const unsigned char *in, int n); // may ONLY be called if Crypto_Available() 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); 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); #define CRYPTO_NOMATCH 0 // process as usual (packet was not used) diff --git a/dpdefs/dpextensions.qc b/dpdefs/dpextensions.qc index 6ca63e60..57d94343 100644 --- a/dpdefs/dpextensions.qc +++ b/dpdefs/dpextensions.qc @@ -668,12 +668,13 @@ float CVAR_TYPEFLAG_READONLY = 32; //idea: motorsep, Spike //DarkPlaces implementation: divVerent //builtin definitions: -string(string digest, string data, ...) digest_hex = #638; +string(string digest, string data, ...) digest_hex = #639; //description: //returns a given hex digest of given data -//digest is always encoded in hexadecimal +//the returned digest is always encoded in hexadecimal //only the "MD4" digest is always supported! //if the given digest is not supported, string_null is returned +//the digest string is matched case sensitively, use "MD4", not "md4"! //DP_QC_DIGEST_SHA256 //idea: motorsep, Spike @@ -1257,6 +1258,7 @@ float(string name, string value) registercvar = #93; //DP_SND_FAKETRACKS //idea: requested + //darkplaces implementation: Elric //description: //the engine plays sound/cdtracks/track001.wav instead of cd track 1 and so on if found, this allows games and mods to have music tracks without using ambientsound. diff --git a/mvm_cmds.c b/mvm_cmds.c index 5b02c245..fbf4fd3d 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -26,6 +26,8 @@ const char *vm_m_extensions = "DP_QC_CRC16 " "DP_QC_CVAR_TYPE " "DP_QC_CVAR_DESCRIPTION " +"DP_QC_DIGEST " +"DP_QC_DIGEST_SHA256 " "DP_QC_FINDCHAIN_TOFIELD " "DP_QC_I18N " "DP_QC_LOG " @@ -1512,6 +1514,8 @@ VM_M_crypto_getidfp, // #634 string(string addr) crypto_getidfp VM_M_crypto_getencryptlevel, // #635 string(string addr) crypto_getencryptlevel VM_M_crypto_getmykeyfp, // #636 string(float addr) crypto_getmykeyfp VM_M_crypto_getmyidfp, // #637 string(float addr) crypto_getmyidfp +NULL, // #638 +VM_digest_hex, // #639 NULL }; diff --git a/prvm_cmds.c b/prvm_cmds.c index 716762ed..51a3648f 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -280,6 +280,13 @@ static qboolean checkextension(const char *name) return false; #endif } + + // special sheck for d0_blind_id + if (!strcasecmp("DP_CRYPTO", name)) + return Crypto_Available(); + if (!strcasecmp("DP_QC_DIGEST_SHA256", name)) + return Crypto_Available(); + return true; } } @@ -5634,12 +5641,61 @@ void VM_crc16(void) { float insensitive; static char s[VM_STRINGTEMP_LENGTH]; - VM_SAFEPARMCOUNTRANGE(2, 8, VM_hash); + VM_SAFEPARMCOUNTRANGE(2, 8, VM_crc16); insensitive = PRVM_G_FLOAT(OFS_PARM0); VM_VarString(1, s, sizeof(s)); PRVM_G_FLOAT(OFS_RETURN) = (unsigned short) ((insensitive ? CRC_Block_CaseInsensitive : CRC_Block) ((unsigned char *) s, strlen(s))); } +// #639 float(string digest, string data, ...) digest_hex +void VM_digest_hex(void) +{ + const char *digest; + + static char out[32]; + static char outhex[65]; + int outlen; + + static char s[VM_STRINGTEMP_LENGTH]; + int len; + + VM_SAFEPARMCOUNTRANGE(2, 8, VM_digest_hex); + digest = PRVM_G_STRING(OFS_PARM0); + if(!digest) + digest = ""; + VM_VarString(1, s, sizeof(s)); + len = strlen(s); + + outlen = 0; + + if(!strcmp(digest, "MD4")) + { + outlen = 16; + mdfour(&out, s, len); + } + else if(!strcmp(digest, "SHA256") && Crypto_Available()) + { + outlen = 32; + sha256(&out, s, len); + } + // no warning needed on mismatch - we return string_null to QC + + if(outlen) + { + int i; + static const char *hexmap = "0123456789abcdef"; + for(i = 0; i < outlen; ++i) + { + outhex[2*i] = hexmap[(out[i] >> 4) & 15]; + outhex[2*i+1] = hexmap[(out[i] >> 0) & 15]; + } + outhex[2*i] = 0; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(outhex); + } + else + PRVM_G_INT(OFS_RETURN) = 0; +} + void VM_wasfreed (void) { VM_SAFEPARMCOUNT(1, VM_wasfreed); diff --git a/prvm_cmds.h b/prvm_cmds.h index e8ed3cbc..50571ad9 100644 --- a/prvm_cmds.h +++ b/prvm_cmds.h @@ -430,6 +430,7 @@ void VM_strreplace (void); void VM_strireplace (void); void VM_crc16(void); +void VM_digest_hex(void); void VM_SetTraceGlobals(const trace_t *trace); void VM_ClearTraceGlobals(void); diff --git a/svvm_cmds.c b/svvm_cmds.c index 8f0d5c78..c0ed230a 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -88,6 +88,8 @@ const char *vm_sv_extensions = "DP_QC_CVAR_DESCRIPTION " "DP_QC_CVAR_STRING " "DP_QC_CVAR_TYPE " +"DP_QC_DIGEST " +"DP_QC_DIGEST_SHA256 " "DP_QC_EDICT_NUM " "DP_QC_ENTITYDATA " "DP_QC_ENTITYSTRING " @@ -3788,6 +3790,16 @@ VM_sprintf, // #627 string sprintf(string format, ...) VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE) VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE) NULL, // #630 +NULL, // #631 +NULL, // #632 +NULL, // #633 +NULL, // #634 +NULL, // #635 +NULL, // #636 +NULL, // #637 +NULL, // #638 +VM_digest_hex, // #639 +NULL, // #640 }; const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);