CryptoAuth_test.c 9.1 KB

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