From d8f26a76ee11831b3b1b21dcdcafb156a2db3612 Mon Sep 17 00:00:00 2001 From: Andrew Bettison Date: Thu, 13 Nov 2014 10:03:07 +1030 Subject: [PATCH] Accept '#passphrase' for bundle secret arguments As well as a hex string. Applies to CLI and also REST API. Maximum pass phrase length is 80 ASCII chars. --- cli.c | 4 ++-- cli.h | 2 +- dataformats.c | 19 +++++++++++++++++++ headerfiles.mk | 1 + httpd.h | 4 ++-- rhizome_cli.c | 4 ++-- rhizome_restful.c | 14 ++++++-------- rhizome_types.h | 19 ++++++++++++++++++- 8 files changed, 51 insertions(+), 16 deletions(-) diff --git a/cli.c b/cli.c index 9ff294a3..22542116 100644 --- a/cli.c +++ b/cli.c @@ -374,9 +374,9 @@ int cli_optional_sid(const char *arg) return !arg[0] || str_is_subscriber_id(arg); } -int cli_optional_bundle_key(const char *arg) +int cli_optional_bundle_secret_key(const char *arg) { - return !arg[0] || str_to_rhizome_bk_t(NULL, arg) != -1; + return !arg[0] || str_to_rhizome_bsk_t(NULL, arg) != -1; } int cli_manifestid(const char *arg) diff --git a/cli.h b/cli.h index b98efc4a..89c62481 100644 --- a/cli.h +++ b/cli.h @@ -88,7 +88,7 @@ int cli_lookup_did(const char *text); int cli_path_regular(const char *arg); int cli_absolute_path(const char *arg); int cli_optional_sid(const char *arg); -int cli_optional_bundle_key(const char *arg); +int cli_optional_bundle_secret_key(const char *arg); int cli_manifestid(const char *arg); int cli_fileid(const char *arg); int cli_optional_bundle_crypt_key(const char *arg); diff --git a/dataformats.c b/dataformats.c index f55cee18..feb4a69e 100644 --- a/dataformats.c +++ b/dataformats.c @@ -141,6 +141,25 @@ int strn_to_rhizome_bk_t(rhizome_bk_t *bkp, const char *hex, const char **endp) return 0; } +int str_to_rhizome_bsk_t(rhizome_bk_t *bskp, const char *text) +{ + return strn_to_rhizome_bsk_t(bskp, text, strlen(text)); +} + +int strn_to_rhizome_bsk_t(rhizome_bk_t *bskp, const char *text, size_t textlen) +{ + if (textlen > 0 && text[0] == '#') { + if (textlen <= 1) + return -1; // missing pass phrase + if (textlen > RHIZOME_BUNDLE_SECRET_MAX_STRLEN + 1) + return -1; // pass phrase too long + if (bskp) + strn_digest_passphrase(bskp->binary, sizeof bskp->binary, text, textlen); + return 0; + } + return strn_to_rhizome_bk_t(bskp, text, NULL); +} + int rhizome_strn_is_bundle_crypt_key(const char *key) { return is_xsubstring(key, RHIZOME_CRYPT_KEY_STRLEN); diff --git a/headerfiles.mk b/headerfiles.mk index 873ebd70..773e64b3 100644 --- a/headerfiles.mk +++ b/headerfiles.mk @@ -5,6 +5,7 @@ HDRS= fifo.h \ overlay_interface.h \ commandline.h \ limit.h \ + rhizome_types.h \ rhizome.h \ httpd.h \ instance.h \ diff --git a/httpd.h b/httpd.h index 248abfe4..2e3860b7 100644 --- a/httpd.h +++ b/httpd.h @@ -116,8 +116,8 @@ typedef struct httpd_request size_t author_hex_len; sid_t author; // For storing the "bundle-secret" hex as we receive it - char secret_hex[RHIZOME_BUNDLE_KEY_STRLEN]; - size_t secret_hex_len; + char secret_text[RHIZOME_BUNDLE_SECRET_MAX_STRLEN]; + size_t secret_text_len; rhizome_bk_t bundle_secret; // The "force-new" parameter char force_new_text[5]; // enough for "false" diff --git a/rhizome_cli.c b/rhizome_cli.c index 521c7d60..3781152a 100644 --- a/rhizome_cli.c +++ b/rhizome_cli.c @@ -120,7 +120,7 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont return -1; cli_arg(parsed, "manifestpath", &manifestpath, NULL, ""); cli_arg(parsed, "manifestid", &manifestid, NULL, ""); - if (cli_arg(parsed, "bsk", &bskhex, cli_optional_bundle_key, NULL) == -1) + if (cli_arg(parsed, "bsk", &bskhex, cli_optional_bundle_secret_key, NULL) == -1) return -1; sid_t authorSid; @@ -490,7 +490,7 @@ static int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_conte if ( cli_arg(parsed, "manifestid", &manifestid, cli_manifestid, "") == -1 || cli_arg(parsed, "manifestpath", &manifestpath, NULL, "") == -1 || cli_arg(parsed, "filepath", &filepath, NULL, "") == -1 - || cli_arg(parsed, "bsk", &bskhex, cli_optional_bundle_key, NULL) == -1) + || cli_arg(parsed, "bsk", &bskhex, cli_optional_bundle_secret_key, NULL) == -1) return -1; int extract = strcasecmp(parsed->args[1], "extract")==0; diff --git a/rhizome_restful.c b/rhizome_restful.c index cdc73f83..6abc1f4a 100644 --- a/rhizome_restful.c +++ b/rhizome_restful.c @@ -414,7 +414,7 @@ static int insert_mime_part_header(struct http_request *hr, const struct mime_pa if (r->u.insert.received_secret) return http_response_form_part(r, "Duplicate", PART_SECRET, NULL, 0); r->u.insert.current_part = PART_SECRET; - assert(r->u.insert.secret_hex_len == 0); + assert(r->u.insert.secret_text_len == 0); } else if (strcmp(h->content_disposition.name, PART_MANIFEST) == 0) { // Reject a request if it has a repeated manifest part. @@ -476,9 +476,9 @@ static int insert_mime_part_body(struct http_request *hr, char *buf, size_t len) } else if (r->u.insert.current_part == PART_SECRET) { accumulate_text(r, PART_SECRET, - r->u.insert.secret_hex, - sizeof r->u.insert.secret_hex, - &r->u.insert.secret_hex_len, + r->u.insert.secret_text, + sizeof r->u.insert.secret_text, + &r->u.insert.secret_text_len, buf, len); } else if (r->u.insert.current_part == PART_MANIFEST) { @@ -515,10 +515,8 @@ static int insert_mime_part_end(struct http_request *hr) DEBUGF("received %s = %s", PART_AUTHOR, alloca_tohex_sid_t(r->u.insert.author)); } else if (r->u.insert.current_part == PART_SECRET) { - if ( r->u.insert.secret_hex_len != sizeof r->u.insert.secret_hex - || strn_to_rhizome_bk_t(&r->u.insert.bundle_secret, r->u.insert.secret_hex, NULL) == -1 - ) - return http_response_form_part(r, "Invalid", PART_SECRET, r->u.insert.secret_hex, r->u.insert.secret_hex_len); + if (strn_to_rhizome_bsk_t(&r->u.insert.bundle_secret, r->u.insert.secret_text, r->u.insert.secret_text_len) == -1) + return http_response_form_part(r, "Invalid", PART_SECRET, r->u.insert.secret_text, r->u.insert.secret_text_len); r->u.insert.received_secret = 1; if (config.debug.rhizome) DEBUGF("received %s = %s", PART_SECRET, alloca_tohex_rhizome_bk_t(r->u.insert.bundle_secret)); diff --git a/rhizome_types.h b/rhizome_types.h index e7feaa26..5a66a00b 100644 --- a/rhizome_types.h +++ b/rhizome_types.h @@ -44,6 +44,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define RHIZOME_CRYPT_KEY_BYTES crypto_stream_xsalsa20_ref_KEYBYTES #define RHIZOME_CRYPT_KEY_STRLEN (RHIZOME_CRYPT_KEY_BYTES * 2) +#define RHIZOME_PASSPHRASE_MAX_STRLEN 80 + +#if RHIZOME_PASSPHRASE_MAX_STRLEN > RHIZOME_BUNDLE_KEY_STRLEN +# define RHIZOME_BUNDLE_SECRET_MAX_STRLEN RHIZOME_PASSPHRASE_MAX_STRLEN +#else +# define RHIZOME_BUNDLE_SECRET_MAX_STRLEN RHIZOME_BUNDLE_KEY_STRLEN +#endif + #define RHIZOME_BAR_BYTES 32 #define RHIZOME_BAR_PREFIX_BYTES 15 #define RHIZOME_BAR_PREFIX_OFFSET 0 @@ -91,7 +99,7 @@ int cmp_rhizome_filehash_t(const rhizome_filehash_t *a, const rhizome_filehash_t int str_to_rhizome_filehash_t(rhizome_filehash_t *fh, const char *hex); int strn_to_rhizome_filehash_t(rhizome_filehash_t *fh, const char *hex, const char **endp); -/* Fundamental data type: Rhizome Bundle Key +/* Fundamental data type: Rhizome Bundle Key (BK) * * @author Andrew Bettison */ @@ -108,9 +116,18 @@ __RHIZOME_TYPES_INLINE int rhizome_is_bk_none(const rhizome_bk_t *bk) { #define alloca_tohex_rhizome_bk_t(bk) alloca_tohex((bk).binary, sizeof (*(rhizome_bk_t*)0).binary) int cmp_rhizome_bk_t(const rhizome_bk_t *a, const rhizome_bk_t *b); + +// The BK field can only be in hex format int str_to_rhizome_bk_t(rhizome_bk_t *bk, const char *hex); int strn_to_rhizome_bk_t(rhizome_bk_t *bk, const char *hex, const char **endp); +// The Bundle Secret can be given as hex or as a passphrase +int str_to_rhizome_bsk_t(rhizome_bk_t *bsk, const char *text); +int strn_to_rhizome_bsk_t(rhizome_bk_t *bsk, const char *text, size_t textlen); + +/* Fundamental data type: Rhizome BAR + */ + typedef struct rhizome_bar_binary { unsigned char binary[RHIZOME_BAR_BYTES]; } rhizome_bar_t;