/* vim: set expandtab ts=4 sw=4: */ /* * You may redistribute this program and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define string_strcpy #define string_strlen #include "benc/List.h" #include "benc/String.h" #include "crypto/CryptoAuth_pvt.h" #include "crypto/random/Random.h" #include "crypto/random/test/DeterminentRandomSeed.h" #include "io/FileWriter.h" #include "memory/MallocAllocator.h" #include "memory/Allocator.h" #include "util/platform/libc/string.h" #include "util/events/EventBase.h" #include "util/Assert.h" #include "util/Bits.h" #include "util/Hex.h" #include "util/log/WriterLog.h" #include "wire/Error.h" #include "wire/Message.h" #include #define BUFFER_SIZE 8192*4 static uint8_t* privateKey = (uint8_t*) "0123456789abcdefghijklmnopqrstuv"; static uint8_t* publicKey = (uint8_t*) "\x3f\x5b\x96\x62\x11\x11\xd8\x9c\x7d\x3f\x51\x71\x68\x78\xfa\xb4" "\xc3\xcf\xd9\x7e\x32\x04\x12\xb4\xaf\x7e\x22\x92\xa5\xdf\x31\x71"; static struct EventBase* eventBase; static uint8_t* hello = (uint8_t*) "Hello World"; 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}; 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_always(!Bits_memcmp(expected, output, 56)); Assert_always(!CryptoAuth_decryptRndNonce(nonce, &m, secret)); Assert_always(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_always(Bits_memcmp(ca->publicKey, publicKey, 32) == 0); Allocator_free(allocator); } static uint8_t receiveMessage(struct Message* message, struct Interface* iface) { *((struct Message**)iface->receiverContext) = message; return Error_NONE; } static uint8_t sendMessage(struct Message* message, struct Interface* iface) { *((struct Message**)iface->senderContext) = message; return Error_NONE; } static struct CryptoAuth_Wrapper* setUp(uint8_t* myPrivateKey, uint8_t* herPublicKey, uint8_t* authPassword, struct Message** resultMessage) { struct Allocator* allocator = MallocAllocator_new(8192*2); struct Writer* writer = FileWriter_new(stdout, allocator); struct Log* logger = WriterLog_new(writer, allocator); struct CryptoAuth* ca = CryptoAuth_new(allocator, myPrivateKey, eventBase, logger, evilRandom(allocator, logger)); struct Interface* iface = Allocator_clone(allocator, (&(struct Interface) { .sendMessage = sendMessage, .senderContext = resultMessage })); struct CryptoAuth_Wrapper* wrapper = Allocator_clone(allocator, (&(struct CryptoAuth_Wrapper) { .context = (struct CryptoAuth_pvt*) ca, .wrappedInterface = iface })); #ifdef Identity_CHECK wrapper->Identity_verifier = ((struct CryptoAuth_pvt*)ca)->Identity_verifier; #endif if (authPassword) { struct Interface temp = { .senderContext = wrapper, .allocator = allocator }; String str = { .bytes = (char*) authPassword, .len = strlen((char*)authPassword) }; CryptoAuth_setAuth(&str, 1, &temp); } if (herPublicKey) { Bits_memcpyConst(wrapper->herPerminentPubKey, herPublicKey, 32); } return wrapper; } static void testHello(uint8_t* password, uint8_t* expectedOutput) { Assert_always(strlen((char*)expectedOutput) == 264); struct Message* outMessage; struct CryptoAuth_Wrapper* wrapper = setUp(NULL, (uint8_t*) "wxyzabcdefghijklmnopqrstuv987654", password, &outMessage); uint8_t msgBuff[Headers_CryptoAuth_SIZE + 12]; struct Message msg = { .length = 12, .padding = Headers_CryptoAuth_SIZE, .bytes = msgBuff + Headers_CryptoAuth_SIZE }; Bits_memcpyConst(msg.bytes, hello, 12); CryptoAuth_encryptHandshake(&msg, wrapper, 0); uint8_t actual[265]; Assert_always(Hex_encode(actual, 265, outMessage->bytes, outMessage->length) > 0); //printf("%s", actual); if (Bits_memcmp(actual, expectedOutput, 264)) { Assert_failure("Test failed.\n" "Expected %s\n" " Got %s\n", expectedOutput, actual); } } static void helloNoAuth() { uint8_t* expected = (uint8_t*) "00000000007691d3802a9d04fc403525497a185dabda71739c1f35465fac3448" "b92a0c36ebff1cf7050383c91e7d56ec2336c09739fa8e91d8dc5bec63e8fad0" "74bee22a90642a6b4188f374afd90ccc97bb61873b5d8a3b4a6071b60b26a8c7" "2d6484634df315c4d3ad63de42fe3e4ebfd83bcdab2e1f5f40dc5a08eda4e6c6" "b7067d3b"; testHello(NULL, expected); } static void helloWithAuth() { uint8_t* expected = (uint8_t*) "0000000001641c99f7719f5780003eb1497a185dabda71739c1f35465fac3448" "b92a0c36ebff1cf7050383c91e7d56ec2336c09739fa8e91d8dc5bec63e8fad0" "74bee22a90642a6b022e089e0550ca84b86884af6a0263fa5fff9ba07583aea4" "acb000dbe4115623cf335c63981b9645b6c89fbdc3ad757744879751de0f215d" "2479131d"; testHello((uint8_t*)"password", expected); } static void receiveHelloWithNoAuth() { uint8_t* messageHex = (uint8_t*) "0000000000ffffffffffffff7fffffffffffffffffffffffffffffffffffffff" "ffffffffffffffff847c0d2c375234f365e660955187a3735a0f7613d1609d3a" "6a4d8c53aeaa5a22ea9cf275eee0185edf7f211192f12e8e642a325ed76925fe" "3c76d313b767a10aca584ca0b979dee990a737da7d68366fa3846d43d541de91" "29ea3e12"; uint8_t message[132]; Assert_always(Hex_decode(message, 132, messageHex, strlen((char*)messageHex)) > 0); struct Message incoming = { .length = 132, .padding = 0, .bytes = message }; struct CryptoAuth_Wrapper* wrapper = setUp(privateKey, NULL, NULL, NULL); struct Message* finalOut = NULL; wrapper->externalInterface.receiveMessage = receiveMessage; wrapper->externalInterface.receiverContext = &finalOut; CryptoAuth_receiveMessage(&incoming, &(struct Interface) { .receiverContext = wrapper } ); Assert_always(finalOut); Assert_always(finalOut->length == 12); Assert_always(Bits_memcmp(hello, finalOut->bytes, 12) == 0); //printf("bytes=%s length=%u\n", finalOut->bytes, finalOut->length); } static void repeatHello() { struct Allocator* allocator = MallocAllocator_new(1<<20); struct Writer* logwriter = FileWriter_new(stdout, allocator); struct Log* logger = WriterLog_new(logwriter, allocator); struct CryptoAuth* ca = CryptoAuth_new(allocator, NULL, eventBase, logger, evilRandom(allocator, logger)); struct Message* out = NULL; struct Interface iface = { .sendMessage = sendMessage, .senderContext = &out }; struct CryptoAuth_Wrapper wrapper = { .context = (struct CryptoAuth_pvt*) ca, .wrappedInterface = &iface }; Bits_memcpyConst(wrapper.herPerminentPubKey, publicKey, 32); uint8_t* hello = (uint8_t*) "Hello World"; uint8_t msgBuff[Headers_CryptoAuth_SIZE + 12]; struct Message msg = { .length = 12, .padding = Headers_CryptoAuth_SIZE, .bytes = msgBuff + Headers_CryptoAuth_SIZE }; struct Message msg2; Bits_memcpyConst(&msg2, &msg, sizeof(struct Message)); Bits_memcpyConst(msg2.bytes, hello, 12); CryptoAuth_encryptHandshake(&msg, &wrapper, 0); Bits_memcpyConst(msg2.bytes, hello, 12); CryptoAuth_encryptHandshake(&msg2, &wrapper, 0); // Check the nonce Assert_always(!Bits_memcmp(msg2.bytes, "\0\0\0\1", 4)); ca = CryptoAuth_new(allocator, privateKey, eventBase, logger, evilRandom(allocator, logger)); struct Message* finalOut = NULL; struct CryptoAuth_Wrapper wrapper2 = { .context = (struct CryptoAuth_pvt*) ca, .externalInterface = { .receiveMessage = receiveMessage, .receiverContext = &finalOut }, .wrappedInterface = &iface }; #ifdef Identity_CHECK wrapper2.Identity_verifier = ((struct CryptoAuth_pvt*)ca)->Identity_verifier; #endif CryptoAuth_receiveMessage(out, &(struct Interface) { .receiverContext = &wrapper2 } ); Assert_always(finalOut); Assert_always(finalOut->length == 12); Assert_always(Bits_memcmp(hello, finalOut->bytes, 12) == 0); //printf("bytes=%s length=%u\n", finalOut->bytes, finalOut->length); Allocator_free(allocator); } static void testGetUsers() { struct Allocator* allocator = MallocAllocator_new(1<<20); struct EventBase* base = EventBase_new(allocator); struct CryptoAuth* ca = CryptoAuth_new(allocator, NULL, base, NULL, evilRandom(allocator, NULL)); List* users = NULL; users = CryptoAuth_getUsers(ca, allocator); Assert_always(List_size(users) == -1); CryptoAuth_addUser(String_CONST("pass1"), 1, String_CONST("user1"), ca); users = CryptoAuth_getUsers(ca, allocator); Assert_always(List_size(users) == 1); Assert_always(String_equals(String_CONST("user1"),List_getString(users,0))); CryptoAuth_addUser(String_CONST("pass2"), 1, String_CONST("user2"), ca); users = CryptoAuth_getUsers(ca, allocator); Assert_always(List_size(users) == 2); Assert_always(String_equals(String_CONST("user2"),List_getString(users,0))); Assert_always(String_equals(String_CONST("user1"),List_getString(users,1))); Allocator_free(allocator); } int main() { testGetUsers(); struct Allocator* allocator = MallocAllocator_new(4096); eventBase = EventBase_new(allocator); helloNoAuth(); helloWithAuth(); receiveHelloWithNoAuth(); encryptRndNonceTest(); createNew(); repeatHello(); Allocator_free(allocator); return 0; }