Browse Source

more crap

Caleb James DeLisle 9 years ago
parent
commit
12fd242eae

+ 2 - 2
crypto/CryptoAuth.c

@@ -409,7 +409,7 @@ static void encryptHandshake(struct Message* message,
             uint8_t tempPrivateKeyHex[65];
             Hex_encode(tempPrivateKeyHex, 65, session->ourTempPrivKey, 32);
             uint8_t tempPubKeyHex[65];
-            Hex_encode(tempPubKeyHex, 65, header->handshake.encryptedTempKey, 32);
+            Hex_encode(tempPubKeyHex, 65, session->ourTempPubKey, 32);
             Log_keys(session->context->logger, "Generating temporary keypair\n"
                                                 "    myTempPrivateKey=%s\n"
                                                 "     myTempPublicKey=%s\n",
@@ -704,7 +704,7 @@ static USE_RES int decryptHandshake(struct CryptoAuth_Session_pvt* session,
     }
 
     // Decrypt her temp public key and the message.
-    if (decryptRndNonce(header->handshake.nonce, message, sharedSecret) != 0) {
+    if (decryptRndNonce(header->handshake.nonce, message, sharedSecret)) {
         // just in case
         Bits_memset(header, 0, CryptoHeader_SIZE);
         cryptoAuthDebug(session, "DROP message with nonce [%d], decryption failed", nonce);

+ 21 - 103
crypto/test/CryptoAuth_test.c

@@ -73,7 +73,7 @@ static struct Context* init(uint8_t* privateKey, uint8_t* herPublicKey, uint8_t*
 
 static struct Context* simpleInit()
 {
-    return init(NULL, NULL, NULL);
+    return init(PRIVATEKEY, PUBLICKEY, NULL);
 }
 
 static struct Message* encryptMsg(struct Context* ctx,
@@ -81,9 +81,11 @@ static struct Message* encryptMsg(struct Context* ctx,
                                   const char* x)
 {
     struct Allocator* alloc = Allocator_child(ctx->alloc);
-    struct Message* msg = Message_new(1, CString_strlen(x) + CryptoHeader_SIZE, alloc);
-    msg->bytes[0] = '\0';
-    Message_push(msg, x, CString_strlen(x), NULL);
+    int len = (((CString_strlen(x)+1) / 8) + 1) * 8;
+    struct Message* msg = Message_new(len, CryptoHeader_SIZE, alloc);
+    CString_strcpy(msg->bytes, x);
+    msg->length = CString_strlen(x);
+    msg->bytes[msg->length] = 0;
     Assert_true(!CryptoAuth_encrypt(encryptWith, msg));
     Assert_true(msg->length > ((int)CString_strlen(x) + 4));
     return msg;
@@ -99,8 +101,11 @@ static void decryptMsg(struct Context* ctx,
         Assert_true(CryptoAuth_decrypt(decryptWith, msg));
     } else {
         Assert_true(!CryptoAuth_decrypt(decryptWith, msg));
-        if ((int)CString_strlen(x) != msg->length || CString_strncmp(msg->bytes, x, msg->length)) {
-            Assert_failure("expected %s, got %s\n", x, msg->bytes);
+        if ((int)CString_strlen(x) != msg->length ||
+            CString_strncmp(msg->bytes, x, msg->length))
+        {
+            Assert_failure("expected [%s](%d), got [%s](%d)\n",
+                x, (int)CString_strlen(x), msg->bytes, msg->length);
         }
     }
 }
@@ -142,7 +147,7 @@ static void repeatKey()
 
 static void repeatHello()
 {
-    struct Context* ctx = init(PRIVATEKEY, PUBLICKEY, NULL);
+    struct Context* ctx = simpleInit();
     sendToIf2(ctx, "hello world");
     sendToIf2(ctx, "r u thar?");
     sendToIf1(ctx, "hello cjdns");
@@ -180,109 +185,32 @@ static void auth()
     Allocator_free(ctx->alloc);
 }
 
-static void authWithoutKey()
-{
-    struct Context* ctx = init(NULL, NULL, "password");
-    sendToIf2(ctx, "hello world");
-    sendToIf1(ctx, "hello cjdns");
-    sendToIf2(ctx, "hai");
-    sendToIf1(ctx, "goodbye");
-    Allocator_free(ctx->alloc);
-}
-
-static void poly1305()
-{
-    struct Context* ctx = init(PRIVATEKEY, PUBLICKEY, NULL);
-    sendToIf2(ctx, "hello world");
-    sendToIf1(ctx, "hello cjdns");
-    sendToIf2(ctx, "hai");
-    sendToIf1(ctx, "goodbye");
-    Allocator_free(ctx->alloc);
-}
-
-static void poly1305UnknownKey()
-{
-    struct Context* ctx = init(NULL, NULL, NULL);
-    sendToIf2(ctx, "hello world");
-    sendToIf1(ctx, "hello cjdns");
-    sendToIf2(ctx, "hai");
-    sendToIf1(ctx, "goodbye");
-    Allocator_free(ctx->alloc);
-}
-
-static void poly1305AndPassword()
-{
-    struct Context* ctx = init(PRIVATEKEY, PUBLICKEY, "aPassword");
-    sendToIf2(ctx, "hello world");
-    sendToIf1(ctx, "hello cjdns");
-    sendToIf2(ctx, "hai");
-    sendToIf1(ctx, "goodbye");
-    Allocator_free(ctx->alloc);
-}
-
-static void poly1305UnknownKeyAndPassword()
-{
-    struct Context* ctx = init(NULL, NULL, "anotherPassword");
-    sendToIf2(ctx, "hello world");
-    sendToIf1(ctx, "hello cjdns");
-    sendToIf2(ctx, "hai");
-    sendToIf1(ctx, "goodbye");
-    Allocator_free(ctx->alloc);
-}
-
-static void connectToMe()
-{
-    struct Context* ctx = simpleInit();
-    sendToIf1(ctx, "hello world");
-    sendToIf1(ctx, "hello cjdns");
-    sendToIf2(ctx, "hai");
-    sendToIf1(ctx, "goodbye");
-    Allocator_free(ctx->alloc);
-}
-
-static void connectToMeDropMsg()
-{
-    struct Context* ctx = simpleInit();
-
-    // send a message which is lost in the network.
-    encryptMsg(ctx, ctx->sess2, "hello world");
-
-    // Now we learn their key some other way...
-    Bits_memcpyConst(ctx->sess2->herPublicKey, ctx->ca1->publicKey, 32);
-
-    sendToIf1(ctx, "hello again world");
-    sendToIf2(ctx, "hai");
-    sendToIf1(ctx, "goodbye");
-    Allocator_free(ctx->alloc);
-}
-
 static void replayKeyPacket(int scenario)
 {
     struct Context* ctx = simpleInit();
 
-    sendToIf1(ctx, "hello world");
+    sendToIf2(ctx, "hello world");
 
     struct Message* msg = encryptMsg(ctx, ctx->sess2, "hello replay key");
     struct Message* toReplay = Message_clone(msg, ctx->alloc);
-    decryptMsg(ctx, msg, ctx->sess2, "hello replay key");
+    decryptMsg(ctx, msg, ctx->sess1, "hello replay key");
 
     if (scenario == 1) {
-        // If we replay at this stage, the packet makes it and is decrypted.
-        decryptMsg(ctx, toReplay, ctx->sess2, "hello replay key");
+        // the packet is failed because we know it's a dupe from the temp key.
+        decryptMsg(ctx, toReplay, ctx->sess1, NULL);
     }
 
-    sendToIf1(ctx, "first traffic packet");
+    sendToIf2(ctx, "first traffic packet");
 
     if (scenario == 2) {
-        // If we replay at this stage, the packet still makes it and is decrypted.
-        decryptMsg(ctx, toReplay, ctx->sess2, "hello replay key");
+        decryptMsg(ctx, toReplay, ctx->sess1, NULL);
     }
 
-    sendToIf2(ctx, "second traffic packet");
+    sendToIf1(ctx, "second traffic packet");
 
     if (scenario == 3) {
         // If we replay at this stage, the packet is dropped as a stray key
-        decryptMsg(ctx, toReplay, ctx->sess2, NULL);
+        decryptMsg(ctx, toReplay, ctx->sess1, NULL);
     }
 
     Allocator_free(ctx->alloc);
@@ -330,10 +258,7 @@ static void reset()
     decryptMsg(ctx, encryptMsg(ctx, ctx->sess2, "lost"), ctx->sess1, NULL);
 
     // This is because we want to prevent replay attacks from tearing down a session.
-    decryptMsg(ctx, encryptMsg(ctx, ctx->sess1, "hello which must be dropped"), ctx->sess2, NULL);
-    decryptMsg(ctx, encryptMsg(ctx, ctx->sess1, "hello which must also drop"), ctx->sess2, NULL);
-
-    CryptoAuth_reset(ctx->sess2);
+    decryptMsg(ctx, encryptMsg(ctx, ctx->sess1, "hello"), ctx->sess2, "hello");
 
     sendToIf1(ctx, "hello again");
     sendToIf2(ctx, "hai");
@@ -379,13 +304,6 @@ int main()
     repeatHello();
     chatter();
     auth();
-    authWithoutKey();
-    poly1305();
-    poly1305UnknownKey();
-    poly1305AndPassword();
-    poly1305UnknownKeyAndPassword();
-    connectToMe();
-    connectToMeDropMsg();
     replayKeyPacket(1);
     replayKeyPacket(2);
     replayKeyPacket(3);

+ 2 - 0
dht/DHTMessage.h

@@ -43,6 +43,8 @@ struct DHTMessage
     struct EncodingScheme* encodingScheme;
     int encIndex;
 
+    int pleaseRespond;
+
     /**
      * If this message is an outgoing reply, replyTo is the original query.
      * For incoming replies or any queries, it is NULL.

+ 11 - 0
dht/Pathfinder.c

@@ -103,6 +103,12 @@ static int incomingFromDHT(struct DHTMessage* dmessage, void* vpf)
 
     Log_debug(pf->log, "Outgoing DHT");
 
+    if (dmessage->replyTo) {
+        // see incomingMsg
+        dmessage->replyTo->pleaseRespond = true;
+        return 0;
+    }
+
     Iface_send(&pf->eventIf, msg);
     return 0;
 }
@@ -305,6 +311,11 @@ static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf)
 
     DHTModuleRegistry_handleIncoming(&dht, pf->registry);
 
+    if (dht.pleaseRespond) {
+        // what a beautiful hack, see incomingFromDHT
+        return Iface_next(&pf->eventIf, msg);
+    }
+
     return NULL;
 }
 

+ 1 - 2
interface/FramingIface.c

@@ -123,9 +123,8 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* streamIf)
         }
 
         if (fi->bytesRemaining == (uint32_t)msg->length) {
-            Iface_send(&fi->messageIf, msg);
             fi->bytesRemaining = 0;
-            return NULL;
+            return Iface_next(&fi->messageIf, msg);
 
         } else if (fi->bytesRemaining <= (uint32_t)msg->length) {
             struct Message* m = Allocator_clone(msg->alloc, msg);

+ 85 - 20
interface/Iface.h

@@ -18,6 +18,7 @@
 #include <stdint.h>
 
 #include "wire/Message.h"
+#include "util/Defined.h"
 
 struct Iface;
 
@@ -43,56 +44,120 @@ struct Iface
     struct Iface* connectedIf;
 };
 
+/**
+ * Send a message to an Iface.
+ * Whatever interface has been *plumbed* to this interface using Iface_plumb() will receive
+ * the message. If you are in an Iface_Callback function, you must not use this function to
+ * forward the message which you have received as your input, to do so will cause a runtime
+ * assertion error, in order to forward the message which you received, you must use Iface_next()
+ * and it must be a tail-call.
+ */
 static inline void Iface_send(struct Iface* iface, struct Message* msg)
 {
     do {
         struct Iface* conn = iface->connectedIf;
-        if (!conn) { return; }
+
         #ifdef PARANOIA
+            Assert_true(!msg->currentIface);
+            Assert_true(conn);
             Assert_true(conn->send);
             Assert_true(msg);
-            msg->currentIface = iface;
-            iface->currentMsg = msg;
+            struct Message* currentMsg = conn->currentMsg;
+            Assert_true(!msg->currentIface);
+            msg->currentIface = conn;
+            conn->currentMsg = msg;
         #endif
+
+        iface = conn->send(msg, conn);
+
         #ifdef PARANOIA
-            struct Iface* ifaceNext = conn->send(msg, conn);
             msg->currentIface = NULL;
-            iface->currentMsg = NULL;
-            iface = ifaceNext;
-        #else
-            iface = conn->send(conn, msg);
+            conn->currentMsg = currentMsg;
         #endif
-        #ifndef STUPID_OPTIMIZATIONS
+
+        if (!Defined(Iface_OPTIMIZE)) {
             Assert_true(!iface);
-        #endif
+        }
     } while (iface);
 }
 
 /**
- * This is a hack high-performance version of Iface_send() which can only be used as a tail call.
- * You MUST pass the same msg which was passed to you, otherwise it will fail.
+ * Forward a message from inside of an Iface_Callback function.
+ * This function must be a tail-call, you must return the value returned to you.
+ * If you do anything between the call to this function and your return of it's return value,
+ * the order in which that thing happens is undefined.
+ *
+ * Consider the following (bad) code:
+ *     struct Iface* retVal = Iface_next(iface, msg);
+ *     x++;
+ *     return retVal;
+ *
+ * If Iface_OPTIMIZE is enabled, it becomes equivilant to:
+ *     x++;
+ *     struct Iface* retVal = Iface_next(iface, msg);
+ *     return retVal;
+ *
+ * So simplify your life and follow the basic rule of always returning directly the value
+ * from this function, IE: return Iface_next(iface, msg);
  */
 static inline Iface_DEFUN Iface_next(struct Iface* iface, struct Message* msg)
 {
     #ifdef PARANOIA
+        struct Iface* conn = iface->connectedIf;
+        struct Message* currentMsg = conn->currentMsg;
         Assert_true(msg->currentIface);
         Assert_true(msg->currentIface->currentMsg == msg);
+        msg->currentIface->currentMsg = NULL;
+        if (Defined(Iface_OPTIMIZE)) {
+            msg->currentIface = conn;
+            conn->currentMsg = msg;
+        } else {
+            // done inside of Iface_send()
+            msg->currentIface = NULL;
+            conn->currentMsg = NULL;
+        }
     #endif
 
-    #ifdef STUPID_OPTIMIZATIONS
+    if (Defined(Iface_OPTIMIZE)) {
         return iface;
-    #endif
+    }
 
     Iface_send(iface, msg);
+
+    #ifdef PARANOIA
+        conn->currentMsg = currentMsg;
+    #endif
+
     return NULL;
 }
 
-#define Iface_CALL(func, msg, ...) \
-    do {                                                      \
-        struct Iface* Iface_x = func(msg, __VA_ARGS__);       \
-        if (Iface_x) { Iface_send(Iface_x, msg); }            \
-    } while (0)
-// CHECKFILES_IGNORE missing ;
+/**
+ * Call a function which might use Iface_next()
+ * This macro will call a function, passing it a message and other arguments, if the function
+ * you are calling might use Iface_next(), you must call it with this macro instead of calling
+ * it directly.
+ * If you are calling from a Iface_Callback function, you must not use this function to call
+ * the next function with the message passed to you. If  
+ */
+#ifdef PARANOIA
+    #define Iface_CALL(func, msg, ...) \
+        do {                                                \
+            struct Iface Iface_y = { .currentMsg = msg };   \
+            Assert_true(!msg->currentIface);                \
+            msg->currentIface = &Iface_y;                   \
+            struct Iface* Iface_x = func(msg, __VA_ARGS__); \
+            msg->currentIface = NULL;                       \
+            if (Iface_x) { Iface_send(Iface_x, msg); }      \
+        } while (0)
+    // CHECKFILES_IGNORE missing ;
+#else
+    #define Iface_CALL(func, msg, ...) \
+        do {                                                 \
+            struct Iface* Iface_x = func(msg, __VA_ARGS__);  \
+            if (Iface_x) { Iface_send(Iface_x, msg); }       \
+        } while (0)
+    // CHECKFILES_IGNORE missing ;
+#endif
 
 static inline void Iface_plumb(struct Iface* a, struct Iface* b)
 {

+ 1 - 1
interface/test/FramingIface_fuzz_test.c

@@ -70,7 +70,7 @@ int main()
     struct Allocator* mainAlloc = MallocAllocator_new(1<<20);
     struct Log* log = FileWriterLog_new(stdout, mainAlloc);
     struct Random* rand = Random_new(mainAlloc, log, NULL);
-    struct Context* ctx = Allocator_malloc(mainAlloc, sizeof(struct Context));
+    struct Context* ctx = Allocator_calloc(mainAlloc, sizeof(struct Context), 1);
     Identity_set(ctx);
     ctx->internalIf.send = messageOut;
     struct Iface externalIf = { .send = NULL };

+ 6 - 12
net/EventEmitter.c

@@ -176,11 +176,7 @@ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* trickIf)
         for (int i = 0; i < ee->pathfinders->length; i++) {
             struct Pathfinder* pf = ArrayList_Pathfinders_get(ee->pathfinders, i);
             if (!pf || pf->state != Pathfinder_state_CONNECTED) { continue; }
-            struct Message* messageClone = msg;
-            if (ee->pathfinders->length > i+1) {
-                // if only one handler, no need to copy the message...
-                messageClone = Message_clone(msg, msg->alloc);
-            }
+            struct Message* messageClone = Message_clone(msg, msg->alloc);
             Iface_CALL(sendToPathfinder, messageClone, pf);
         }
     }
@@ -224,7 +220,8 @@ static int handleFromPathfinder(enum PFChan_Pathfinder ev,
             Bits_memcpyConst(resp.publicKey, ee->publicKey, 32);
             Message_push(msg, &resp, PFChan_Core_Connect_SIZE, NULL);
             Message_push32(msg, PFChan_Core_CONNECT, NULL);
-            Iface_CALL(sendToPathfinder, msg, pf);
+            struct Message* sendMsg = Message_clone(msg, msg->alloc);
+            Iface_CALL(sendToPathfinder, sendMsg, pf);
             break;
         }
         case PFChan_Pathfinder_SUPERIORITY: {
@@ -236,7 +233,8 @@ static int handleFromPathfinder(enum PFChan_Pathfinder ev,
         }
 
         case PFChan_Pathfinder_PING: {
-            Iface_send(&pf->iface, msg);
+            struct Message* sendMsg = Message_clone(msg, msg->alloc);
+            Iface_send(&pf->iface, sendMsg);
             break;
         }
         case PFChan_Pathfinder_PONG: {
@@ -302,11 +300,7 @@ static Iface_DEFUN incomingFromPathfinder(struct Message* msg, struct Iface* ifa
     struct ArrayList_Ifaces* handlers = getHandlers(ee, ev, false);
     if (!handlers) { return NULL; }
     for (int i = 0; i < handlers->length; i++) {
-        struct Message* messageClone = msg;
-        if (handlers->length > i+1) {
-            // if only one handler, no need to copy the message...
-            messageClone = Message_clone(msg, msg->alloc);
-        }
+        struct Message* messageClone = Message_clone(msg, msg->alloc);
         struct Iface* iface = ArrayList_Ifaces_get(handlers, i);
         // We have to call this manually because we don't have an interface handy which is
         // actually plumbed with this one.

+ 1 - 3
node_build/make.js

@@ -56,9 +56,7 @@ Builder.configure({
         '-pedantic',
         '-D', builder.config.systemName + '=1',
         '-Wno-unused-parameter',
-//        '-Wno-unused-result',
-
-        '-D', 'HAS_BUILTIN_CONSTANT_P',
+        '-fomit-frame-pointer',
 
         '-D', 'Log_' + builder.config.logLevel,
 

+ 1 - 1
wire/Message.h

@@ -60,7 +60,7 @@ static inline struct Message* Message_new(uint32_t messageLength,
                                           struct Allocator* alloc)
 {
     uint8_t* buff = Allocator_malloc(alloc, messageLength + amountOfPadding);
-    struct Message* out = Allocator_malloc(alloc, sizeof(struct Message));
+    struct Message* out = Allocator_calloc(alloc, sizeof(struct Message), 1);
     out->bytes = &buff[amountOfPadding];
     out->length = out->capacity = messageLength;
     out->padding = amountOfPadding;