Example #1
0
static void encryptRndNonceTest()
{
    uint8_t buff[44];
    Bits_memset(buff, 0, 44);

    uint8_t nonce[24];
    Bits_memset(nonce, 0, 24);

    uint8_t secret[32];
    Bits_memset(secret, 0, 32);

    struct Message m = { .bytes=&buff[32], .length=12, .padding=32};
    CString_strcpy((char*) m.bytes, "hello world");

    CryptoAuth_encryptRndNonce(nonce, &m, secret);

    uint8_t* expected = (uint8_t*) "1391ac5d03ba9f7099bffbb6e6c69d67ae5bd79391a5b94399b293dc";
    uint8_t output[57];
    Hex_encode(output, 57, m.bytes, m.length);

    //printf("\n%s\n%s\n", (char*) expected, (char*) output);
    Assert_true(!Bits_memcmp(expected, output, 56));

    Assert_true(!CryptoAuth_decryptRndNonce(nonce, &m, secret));
    Assert_true(m.length == 12 && !Bits_memcmp(m.bytes, "hello world", m.length));
}

static struct Random* evilRandom(struct Allocator* alloc, struct Log* logger)
{
    struct RandomSeed* evilSeed = DeterminentRandomSeed_new(alloc);
    return Random_newWithSeed(alloc, logger, evilSeed, NULL);
}

static void createNew()
{
    struct Allocator* allocator = MallocAllocator_new(BUFFER_SIZE);
    struct CryptoAuth* ca =
        CryptoAuth_new(allocator, privateKey, eventBase, NULL, evilRandom(allocator, NULL));
    /*for (int i = 0; i < 32; i++) {
        printf("%.2x", ca->publicKey[i]);
    }*/
    Assert_true(Bits_memcmp(ca->publicKey, publicKey, 32) == 0);
    Allocator_free(allocator);
}

