]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - crypto.c
Clarify what sprintf does on %1$s %s
[xonotic/darkplaces.git] / crypto.c
index 40f905068af017b7941319d6d25b46126f3dfe98..b9f214544b85a0b6dab582aa712dc15737ef43ea 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -1,4 +1,3 @@
-// TODO key loading, generating, saving
 #include "quakedef.h"
 #include "crypto.h"
 #include "common.h"
@@ -102,7 +101,7 @@ static size_t Crypto_UnParsePack(char *buf, size_t len, unsigned long header, co
 
 #define USE_AES
 
-#ifdef CRYPTO_STATIC
+#ifdef LINK_TO_CRYPTO
 
 #include <d0_blind_id/d0_blind_id.h>
 
@@ -147,8 +146,8 @@ static size_t Crypto_UnParsePack(char *buf, size_t len, unsigned long header, co
 #define qd0_blind_id_sign_with_private_id_sign_detached d0_blind_id_sign_with_private_id_sign_detached
 #define qd0_blind_id_setmallocfuncs d0_blind_id_setmallocfuncs
 #define qd0_blind_id_setmutexfuncs d0_blind_id_setmutexfuncs
-#define qd0_blind_id_verify_public_id d0_bind_id_verify_public_id
-#define qd0_blind_id_verify_private_id d0_bind_id_verify_private_id
+#define qd0_blind_id_verify_public_id d0_blind_id_verify_public_id
+#define qd0_blind_id_verify_private_id d0_blind_id_verify_private_id
 
 #else
 
@@ -285,7 +284,7 @@ static void Crypto_CloseLibrary (void)
 
 #endif
 
-#ifdef CRYPTO_RIJNDAEL_STATIC
+#ifdef LINK_TO_CRYPTO_RIJNDAEL
 
 #include <d0_blind_id/d0_rijndael.h>
 
@@ -534,7 +533,7 @@ static crypto_t *Crypto_ServerFindInstance(lhnetaddress_t *peeraddress, qboolean
        return crypto;
 }
 
-qboolean Crypto_ServerFinishInstance(crypto_t *out, crypto_t *crypto)
+qboolean Crypto_FinishInstance(crypto_t *out, crypto_t *crypto)
 {
        // no check needed here (returned pointers are only used in prefilled fields)
        if(!crypto || !crypto->authenticated)
@@ -545,7 +544,7 @@ qboolean Crypto_ServerFinishInstance(crypto_t *out, crypto_t *crypto)
        }
        CLEAR_CDATA;
        memcpy(out, crypto, sizeof(*out));
-       memset(crypto, 0, sizeof(crypto));
+       memset(crypto, 0, sizeof(*crypto));
        return true;
 }
 
@@ -651,7 +650,7 @@ static void Crypto_StoreHostKey(lhnetaddress_t *peeraddress, const char *keystri
 
                if(idend - idstart == FP64_SIZE && keyend - keystart == FP64_SIZE)
                {
-                       for(keyid = 0; keyid < MAX_PUBKEYS; ++keyid)
+                       for(keyid = MAX_PUBKEYS - 1; keyid >= 0; --keyid)
                                if(pubkeys[keyid])
                                        if(!memcmp(pubkeys_fp64[keyid], keystart, FP64_SIZE))
                                        {
@@ -659,8 +658,7 @@ static void Crypto_StoreHostKey(lhnetaddress_t *peeraddress, const char *keystri
                                                idfp[FP64_SIZE] = 0;
                                                break;
                                        }
-                       if(keyid >= MAX_PUBKEYS)
-                               keyid = -1;
+                       // If this failed, keyid will be -1.
                }
        }
 
@@ -735,7 +733,7 @@ int Crypto_RetrieveLocalKey(int keyid, char *keyfp, size_t keyfplen, char *idfp,
                strlcpy(keyfp, pubkeys_fp64[keyid], keyfplen);
        if(idfp)
                if(pubkeys_havepriv[keyid])
-                       strlcpy(idfp, pubkeys_priv_fp64[keyid], keyfplen);
+                       strlcpy(idfp, pubkeys_priv_fp64[keyid], idfplen);
        if(issigned)
                *issigned = pubkeys_havesig[keyid];
        return 1;
@@ -772,6 +770,34 @@ static void Crypto_BuildChallengeAppend(void)
        challenge_append_length = p - challenge_append;
 }
 
+static qboolean Crypto_SavePubKeyTextFile(int i)
+{
+       qfile_t *f;
+       char vabuf[1024];
+
+       if(!pubkeys_havepriv[i])
+               return false;
+       f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%skey_%d-public-fp%s.txt", *fs_userdir ? fs_userdir : fs_basedir, i, sessionid.string), "w", false);
+       if(!f)
+               return false;
+
+       // we ignore errors for this file, as it's not necessary to have
+       FS_Printf(f, "ID-Fingerprint: %s\n", pubkeys_priv_fp64[i]);
+       FS_Printf(f, "ID-Is-Signed: %s\n", pubkeys_havesig[i] ? "yes" : "no");
+       FS_Printf(f, "ID-Is-For-Key: %s\n", pubkeys_fp64[i]);
+       FS_Printf(f, "\n");
+       FS_Printf(f, "This is a PUBLIC ID file for DarkPlaces.\n");
+       FS_Printf(f, "You are free to share this file or its contents.\n");
+       FS_Printf(f, "\n");
+       FS_Printf(f, "This file will be automatically generated again if deleted.\n");
+       FS_Printf(f, "\n");
+       FS_Printf(f, "However, NEVER share the accompanying SECRET ID file called\n");
+       FS_Printf(f, "key_%d.d0si%s, as doing so would compromise security!\n", i, sessionid.string);
+       FS_Close(f);
+
+       return true;
+}
+
 void Crypto_LoadKeys(void)
 {
        char buf[8192];
@@ -831,6 +857,8 @@ void Crypto_LoadKeys(void)
                                                                        pubkeys_havesig[i] = true;
                                                                else
                                                                        Con_Printf("NOTE: this ID has not yet been signed!\n");
+
+                                                               Crypto_SavePubKeyTextFile(i);
                                                        }
                                                        else
                                                        {
@@ -1010,7 +1038,7 @@ void Crypto_Init(void)
                return;
        }
 
-       Crypto_Rijndael_OpenLibrary(); // if this fails, it's uncritical
+       (void) Crypto_Rijndael_OpenLibrary(); // if this fails, it's uncritical
 
        Crypto_InitHostKeys();
 }
@@ -1126,7 +1154,10 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
        FS_Write(f, buf2, buf2size);
        FS_Close(f);
 
+       Crypto_SavePubKeyTextFile(keygen_i);
+
        Con_Printf("Saved to key_%d.d0si%s\n", keygen_i, sessionid.string);
+
        keygen_i = -1;
        SV_UnlockThreadMutex();
 }
