testcrypt.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588
  1. /*
  2. * testcrypt: a standalone test program that provides direct access to
  3. * PuTTY's cryptography and mp_int code.
  4. */
  5. /*
  6. * This program speaks a line-oriented protocol on standard input and
  7. * standard output. It's a half-duplex protocol: it expects to read
  8. * one line of command, and then produce a fixed amount of output
  9. * (namely a line containing a decimal integer, followed by that many
  10. * lines each containing one return value).
  11. *
  12. * The protocol is human-readable enough to make it debuggable, but
  13. * verbose enough that you probably wouldn't want to speak it by hand
  14. * at any great length. The Python program test/testcrypt.py wraps it
  15. * to give a more useful user-facing API, by invoking this binary as a
  16. * subprocess.
  17. *
  18. * (I decided that was a better idea than making this program an
  19. * actual Python module, partly because you can rewrap the same binary
  20. * in another scripting language if you prefer, but mostly because
  21. * it's easy to attach a debugger to testcrypt or to run it under
  22. * sanitisers or valgrind or what have you.)
  23. */
  24. #include <assert.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include "defs.h"
  30. #include "ssh.h"
  31. #include "sshkeygen.h"
  32. #include "misc.h"
  33. #include "mpint.h"
  34. #include "ecc.h"
  35. static NORETURN PRINTF_LIKE(1, 2) void fatal_error(const char *p, ...)
  36. {
  37. va_list ap;
  38. fprintf(stderr, "testcrypt: ");
  39. va_start(ap, p);
  40. vfprintf(stderr, p, ap);
  41. va_end(ap);
  42. fputc('\n', stderr);
  43. exit(1);
  44. }
  45. void out_of_memory(void) { fatal_error("out of memory"); }
  46. /* For platforms where getticks is defined within this code base */
  47. unsigned long (getticks)(void)
  48. { unreachable("this is a stub needed to link, and should never be called"); }
  49. FILE *f_open(const struct Filename *fn, char const *mode, bool private)
  50. { unreachable("f_open should never be called by this test program"); }
  51. static bool old_keyfile_warning_given;
  52. void old_keyfile_warning(void) { old_keyfile_warning_given = true; }
  53. static bufchain random_data_queue;
  54. static prng *test_prng;
  55. void random_read(void *buf, size_t size)
  56. {
  57. if (test_prng) {
  58. prng_read(test_prng, buf, size);
  59. } else {
  60. if (!bufchain_try_fetch_consume(&random_data_queue, buf, size))
  61. fatal_error("No random data in queue");
  62. }
  63. }
  64. uint64_t prng_reseed_time_ms(void)
  65. {
  66. static uint64_t previous_time = 0;
  67. return previous_time += 200;
  68. }
  69. #define VALUE_TYPES(X) \
  70. X(string, strbuf *, strbuf_free(v)) \
  71. X(mpint, mp_int *, mp_free(v)) \
  72. X(modsqrt, ModsqrtContext *, modsqrt_free(v)) \
  73. X(monty, MontyContext *, monty_free(v)) \
  74. X(wcurve, WeierstrassCurve *, ecc_weierstrass_curve_free(v)) \
  75. X(wpoint, WeierstrassPoint *, ecc_weierstrass_point_free(v)) \
  76. X(mcurve, MontgomeryCurve *, ecc_montgomery_curve_free(v)) \
  77. X(mpoint, MontgomeryPoint *, ecc_montgomery_point_free(v)) \
  78. X(ecurve, EdwardsCurve *, ecc_edwards_curve_free(v)) \
  79. X(epoint, EdwardsPoint *, ecc_edwards_point_free(v)) \
  80. X(hash, ssh_hash *, ssh_hash_free(v)) \
  81. X(key, ssh_key *, ssh_key_free(v)) \
  82. X(cipher, ssh_cipher *, ssh_cipher_free(v)) \
  83. X(mac, ssh2_mac *, ssh2_mac_free(v)) \
  84. X(dh, dh_ctx *, dh_cleanup(v)) \
  85. X(ecdh, ecdh_key *, ssh_ecdhkex_freekey(v)) \
  86. X(rsakex, RSAKey *, ssh_rsakex_freekey(v)) \
  87. X(rsa, RSAKey *, rsa_free(v)) \
  88. X(prng, prng *, prng_free(v)) \
  89. X(keycomponents, key_components *, key_components_free(v)) \
  90. X(pcs, PrimeCandidateSource *, pcs_free(v)) \
  91. X(pgc, PrimeGenerationContext *, primegen_free_context(v)) \
  92. X(pockle, Pockle *, pockle_free(v)) \
  93. /* end of list */
  94. typedef struct Value Value;
  95. enum ValueType {
  96. #define VALTYPE_ENUM(n,t,f) VT_##n,
  97. VALUE_TYPES(VALTYPE_ENUM)
  98. #undef VALTYPE_ENUM
  99. };
  100. typedef enum ValueType ValueType;
  101. static const char *const type_names[] = {
  102. #define VALTYPE_NAME(n,t,f) #n,
  103. VALUE_TYPES(VALTYPE_NAME)
  104. #undef VALTYPE_NAME
  105. };
  106. #define VALTYPE_TYPEDEF(n,t,f) \
  107. typedef t TD_val_##n; \
  108. typedef t *TD_out_val_##n;
  109. VALUE_TYPES(VALTYPE_TYPEDEF)
  110. #undef VALTYPE_TYPEDEF
  111. struct Value {
  112. /*
  113. * Protocol identifier assigned to this value when it was created.
  114. * Lives in the same malloced block as this Value object itself.
  115. */
  116. ptrlen id;
  117. /*
  118. * Type of the value.
  119. */
  120. ValueType type;
  121. /*
  122. * Union of all the things it could hold.
  123. */
  124. union {
  125. #define VALTYPE_UNION(n,t,f) t vu_##n;
  126. VALUE_TYPES(VALTYPE_UNION)
  127. #undef VALTYPE_UNION
  128. char *bare_string;
  129. };
  130. };
  131. static int valuecmp(void *av, void *bv)
  132. {
  133. Value *a = (Value *)av, *b = (Value *)bv;
  134. return ptrlen_strcmp(a->id, b->id);
  135. }
  136. static int valuefind(void *av, void *bv)
  137. {
  138. ptrlen *a = (ptrlen *)av;
  139. Value *b = (Value *)bv;
  140. return ptrlen_strcmp(*a, b->id);
  141. }
  142. static tree234 *values;
  143. static Value *value_new(ValueType vt)
  144. {
  145. static uint64_t next_index = 0;
  146. char *name = dupprintf("%s%"PRIu64, type_names[vt], next_index++);
  147. size_t namelen = strlen(name);
  148. Value *val = snew_plus(Value, namelen+1);
  149. memcpy(snew_plus_get_aux(val), name, namelen+1);
  150. val->id.ptr = snew_plus_get_aux(val);
  151. val->id.len = namelen;
  152. val->type = vt;
  153. Value *added = add234(values, val);
  154. assert(added == val);
  155. sfree(name);
  156. return val;
  157. }
  158. #define VALTYPE_RETURNFN(n,t,f) \
  159. void return_val_##n(strbuf *out, t v) { \
  160. Value *val = value_new(VT_##n); \
  161. val->vu_##n = v; \
  162. put_datapl(out, val->id); \
  163. put_byte(out, '\n'); \
  164. }
  165. VALUE_TYPES(VALTYPE_RETURNFN)
  166. #undef VALTYPE_RETURNFN
  167. static ptrlen get_word(BinarySource *in)
  168. {
  169. ptrlen toret;
  170. toret.ptr = get_ptr(in);
  171. toret.len = 0;
  172. while (get_avail(in) && get_byte(in) != ' ')
  173. toret.len++;
  174. return toret;
  175. }
  176. static const ssh_hashalg *get_hashalg(BinarySource *in)
  177. {
  178. static const struct {
  179. const char *key;
  180. const ssh_hashalg *value;
  181. } algs[] = {
  182. {"md5", &ssh_md5},
  183. {"sha1", &ssh_sha1},
  184. {"sha1_sw", &ssh_sha1_sw},
  185. {"sha1_hw", &ssh_sha1_hw},
  186. {"sha256", &ssh_sha256},
  187. {"sha256_sw", &ssh_sha256_sw},
  188. {"sha256_hw", &ssh_sha256_hw},
  189. {"sha384", &ssh_sha384},
  190. {"sha384_sw", &ssh_sha384_sw},
  191. {"sha384_hw", &ssh_sha384_hw},
  192. {"sha512", &ssh_sha512},
  193. {"sha512_sw", &ssh_sha512_sw},
  194. {"sha512_hw", &ssh_sha512_hw},
  195. {"sha3_224", &ssh_sha3_224},
  196. {"sha3_256", &ssh_sha3_256},
  197. {"sha3_384", &ssh_sha3_384},
  198. {"sha3_512", &ssh_sha3_512},
  199. {"shake256_114bytes", &ssh_shake256_114bytes},
  200. {"blake2b", &ssh_blake2b},
  201. };
  202. ptrlen name = get_word(in);
  203. for (size_t i = 0; i < lenof(algs); i++)
  204. if (ptrlen_eq_string(name, algs[i].key))
  205. return algs[i].value;
  206. fatal_error("hashalg '%.*s': not found", PTRLEN_PRINTF(name));
  207. }
  208. static const ssh2_macalg *get_macalg(BinarySource *in)
  209. {
  210. static const struct {
  211. const char *key;
  212. const ssh2_macalg *value;
  213. } algs[] = {
  214. {"hmac_md5", &ssh_hmac_md5},
  215. {"hmac_sha1", &ssh_hmac_sha1},
  216. {"hmac_sha1_buggy", &ssh_hmac_sha1_buggy},
  217. {"hmac_sha1_96", &ssh_hmac_sha1_96},
  218. {"hmac_sha1_96_buggy", &ssh_hmac_sha1_96_buggy},
  219. {"hmac_sha256", &ssh_hmac_sha256},
  220. {"poly1305", &ssh2_poly1305},
  221. };
  222. ptrlen name = get_word(in);
  223. for (size_t i = 0; i < lenof(algs); i++)
  224. if (ptrlen_eq_string(name, algs[i].key))
  225. return algs[i].value;
  226. fatal_error("macalg '%.*s': not found", PTRLEN_PRINTF(name));
  227. }
  228. static const ssh_keyalg *get_keyalg(BinarySource *in)
  229. {
  230. static const struct {
  231. const char *key;
  232. const ssh_keyalg *value;
  233. } algs[] = {
  234. {"dsa", &ssh_dss},
  235. {"rsa", &ssh_rsa},
  236. {"ed25519", &ssh_ecdsa_ed25519},
  237. {"ed448", &ssh_ecdsa_ed448},
  238. {"p256", &ssh_ecdsa_nistp256},
  239. {"p384", &ssh_ecdsa_nistp384},
  240. {"p521", &ssh_ecdsa_nistp521},
  241. };
  242. ptrlen name = get_word(in);
  243. for (size_t i = 0; i < lenof(algs); i++)
  244. if (ptrlen_eq_string(name, algs[i].key))
  245. return algs[i].value;
  246. fatal_error("keyalg '%.*s': not found", PTRLEN_PRINTF(name));
  247. }
  248. static const ssh_cipheralg *get_cipheralg(BinarySource *in)
  249. {
  250. static const struct {
  251. const char *key;
  252. const ssh_cipheralg *value;
  253. } algs[] = {
  254. {"3des_ctr", &ssh_3des_ssh2_ctr},
  255. {"3des_ssh2", &ssh_3des_ssh2},
  256. {"3des_ssh1", &ssh_3des_ssh1},
  257. {"des_cbc", &ssh_des},
  258. {"aes256_ctr", &ssh_aes256_sdctr},
  259. {"aes256_ctr_hw", &ssh_aes256_sdctr_hw},
  260. {"aes256_ctr_sw", &ssh_aes256_sdctr_sw},
  261. {"aes256_cbc", &ssh_aes256_cbc},
  262. {"aes256_cbc_hw", &ssh_aes256_cbc_hw},
  263. {"aes256_cbc_sw", &ssh_aes256_cbc_sw},
  264. {"aes192_ctr", &ssh_aes192_sdctr},
  265. {"aes192_ctr_hw", &ssh_aes192_sdctr_hw},
  266. {"aes192_ctr_sw", &ssh_aes192_sdctr_sw},
  267. {"aes192_cbc", &ssh_aes192_cbc},
  268. {"aes192_cbc_hw", &ssh_aes192_cbc_hw},
  269. {"aes192_cbc_sw", &ssh_aes192_cbc_sw},
  270. {"aes128_ctr", &ssh_aes128_sdctr},
  271. {"aes128_ctr_hw", &ssh_aes128_sdctr_hw},
  272. {"aes128_ctr_sw", &ssh_aes128_sdctr_sw},
  273. {"aes128_cbc", &ssh_aes128_cbc},
  274. {"aes128_cbc_hw", &ssh_aes128_cbc_hw},
  275. {"aes128_cbc_sw", &ssh_aes128_cbc_sw},
  276. {"blowfish_ctr", &ssh_blowfish_ssh2_ctr},
  277. {"blowfish_ssh2", &ssh_blowfish_ssh2},
  278. {"blowfish_ssh1", &ssh_blowfish_ssh1},
  279. {"arcfour256", &ssh_arcfour256_ssh2},
  280. {"arcfour128", &ssh_arcfour128_ssh2},
  281. {"chacha20_poly1305", &ssh2_chacha20_poly1305},
  282. };
  283. ptrlen name = get_word(in);
  284. for (size_t i = 0; i < lenof(algs); i++)
  285. if (ptrlen_eq_string(name, algs[i].key))
  286. return algs[i].value;
  287. fatal_error("cipheralg '%.*s': not found", PTRLEN_PRINTF(name));
  288. }
  289. static const ssh_kex *get_dh_group(BinarySource *in)
  290. {
  291. static const struct {
  292. const char *key;
  293. const ssh_kexes *value;
  294. } algs[] = {
  295. {"group1", &ssh_diffiehellman_group1},
  296. {"group14", &ssh_diffiehellman_group14},
  297. };
  298. ptrlen name = get_word(in);
  299. for (size_t i = 0; i < lenof(algs); i++)
  300. if (ptrlen_eq_string(name, algs[i].key))
  301. return algs[i].value->list[0];
  302. fatal_error("dh_group '%.*s': not found", PTRLEN_PRINTF(name));
  303. }
  304. static const ssh_kex *get_ecdh_alg(BinarySource *in)
  305. {
  306. static const struct {
  307. const char *key;
  308. const ssh_kex *value;
  309. } algs[] = {
  310. {"curve25519", &ssh_ec_kex_curve25519},
  311. {"curve448", &ssh_ec_kex_curve448},
  312. {"nistp256", &ssh_ec_kex_nistp256},
  313. {"nistp384", &ssh_ec_kex_nistp384},
  314. {"nistp521", &ssh_ec_kex_nistp521},
  315. };
  316. ptrlen name = get_word(in);
  317. for (size_t i = 0; i < lenof(algs); i++)
  318. if (ptrlen_eq_string(name, algs[i].key))
  319. return algs[i].value;
  320. fatal_error("ecdh_alg '%.*s': not found", PTRLEN_PRINTF(name));
  321. }
  322. static RsaSsh1Order get_rsaorder(BinarySource *in)
  323. {
  324. static const struct {
  325. const char *key;
  326. RsaSsh1Order value;
  327. } orders[] = {
  328. {"exponent_first", RSA_SSH1_EXPONENT_FIRST},
  329. {"modulus_first", RSA_SSH1_MODULUS_FIRST},
  330. };
  331. ptrlen name = get_word(in);
  332. for (size_t i = 0; i < lenof(orders); i++)
  333. if (ptrlen_eq_string(name, orders[i].key))
  334. return orders[i].value;
  335. fatal_error("rsaorder '%.*s': not found", PTRLEN_PRINTF(name));
  336. }
  337. static const PrimeGenerationPolicy *get_primegenpolicy(BinarySource *in)
  338. {
  339. static const struct {
  340. const char *key;
  341. const PrimeGenerationPolicy *value;
  342. } algs[] = {
  343. {"probabilistic", &primegen_probabilistic},
  344. {"provable_fast", &primegen_provable_fast},
  345. {"provable_maurer_simple", &primegen_provable_maurer_simple},
  346. {"provable_maurer_complex", &primegen_provable_maurer_complex},
  347. };
  348. ptrlen name = get_word(in);
  349. for (size_t i = 0; i < lenof(algs); i++)
  350. if (ptrlen_eq_string(name, algs[i].key))
  351. return algs[i].value;
  352. fatal_error("primegenpolicy '%.*s': not found", PTRLEN_PRINTF(name));
  353. }
  354. static Argon2Flavour get_argon2flavour(BinarySource *in)
  355. {
  356. static const struct {
  357. const char *key;
  358. Argon2Flavour value;
  359. } algs[] = {
  360. {"d", Argon2d},
  361. {"i", Argon2i},
  362. {"id", Argon2id},
  363. /* I expect to forget which spelling I chose, so let's support many */
  364. {"argon2d", Argon2d},
  365. {"argon2i", Argon2i},
  366. {"argon2id", Argon2id},
  367. {"Argon2d", Argon2d},
  368. {"Argon2i", Argon2i},
  369. {"Argon2id", Argon2id},
  370. };
  371. ptrlen name = get_word(in);
  372. for (size_t i = 0; i < lenof(algs); i++)
  373. if (ptrlen_eq_string(name, algs[i].key))
  374. return algs[i].value;
  375. fatal_error("Argon2 flavour '%.*s': not found", PTRLEN_PRINTF(name));
  376. }
  377. static FingerprintType get_fptype(BinarySource *in)
  378. {
  379. static const struct {
  380. const char *key;
  381. FingerprintType value;
  382. } ids[] = {
  383. {"md5", SSH_FPTYPE_MD5},
  384. {"sha256", SSH_FPTYPE_SHA256},
  385. };
  386. ptrlen name = get_word(in);
  387. for (size_t i = 0; i < lenof(ids); i++)
  388. if (ptrlen_eq_string(name, ids[i].key))
  389. return ids[i].value;
  390. fatal_error("fingerprint type '%.*s': not found", PTRLEN_PRINTF(name));
  391. }
  392. static uintmax_t get_uint(BinarySource *in)
  393. {
  394. ptrlen word = get_word(in);
  395. char *string = mkstr(word);
  396. uintmax_t toret = strtoumax(string, NULL, 0);
  397. sfree(string);
  398. return toret;
  399. }
  400. static bool get_boolean(BinarySource *in)
  401. {
  402. return ptrlen_eq_string(get_word(in), "true");
  403. }
  404. static Value *lookup_value(ptrlen word)
  405. {
  406. Value *val = find234(values, &word, valuefind);
  407. if (!val)
  408. fatal_error("id '%.*s': not found", PTRLEN_PRINTF(word));
  409. return val;
  410. }
  411. static Value *get_value(BinarySource *in)
  412. {
  413. return lookup_value(get_word(in));
  414. }
  415. typedef void (*finaliser_fn_t)(strbuf *out, void *ctx);
  416. struct finaliser {
  417. finaliser_fn_t fn;
  418. void *ctx;
  419. };
  420. static struct finaliser *finalisers;
  421. static size_t nfinalisers, finalisersize;
  422. static void add_finaliser(finaliser_fn_t fn, void *ctx)
  423. {
  424. sgrowarray(finalisers, finalisersize, nfinalisers);
  425. finalisers[nfinalisers].fn = fn;
  426. finalisers[nfinalisers].ctx = ctx;
  427. nfinalisers++;
  428. }
  429. static void run_finalisers(strbuf *out)
  430. {
  431. for (size_t i = 0; i < nfinalisers; i++)
  432. finalisers[i].fn(out, finalisers[i].ctx);
  433. nfinalisers = 0;
  434. }
  435. static void finaliser_return_value(strbuf *out, void *ctx)
  436. {
  437. Value *val = (Value *)ctx;
  438. put_datapl(out, val->id);
  439. put_byte(out, '\n');
  440. }
  441. static void finaliser_sfree(strbuf *out, void *ctx)
  442. {
  443. sfree(ctx);
  444. }
  445. #define VALTYPE_GETFN(n,t,f) \
  446. static Value *unwrap_value_##n(Value *val) { \
  447. ValueType expected = VT_##n; \
  448. if (expected != val->type) \
  449. fatal_error("id '%.*s': expected %s, got %s", \
  450. PTRLEN_PRINTF(val->id), \
  451. type_names[expected], type_names[val->type]); \
  452. return val; \
  453. } \
  454. static Value *get_value_##n(BinarySource *in) { \
  455. return unwrap_value_##n(get_value(in)); \
  456. } \
  457. static t get_val_##n(BinarySource *in) { \
  458. return get_value_##n(in)->vu_##n; \
  459. }
  460. VALUE_TYPES(VALTYPE_GETFN)
  461. #undef VALTYPE_GETFN
  462. static ptrlen get_val_string_ptrlen(BinarySource *in)
  463. {
  464. return ptrlen_from_strbuf(get_val_string(in));
  465. }
  466. static char *get_val_string_asciz(BinarySource *in)
  467. {
  468. return get_val_string(in)->s;
  469. }
  470. static strbuf *get_opt_val_string(BinarySource *in);
  471. static char *get_opt_val_string_asciz(BinarySource *in)
  472. {
  473. strbuf *sb = get_opt_val_string(in);
  474. return sb ? sb->s : NULL;
  475. }
  476. static mp_int **get_out_val_mpint(BinarySource *in)
  477. {
  478. Value *val = value_new(VT_mpint);
  479. add_finaliser(finaliser_return_value, val);
  480. return &val->vu_mpint;
  481. }
  482. struct mpint_list {
  483. size_t n;
  484. mp_int **integers;
  485. };
  486. static struct mpint_list get_mpint_list(BinarySource *in)
  487. {
  488. size_t n = get_uint(in);
  489. struct mpint_list mpl;
  490. mpl.n = n;
  491. mpl.integers = snewn(n, mp_int *);
  492. for (size_t i = 0; i < n; i++)
  493. mpl.integers[i] = get_val_mpint(in);
  494. add_finaliser(finaliser_sfree, mpl.integers);
  495. return mpl;
  496. }
  497. static void finaliser_return_uint(strbuf *out, void *ctx)
  498. {
  499. unsigned *uval = (unsigned *)ctx;
  500. strbuf_catf(out, "%u\n", *uval);
  501. sfree(uval);
  502. }
  503. static unsigned *get_out_uint(BinarySource *in)
  504. {
  505. unsigned *uval = snew(unsigned);
  506. add_finaliser(finaliser_return_uint, uval);
  507. return uval;
  508. }
  509. static BinarySink *get_out_val_string_binarysink(BinarySource *in)
  510. {
  511. Value *val = value_new(VT_string);
  512. val->vu_string = strbuf_new();
  513. add_finaliser(finaliser_return_value, val);
  514. return BinarySink_UPCAST(val->vu_string);
  515. }
  516. static void return_val_string_asciz_const(strbuf *out, const char *s);
  517. static void return_val_string_asciz(strbuf *out, char *s);
  518. static void finaliser_return_opt_string_asciz(strbuf *out, void *ctx)
  519. {
  520. char **valp = (char **)ctx;
  521. char *val = *valp;
  522. sfree(valp);
  523. if (!val)
  524. strbuf_catf(out, "NULL\n");
  525. else
  526. return_val_string_asciz(out, val);
  527. }
  528. static char **get_out_opt_val_string_asciz(BinarySource *in)
  529. {
  530. char **valp = snew(char *);
  531. *valp = NULL;
  532. add_finaliser(finaliser_return_opt_string_asciz, valp);
  533. return valp;
  534. }
  535. static void finaliser_return_opt_string_asciz_const(strbuf *out, void *ctx)
  536. {
  537. const char **valp = (const char **)ctx;
  538. const char *val = *valp;
  539. sfree(valp);
  540. if (!val)
  541. strbuf_catf(out, "NULL\n");
  542. else
  543. return_val_string_asciz_const(out, val);
  544. }
  545. static const char **get_out_opt_val_string_asciz_const(BinarySource *in)
  546. {
  547. const char **valp = snew(const char *);
  548. *valp = NULL;
  549. add_finaliser(finaliser_return_opt_string_asciz_const, valp);
  550. return valp;
  551. }
  552. static BinarySource *get_val_string_binarysource(BinarySource *in)
  553. {
  554. strbuf *sb = get_val_string(in);
  555. BinarySource *src = snew(BinarySource);
  556. BinarySource_BARE_INIT(src, sb->u, sb->len);
  557. add_finaliser(finaliser_sfree, src);
  558. return src;
  559. }
  560. #define GET_CONSUMED_FN(type) \
  561. typedef TD_val_##type TD_consumed_val_##type; \
  562. static TD_val_##type get_consumed_val_##type(BinarySource *in) \
  563. { \
  564. Value *val = get_value_##type(in); \
  565. TD_val_##type toret = val->vu_##type; \
  566. del234(values, val); \
  567. sfree(val); \
  568. return toret; \
  569. }
  570. GET_CONSUMED_FN(hash)
  571. GET_CONSUMED_FN(pcs)
  572. static void return_int(strbuf *out, intmax_t u)
  573. {
  574. strbuf_catf(out, "%"PRIdMAX"\n", u);
  575. }
  576. static void return_uint(strbuf *out, uintmax_t u)
  577. {
  578. strbuf_catf(out, "0x%"PRIXMAX"\n", u);
  579. }
  580. static void return_boolean(strbuf *out, bool b)
  581. {
  582. strbuf_catf(out, "%s\n", b ? "true" : "false");
  583. }
  584. static void return_pocklestatus(strbuf *out, PockleStatus status)
  585. {
  586. switch (status) {
  587. default:
  588. strbuf_catf(out, "POCKLE_BAD_STATUS_VALUE\n");
  589. break;
  590. #define STATUS_CASE(id) \
  591. case id: \
  592. strbuf_catf(out, "%s\n", #id); \
  593. break;
  594. POCKLE_STATUSES(STATUS_CASE);
  595. #undef STATUS_CASE
  596. }
  597. }
  598. static void return_val_string_asciz_const(strbuf *out, const char *s)
  599. {
  600. strbuf *sb = strbuf_new();
  601. put_data(sb, s, strlen(s));
  602. return_val_string(out, sb);
  603. }
  604. static void return_val_string_asciz(strbuf *out, char *s)
  605. {
  606. return_val_string_asciz_const(out, s);
  607. sfree(s);
  608. }
  609. #define NULLABLE_RETURN_WRAPPER(type_name, c_type) \
  610. static void return_opt_##type_name(strbuf *out, c_type ptr) \
  611. { \
  612. if (!ptr) \
  613. strbuf_catf(out, "NULL\n"); \
  614. else \
  615. return_##type_name(out, ptr); \
  616. }
  617. NULLABLE_RETURN_WRAPPER(val_string, strbuf *)
  618. NULLABLE_RETURN_WRAPPER(val_string_asciz, char *)
  619. NULLABLE_RETURN_WRAPPER(val_string_asciz_const, const char *)
  620. NULLABLE_RETURN_WRAPPER(val_cipher, ssh_cipher *)
  621. NULLABLE_RETURN_WRAPPER(val_hash, ssh_hash *)
  622. NULLABLE_RETURN_WRAPPER(val_key, ssh_key *)
  623. NULLABLE_RETURN_WRAPPER(val_mpint, mp_int *)
  624. static void handle_hello(BinarySource *in, strbuf *out)
  625. {
  626. strbuf_catf(out, "hello, world\n");
  627. }
  628. static void rsa_free(RSAKey *rsa)
  629. {
  630. freersakey(rsa);
  631. sfree(rsa);
  632. }
  633. static void free_value(Value *val)
  634. {
  635. switch (val->type) {
  636. #define VALTYPE_FREE(n,t,f) case VT_##n: { t v = val->vu_##n; (f); break; }
  637. VALUE_TYPES(VALTYPE_FREE)
  638. #undef VALTYPE_FREE
  639. }
  640. sfree(val);
  641. }
  642. static void handle_free(BinarySource *in, strbuf *out)
  643. {
  644. Value *val = get_value(in);
  645. del234(values, val);
  646. free_value(val);
  647. }
  648. static void handle_newstring(BinarySource *in, strbuf *out)
  649. {
  650. strbuf *sb = strbuf_new();
  651. while (get_avail(in)) {
  652. char c = get_byte(in);
  653. if (c == '%') {
  654. char hex[3];
  655. hex[0] = get_byte(in);
  656. if (hex[0] != '%') {
  657. hex[1] = get_byte(in);
  658. hex[2] = '\0';
  659. c = strtoul(hex, NULL, 16);
  660. }
  661. }
  662. put_byte(sb, c);
  663. }
  664. return_val_string(out, sb);
  665. }
  666. static void handle_getstring(BinarySource *in, strbuf *out)
  667. {
  668. strbuf *sb = get_val_string(in);
  669. for (size_t i = 0; i < sb->len; i++) {
  670. char c = sb->s[i];
  671. if (c > ' ' && c < 0x7F && c != '%') {
  672. put_byte(out, c);
  673. } else {
  674. strbuf_catf(out, "%%%02X", 0xFFU & (unsigned)c);
  675. }
  676. }
  677. put_byte(out, '\n');
  678. }
  679. static void handle_mp_literal(BinarySource *in, strbuf *out)
  680. {
  681. ptrlen pl = get_word(in);
  682. char *str = mkstr(pl);
  683. mp_int *mp = mp__from_string_literal(str);
  684. sfree(str);
  685. return_val_mpint(out, mp);
  686. }
  687. static void handle_mp_dump(BinarySource *in, strbuf *out)
  688. {
  689. mp_int *mp = get_val_mpint(in);
  690. for (size_t i = mp_max_bytes(mp); i-- > 0 ;)
  691. strbuf_catf(out, "%02X", mp_get_byte(mp, i));
  692. put_byte(out, '\n');
  693. }
  694. static void random_queue(ptrlen pl)
  695. {
  696. bufchain_add(&random_data_queue, pl.ptr, pl.len);
  697. }
  698. static size_t random_queue_len(void)
  699. {
  700. return bufchain_size(&random_data_queue);
  701. }
  702. static void random_clear(void)
  703. {
  704. if (test_prng) {
  705. prng_free(test_prng);
  706. test_prng = NULL;
  707. }
  708. bufchain_clear(&random_data_queue);
  709. }
  710. static void random_make_prng(const ssh_hashalg *hashalg, ptrlen seed)
  711. {
  712. random_clear();
  713. test_prng = prng_new(hashalg);
  714. prng_seed_begin(test_prng);
  715. put_datapl(test_prng, seed);
  716. prng_seed_finish(test_prng);
  717. }
  718. mp_int *monty_identity_wrapper(MontyContext *mc)
  719. {
  720. return mp_copy(monty_identity(mc));
  721. }
  722. #define monty_identity monty_identity_wrapper
  723. mp_int *monty_modulus_wrapper(MontyContext *mc)
  724. {
  725. return mp_copy(monty_modulus(mc));
  726. }
  727. #define monty_modulus monty_modulus_wrapper
  728. strbuf *ssh_hash_digest_wrapper(ssh_hash *h)
  729. {
  730. strbuf *sb = strbuf_new();
  731. void *p = strbuf_append(sb, ssh_hash_alg(h)->hlen);
  732. ssh_hash_digest(h, p);
  733. return sb;
  734. }
  735. #undef ssh_hash_digest
  736. #define ssh_hash_digest ssh_hash_digest_wrapper
  737. strbuf *ssh_hash_final_wrapper(ssh_hash *h)
  738. {
  739. strbuf *sb = strbuf_new();
  740. void *p = strbuf_append(sb, ssh_hash_alg(h)->hlen);
  741. ssh_hash_final(h, p);
  742. return sb;
  743. }
  744. #undef ssh_hash_final
  745. #define ssh_hash_final ssh_hash_final_wrapper
  746. void ssh_cipher_setiv_wrapper(ssh_cipher *c, ptrlen key)
  747. {
  748. if (key.len != ssh_cipher_alg(c)->blksize)
  749. fatal_error("ssh_cipher_setiv: needs exactly %d bytes",
  750. ssh_cipher_alg(c)->blksize);
  751. ssh_cipher_setiv(c, key.ptr);
  752. }
  753. #undef ssh_cipher_setiv
  754. #define ssh_cipher_setiv ssh_cipher_setiv_wrapper
  755. void ssh_cipher_setkey_wrapper(ssh_cipher *c, ptrlen key)
  756. {
  757. if (key.len != ssh_cipher_alg(c)->padded_keybytes)
  758. fatal_error("ssh_cipher_setkey: needs exactly %d bytes",
  759. ssh_cipher_alg(c)->padded_keybytes);
  760. ssh_cipher_setkey(c, key.ptr);
  761. }
  762. #undef ssh_cipher_setkey
  763. #define ssh_cipher_setkey ssh_cipher_setkey_wrapper
  764. strbuf *ssh_cipher_encrypt_wrapper(ssh_cipher *c, ptrlen input)
  765. {
  766. if (input.len % ssh_cipher_alg(c)->blksize)
  767. fatal_error("ssh_cipher_encrypt: needs a multiple of %d bytes",
  768. ssh_cipher_alg(c)->blksize);
  769. strbuf *sb = strbuf_new();
  770. put_datapl(sb, input);
  771. ssh_cipher_encrypt(c, sb->u, sb->len);
  772. return sb;
  773. }
  774. #undef ssh_cipher_encrypt
  775. #define ssh_cipher_encrypt ssh_cipher_encrypt_wrapper
  776. strbuf *ssh_cipher_decrypt_wrapper(ssh_cipher *c, ptrlen input)
  777. {
  778. if (input.len % ssh_cipher_alg(c)->blksize)
  779. fatal_error("ssh_cipher_decrypt: needs a multiple of %d bytes",
  780. ssh_cipher_alg(c)->blksize);
  781. strbuf *sb = strbuf_new();
  782. put_datapl(sb, input);
  783. ssh_cipher_decrypt(c, sb->u, sb->len);
  784. return sb;
  785. }
  786. #undef ssh_cipher_decrypt
  787. #define ssh_cipher_decrypt ssh_cipher_decrypt_wrapper
  788. strbuf *ssh_cipher_encrypt_length_wrapper(ssh_cipher *c, ptrlen input,
  789. unsigned long seq)
  790. {
  791. if (input.len != 4)
  792. fatal_error("ssh_cipher_encrypt_length: needs exactly 4 bytes");
  793. strbuf *sb = strbuf_new();
  794. put_datapl(sb, input);
  795. ssh_cipher_encrypt_length(c, sb->u, sb->len, seq);
  796. return sb;
  797. }
  798. #undef ssh_cipher_encrypt_length
  799. #define ssh_cipher_encrypt_length ssh_cipher_encrypt_length_wrapper
  800. strbuf *ssh_cipher_decrypt_length_wrapper(ssh_cipher *c, ptrlen input,
  801. unsigned long seq)
  802. {
  803. if (input.len % ssh_cipher_alg(c)->blksize)
  804. fatal_error("ssh_cipher_decrypt_length: needs exactly 4 bytes");
  805. strbuf *sb = strbuf_new();
  806. put_datapl(sb, input);
  807. ssh_cipher_decrypt_length(c, sb->u, sb->len, seq);
  808. return sb;
  809. }
  810. #undef ssh_cipher_decrypt_length
  811. #define ssh_cipher_decrypt_length ssh_cipher_decrypt_length_wrapper
  812. strbuf *ssh2_mac_genresult_wrapper(ssh2_mac *m)
  813. {
  814. strbuf *sb = strbuf_new();
  815. void *u = strbuf_append(sb, ssh2_mac_alg(m)->len);
  816. ssh2_mac_genresult(m, u);
  817. return sb;
  818. }
  819. #undef ssh2_mac_genresult
  820. #define ssh2_mac_genresult ssh2_mac_genresult_wrapper
  821. bool dh_validate_f_wrapper(dh_ctx *dh, mp_int *f)
  822. {
  823. return dh_validate_f(dh, f) == NULL;
  824. }
  825. #define dh_validate_f dh_validate_f_wrapper
  826. void ssh_hash_update(ssh_hash *h, ptrlen pl)
  827. {
  828. put_datapl(h, pl);
  829. }
  830. void ssh2_mac_update(ssh2_mac *m, ptrlen pl)
  831. {
  832. put_datapl(m, pl);
  833. }
  834. static RSAKey *rsa_new(void)
  835. {
  836. RSAKey *rsa = snew(RSAKey);
  837. memset(rsa, 0, sizeof(RSAKey));
  838. return rsa;
  839. }
  840. strbuf *rsa_ssh1_encrypt_wrapper(ptrlen input, RSAKey *key)
  841. {
  842. /* Fold the boolean return value in C into the string return value
  843. * for this purpose, by returning NULL on failure */
  844. strbuf *sb = strbuf_new();
  845. put_datapl(sb, input);
  846. put_padding(sb, key->bytes - input.len, 0);
  847. if (!rsa_ssh1_encrypt(sb->u, input.len, key)) {
  848. strbuf_free(sb);
  849. return NULL;
  850. }
  851. return sb;
  852. }
  853. #define rsa_ssh1_encrypt rsa_ssh1_encrypt_wrapper
  854. strbuf *rsa_ssh1_decrypt_pkcs1_wrapper(mp_int *input, RSAKey *key)
  855. {
  856. /* Again, return "" on failure */
  857. strbuf *sb = strbuf_new();
  858. if (!rsa_ssh1_decrypt_pkcs1(input, key, sb))
  859. strbuf_clear(sb);
  860. return sb;
  861. }
  862. #define rsa_ssh1_decrypt_pkcs1 rsa_ssh1_decrypt_pkcs1_wrapper
  863. strbuf *des_encrypt_xdmauth_wrapper(ptrlen key, ptrlen data)
  864. {
  865. if (key.len != 7)
  866. fatal_error("des_encrypt_xdmauth: key must be 7 bytes long");
  867. if (data.len % 8 != 0)
  868. fatal_error("des_encrypt_xdmauth: data must be a multiple of 8 bytes");
  869. strbuf *sb = strbuf_new();
  870. put_datapl(sb, data);
  871. des_encrypt_xdmauth(key.ptr, sb->u, sb->len);
  872. return sb;
  873. }
  874. #define des_encrypt_xdmauth des_encrypt_xdmauth_wrapper
  875. strbuf *des_decrypt_xdmauth_wrapper(ptrlen key, ptrlen data)
  876. {
  877. if (key.len != 7)
  878. fatal_error("des_decrypt_xdmauth: key must be 7 bytes long");
  879. if (data.len % 8 != 0)
  880. fatal_error("des_decrypt_xdmauth: data must be a multiple of 8 bytes");
  881. strbuf *sb = strbuf_new();
  882. put_datapl(sb, data);
  883. des_decrypt_xdmauth(key.ptr, sb->u, sb->len);
  884. return sb;
  885. }
  886. #define des_decrypt_xdmauth des_decrypt_xdmauth_wrapper
  887. strbuf *des3_encrypt_pubkey_wrapper(ptrlen key, ptrlen data)
  888. {
  889. if (key.len != 16)
  890. fatal_error("des3_encrypt_pubkey: key must be 16 bytes long");
  891. if (data.len % 8 != 0)
  892. fatal_error("des3_encrypt_pubkey: data must be a multiple of 8 bytes");
  893. strbuf *sb = strbuf_new();
  894. put_datapl(sb, data);
  895. des3_encrypt_pubkey(key.ptr, sb->u, sb->len);
  896. return sb;
  897. }
  898. #define des3_encrypt_pubkey des3_encrypt_pubkey_wrapper
  899. strbuf *des3_decrypt_pubkey_wrapper(ptrlen key, ptrlen data)
  900. {
  901. if (key.len != 16)
  902. fatal_error("des3_decrypt_pubkey: key must be 16 bytes long");
  903. if (data.len % 8 != 0)
  904. fatal_error("des3_decrypt_pubkey: data must be a multiple of 8 bytes");
  905. strbuf *sb = strbuf_new();
  906. put_datapl(sb, data);
  907. des3_decrypt_pubkey(key.ptr, sb->u, sb->len);
  908. return sb;
  909. }
  910. #define des3_decrypt_pubkey des3_decrypt_pubkey_wrapper
  911. strbuf *des3_encrypt_pubkey_ossh_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  912. {
  913. if (key.len != 24)
  914. fatal_error("des3_encrypt_pubkey_ossh: key must be 24 bytes long");
  915. if (iv.len != 8)
  916. fatal_error("des3_encrypt_pubkey_ossh: iv must be 8 bytes long");
  917. if (data.len % 8 != 0)
  918. fatal_error("des3_encrypt_pubkey_ossh: data must be a multiple of 8 bytes");
  919. strbuf *sb = strbuf_new();
  920. put_datapl(sb, data);
  921. des3_encrypt_pubkey_ossh(key.ptr, iv.ptr, sb->u, sb->len);
  922. return sb;
  923. }
  924. #define des3_encrypt_pubkey_ossh des3_encrypt_pubkey_ossh_wrapper
  925. strbuf *des3_decrypt_pubkey_ossh_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  926. {
  927. if (key.len != 24)
  928. fatal_error("des3_decrypt_pubkey_ossh: key must be 24 bytes long");
  929. if (iv.len != 8)
  930. fatal_error("des3_encrypt_pubkey_ossh: iv must be 8 bytes long");
  931. if (data.len % 8 != 0)
  932. fatal_error("des3_decrypt_pubkey_ossh: data must be a multiple of 8 bytes");
  933. strbuf *sb = strbuf_new();
  934. put_datapl(sb, data);
  935. des3_decrypt_pubkey_ossh(key.ptr, iv.ptr, sb->u, sb->len);
  936. return sb;
  937. }
  938. #define des3_decrypt_pubkey_ossh des3_decrypt_pubkey_ossh_wrapper
  939. strbuf *aes256_encrypt_pubkey_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  940. {
  941. if (key.len != 32)
  942. fatal_error("aes256_encrypt_pubkey: key must be 32 bytes long");
  943. if (iv.len != 16)
  944. fatal_error("aes256_encrypt_pubkey: iv must be 16 bytes long");
  945. if (data.len % 16 != 0)
  946. fatal_error("aes256_encrypt_pubkey: data must be a multiple of 16 bytes");
  947. strbuf *sb = strbuf_new();
  948. put_datapl(sb, data);
  949. aes256_encrypt_pubkey(key.ptr, iv.ptr, sb->u, sb->len);
  950. return sb;
  951. }
  952. #define aes256_encrypt_pubkey aes256_encrypt_pubkey_wrapper
  953. strbuf *aes256_decrypt_pubkey_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  954. {
  955. if (key.len != 32)
  956. fatal_error("aes256_decrypt_pubkey: key must be 32 bytes long");
  957. if (iv.len != 16)
  958. fatal_error("aes256_encrypt_pubkey: iv must be 16 bytes long");
  959. if (data.len % 16 != 0)
  960. fatal_error("aes256_decrypt_pubkey: data must be a multiple of 16 bytes");
  961. strbuf *sb = strbuf_new();
  962. put_datapl(sb, data);
  963. aes256_decrypt_pubkey(key.ptr, iv.ptr, sb->u, sb->len);
  964. return sb;
  965. }
  966. #define aes256_decrypt_pubkey aes256_decrypt_pubkey_wrapper
  967. strbuf *prng_read_wrapper(prng *pr, size_t size)
  968. {
  969. strbuf *sb = strbuf_new();
  970. prng_read(pr, strbuf_append(sb, size), size);
  971. return sb;
  972. }
  973. #define prng_read prng_read_wrapper
  974. void prng_seed_update(prng *pr, ptrlen data)
  975. {
  976. put_datapl(pr, data);
  977. }
  978. bool crcda_detect(ptrlen packet, ptrlen iv)
  979. {
  980. if (iv.len != 0 && iv.len != 8)
  981. fatal_error("crcda_detect: iv must be empty or 8 bytes long");
  982. if (packet.len % 8 != 0)
  983. fatal_error("crcda_detect: packet must be a multiple of 8 bytes");
  984. struct crcda_ctx *ctx = crcda_make_context();
  985. bool toret = detect_attack(ctx, packet.ptr, packet.len,
  986. iv.len ? iv.ptr : NULL);
  987. crcda_free_context(ctx);
  988. return toret;
  989. }
  990. ssh_key *ppk_load_s_wrapper(BinarySource *src, char **comment,
  991. const char *passphrase, const char **errorstr)
  992. {
  993. ssh2_userkey *uk = ppk_load_s(src, passphrase, errorstr);
  994. if (uk == SSH2_WRONG_PASSPHRASE) {
  995. /* Fudge this special return value */
  996. *errorstr = "SSH2_WRONG_PASSPHRASE";
  997. return NULL;
  998. }
  999. if (uk == NULL)
  1000. return NULL;
  1001. ssh_key *toret = uk->key;
  1002. *comment = uk->comment;
  1003. sfree(uk);
  1004. return toret;
  1005. }
  1006. #define ppk_load_s ppk_load_s_wrapper
  1007. int rsa1_load_s_wrapper(BinarySource *src, RSAKey *rsa, char **comment,
  1008. const char *passphrase, const char **errorstr)
  1009. {
  1010. int toret = rsa1_load_s(src, rsa, passphrase, errorstr);
  1011. *comment = rsa->comment;
  1012. rsa->comment = NULL;
  1013. return toret;
  1014. }
  1015. #define rsa1_load_s rsa1_load_s_wrapper
  1016. strbuf *ppk_save_sb_wrapper(
  1017. ssh_key *key, const char *comment, const char *passphrase,
  1018. unsigned fmt_version, Argon2Flavour flavour,
  1019. uint32_t mem, uint32_t passes, uint32_t parallel)
  1020. {
  1021. /*
  1022. * For repeatable testing purposes, we never want a timing-dependent
  1023. * choice of password hashing parameters, so this is easy.
  1024. */
  1025. ppk_save_parameters save_params;
  1026. memset(&save_params, 0, sizeof(save_params));
  1027. save_params.fmt_version = fmt_version;
  1028. save_params.argon2_flavour = flavour;
  1029. save_params.argon2_mem = mem;
  1030. save_params.argon2_passes_auto = false;
  1031. save_params.argon2_passes = passes;
  1032. save_params.argon2_parallelism = parallel;
  1033. ssh2_userkey uk;
  1034. uk.key = key;
  1035. uk.comment = dupstr(comment);
  1036. strbuf *toret = ppk_save_sb(&uk, passphrase, &save_params);
  1037. sfree(uk.comment);
  1038. return toret;
  1039. }
  1040. #define ppk_save_sb ppk_save_sb_wrapper
  1041. strbuf *rsa1_save_sb_wrapper(RSAKey *key, const char *comment,
  1042. const char *passphrase)
  1043. {
  1044. key->comment = dupstr(comment);
  1045. strbuf *toret = rsa1_save_sb(key, passphrase);
  1046. sfree(key->comment);
  1047. key->comment = NULL;
  1048. return toret;
  1049. }
  1050. #define rsa1_save_sb rsa1_save_sb_wrapper
  1051. #define return_void(out, expression) (expression)
  1052. static ProgressReceiver null_progress = { .vt = &null_progress_vt };
  1053. mp_int *primegen_generate_wrapper(
  1054. PrimeGenerationContext *ctx, PrimeCandidateSource *pcs)
  1055. {
  1056. return primegen_generate(ctx, pcs, &null_progress);
  1057. }
  1058. #define primegen_generate primegen_generate_wrapper
  1059. RSAKey *rsa1_generate(int bits, bool strong, PrimeGenerationContext *pgc)
  1060. {
  1061. RSAKey *rsakey = snew(RSAKey);
  1062. rsa_generate(rsakey, bits, strong, pgc, &null_progress);
  1063. rsakey->comment = NULL;
  1064. return rsakey;
  1065. }
  1066. ssh_key *rsa_generate_wrapper(int bits, bool strong,
  1067. PrimeGenerationContext *pgc)
  1068. {
  1069. return &rsa1_generate(bits, strong, pgc)->sshk;
  1070. }
  1071. #define rsa_generate rsa_generate_wrapper
  1072. ssh_key *dsa_generate_wrapper(int bits, PrimeGenerationContext *pgc)
  1073. {
  1074. struct dss_key *dsskey = snew(struct dss_key);
  1075. dsa_generate(dsskey, bits, pgc, &null_progress);
  1076. return &dsskey->sshk;
  1077. }
  1078. #define dsa_generate dsa_generate_wrapper
  1079. ssh_key *ecdsa_generate_wrapper(int bits)
  1080. {
  1081. struct ecdsa_key *ek = snew(struct ecdsa_key);
  1082. if (!ecdsa_generate(ek, bits)) {
  1083. sfree(ek);
  1084. return NULL;
  1085. }
  1086. return &ek->sshk;
  1087. }
  1088. #define ecdsa_generate ecdsa_generate_wrapper
  1089. ssh_key *eddsa_generate_wrapper(int bits)
  1090. {
  1091. struct eddsa_key *ek = snew(struct eddsa_key);
  1092. if (!eddsa_generate(ek, bits)) {
  1093. sfree(ek);
  1094. return NULL;
  1095. }
  1096. return &ek->sshk;
  1097. }
  1098. #define eddsa_generate eddsa_generate_wrapper
  1099. size_t key_components_count(key_components *kc) { return kc->ncomponents; }
  1100. const char *key_components_nth_name(key_components *kc, size_t n)
  1101. {
  1102. return (n >= kc->ncomponents ? NULL :
  1103. kc->components[n].name);
  1104. }
  1105. const char *key_components_nth_str(key_components *kc, size_t n)
  1106. {
  1107. return (n >= kc->ncomponents ? NULL :
  1108. kc->components[n].is_mp_int ? NULL :
  1109. kc->components[n].text);
  1110. }
  1111. mp_int *key_components_nth_mp(key_components *kc, size_t n)
  1112. {
  1113. return (n >= kc->ncomponents ? NULL :
  1114. !kc->components[n].is_mp_int ? NULL :
  1115. mp_copy(kc->components[n].mp));
  1116. }
  1117. PockleStatus pockle_add_prime_wrapper(Pockle *pockle, mp_int *p,
  1118. struct mpint_list mpl, mp_int *witness)
  1119. {
  1120. return pockle_add_prime(pockle, p, mpl.integers, mpl.n, witness);
  1121. }
  1122. #define pockle_add_prime pockle_add_prime_wrapper
  1123. strbuf *argon2_wrapper(Argon2Flavour flavour, uint32_t mem, uint32_t passes,
  1124. uint32_t parallel, uint32_t taglen,
  1125. ptrlen P, ptrlen S, ptrlen K, ptrlen X)
  1126. {
  1127. strbuf *out = strbuf_new();
  1128. argon2(flavour, mem, passes, parallel, taglen, P, S, K, X, out);
  1129. return out;
  1130. }
  1131. #define argon2 argon2_wrapper
  1132. #define OPTIONAL_PTR_FUNC(type) \
  1133. typedef TD_val_##type TD_opt_val_##type; \
  1134. static TD_opt_val_##type get_opt_val_##type(BinarySource *in) { \
  1135. ptrlen word = get_word(in); \
  1136. if (ptrlen_eq_string(word, "NULL")) \
  1137. return NULL; \
  1138. return unwrap_value_##type(lookup_value(word))->vu_##type; \
  1139. }
  1140. OPTIONAL_PTR_FUNC(cipher)
  1141. OPTIONAL_PTR_FUNC(mpint)
  1142. OPTIONAL_PTR_FUNC(string)
  1143. typedef uintmax_t TD_uint;
  1144. typedef bool TD_boolean;
  1145. typedef ptrlen TD_val_string_ptrlen;
  1146. typedef char *TD_val_string_asciz;
  1147. typedef BinarySource *TD_val_string_binarysource;
  1148. typedef unsigned *TD_out_uint;
  1149. typedef BinarySink *TD_out_val_string_binarysink;
  1150. typedef const char *TD_opt_val_string_asciz;
  1151. typedef char **TD_out_val_string_asciz;
  1152. typedef char **TD_out_opt_val_string_asciz;
  1153. typedef const char **TD_out_opt_val_string_asciz_const;
  1154. typedef ssh_hash *TD_consumed_val_hash;
  1155. typedef const ssh_hashalg *TD_hashalg;
  1156. typedef const ssh2_macalg *TD_macalg;
  1157. typedef const ssh_keyalg *TD_keyalg;
  1158. typedef const ssh_cipheralg *TD_cipheralg;
  1159. typedef const ssh_kex *TD_dh_group;
  1160. typedef const ssh_kex *TD_ecdh_alg;
  1161. typedef RsaSsh1Order TD_rsaorder;
  1162. typedef key_components *TD_keycomponents;
  1163. typedef const PrimeGenerationPolicy *TD_primegenpolicy;
  1164. typedef struct mpint_list TD_mpint_list;
  1165. typedef PockleStatus TD_pocklestatus;
  1166. typedef Argon2Flavour TD_argon2flavour;
  1167. typedef FingerprintType TD_fptype;
  1168. #define FUNC0(rettype, function) \
  1169. static void handle_##function(BinarySource *in, strbuf *out) { \
  1170. return_##rettype(out, function()); \
  1171. }
  1172. #define FUNC1(rettype, function, type1) \
  1173. static void handle_##function(BinarySource *in, strbuf *out) { \
  1174. TD_##type1 arg1 = get_##type1(in); \
  1175. return_##rettype(out, function(arg1)); \
  1176. }
  1177. #define FUNC2(rettype, function, type1, type2) \
  1178. static void handle_##function(BinarySource *in, strbuf *out) { \
  1179. TD_##type1 arg1 = get_##type1(in); \
  1180. TD_##type2 arg2 = get_##type2(in); \
  1181. return_##rettype(out, function(arg1, arg2)); \
  1182. }
  1183. #define FUNC3(rettype, function, type1, type2, type3) \
  1184. static void handle_##function(BinarySource *in, strbuf *out) { \
  1185. TD_##type1 arg1 = get_##type1(in); \
  1186. TD_##type2 arg2 = get_##type2(in); \
  1187. TD_##type3 arg3 = get_##type3(in); \
  1188. return_##rettype(out, function(arg1, arg2, arg3)); \
  1189. }
  1190. #define FUNC4(rettype, function, type1, type2, type3, type4) \
  1191. static void handle_##function(BinarySource *in, strbuf *out) { \
  1192. TD_##type1 arg1 = get_##type1(in); \
  1193. TD_##type2 arg2 = get_##type2(in); \
  1194. TD_##type3 arg3 = get_##type3(in); \
  1195. TD_##type4 arg4 = get_##type4(in); \
  1196. return_##rettype(out, function(arg1, arg2, arg3, arg4)); \
  1197. }
  1198. #define FUNC5(rettype, function, type1, type2, type3, type4, type5) \
  1199. static void handle_##function(BinarySource *in, strbuf *out) { \
  1200. TD_##type1 arg1 = get_##type1(in); \
  1201. TD_##type2 arg2 = get_##type2(in); \
  1202. TD_##type3 arg3 = get_##type3(in); \
  1203. TD_##type4 arg4 = get_##type4(in); \
  1204. TD_##type5 arg5 = get_##type5(in); \
  1205. return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5)); \
  1206. }
  1207. #define FUNC6(rettype, function, type1, type2, type3, type4, type5, \
  1208. type6) \
  1209. static void handle_##function(BinarySource *in, strbuf *out) { \
  1210. TD_##type1 arg1 = get_##type1(in); \
  1211. TD_##type2 arg2 = get_##type2(in); \
  1212. TD_##type3 arg3 = get_##type3(in); \
  1213. TD_##type4 arg4 = get_##type4(in); \
  1214. TD_##type5 arg5 = get_##type5(in); \
  1215. TD_##type6 arg6 = get_##type6(in); \
  1216. return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \
  1217. arg6)); \
  1218. }
  1219. #define FUNC7(rettype, function, type1, type2, type3, type4, type5, \
  1220. type6, type7) \
  1221. static void handle_##function(BinarySource *in, strbuf *out) { \
  1222. TD_##type1 arg1 = get_##type1(in); \
  1223. TD_##type2 arg2 = get_##type2(in); \
  1224. TD_##type3 arg3 = get_##type3(in); \
  1225. TD_##type4 arg4 = get_##type4(in); \
  1226. TD_##type5 arg5 = get_##type5(in); \
  1227. TD_##type6 arg6 = get_##type6(in); \
  1228. TD_##type7 arg7 = get_##type7(in); \
  1229. return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \
  1230. arg6, arg7)); \
  1231. }
  1232. #define FUNC8(rettype, function, type1, type2, type3, type4, type5, \
  1233. type6, type7, type8) \
  1234. static void handle_##function(BinarySource *in, strbuf *out) { \
  1235. TD_##type1 arg1 = get_##type1(in); \
  1236. TD_##type2 arg2 = get_##type2(in); \
  1237. TD_##type3 arg3 = get_##type3(in); \
  1238. TD_##type4 arg4 = get_##type4(in); \
  1239. TD_##type5 arg5 = get_##type5(in); \
  1240. TD_##type6 arg6 = get_##type6(in); \
  1241. TD_##type7 arg7 = get_##type7(in); \
  1242. TD_##type8 arg8 = get_##type8(in); \
  1243. return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \
  1244. arg6, arg7, arg8)); \
  1245. }
  1246. #define FUNC9(rettype, function, type1, type2, type3, type4, type5, \
  1247. type6, type7, type8, type9) \
  1248. static void handle_##function(BinarySource *in, strbuf *out) { \
  1249. TD_##type1 arg1 = get_##type1(in); \
  1250. TD_##type2 arg2 = get_##type2(in); \
  1251. TD_##type3 arg3 = get_##type3(in); \
  1252. TD_##type4 arg4 = get_##type4(in); \
  1253. TD_##type5 arg5 = get_##type5(in); \
  1254. TD_##type6 arg6 = get_##type6(in); \
  1255. TD_##type7 arg7 = get_##type7(in); \
  1256. TD_##type8 arg8 = get_##type8(in); \
  1257. TD_##type9 arg9 = get_##type9(in); \
  1258. return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \
  1259. arg6, arg7, arg8, arg9)); \
  1260. }
  1261. #include "testcrypt.h"
  1262. #undef FUNC9
  1263. #undef FUNC8
  1264. #undef FUNC7
  1265. #undef FUNC6
  1266. #undef FUNC5
  1267. #undef FUNC4
  1268. #undef FUNC3
  1269. #undef FUNC2
  1270. #undef FUNC1
  1271. #undef FUNC0
  1272. static void process_line(BinarySource *in, strbuf *out)
  1273. {
  1274. ptrlen id = get_word(in);
  1275. #define DISPATCH_INTERNAL(cmdname, handler) do { \
  1276. if (ptrlen_eq_string(id, cmdname)) { \
  1277. handler(in, out); \
  1278. return; \
  1279. } \
  1280. } while (0)
  1281. #define DISPATCH_COMMAND(cmd) DISPATCH_INTERNAL(#cmd, handle_##cmd)
  1282. DISPATCH_COMMAND(hello);
  1283. DISPATCH_COMMAND(free);
  1284. DISPATCH_COMMAND(newstring);
  1285. DISPATCH_COMMAND(getstring);
  1286. DISPATCH_COMMAND(mp_literal);
  1287. DISPATCH_COMMAND(mp_dump);
  1288. #undef DISPATCH_COMMAND
  1289. #define FUNC0(ret,fn) DISPATCH_INTERNAL(#fn,handle_##fn);
  1290. #define FUNC1(ret,fn,x) DISPATCH_INTERNAL(#fn,handle_##fn);
  1291. #define FUNC2(ret,fn,x,y) DISPATCH_INTERNAL(#fn,handle_##fn);
  1292. #define FUNC3(ret,fn,x,y,z) DISPATCH_INTERNAL(#fn,handle_##fn);
  1293. #define FUNC4(ret,fn,x,y,z,v) DISPATCH_INTERNAL(#fn,handle_##fn);
  1294. #define FUNC5(ret,fn,x,y,z,v,w) DISPATCH_INTERNAL(#fn,handle_##fn);
  1295. #define FUNC6(ret,fn,x,y,z,v,w,u) DISPATCH_INTERNAL(#fn,handle_##fn);
  1296. #define FUNC7(ret,fn,x,y,z,v,w,u,t) DISPATCH_INTERNAL(#fn,handle_##fn);
  1297. #define FUNC8(ret,fn,x,y,z,v,w,u,t,s) DISPATCH_INTERNAL(#fn,handle_##fn);
  1298. #define FUNC9(ret,fn,x,y,z,v,w,u,t,s,r) DISPATCH_INTERNAL(#fn,handle_##fn);
  1299. #include "testcrypt.h"
  1300. #undef FUNC9
  1301. #undef FUNC8
  1302. #undef FUNC7
  1303. #undef FUNC6
  1304. #undef FUNC5
  1305. #undef FUNC4
  1306. #undef FUNC3
  1307. #undef FUNC2
  1308. #undef FUNC1
  1309. #undef FUNC0
  1310. #undef DISPATCH_INTERNAL
  1311. fatal_error("command '%.*s': unrecognised", PTRLEN_PRINTF(id));
  1312. }
  1313. static void free_all_values(void)
  1314. {
  1315. for (Value *val; (val = delpos234(values, 0)) != NULL ;)
  1316. free_value(val);
  1317. freetree234(values);
  1318. }
  1319. void dputs(const char *buf)
  1320. {
  1321. fputs(buf, stderr);
  1322. }
  1323. int main(int argc, char **argv)
  1324. {
  1325. const char *infile = NULL, *outfile = NULL;
  1326. bool doing_opts = true;
  1327. while (--argc > 0) {
  1328. char *p = *++argv;
  1329. if (p[0] == '-' && doing_opts) {
  1330. if (!strcmp(p, "-o")) {
  1331. if (--argc <= 0) {
  1332. fprintf(stderr, "'-o' expects a filename\n");
  1333. return 1;
  1334. }
  1335. outfile = *++argv;
  1336. } else if (!strcmp(p, "--")) {
  1337. doing_opts = false;
  1338. } else if (!strcmp(p, "--help")) {
  1339. printf("usage: testcrypt [INFILE] [-o OUTFILE]\n");
  1340. printf(" also: testcrypt --help display this text\n");
  1341. return 0;
  1342. } else {
  1343. fprintf(stderr, "unknown command line option '%s'\n", p);
  1344. return 1;
  1345. }
  1346. } else if (!infile) {
  1347. infile = p;
  1348. } else {
  1349. fprintf(stderr, "can only handle one input file name\n");
  1350. return 1;
  1351. }
  1352. }
  1353. FILE *infp = stdin;
  1354. if (infile) {
  1355. infp = fopen(infile, "r");
  1356. if (!infp) {
  1357. fprintf(stderr, "%s: open: %s\n", infile, strerror(errno));
  1358. return 1;
  1359. }
  1360. }
  1361. FILE *outfp = stdout;
  1362. if (outfile) {
  1363. outfp = fopen(outfile, "w");
  1364. if (!outfp) {
  1365. fprintf(stderr, "%s: open: %s\n", outfile, strerror(errno));
  1366. return 1;
  1367. }
  1368. }
  1369. values = newtree234(valuecmp);
  1370. atexit(free_all_values);
  1371. for (char *line; (line = chomp(fgetline(infp))) != NULL ;) {
  1372. BinarySource src[1];
  1373. BinarySource_BARE_INIT(src, line, strlen(line));
  1374. strbuf *sb = strbuf_new();
  1375. process_line(src, sb);
  1376. run_finalisers(sb);
  1377. size_t lines = 0;
  1378. for (size_t i = 0; i < sb->len; i++)
  1379. if (sb->s[i] == '\n')
  1380. lines++;
  1381. fprintf(outfp, "%"SIZEu"\n%s", lines, sb->s);
  1382. fflush(outfp);
  1383. strbuf_free(sb);
  1384. sfree(line);
  1385. }
  1386. if (infp != stdin)
  1387. fclose(infp);
  1388. if (outfp != stdin)
  1389. fclose(outfp);
  1390. return 0;
  1391. }