static uint8_t receiveMessage(struct Message* message, struct Interface* iface)
{
    Message_pop(message, NULL, 4, NULL);
    *((struct Message**)iface->receiverContext) = message;
    return Error_NONE;
}
Example #2
0
int main()
{
    AddressCalc_addressForPublicKey(nodeCjdnsIp6, fakePubKey);
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Writer* w = FileWriter_new(stdout, alloc);
    struct Log* logger = WriterLog_new(w, alloc);
    struct Random* rand = Random_new(alloc, logger, NULL);
    struct EventBase* eb = EventBase_new(alloc);

    struct IpTunnel* ipTun = IpTunnel_new(logger, eb, alloc, rand, NULL);
    struct Sockaddr_storage ip6ToGive;
    Sockaddr_parse("fd01:0101:0101:0101:0101:0101:0101:0101", &ip6ToGive);
    IpTunnel_allowConnection(fakePubKey, &ip6ToGive.addr, NULL, ipTun);

    struct Message* message;
    Message_STACK(message, 64, 512);
    message->alloc = alloc;

    const char* requestForAddresses =
        "d"
          "1:q" "21:IpTunnel_getAddresses"
          "4:txid" "4:abcd"
        "e";
    CString_strcpy((char*)message->bytes, requestForAddresses);
    message->length = CString_strlen(requestForAddresses);

    Message_shift(message, Headers_UDPHeader_SIZE, NULL);
    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes;

    uh->srcPort_be = 0;
    uh->destPort_be = 0;
    uh->length_be = Endian_hostToBigEndian16(message->length - Headers_UDPHeader_SIZE);
    uint16_t* checksum = &uh->checksum_be;
    *checksum = 0;
    uint32_t length = message->length;

    Message_shift(message, Headers_IP6Header_SIZE, NULL);
    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;

    ip->versionClassAndFlowLabel = 0;
    ip->flowLabelLow_be = 0;
    ip->payloadLength_be = Endian_hostToBigEndian16(length);
    ip->nextHeader = 17;
    ip->hopLimit = 255;
    Bits_memset(ip->sourceAddr, 0, 32);
    Headers_setIpVersion(ip);

    Message_shift(message, IpTunnel_PacketInfoHeader_SIZE, NULL);
    struct IpTunnel_PacketInfoHeader* pi = (struct IpTunnel_PacketInfoHeader*) message->bytes;

    Bits_memcpyConst(pi->nodeIp6Addr, nodeCjdnsIp6, 16);
    Bits_memcpyConst(pi->nodeKey, fakePubKey, 32);

    *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length);

    ipTun->nodeInterface.receiveMessage = responseWithIpCallback;
    ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface);
    Assert_true(called);
    called = 0;

    // Now create a message for someone else.
    Message_shift(message,
        Headers_UDPHeader_SIZE
        + Headers_IP6Header_SIZE
        + IpTunnel_PacketInfoHeader_SIZE,
        NULL);
    Bits_memcpyConst(ip->sourceAddr, fakeIp6ToGive, 16);
    // This can't be zero.
    Bits_memset(ip->destinationAddr, 1, 16);

    ipTun->tunInterface.receiveMessage = messageToTun;
    ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface);
    Assert_true(called);

    Allocator_free(alloc);
    return 0;
}
Example #3
0
int main()
{
    AddressCalc_addressForPublicKey(nodeCjdnsIp6, fakePubKey);
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Log* logger = FileWriterLog_new(stdout, alloc);
    struct Random* rand = Random_new(alloc, logger, NULL);
    struct EventBase* eb = EventBase_new(alloc);

    struct IpTunnel* ipTun = IpTunnel_new(logger, eb, alloc, rand);
    struct Sockaddr_storage ip6ToGive;
    Sockaddr_parse("fd01:0101:0101:0101:0101:0101:0101:0101", &ip6ToGive);
    IpTunnel_allowConnection(fakePubKey, &ip6ToGive.addr, 0, NULL, 0, ipTun);

    struct Message* message;
    Message_STACK(message, 64, 512);
    message->alloc = alloc;

    const char* requestForAddresses =
        "d"
          "1:q" "21:IpTunnel_getAddresses"
          "4:txid" "4:abcd"
        "e";
    CString_strcpy((char*)message->bytes, requestForAddresses);
    message->length = CString_strlen(requestForAddresses);

    Message_shift(message, Headers_UDPHeader_SIZE, NULL);
    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes;

    uh->srcPort_be = 0;
    uh->destPort_be = 0;
    uh->length_be = Endian_hostToBigEndian16(message->length - Headers_UDPHeader_SIZE);
    uint16_t* checksum = &uh->checksum_be;
    *checksum = 0;
    uint32_t length = message->length;

    Message_shift(message, Headers_IP6Header_SIZE, NULL);
    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;

    ip->versionClassAndFlowLabel = 0;
    ip->flowLabelLow_be = 0;
    ip->payloadLength_be = Endian_hostToBigEndian16(length);
    ip->nextHeader = 17;
    ip->hopLimit = 255;
    Bits_memset(ip->sourceAddr, 0, 32);
    Headers_setIpVersion(ip);

    Message_shift(message, RouteHeader_SIZE + DataHeader_SIZE, NULL);
    struct RouteHeader* rh = (struct RouteHeader*) message->bytes;
    struct DataHeader* dh = (struct DataHeader*) &rh[1];

    Bits_memset(rh, 0, RouteHeader_SIZE + DataHeader_SIZE);
    Bits_memcpy(rh->ip6, nodeCjdnsIp6, 16);
    Bits_memcpy(rh->publicKey, fakePubKey, 32);
    DataHeader_setContentType(dh, ContentType_IPTUN);

    *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length);

    int origCap = message->capacity;
    int origLen = message->length;

    struct Iface nodeIface = { .send = responseWithIpCallback };
    Iface_plumb(&nodeIface, &ipTun->nodeInterface);
    struct Iface tunIface = { .send = messageToTun };
    Iface_plumb(&tunIface, &ipTun->tunInterface);

    Iface_send(&nodeIface, message);
    Assert_true(called == 2);
    called = 0;

    // This is a hack, reusing the message will cause breakage if IpTunnel is refactored.
    Message_reset(message);
    Message_shift(message, origCap, NULL);
    message->length = origLen;

    Bits_memcpy(ip->sourceAddr, fakeIp6ToGive, 16);
    // This can't be zero.
    Bits_memset(ip->destinationAddr, 1, 16);

    Iface_send(&nodeIface, message);
    Assert_true(called == 1);

    Allocator_free(alloc);
    return 0;
}
Example #4
0
static void testAddr(struct Context* ctx,
                     char* addr4, int prefix4, int alloc4,
                     char* addr6, int prefix6, int alloc6)
{
    struct Allocator* alloc = Allocator_child(ctx->alloc);
    struct IpTunnel* ipTun = IpTunnel_new(ctx->log, ctx->base, alloc, ctx->rand, NULL);

    struct Sockaddr* sa4 = NULL;
    struct Sockaddr_storage ip6ToGive;
    struct Sockaddr_storage ip4ToGive;
    if (addr4) {
        Assert_true(!Sockaddr_parse(addr4, &ip4ToGive));
        sa4 = &ip4ToGive.addr;
        Assert_true(Sockaddr_getFamily(sa4) == Sockaddr_AF_INET);
    }
    struct Sockaddr* sa6 = NULL;
    if (addr6) {
        Assert_true(!Sockaddr_parse(addr6, &ip6ToGive));
        sa6 = &ip6ToGive.addr;
        Assert_true(Sockaddr_getFamily(sa6) == Sockaddr_AF_INET6);
    }

    IpTunnel_allowConnection(ctx->pubKey,
                             sa6, prefix6, alloc6,
                             sa4, prefix4, alloc4,
                             ipTun);

    struct Message* msg = Message_new(64, 512, alloc);
    const char* requestForAddresses =
        "d"
          "1:q" "21:IpTunnel_getAddresses"
          "4:txid" "4:abcd"
        "e";
    CString_strcpy(msg->bytes, requestForAddresses);
    msg->length = CString_strlen(requestForAddresses);

    Message_push(msg, NULL, Headers_UDPHeader_SIZE, NULL);
    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) msg->bytes;
    uh->length_be = Endian_hostToBigEndian16(msg->length - Headers_UDPHeader_SIZE);

    uint16_t* checksum = &((struct Headers_UDPHeader*) msg->bytes)->checksum_be;
    *checksum = 0;
    uint32_t length = msg->length;

    // Because of old reasons, we need to have at least an empty IPv6 header
    Message_push(msg, NULL, Headers_IP6Header_SIZE, NULL);
    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) msg->bytes;
    Headers_setIpVersion(ip);
    ip->payloadLength_be = Endian_hostToBigEndian16(msg->length - Headers_IP6Header_SIZE);
    ip->nextHeader = 17;

    *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length);

    pushRouteDataHeaders(ctx, msg);

    struct IfaceContext* nodeIf = Allocator_calloc(alloc, sizeof(struct IfaceContext), 1);
    nodeIf->ctx = ctx;
    nodeIf->iface.send = responseWithIpCallback;
    struct IfaceContext* tunIf = Allocator_calloc(alloc, sizeof(struct IfaceContext), 1);
    tunIf->ctx = ctx;
    tunIf->iface.send = messageToTun;
    Iface_plumb(&nodeIf->iface, &ipTun->nodeInterface);
    Iface_plumb(&tunIf->iface, &ipTun->tunInterface);
    ctx->expectedResponse =
        getExpectedResponse(sa4, prefix4, alloc4, sa6, prefix6, alloc6, alloc);
    Iface_send(&nodeIf->iface, msg);
    Assert_true(ctx->called == 2);
    ctx->called = 0;

    if (sa4) {
        uint8_t* addrBytes = NULL;
        Assert_true(Sockaddr_getAddress(sa4, &addrBytes) == 4);
        uint32_t addr;
        Bits_memcpy(&addr, addrBytes, 4);
        addr = Endian_bigEndianToHost32(addr);
        // Send from the address specified
        Assert_true(trySend4(alloc, addr, &nodeIf->iface, ctx));

        if (alloc4 < 32) {
            // Send from another (random) address in the prefix
            uint32_t flip = Random_uint32(ctx->rand) >> alloc4;
            if (prefix4 != 32) {
                Assert_true(trySend4(alloc, addr ^ flip, &nodeIf->iface, ctx));
            } else {
                // If netSize is not specified, we do not allow multi-address
                Assert_true(!trySend4(alloc, addr ^ flip, &nodeIf->iface, ctx));
            }
        } else {
Example #5
0
static void encryptRndNonceTest()
{
    uint8_t buff[44];
    Bits_memset(buff, 0, 44);

    uint8_t nonce[24];
    Bits_memset(nonce, 0, 24);

    uint8_t secret[32];
    Bits_memset(secret, 0, 32);

    struct Message m = { .bytes=&buff[32], .length=HELLOWORLDLEN, .padding=32};
    CString_strcpy((char*) m.bytes, HELLOWORLDLOWER);

    CryptoAuth_encryptRndNonce(nonce, &m, secret);

    uint8_t* expected = (uint8_t*) "1391ac5d03ba9f7099bffbb6e6c69d67ae5bd79391a5b94399b293dc";
    uint8_t output[57];
    Hex_encode(output, 57, m.bytes, m.length);

    printf("\n%s\n%s\n", (char*) expected, (char*) output);
    Assert_true(!Bits_memcmp(expected, output, 56));

    Assert_true(!CryptoAuth_decryptRndNonce(nonce, &m, secret));
    Assert_true(m.length == HELLOWORLDLEN && !Bits_memcmp(m.bytes, HELLOWORLDLOWER, m.length));
}

static struct Random* evilRandom(struct Allocator* alloc, struct Log* logger)
{
    struct RandomSeed* evilSeed = DeterminentRandomSeed_new(alloc, NULL);
    return Random_newWithSeed(alloc, logger, evilSeed, NULL);
}

struct Context
{
    struct Allocator* alloc;
    struct CryptoAuth* ca;
    struct CryptoAuth_Session* sess;
    struct Log* log;
    struct EventBase* base;
};

static struct Context* setUp(uint8_t* myPrivateKey,
                             uint8_t* herPublicKey,
                             uint8_t* authPassword,
                             struct Allocator* alloc)
{
    struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1);
    struct Log* log = ctx->log = FileWriterLog_new(stdout, alloc);
    struct EventBase* base = ctx->base = EventBase_new(alloc);
    struct CryptoAuth* ca = ctx->ca =
        CryptoAuth_new(alloc, myPrivateKey, base, log, evilRandom(alloc, log));

    struct CryptoAuth_Session* sess = ctx->sess =
        CryptoAuth_newSession(ca, alloc, herPublicKey, NULL, false, Gcc_FILE);

    if (authPassword) {
        CryptoAuth_setAuth(String_CONST(authPassword), NULL, sess);
    }

    return ctx;
}

static void testHello(uint8_t* password, uint8_t* expectedOutput)
{
    Assert_true(CString_strlen((char*)expectedOutput) == 264);
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Context* ctx = setUp(NULL, HERPUBKEY, password, alloc);
    struct Message* msg = Message_new(0, CryptoHeader_SIZE + 12, alloc);
    Message_push(msg, HELLOWORLD, HELLOWORLDLEN, NULL);

    Assert_true(!CryptoAuth_encrypt(ctx->sess, msg));

    char* actual = Hex_print(msg->bytes, msg->length, alloc);
    if (CString_strcmp(actual, expectedOutput)) {
        Assert_failure("Test failed.\n"
                       "Expected %s\n"
                       "     Got %s\n", expectedOutput, actual);
    }
    Allocator_free(alloc);
}