implement digest_hex()
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 1 Oct 2011 13:29:16 +0000 (13:29 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 1 Oct 2011 13:29:16 +0000 (13:29 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11382 d7cf8633-e32d-0410-b094-e92efae38249

clvm_cmds.c
crypto.c
crypto.h
dpdefs/dpextensions.qc
mvm_cmds.c
prvm_cmds.c
prvm_cmds.h
svvm_cmds.c

index 289d071..965b64e 100644 (file)
@@ -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);
index ef28146..7bd36d1 100644 (file)
--- 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)
 {
index 507c0a0..2cff5c2 100644 (file)
--- 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)
index 6ca63e6..57d9434 100644 (file)
@@ -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.
index 5b02c24..fbf4fd3 100644 (file)
@@ -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
 };
 
index 716762e..51a3648 100644 (file)
@@ -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);
index e8ed3cb..50571ad 100644 (file)
@@ -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);
index 8f0d5c7..c0ed230 100644 (file)
@@ -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);