1
0

CryptoAuth_test.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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 <https://www.gnu.org/licenses/>.
  14. */
  15. #include "crypto/random/Random.h"
  16. #include "crypto/Ca.h"
  17. #include "crypto/CryptoAuth.h"
  18. #include "benc/String.h"
  19. #include "memory/Allocator.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/FileWriterLog.h"
  26. #include "wire/CryptoHeader.h"
  27. #include "crypto/test/TestCa.h"
  28. #include "crypto/random/test/DeterminentRandomSeed.h"
  29. #include "util/CString.h"
  30. #define PRIVATEKEY_A \
  31. Constant_stringForHex("53ff22b2eb94ce8c5f1852c0f557eb901f067e5273d541e0a21e143c20dff9da")
  32. #define PUBLICKEY_A \
  33. Constant_stringForHex("e3ff75af6e4414494df22f200ffeaa56e7976d991d33cc87f52427e27f83235d")
  34. #define PRIVATEKEY_B \
  35. Constant_stringForHex("b71c4f43e3d4b1879b5065d44a1cb43eaf07ddba96de6a72ca761c4ef4bd2988")
  36. #define PUBLICKEY_B \
  37. Constant_stringForHex("27c303cdc1f96e4b28d51c75130aff6cad52098f2d752615b7b6509ed6a89477")
  38. #define USEROBJ "This represents a user"
  39. struct Node
  40. {
  41. TestCa_t* ca;
  42. TestCa_Session_t* sess;
  43. struct Iface plaintext;
  44. struct Iface ciphertext;
  45. const char* expectPlaintext;
  46. enum CryptoAuth_DecryptErr expectErr;
  47. struct Log* log;
  48. Identity
  49. };
  50. struct Context
  51. {
  52. struct Node node1;
  53. struct Node node2;
  54. struct Allocator* alloc;
  55. struct Log* log;
  56. struct EventBase* base;
  57. Identity
  58. };
  59. static struct Random* evilRandom(struct Allocator* alloc, struct Log* logger, const char* seed)
  60. {
  61. uint8_t buf[64] = {0};
  62. Assert_true(CString_strlen(seed) < 60);
  63. CString_strcpy(buf, seed);
  64. RandomSeed_t* evilSeed = DeterminentRandomSeed_new(alloc, buf);
  65. return Random_newWithSeed(alloc, logger, evilSeed, NULL);
  66. }
  67. static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* if1)
  68. {
  69. struct Node* n = Identity_containerOf(if1, struct Node, plaintext);
  70. Log_debug(n->log, "Got message from afterDecrypt");
  71. enum CryptoAuth_DecryptErr e = Er_assert(Message_epop32h(msg));
  72. if (e != n->expectErr) {
  73. Assert_failure("expected decrypt error [%d], got [%d]\n", n->expectErr, e);
  74. }
  75. n->expectErr = CryptoAuth_DecryptErr_NONE;
  76. if (!n->expectPlaintext) {
  77. if (e) {
  78. return NULL;
  79. }
  80. Assert_failure("expected <NULL>, got [%s](%d)\n", msg->msgbytes, Message_getLength(msg));
  81. }
  82. if ((int)CString_strlen(n->expectPlaintext) != Message_getLength(msg) ||
  83. CString_strncmp(msg->msgbytes, n->expectPlaintext, Message_getLength(msg)))
  84. {
  85. Assert_failure("expected [%s](%d), got [%s](%d)\n",
  86. n->expectPlaintext, (int)CString_strlen(n->expectPlaintext), msg->msgbytes, Message_getLength(msg));
  87. }
  88. n->expectPlaintext = NULL;
  89. return NULL;
  90. }
  91. static Iface_DEFUN afterEncrypt(struct Message* msg, struct Iface* if1)
  92. {
  93. return NULL;
  94. }
  95. static struct Context* init(uint8_t* privateKeyA,
  96. uint8_t* publicKeyA,
  97. uint8_t* password,
  98. uint8_t* privateKeyB,
  99. uint8_t* publicKeyB,
  100. enum TestCa_Config cfg)
  101. {
  102. struct Allocator* alloc = Allocator_new(1048576);
  103. struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1);
  104. Identity_set(ctx);
  105. Identity_set(&ctx->node1);
  106. Identity_set(&ctx->node2);
  107. ctx->alloc = alloc;
  108. ctx->node1.plaintext.send = afterDecrypt;
  109. ctx->node2.plaintext.send = afterDecrypt;
  110. ctx->node1.ciphertext.send = afterEncrypt;
  111. ctx->node2.ciphertext.send = afterEncrypt;
  112. struct Log* logger = ctx->log = FileWriterLog_new(stdout, alloc);
  113. struct Random* randA = evilRandom(alloc, logger, "ALPHA");
  114. struct Random* randB = evilRandom(alloc, logger, "ALPHA");
  115. struct Random* randC = evilRandom(alloc, logger, "BRAVO");
  116. struct Random* randD = evilRandom(alloc, logger, "BRAVO");
  117. struct EventBase* base = ctx->base = EventBase_new(alloc);
  118. ctx->node1.log = logger;
  119. ctx->node2.log = logger;
  120. ctx->node1.ca = TestCa_new(alloc, privateKeyA, base, logger, randA, randB, cfg);
  121. ctx->node1.sess = TestCa_newSession(ctx->node1.ca, alloc, publicKeyB, false, "cif1", true);
  122. ctx->node2.ca = TestCa_new(alloc, privateKeyB, base, logger, randC, randD, cfg);
  123. if (password) {
  124. String* passStr = String_CONST(password);
  125. TestCa_setAuth(passStr, NULL, ctx->node1.sess);
  126. TestCa_addUser_ipv6(passStr, String_new(USEROBJ, alloc), NULL, ctx->node2.ca);
  127. }
  128. ctx->node2.sess = TestCa_newSession(ctx->node2.ca, alloc, publicKeyA, false, "cif2", true);
  129. Iface_plumb(&ctx->node1.sess->plaintext, &ctx->node1.plaintext);
  130. Iface_plumb(&ctx->node1.sess->ciphertext, &ctx->node1.ciphertext);
  131. Iface_plumb(&ctx->node2.sess->plaintext, &ctx->node2.plaintext);
  132. Iface_plumb(&ctx->node2.sess->ciphertext, &ctx->node2.ciphertext);
  133. return ctx;
  134. }
  135. static struct Context* simpleInit(enum TestCa_Config cfg)
  136. {
  137. return init(PRIVATEKEY_A, PUBLICKEY_A, NULL, PRIVATEKEY_B, PUBLICKEY_B, cfg);
  138. }
  139. static struct Message* encryptMsg(struct Context* ctx,
  140. struct Node* n,
  141. const char* x)
  142. {
  143. struct Allocator* alloc = Allocator_child(ctx->alloc);
  144. int len = (((CString_strlen(x)+1) / 8) + 1) * 8;
  145. struct Message* msg = Message_new(len, CryptoHeader_SIZE + 32, alloc);
  146. CString_strcpy(msg->msgbytes, x);
  147. Er_assert(Message_truncate(msg, CString_strlen(x)));
  148. //msg->bytes[Message_getLength(msg)] = 0;
  149. struct RTypes_Error_t* e = Iface_send(&n->plaintext, msg);
  150. if (e) {
  151. printf("%s\n", Rffi_printError(e, ctx->alloc));
  152. Assert_failure("error was not null");
  153. }
  154. Assert_true(Message_getLength(msg) > ((int)CString_strlen(x) + 4));
  155. return msg;
  156. }
  157. static struct Message* decryptMsg(struct Context* ctx,
  158. struct Message* msg,
  159. struct Node* n,
  160. const char* expectResult,
  161. enum CryptoAuth_DecryptErr expectErr)
  162. {
  163. Assert_true(!n->expectPlaintext && !n->expectErr);
  164. n->expectPlaintext = expectResult;
  165. n->expectErr = expectErr;
  166. Er_assert(Message_epush(msg, NULL, 16)); // peer ipv6
  167. Iface_send(&n->ciphertext, msg);
  168. Assert_true(!n->expectPlaintext && !n->expectErr);
  169. return msg;
  170. }
  171. static void sendToIf1(struct Context* ctx, const char* x)
  172. {
  173. struct Message* msg = encryptMsg(ctx, &ctx->node2, x);
  174. decryptMsg(ctx, msg, &ctx->node1, x, CryptoAuth_DecryptErr_NONE);
  175. Allocator_free(Message_getAlloc(msg));
  176. }
  177. static void sendToIf2(struct Context* ctx, const char* x)
  178. {
  179. struct Message* msg = encryptMsg(ctx, &ctx->node1, x);
  180. decryptMsg(ctx, msg, &ctx->node2, x, CryptoAuth_DecryptErr_NONE);
  181. Allocator_free(Message_getAlloc(msg));
  182. }
  183. static void normal(enum TestCa_Config cfg)
  184. {
  185. struct Context* ctx = simpleInit(cfg);
  186. sendToIf2(ctx, "hello world");
  187. sendToIf1(ctx, "hello cjdns");
  188. sendToIf2(ctx, "hai");
  189. sendToIf1(ctx, "goodbye");
  190. Allocator_free(ctx->alloc);
  191. }
  192. static void repeatKey(enum TestCa_Config cfg)
  193. {
  194. struct Context* ctx = simpleInit(cfg);
  195. sendToIf2(ctx, "hello world");
  196. sendToIf2(ctx, "r u thar?");
  197. sendToIf1(ctx, "hello cjdns");
  198. sendToIf2(ctx, "hai");
  199. sendToIf1(ctx, "goodbye");
  200. Allocator_free(ctx->alloc);
  201. }
  202. static void repeatHello(enum TestCa_Config cfg)
  203. {
  204. struct Context* ctx = simpleInit(cfg);
  205. sendToIf2(ctx, "hello world");
  206. sendToIf2(ctx, "r u thar?");
  207. sendToIf1(ctx, "hello cjdns");
  208. sendToIf2(ctx, "hai");
  209. sendToIf1(ctx, "goodbye");
  210. Allocator_free(ctx->alloc);
  211. }
  212. static void chatter(enum TestCa_Config cfg)
  213. {
  214. struct Context* ctx = simpleInit(cfg);
  215. sendToIf2(ctx, "hello world");
  216. sendToIf1(ctx, "hello cjdns");
  217. sendToIf2(ctx, "hai");
  218. sendToIf1(ctx, "goodbye");
  219. sendToIf1(ctx, "hello cjdns");
  220. sendToIf2(ctx, "hai");
  221. sendToIf1(ctx, "goodbye");
  222. sendToIf1(ctx, "hello cjdns");
  223. sendToIf2(ctx, "hai");
  224. sendToIf1(ctx, "goodbye");
  225. sendToIf1(ctx, "hello cjdns");
  226. sendToIf2(ctx, "hai");
  227. sendToIf1(ctx, "goodbye");
  228. Allocator_free(ctx->alloc);
  229. }
  230. static void auth(enum TestCa_Config cfg)
  231. {
  232. struct Context* ctx = init(
  233. PRIVATEKEY_A, PUBLICKEY_A, "password", PRIVATEKEY_B, PUBLICKEY_B, cfg);
  234. sendToIf2(ctx, "hello world");
  235. sendToIf1(ctx, "hello cjdns");
  236. sendToIf2(ctx, "hai");
  237. sendToIf1(ctx, "goodbye");
  238. Allocator_free(ctx->alloc);
  239. }
  240. static void replayKeyPacket(int scenario, enum TestCa_Config cfg)
  241. {
  242. struct Context* ctx = simpleInit(cfg);
  243. sendToIf2(ctx, "hello world");
  244. struct Message* msg = encryptMsg(ctx, &ctx->node2, "hello replay key");
  245. struct Message* toReplay = Message_clone(msg, ctx->alloc);
  246. decryptMsg(ctx, msg, &ctx->node1, "hello replay key", CryptoAuth_DecryptErr_NONE);
  247. if (scenario == 1) {
  248. // the packet is failed because we know it's a dupe from the temp key.
  249. decryptMsg(ctx, toReplay, &ctx->node1, NULL, CryptoAuth_DecryptErr_INVALID_PACKET);
  250. }
  251. sendToIf2(ctx, "first traffic packet");
  252. if (scenario == 2) {
  253. decryptMsg(ctx, toReplay, &ctx->node1, NULL, CryptoAuth_DecryptErr_INVALID_PACKET);
  254. }
  255. sendToIf1(ctx, "second traffic packet");
  256. if (scenario == 3) {
  257. // If we replay at this stage, the packet is dropped as a stray key
  258. decryptMsg(ctx, toReplay, &ctx->node1, NULL, CryptoAuth_DecryptErr_KEY_PKT_ESTABLISHED_SESSION);
  259. }
  260. Allocator_free(ctx->alloc);
  261. }
  262. /**
  263. * Alice and Bob both decided they wanted to talk to eachother at precisely the same time.
  264. * This means two Hello packets crossed on the wire. Both arrived at their destination but
  265. * if each triggers a re-initialization of the CA session, nobody will be synchronized!
  266. */
  267. static void hellosCrossedOnTheWire(enum TestCa_Config cfg)
  268. {
  269. struct Context* ctx = simpleInit(cfg);
  270. uint8_t pk1[32];
  271. TestCa_getPubKey(ctx->node1.ca, pk1);
  272. uint8_t hpk2[32];
  273. TestCa_getHerPubKey(ctx->node2.sess, hpk2);
  274. Assert_true(!Bits_memcmp(pk1, hpk2, 32));
  275. struct Message* hello2 = encryptMsg(ctx, &ctx->node2, "hello2");
  276. struct Message* hello1 = encryptMsg(ctx, &ctx->node1, "hello1");
  277. decryptMsg(ctx, hello2, &ctx->node1, "hello2", 0);
  278. decryptMsg(ctx, hello1, &ctx->node2, "hello1", 0);
  279. sendToIf2(ctx, "hello world");
  280. sendToIf1(ctx, "hello cjdns");
  281. sendToIf2(ctx, "hai");
  282. sendToIf1(ctx, "goodbye");
  283. Allocator_free(ctx->alloc);
  284. }
  285. static void reset(enum TestCa_Config cfg)
  286. {
  287. struct Context* ctx = simpleInit(cfg);
  288. sendToIf2(ctx, "hello world");
  289. sendToIf1(ctx, "hello cjdns");
  290. sendToIf2(ctx, "hai");
  291. sendToIf1(ctx, "brb");
  292. Assert_true(TestCa_getState(ctx->node1.sess) == CryptoAuth_State_ESTABLISHED);
  293. Assert_true(TestCa_getState(ctx->node2.sess) == CryptoAuth_State_ESTABLISHED);
  294. TestCa_reset(ctx->node1.sess);
  295. // sess2 still talking to sess1 but sess1 is reset and cannot read the packets.
  296. decryptMsg(ctx, encryptMsg(ctx, &ctx->node2, "will be lost"), &ctx->node1, NULL,
  297. CryptoAuth_DecryptErr_NO_SESSION);
  298. decryptMsg(ctx, encryptMsg(ctx, &ctx->node2, "lost"), &ctx->node1, NULL,
  299. CryptoAuth_DecryptErr_NO_SESSION);
  300. // This is because we want to prevent replay attacks from tearing down a session.
  301. decryptMsg(ctx, encryptMsg(ctx, &ctx->node1, "hello"), &ctx->node2, "hello", 0);
  302. sendToIf1(ctx, "hello again");
  303. sendToIf2(ctx, "hai");
  304. sendToIf1(ctx, "ok works");
  305. sendToIf2(ctx, "yup");
  306. Assert_true(TestCa_getState(ctx->node1.sess) == CryptoAuth_State_ESTABLISHED);
  307. Assert_true(TestCa_getState(ctx->node2.sess) == CryptoAuth_State_ESTABLISHED);
  308. Allocator_free(ctx->alloc);
  309. }
  310. // This is slightly different from replayKeyPacket because the second key packet is valid,
  311. // it's just delayed.
  312. static void twoKeyPackets(int scenario, enum TestCa_Config cfg)
  313. {
  314. struct Context* ctx = simpleInit(cfg);
  315. sendToIf2(ctx, "hello world");
  316. sendToIf1(ctx, "key packet 1");
  317. struct Message* key2 = encryptMsg(ctx, &ctx->node2, "key packet 2");
  318. if (scenario == 1) {
  319. sendToIf1(ctx, "key packet 3");
  320. decryptMsg(ctx, key2, &ctx->node1, "key packet 2", 0);
  321. } else if (scenario == 2) {
  322. sendToIf2(ctx, "initial data packet");
  323. decryptMsg(ctx, key2, &ctx->node1, "key packet 2", 0);
  324. sendToIf1(ctx, "second data packet");
  325. sendToIf2(ctx, "third data packet");
  326. } else if (scenario == 3) {
  327. sendToIf2(ctx, "initial data packet");
  328. sendToIf1(ctx, "second data packet");
  329. decryptMsg(ctx, key2, &ctx->node1, NULL, CryptoAuth_DecryptErr_KEY_PKT_ESTABLISHED_SESSION);
  330. }
  331. Allocator_free(ctx->alloc);
  332. }
  333. static void iteration(enum TestCa_Config cfg)
  334. {
  335. normal(cfg);
  336. repeatKey(cfg);
  337. repeatHello(cfg);
  338. chatter(cfg);
  339. auth(cfg);
  340. replayKeyPacket(1, cfg);
  341. replayKeyPacket(2, cfg);
  342. replayKeyPacket(3, cfg);
  343. hellosCrossedOnTheWire(cfg);
  344. reset(cfg);
  345. twoKeyPackets(1, cfg);
  346. twoKeyPackets(2, cfg);
  347. twoKeyPackets(3, cfg);
  348. }
  349. int main()
  350. {
  351. iteration(TestCa_Config_OLD);
  352. iteration(TestCa_Config_OLD_NEW);
  353. //iteration(TestCa_Config_NOISE); // TODO(cjd): re-enable this
  354. return 0;
  355. }