CryptoAuth_test.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #define string_strcmp
  16. #define string_strncmp
  17. #define string_strlen
  18. #include "crypto/random/Random.h"
  19. #include "crypto/CryptoAuth.h"
  20. #include "io/FileWriter.h"
  21. #include "benc/String.h"
  22. #include "memory/MallocAllocator.h"
  23. #include "util/platform/libc/string.h"
  24. #include "util/events/EventBase.h"
  25. #include "util/Assert.h"
  26. #include "util/Bits.h"
  27. #include "util/Hex.h"
  28. #include "util/Endian.h"
  29. #include "util/log/WriterLog.h"
  30. #include "wire/Error.h"
  31. #include <stdio.h>
  32. static uint8_t* privateKey = (uint8_t*)
  33. "\x20\xca\x45\xd9\x5b\xbf\xca\xe7\x35\x3c\xd2\xdf\xfa\x12\x84\x4b"
  34. "\x4e\xff\xbe\x7d\x39\xd8\x4d\x8e\x14\x2b\x9d\x21\x89\x5b\x38\x09";
  35. static uint8_t* publicKey = (uint8_t*)
  36. "\x51\xaf\x8d\xd9\x35\xe8\x61\x86\x3e\x94\x2b\x1b\x6d\x21\x22\xe0"
  37. "\x2f\xb2\xd0\x88\x20\xbb\xf3\xf0\x6f\xcd\xe5\x85\x30\xe0\x08\x34";
  38. static struct CryptoAuth* ca1;
  39. static struct Interface* if1;
  40. static struct Interface* cif1;
  41. static struct CryptoAuth* ca2;
  42. static struct Interface* if2;
  43. static struct Interface* cif2;
  44. static struct Message msg;
  45. #define BUFFER_SIZE 400
  46. static uint8_t* textBuff;
  47. #define ALIGNED_LEN(x) (strlen(x) + 4 - (strlen(x) % 4))
  48. #define MK_MSG(x) \
  49. Bits_memset(textBuff, 0, BUFFER_SIZE); \
  50. Bits_memcpy(&textBuff[BUFFER_SIZE - ALIGNED_LEN(x)], x, strlen(x)); \
  51. msg.length = strlen(x); \
  52. msg.bytes = textBuff + BUFFER_SIZE - ALIGNED_LEN(x); \
  53. msg.padding = BUFFER_SIZE - ALIGNED_LEN(x)
  54. static uint8_t* if1Msg;
  55. static uint8_t* if2Msg;
  56. static char* userObj = "This represents a user";
  57. static bool suppressMessages = false;
  58. static int if1Messages = 0;
  59. static int if2Messages = 0;
  60. static uint8_t sendMessageToIf2(struct Message* message, struct Interface* iface)
  61. {
  62. uint32_t nonce = Endian_bigEndianToHost32(((uint32_t*)message->bytes)[0]);
  63. printf("sent message --> nonce=%d%s\n", nonce, suppressMessages ? " SUPPRESSED" : "");
  64. if (!suppressMessages) {
  65. Assert_always(message->length + message->padding <= BUFFER_SIZE);
  66. if2->receiveMessage(message, if2);
  67. }
  68. return Error_NONE;
  69. }
  70. static uint8_t sendMessageToIf1(struct Message* message, struct Interface* iface)
  71. {
  72. uint32_t nonce = Endian_bigEndianToHost32(((uint32_t*)message->bytes)[0]);
  73. printf("sent message <-- nonce=%d%s\n", nonce, suppressMessages ? " SUPPRESSED" : "");
  74. if (!suppressMessages) {
  75. Assert_always(message->length + message->padding <= BUFFER_SIZE);
  76. if1->receiveMessage(message, if1);
  77. }
  78. return Error_NONE;
  79. }
  80. static uint8_t recvMessageOnIf1(struct Message* message, struct Interface* iface)
  81. {
  82. if1Messages++;
  83. fputs("if1 got message! ", stdout);
  84. fwrite(message->bytes, 1, message->length, stdout);
  85. puts("");
  86. if1Msg = Message_clone(message, iface->allocator)->bytes;
  87. return Error_NONE;
  88. }
  89. static uint8_t recvMessageOnIf2(struct Message* message, struct Interface* iface)
  90. {
  91. if2Messages++;
  92. fputs("if2 got message! ", stdout);
  93. fwrite(message->bytes, 1, message->length, stdout);
  94. puts("");
  95. if2Msg = Message_clone(message, iface->allocator)->bytes;
  96. return Error_NONE;
  97. }
  98. static int init(const uint8_t* privateKey,
  99. uint8_t* publicKey,
  100. const uint8_t* password)
  101. {
  102. printf("\nSetting up:\n");
  103. struct Allocator* allocator = MallocAllocator_new(1048576);
  104. textBuff = Allocator_malloc(allocator, BUFFER_SIZE);
  105. struct Writer* logwriter = FileWriter_new(stdout, allocator);
  106. struct Log* logger = WriterLog_new(logwriter, allocator);
  107. struct Random* rand = Random_new(allocator, logger, NULL);
  108. struct EventBase* base = EventBase_new(allocator);
  109. ca1 = CryptoAuth_new(allocator, NULL, base, logger, rand);
  110. if1 = Allocator_clone(allocator, (&(struct Interface) {
  111. .sendMessage = sendMessageToIf2,
  112. .receiveMessage = recvMessageOnIf2,
  113. .allocator = allocator
  114. }));
  115. cif1 = CryptoAuth_wrapInterface(if1, publicKey, NULL, false, "cif1", ca1);
  116. cif1->receiveMessage = recvMessageOnIf1;
  117. ca2 = CryptoAuth_new(allocator, privateKey, base, logger, rand);
  118. if (password) {
  119. String passStr = {.bytes=(char*)password,.len=strlen((char*)password)};
  120. CryptoAuth_setAuth(&passStr, 1, cif1);
  121. CryptoAuth_addUser(&passStr, 1, String_new(userObj, allocator), ca2);
  122. }
  123. if2 = Allocator_clone(allocator, (&(struct Interface) {
  124. .sendMessage = sendMessageToIf1,
  125. .allocator = allocator
  126. }));
  127. cif2 = CryptoAuth_wrapInterface(if2, NULL, NULL, false, "cif2", ca2);
  128. cif2->receiveMessage = recvMessageOnIf2;
  129. return 0;
  130. }
  131. static int simpleInit()
  132. {
  133. return init(NULL, NULL, NULL);
  134. }
  135. static int sendToIf1(const char* x)
  136. {
  137. if1Msg = NULL;
  138. MK_MSG(x);
  139. cif2->sendMessage(&msg, cif2);
  140. if (!suppressMessages) {
  141. Assert_always(if1Msg);
  142. if (strncmp((char*)if1Msg, x, strlen(x)) != 0) {
  143. printf("expected %s, got %s\n", x, (char*)if1Msg);
  144. Assert_always(0);
  145. }
  146. } else {
  147. Assert_always(!if1Msg);
  148. }
  149. return 0;
  150. }
  151. static int sendToIf2(const char* x)
  152. {
  153. if2Msg = NULL;
  154. MK_MSG(x);
  155. cif1->sendMessage(&msg, cif1);
  156. if (!suppressMessages) {
  157. Assert_always(if2Msg);
  158. if (strncmp((char*)if2Msg, x, strlen(x)) != 0) {
  159. printf("expected %s, got %s\n", x, (char*)if2Msg);
  160. Assert_always(0);
  161. }
  162. } else {
  163. Assert_always(!if2Msg);
  164. }
  165. return 0;
  166. }
  167. static int normal()
  168. {
  169. simpleInit();
  170. return
  171. sendToIf2("hello world")
  172. | sendToIf1("hello cjdns")
  173. | sendToIf2("hai")
  174. | sendToIf1("goodbye");
  175. }
  176. static int repeatKey()
  177. {
  178. simpleInit();
  179. return
  180. sendToIf2("hello world")
  181. | sendToIf2("r u thar?")
  182. | sendToIf1("hello cjdns")
  183. | sendToIf2("hai")
  184. | sendToIf1("goodbye");
  185. }
  186. static int repeatHello()
  187. {
  188. init(privateKey, publicKey, NULL);
  189. return
  190. sendToIf2("hello world")
  191. | sendToIf2("r u thar?")
  192. | sendToIf1("hello cjdns")
  193. | sendToIf2("hai")
  194. | sendToIf1("goodbye");
  195. }
  196. static int chatter()
  197. {
  198. simpleInit();
  199. return
  200. sendToIf2("hello world")
  201. | sendToIf1("hello cjdns")
  202. | sendToIf2("hai")
  203. | sendToIf1("goodbye")
  204. | sendToIf1("hello cjdns")
  205. | sendToIf2("hai")
  206. | sendToIf1("goodbye")
  207. | sendToIf1("hello cjdns")
  208. | sendToIf2("hai")
  209. | sendToIf1("goodbye")
  210. | sendToIf1("hello cjdns")
  211. | sendToIf2("hai")
  212. | sendToIf1("goodbye");
  213. }
  214. static int auth()
  215. {
  216. init(privateKey, publicKey, (uint8_t*)"password");
  217. return
  218. sendToIf2("hello world")
  219. | sendToIf1("hello cjdns")
  220. | sendToIf2("hai")
  221. | sendToIf1("goodbye");
  222. }
  223. static int authWithoutKey()
  224. {
  225. init(NULL, NULL, (uint8_t*)"password");
  226. return
  227. sendToIf2("hello world")
  228. | sendToIf1("hello cjdns")
  229. | sendToIf2("hai")
  230. | sendToIf1("goodbye");
  231. }
  232. static int poly1305()
  233. {
  234. init(privateKey, publicKey, NULL);
  235. return
  236. sendToIf2("hello world")
  237. | sendToIf1("hello cjdns")
  238. | sendToIf2("hai")
  239. | sendToIf1("goodbye");
  240. }
  241. static int poly1305UnknownKey()
  242. {
  243. init(NULL, NULL, NULL);
  244. return
  245. sendToIf2("hello world")
  246. | sendToIf1("hello cjdns")
  247. | sendToIf2("hai")
  248. | sendToIf1("goodbye");
  249. }
  250. static int poly1305AndPassword()
  251. {
  252. init(privateKey, publicKey, (uint8_t*)"aPassword");
  253. return
  254. sendToIf2("hello world")
  255. | sendToIf1("hello cjdns")
  256. | sendToIf2("hai")
  257. | sendToIf1("goodbye");
  258. }
  259. static int poly1305UnknownKeyAndPassword()
  260. {
  261. init(NULL, NULL, (uint8_t*)"anotherPassword");
  262. return
  263. sendToIf2("hello world")
  264. | sendToIf1("hello cjdns")
  265. | sendToIf2("hai")
  266. | sendToIf1("goodbye");
  267. }
  268. static void connectToMe()
  269. {
  270. simpleInit();
  271. sendToIf1("hello world");
  272. sendToIf1("hello cjdns");
  273. sendToIf2("hai");
  274. sendToIf1("goodbye");
  275. }
  276. static void connectToMeDropMsg()
  277. {
  278. simpleInit();
  279. // send a message which is lost in the network.
  280. suppressMessages = true;
  281. sendToIf1("hello world");
  282. suppressMessages = false;
  283. // Now we learn their key some other way...
  284. uint8_t* pk = CryptoAuth_getHerPublicKey(cif2);
  285. Bits_memcpyConst(pk, ca1->publicKey, 32);
  286. sendToIf1("hello again world");
  287. sendToIf2("hai");
  288. sendToIf1("goodbye");
  289. }
  290. int main()
  291. {
  292. normal();
  293. repeatKey();
  294. repeatHello();
  295. chatter();
  296. auth();
  297. authWithoutKey();
  298. poly1305();
  299. poly1305UnknownKey();
  300. poly1305AndPassword();
  301. poly1305UnknownKeyAndPassword();
  302. connectToMe();
  303. connectToMeDropMsg();
  304. return 0;
  305. }