TestCa.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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/test/TestCa.h"
  16. #include "crypto/CryptoAuth.h"
  17. #include "rust/cjdns_sys/Rffi.h"
  18. #include "util/Hex.h"
  19. struct TestCa_s {
  20. RTypes_CryptoAuth2_t* ca2;
  21. struct CryptoAuth* ca;
  22. bool noise;
  23. };
  24. typedef struct TestCa_Session_pvt_s {
  25. TestCa_Session_t pub;
  26. RTypes_CryptoAuth2_Session_t* s2;
  27. struct CryptoAuth_Session* s;
  28. struct Iface sPlain;
  29. struct Iface sCipher;
  30. struct Iface s2Plain;
  31. struct Iface s2Cipher;
  32. Identity
  33. } TestCa_Session_pvt_t;
  34. TestCa_t* TestCa_new(
  35. Allocator_t *allocator,
  36. const uint8_t *privateKey,
  37. EventBase_t* eventBase,
  38. struct Log* logger,
  39. struct Random* rand0,
  40. struct Random* rand1,
  41. enum TestCa_Config cfg)
  42. {
  43. TestCa_t* out = Allocator_calloc(allocator, sizeof(TestCa_t), 1);
  44. if (cfg == TestCa_Config_OLD || cfg == TestCa_Config_OLD_NEW) {
  45. out->ca = CryptoAuth_new(allocator, privateKey, eventBase, logger, rand0);
  46. }
  47. if (cfg == TestCa_Config_OLD_NEW || cfg == TestCa_Config_NOISE) {
  48. out->ca2 = Rffi_CryptoAuth2_new(allocator, privateKey, rand1);
  49. }
  50. if (cfg == TestCa_Config_NOISE) {
  51. out->noise = true;
  52. }
  53. return out;
  54. }
  55. int TestCa_addUser_ipv6(
  56. String_t *password,
  57. String_t *login,
  58. uint8_t *ipv6,
  59. TestCa_t *ca)
  60. {
  61. int ret = 0;
  62. if (ca->ca) {
  63. ret = CryptoAuth_addUser_ipv6(password, login, ipv6, ca->ca);
  64. }
  65. if (ca->ca2) {
  66. int ret2 = Rffi_CryptoAuth2_addUser_ipv6(password, login, ipv6, ca->ca2);
  67. if (ca->ca) {
  68. Assert_true(ret == ret2);
  69. }
  70. return ret2;
  71. }
  72. return ret;
  73. }
  74. int TestCa_removeUsers(TestCa_t* ca, String_t* user)
  75. {
  76. int i1 = 0;
  77. if (ca->ca) {
  78. i1 = CryptoAuth_removeUsers(ca->ca, user);
  79. }
  80. if (ca->ca2) {
  81. int i2 = Rffi_CryptoAuth2_removeUsers(ca->ca2, user);
  82. if (ca->ca) {
  83. Assert_true(i1 == i2);
  84. }
  85. return i2;
  86. }
  87. return i1;
  88. }
  89. RTypes_StrList_t* TestCa_getUsers(const TestCa_t *ca, Allocator_t *alloc)
  90. {
  91. RTypes_StrList_t* l1 = NULL;
  92. if (ca->ca) {
  93. l1 = CryptoAuth_getUsers(ca->ca, alloc);
  94. }
  95. if (ca->ca2) {
  96. RTypes_StrList_t* l2 = Rffi_CryptoAuth2_getUsers(ca->ca2, alloc);
  97. Assert_true(l1->len == l2->len);
  98. for (uintptr_t i = 0; i < l1->len; i++) {
  99. Assert_true(String_equals(l1->items[i], l2->items[i]));
  100. }
  101. return l2;
  102. }
  103. return l1;
  104. }
  105. #define PASS 1
  106. #define STOP 2
  107. #define VERIFY 3
  108. #include <stdio.h>
  109. static Iface_DEFUN messagePlaintext(Message_t *msg, struct Iface* iface)
  110. {
  111. TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, pub.plaintext);
  112. Message_t* m2 = NULL;
  113. if (sess->s2) {
  114. if (sess->s) {
  115. m2 = Message_clone(msg, Message_getAlloc(msg));
  116. } else {
  117. m2 = msg;
  118. msg = NULL;
  119. }
  120. }
  121. struct RTypes_Error_t* i1 = NULL;
  122. if (sess->s) {
  123. int flag = sess->s2 ? STOP : PASS;
  124. Err(Message_epushAd(msg, &flag, sizeof flag));
  125. printf("Send [%d]\n", flag);
  126. i1 = Iface_send(&sess->sPlain, msg);
  127. }
  128. if (sess->s2) {
  129. if (sess->s) {
  130. Err(Message_epushAd(m2, &msg, sizeof &msg));
  131. }
  132. int flag = sess->s ? VERIFY : PASS;
  133. Err(Message_epushAd(m2, &flag, sizeof flag));
  134. printf("Send2 [%d]\n", flag);
  135. struct RTypes_Error_t* i2 = Iface_send(&sess->s2Plain, m2);
  136. if (sess->s) {
  137. Assert_true((i2 == NULL) == (i1 == NULL));
  138. }
  139. printf("Send2 done\n");
  140. return i2;
  141. }
  142. return i1;
  143. }
  144. static Iface_DEFUN messageCiphertext(Message_t *msg, struct Iface* iface)
  145. {
  146. TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, pub.ciphertext);
  147. Message_t* m2 = NULL;
  148. if (sess->s2) {
  149. if (sess->s) {
  150. m2 = Message_clone(msg, Message_getAlloc(msg));
  151. } else {
  152. m2 = msg;
  153. msg = NULL;
  154. }
  155. }
  156. struct RTypes_Error_t* i1 = NULL;
  157. if (sess->s) {
  158. int flag = sess->s2 ? STOP : PASS;
  159. Err(Message_epushAd(msg, &flag, sizeof flag));
  160. i1 = Iface_send(&sess->sCipher, msg);
  161. }
  162. if (sess->s2) {
  163. int flag = PASS;
  164. if (sess->s) {
  165. uintptr_t mp = (uintptr_t)msg;
  166. Err(Message_epushAd(m2, &mp, sizeof &mp));
  167. flag = VERIFY;
  168. }
  169. Err(Message_epushAd(m2, &flag, sizeof flag));
  170. struct RTypes_Error_t* i2 = Iface_send(&sess->s2Cipher, m2);
  171. if (sess->s) {
  172. Assert_true((i2 == NULL) == (i1 == NULL));
  173. }
  174. return i2;
  175. }
  176. return i1;
  177. }
  178. static bool check(Message_t *msg, TestCa_Session_pvt_t* sess)
  179. {
  180. int flag = 0;
  181. Err(Message_epopAd(msg, &flag, sizeof flag));
  182. if (flag == PASS) {
  183. printf("Passing message\n");
  184. } else if (flag == STOP) {
  185. // do nothing, wait for the next message to come through....
  186. printf("Stopping message\n");
  187. return true;
  188. } else if (flag == VERIFY) {
  189. uintptr_t m2p = 0;
  190. Err(Message_epopAd(msg, &m2p, sizeof m2p));
  191. printf("Verifying message %lx\n", (unsigned long) m2p);
  192. Message_t* m2 = (Message_t*) m2p;
  193. if (Message_getLength(msg) != Message_getLength(m2)) {
  194. Assert_failure("Message_getLength(msg) != m2->length: %d != %d",
  195. Message_getLength(msg), Message_getLength(m2));
  196. }
  197. if (Bits_memcmp(Message_bytes(msg), Message_bytes(m2), Message_getLength(msg))) {
  198. const char* msgH = Hex_print(Message_bytes(msg), Message_getLength(msg), Message_getAlloc(msg));
  199. const char* m2H = Hex_print(Message_bytes(m2), Message_getLength(m2), Message_getAlloc(m2));
  200. Assert_failure("msg->bytes != m2->bytes:\n%s\n%s\n", msgH, m2H);
  201. }
  202. Assert_true(!Bits_memcmp(Message_bytes(msg), Message_bytes(m2), Message_getLength(msg)));
  203. } else {
  204. Assert_failure("unexpected flag [%d]", flag);
  205. }
  206. return false;
  207. }
  208. static Iface_DEFUN sPlainRecv(Message_t *msg, struct Iface* iface)
  209. {
  210. TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, sPlain);
  211. if (check(msg, sess)) { return NULL; }
  212. return Iface_next(&sess->pub.plaintext, msg);
  213. }
  214. static Iface_DEFUN s2PlainRecv(Message_t *msg, struct Iface* iface)
  215. {
  216. TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, s2Plain);
  217. if (check(msg, sess)) { return NULL; }
  218. return Iface_next(&sess->pub.plaintext, msg);
  219. }
  220. static Iface_DEFUN sCipherRecv(Message_t *msg, struct Iface* iface)
  221. {
  222. TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, sCipher);
  223. if (check(msg, sess)) { return NULL; }
  224. return Iface_next(&sess->pub.ciphertext, msg);
  225. }
  226. static Iface_DEFUN s2CipherRecv(Message_t *msg, struct Iface* iface)
  227. {
  228. TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, s2Cipher);
  229. if (check(msg, sess)) { return NULL; }
  230. return Iface_next(&sess->pub.ciphertext, msg);
  231. }
  232. TestCa_Session_t* TestCa_newSession(
  233. TestCa_t *ca,
  234. Allocator_t *alloc,
  235. const uint8_t *herPublicKey,
  236. bool requireAuth,
  237. char *name,
  238. bool useNoise)
  239. {
  240. TestCa_Session_pvt_t* out = Allocator_calloc(alloc, sizeof(TestCa_Session_pvt_t), 1);
  241. Identity_set(out);
  242. out->sCipher.send = sCipherRecv;
  243. out->sPlain.send = sPlainRecv;
  244. out->s2Cipher.send = s2CipherRecv;
  245. out->s2Plain.send = s2PlainRecv;
  246. if (ca->ca) {
  247. out->s = CryptoAuth_newSession(ca->ca, alloc, herPublicKey, requireAuth, name, false);
  248. Iface_plumb(&out->sCipher, &out->s->ciphertext);
  249. Iface_plumb(&out->sPlain, &out->s->plaintext);
  250. }
  251. if (ca->ca2) {
  252. out->s2 = Rffi_CryptoAuth2_newSession(
  253. ca->ca2, alloc, herPublicKey, requireAuth, name, ca->noise && useNoise);
  254. Iface_plumb(&out->s2Cipher, out->s2->ciphertext);
  255. Iface_plumb(&out->s2Plain, out->s2->plaintext);
  256. }
  257. out->pub.plaintext.send = messagePlaintext;
  258. out->pub.ciphertext.send = messageCiphertext;
  259. return &out->pub;
  260. }
  261. void TestCa_setAuth(const String_t* password, const String_t* login, TestCa_Session_t* session)
  262. {
  263. TestCa_Session_pvt_t* sess = Identity_check((TestCa_Session_pvt_t*) session);
  264. if (sess->s) {
  265. CryptoAuth_setAuth(password, login, sess->s);
  266. }
  267. if (sess->s2) {
  268. Rffi_CryptoAuth2_setAuth(password, login, sess->s2);
  269. }
  270. }
  271. void TestCa_resetIfTimeout(TestCa_Session_t* session)
  272. {
  273. TestCa_Session_pvt_t* sess = Identity_check((TestCa_Session_pvt_t*) session);
  274. if (sess->s) {
  275. CryptoAuth_resetIfTimeout(sess->s);
  276. }
  277. if (sess->s2) {
  278. Rffi_CryptoAuth2_resetIfTimeout(sess->s2);
  279. }
  280. }
  281. void TestCa_reset(TestCa_Session_t* session)
  282. {
  283. TestCa_Session_pvt_t* sess = Identity_check((TestCa_Session_pvt_t*) session);
  284. if (sess->s) {
  285. CryptoAuth_reset(sess->s);
  286. }
  287. if (sess->s2) {
  288. Rffi_CryptoAuth2_reset(sess->s2);
  289. }
  290. }
  291. RTypes_CryptoAuth_State_t TestCa_getState(TestCa_Session_t* session)
  292. {
  293. TestCa_Session_pvt_t* sess = Identity_check((TestCa_Session_pvt_t*) session);
  294. RTypes_CryptoAuth_State_t st = 0;
  295. if (sess->s) {
  296. st = CryptoAuth_getState(sess->s);
  297. }
  298. if (sess->s2) {
  299. RTypes_CryptoAuth_State_t st2 = Rffi_CryptoAuth2_getState(sess->s2);
  300. if (sess->s) {
  301. Assert_true(st2 == st);
  302. }
  303. return st2;
  304. }
  305. return st;
  306. }
  307. void TestCa_getHerPubKey(TestCa_Session_t* session, uint8_t* buf)
  308. {
  309. TestCa_Session_pvt_t* sess = Identity_check((TestCa_Session_pvt_t*) session);
  310. uint8_t hpk1[32];
  311. if (sess->s) {
  312. CryptoAuth_getHerPubKey(sess->s, hpk1);
  313. }
  314. if (sess->s2) {
  315. Rffi_CryptoAuth2_getHerPubKey(sess->s2, buf);
  316. if (sess->s) {
  317. Assert_true(!Bits_memcmp(hpk1, buf, 32));
  318. }
  319. return;
  320. }
  321. Bits_memcpy(buf, hpk1, 32);
  322. }
  323. void TestCa_getPubKey(TestCa_t *ca, uint8_t* buf)
  324. {
  325. uint8_t pk1[32];
  326. if (ca->ca) {
  327. CryptoAuth_getPubKey(ca->ca, pk1);
  328. }
  329. if (ca->ca2) {
  330. Rffi_CryptoAuth2_getPubKey(ca->ca2, buf);
  331. if (ca->ca) {
  332. Assert_true(!Bits_memcmp(pk1, buf, 32));
  333. }
  334. return;
  335. }
  336. Bits_memcpy(buf, pk1, 32);
  337. }