@@ -1243,6 +1274,8 @@ static void Crypto_KeyGen_f(void)
                FS_Write(f, buf2, buf2size);
                FS_Close(f);
 
+               Crypto_SavePubKeyTextFile(keygen_i);
+
                Con_Printf("Saved unsigned key to key_%d.d0si%s\n", keygen_i, sessionid.string);
        }
        p[0] = buf;
@@ -1271,7 +1304,7 @@ static void Crypto_KeyGen_f(void)
                return;
        }
        buf2l += buf2pos;
-       buf[buf2l] = 0;
+       buf2[buf2l] = 0;
        if(!Curl_Begin_ToMemory(buf2, 0, (unsigned char *) keygen_buf, sizeof(keygen_buf), Crypto_KeyGen_Finished, NULL))
        {
                Con_Printf("curl failed\n");
@@ -1729,13 +1762,13 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                        p = GetUntilNul(&data_in, &len_in);
                        if(p && *p)
                        {
+                               // Find the highest numbered matching key for p.
                                for(i = 0; i < MAX_PUBKEYS; ++i)
                                {
                                        if(pubkeys[i])
                                                if(!strcmp(p, pubkeys_fp64[i]))
                                                        if(pubkeys_havepriv[i])
-                                                               if(serverid < 0)
-                                                                       serverid = i;
+                                                               serverid = i;
                                }
                                if(serverid < 0)
                                        return Crypto_ServerError(data_out, len_out, "Invalid server key", NULL);
@@ -1743,12 +1776,12 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                        p = GetUntilNul(&data_in, &len_in);
                        if(p && *p)
                        {
+                               // Find the highest numbered matching key for p.
                                for(i = 0; i < MAX_PUBKEYS; ++i)
                                {
                                        if(pubkeys[i])
                                                if(!strcmp(p, pubkeys_fp64[i]))
-                                                       if(clientid < 0)
-                                                               clientid = i;
+                                                       clientid = i;
                                }
                                if(clientid < 0)
                                        return Crypto_ServerError(data_out, len_out, "Invalid client key", NULL);
@@ -2123,7 +2156,7 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
                int clientid = -1, serverid = -1, wantserverid = -1;
                qboolean server_can_auth = true;
                char wantserver_idfp[FP64_SIZE+1];
-               int wantserver_aeslevel;
+               int wantserver_aeslevel = 0;
 
                // if we have a stored host key for the server, assume serverid to already be selected!
                // (the loop will refuse to overwrite this one then)
@@ -2201,22 +2234,20 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
                                        break;
                                continue;
                        }
+                       // Find the highest numbered matching key for p.
                        for(i = 0; i < MAX_PUBKEYS; ++i)
                        {
                                if(pubkeys[i])
                                if(!strcmp(p, pubkeys_fp64[i]))
                                {
                                        if(pubkeys_havepriv[i])
-                                               if(clientid < 0)
-                                                       clientid = i;
+                                               clientid = i;
                                        if(server_can_auth)
-                                               if(serverid < 0)
-                                                       if(wantserverid < 0 || i == wantserverid)
-                                                               serverid = i;
+                                               if(wantserverid < 0 || i == wantserverid)
+                                                       serverid = i;
                                }
                        }
-                       if(clientid >= 0 && serverid >= 0)
-                               break;
+                       // Not breaking, as higher keys in the list always have priority.
                }
 
                // if stored host key is not found:
@@ -2225,7 +2256,6 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
 
                if(serverid >= 0 || clientid >= 0)
                {
-                       // TODO at this point, fill clientside crypto struct!
                        MAKE_CDATA;
                        CDATA->cdata_id = ++cdata_id;
                        CDATA->s = serverid;