From 5cfc90ff0de9d51c1556186e4935e9f4cb0cb7a0 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 6 Jan 2020 19:58:25 +0000 Subject: [PATCH] Expose the key-file marshalling functions in testcrypt. This will allow me to write tests for them. --- Recipe | 4 +- testcrypt.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++- testcrypt.h | 13 ++++++ 3 files changed, 135 insertions(+), 4 deletions(-) diff --git a/Recipe b/Recipe index d6171b5d..34339774 100644 --- a/Recipe +++ b/Recipe @@ -392,9 +392,9 @@ osxlaunch : [UT] osxlaunch fuzzterm : [UT] UXTERM CHARSET MISC version uxmisc uxucs fuzzterm time settings + uxstore be_none uxnogtk memory -testcrypt : [UT] testcrypt SSHCRYPTO sshprng sshprime marshal utils +testcrypt : [UT] testcrypt SSHCRYPTO sshprng sshprime sshpubk marshal utils + memory tree234 uxutils KEYGEN -testcrypt : [C] testcrypt SSHCRYPTO sshprng sshprime marshal utils +testcrypt : [C] testcrypt SSHCRYPTO sshprng sshprime sshpubk marshal utils + memory tree234 winmiscs KEYGEN testsc : [UT] testsc SSHCRYPTO marshal utils memory tree234 wildcard + sshmac uxutils diff --git a/testcrypt.c b/testcrypt.c index 49fa72e7..26cee4ae 100644 --- a/testcrypt.c +++ b/testcrypt.c @@ -48,6 +48,12 @@ static NORETURN void fatal_error(const char *p, ...) void out_of_memory(void) { fatal_error("out of memory"); } +FILE *f_open(const struct Filename *fn, char const *mode, bool private) +{ unreachable("f_open should never be called by this test program"); } + +static bool old_keyfile_warning_given; +void old_keyfile_warning(void) { old_keyfile_warning_given = true; } + static bufchain random_data_queue; void random_read(void *buf, size_t size) { @@ -118,6 +124,8 @@ struct Value { #define VALTYPE_UNION(n,t,f) t vu_##n; VALUE_TYPES(VALTYPE_UNION) #undef VALTYPE_UNION + + char *bare_string; }; }; @@ -428,6 +436,14 @@ static char *get_val_string_asciz(BinarySource *in) return get_val_string(in)->s; } +static strbuf *get_opt_val_string(BinarySource *in); + +static char *get_opt_val_string_asciz(BinarySource *in) +{ + strbuf *sb = get_opt_val_string(in); + return sb ? sb->s : NULL; +} + static mp_int **get_out_val_mpint(BinarySource *in) { Value *val = value_new(VT_mpint); @@ -457,6 +473,47 @@ static BinarySink *get_out_val_string_binarysink(BinarySource *in) return BinarySink_UPCAST(val->vu_string); } +static void return_val_string_asciz_const(strbuf *out, const char *s); +static void return_val_string_asciz(strbuf *out, char *s); + +static void finaliser_return_opt_string_asciz(strbuf *out, void *ctx) +{ + char **valp = (char **)ctx; + char *val = *valp; + sfree(valp); + if (!val) + strbuf_catf(out, "NULL\n"); + else + return_val_string_asciz(out, val); +} + +static char **get_out_opt_val_string_asciz(BinarySource *in) +{ + char **valp = snew(char *); + *valp = NULL; + add_finaliser(finaliser_return_opt_string_asciz, valp); + return valp; +} + +static void finaliser_return_opt_string_asciz_const(strbuf *out, void *ctx) +{ + const char **valp = (const char **)ctx; + const char *val = *valp; + sfree(valp); + if (!val) + strbuf_catf(out, "NULL\n"); + else + return_val_string_asciz_const(out, val); +} + +static const char **get_out_opt_val_string_asciz_const(BinarySource *in) +{ + const char **valp = snew(const char *); + *valp = NULL; + add_finaliser(finaliser_return_opt_string_asciz_const, valp); + return valp; +} + static void finaliser_sfree(strbuf *out, void *ctx) { sfree(ctx); @@ -495,14 +552,19 @@ static void return_boolean(strbuf *out, bool b) strbuf_catf(out, "%s\n", b ? "true" : "false"); } -static void return_val_string_asciz(strbuf *out, char *s) +static void return_val_string_asciz_const(strbuf *out, const char *s) { strbuf *sb = strbuf_new(); put_data(sb, s, strlen(s)); - sfree(s); return_val_string(out, sb); } +static void return_val_string_asciz(strbuf *out, char *s) +{ + return_val_string_asciz_const(out, s); + sfree(s); +} + #define NULLABLE_RETURN_WRAPPER(type_name, c_type) \ static void return_opt_##type_name(strbuf *out, c_type ptr) \ { \ @@ -908,6 +970,57 @@ bool crcda_detect(ptrlen packet, ptrlen iv) return toret; } +ssh_key *ppk_load_s_wrapper(BinarySource *src, char **comment, + const char *passphrase, const char **errorstr) +{ + ssh2_userkey *uk = ppk_load_s(src, passphrase, errorstr); + if (uk == SSH2_WRONG_PASSPHRASE) { + /* Fudge this special return value */ + *errorstr = "SSH2_WRONG_PASSPHRASE"; + return NULL; + } + if (uk == NULL) + return NULL; + ssh_key *toret = uk->key; + *comment = uk->comment; + sfree(uk); + return toret; +} +#define ppk_load_s ppk_load_s_wrapper + +int rsa1_load_s_wrapper(BinarySource *src, RSAKey *rsa, char **comment, + const char *passphrase, const char **errorstr) +{ + int toret = rsa1_load_s(src, rsa, passphrase, errorstr); + *comment = rsa->comment; + rsa->comment = NULL; + return toret; +} +#define rsa1_load_s rsa1_load_s_wrapper + +strbuf *ppk_save_sb_wrapper(ssh_key *key, const char *comment, + const char *passphrase) +{ + ssh2_userkey uk; + uk.key = key; + uk.comment = dupstr(comment); + strbuf *toret = ppk_save_sb(&uk, passphrase); + sfree(uk.comment); + return toret; +} +#define ppk_save_sb ppk_save_sb_wrapper + +strbuf *rsa1_save_sb_wrapper(RSAKey *key, const char *comment, + const char *passphrase) +{ + key->comment = dupstr(comment); + strbuf *toret = rsa1_save_sb(key, passphrase); + sfree(key->comment); + key->comment = NULL; + return toret; +} +#define rsa1_save_sb rsa1_save_sb_wrapper + #define return_void(out, expression) (expression) static void no_progress(void *param, int action, int phase, int iprogress) {} @@ -980,6 +1093,7 @@ VALUE_TYPES(VALTYPE_TYPEDEF) } OPTIONAL_PTR_FUNC(cipher) OPTIONAL_PTR_FUNC(mpint) +OPTIONAL_PTR_FUNC(string) typedef uintmax_t TD_uint; typedef ptrlen TD_val_string_ptrlen; @@ -987,6 +1101,10 @@ typedef char *TD_val_string_asciz; typedef BinarySource *TD_val_string_binarysource; typedef unsigned *TD_out_uint; typedef BinarySink *TD_out_val_string_binarysink; +typedef const char *TD_opt_val_string_asciz; +typedef char **TD_out_val_string_asciz; +typedef char **TD_out_opt_val_string_asciz; +typedef const char **TD_out_opt_val_string_asciz_const; typedef ssh_hash *TD_consumed_val_hash; typedef const ssh_hashalg *TD_hashalg; typedef const ssh2_macalg *TD_macalg; diff --git a/testcrypt.h b/testcrypt.h index e4edcc37..d34cd506 100644 --- a/testcrypt.h +++ b/testcrypt.h @@ -228,6 +228,19 @@ FUNC1(void, prng_seed_finish, val_prng) FUNC2(val_string, prng_read, val_prng, uint) FUNC3(void, prng_add_entropy, val_prng, uint, val_string_ptrlen) +/* + * Key load/save functions, or rather, the BinarySource / strbuf API + * that sits just inside the file I/O versions. + */ +FUNC2(boolean, ppk_encrypted_s, val_string_binarysource, out_opt_val_string_asciz) +FUNC2(boolean, rsa1_encrypted_s, val_string_binarysource, out_opt_val_string_asciz) +FUNC5(boolean, ppk_loadpub_s, val_string_binarysource, out_opt_val_string_asciz, out_val_string_binarysink, out_opt_val_string_asciz, out_opt_val_string_asciz_const) +FUNC4(int, rsa1_loadpub_s, val_string_binarysource, out_val_string_binarysink, out_opt_val_string_asciz, out_opt_val_string_asciz_const) +FUNC4(opt_val_key, ppk_load_s, val_string_binarysource, out_opt_val_string_asciz, opt_val_string_asciz, out_opt_val_string_asciz_const) +FUNC5(int, rsa1_load_s, val_string_binarysource, val_rsa, out_opt_val_string_asciz, opt_val_string_asciz, out_opt_val_string_asciz_const) +FUNC3(val_string, ppk_save_sb, val_key, opt_val_string_asciz, opt_val_string_asciz) +FUNC3(val_string, rsa1_save_sb, val_rsa, opt_val_string_asciz, opt_val_string_asciz) + /* * Key generation functions. */