commit ed48b0fe56df2f719cd7cd274c664f7037f98b75 Author: Nick Mathewson <ni...@torproject.org> Date: Fri Oct 18 10:25:00 2013 -0700
Support for writing ed25519 public/private components to disk. This refactors the "== type:tag ==" code from crypto_curve25519.c --- src/common/crypto_curve25519.c | 128 ++++++++++++++++++++++++++++++---------- src/common/crypto_curve25519.h | 12 ++++ src/common/crypto_ed25519.c | 60 +++++++++++++++++++ src/common/crypto_ed25519.h | 17 +++++- 4 files changed, 183 insertions(+), 34 deletions(-) diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c index 290e88d..484dd76 100644 --- a/src/common/crypto_curve25519.c +++ b/src/common/crypto_curve25519.c @@ -8,6 +8,7 @@ #ifdef HAVE_SYS_STAT_H #include <sys/stat.h> #endif +#include "container.h" #include "crypto.h" #include "crypto_curve25519.h" #include "util.h" @@ -127,69 +128,132 @@ curve25519_keypair_generate(curve25519_keypair_t *keypair_out, return 0; } +/** DOCDOC */ int -curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair, - const char *fname, - const char *tag) +crypto_write_tagged_contents_to_file(const char *fname, + const char *typestring, + const char *tag, + const uint8_t *data, + size_t datalen) { - char contents[32 + CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN]; - int r; + char header[32]; + smartlist_t *chunks = smartlist_new(); + sized_chunk_t ch0, ch1; + int r = -1; - memset(contents, 0, sizeof(contents)); - tor_snprintf(contents, sizeof(contents), "== c25519v1: %s ==", tag); - tor_assert(strlen(contents) <= 32); - memcpy(contents+32, keypair->seckey.secret_key, CURVE25519_SECKEY_LEN); - memcpy(contents+32+CURVE25519_SECKEY_LEN, - keypair->pubkey.public_key, CURVE25519_PUBKEY_LEN); + memset(header, 0, sizeof(header)); + if (tor_snprintf(header, sizeof(header), + "== %s: %s ==", typestring, tag) < 0) + goto end; + ch0.bytes = header; + ch0.len = 32; + ch1.bytes = (const char*) data; + ch1.len = datalen; + smartlist_add(chunks, &ch0); + smartlist_add(chunks, &ch1); - r = write_bytes_to_file(fname, contents, sizeof(contents), 1); + r = write_chunks_to_file(fname, chunks, 1, 0); - memwipe(contents, 0, sizeof(contents)); + end: + smartlist_free(chunks); return r; } -int -curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out, - char **tag_out, - const char *fname) +/** DOCDOC */ +ssize_t +crypto_read_tagged_contents_from_file(const char *fname, + const char *typestring, + char **tag_out, + uint8_t *data_out, + ssize_t data_out_len) { char prefix[33]; - char *content; + char *content = NULL; struct stat st; - int r = -1; + ssize_t r = -1; *tag_out = NULL; - st.st_size = 0; content = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st); if (! content) goto end; - if (st.st_size != 32 + CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN) + if (st.st_size < 32 || st.st_size > 32 + data_out_len) goto end; memcpy(prefix, content, 32); - prefix[32] = '\0'; - if (strcmpstart(prefix, "== c25519v1: ") || - strcmpend(prefix, " ==")) + prefix[32] = 0; + /* Check type, extract tag. */ + if (strcmpstart(prefix, "== ") || strcmpend(prefix, " ==") || + ! tor_mem_is_zero(prefix+strlen(prefix), 32-strlen(prefix))) goto end; - *tag_out = tor_strndup(prefix+strlen("== c25519v1: "), - strlen(prefix) - strlen("== c25519v1: ==")); + if (strcmpstart(prefix+3, typestring) || + 3+strlen(typestring) >= 32 || + strcmpstart(prefix+3+strlen(typestring), ": ")) + goto end; + + *tag_out = tor_strndup(prefix+5+strlen(typestring), + strlen(prefix)-8-strlen(typestring)); + + memcpy(data_out, content+32, st.st_size-32); + r = st.st_size - 32; + + end: + if (content) + memwipe(content, 0, st.st_size); + tor_free(content); + return r; +} + +/** DOCDOC */ +int +curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair, + const char *fname, + const char *tag) +{ + uint8_t contents[CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN]; + int r; - memcpy(keypair_out->seckey.secret_key, content+32, CURVE25519_SECKEY_LEN); + memcpy(contents, keypair->seckey.secret_key, CURVE25519_SECKEY_LEN); + memcpy(contents+CURVE25519_SECKEY_LEN, + keypair->pubkey.public_key, CURVE25519_PUBKEY_LEN); + + r = crypto_write_tagged_contents_to_file(fname, + "c25519v1", + tag, + contents, + sizeof(contents)); + + memwipe(contents, 0, sizeof(contents)); + return r; +} + +/** DOCDOC */ +int +curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out, + char **tag_out, + const char *fname) +{ + uint8_t content[CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN]; + ssize_t len; + int r = -1; + + len = crypto_read_tagged_contents_from_file(fname, "c25519v1", tag_out, + content, sizeof(content)); + if (len != sizeof(content)) + goto end; + + memcpy(keypair_out->seckey.secret_key, content, CURVE25519_SECKEY_LEN); curve25519_public_key_generate(&keypair_out->pubkey, &keypair_out->seckey); if (tor_memneq(keypair_out->pubkey.public_key, - content + 32 + CURVE25519_SECKEY_LEN, + content + CURVE25519_SECKEY_LEN, CURVE25519_PUBKEY_LEN)) goto end; r = 0; end: - if (content) { - memwipe(content, 0, (size_t) st.st_size); - tor_free(content); - } + memwipe(content, 0, sizeof(content)); if (r != 0) { memset(keypair_out, 0, sizeof(*keypair_out)); tor_free(*tag_out); diff --git a/src/common/crypto_curve25519.h b/src/common/crypto_curve25519.h index fece2fe..404f99c 100644 --- a/src/common/crypto_curve25519.h +++ b/src/common/crypto_curve25519.h @@ -72,5 +72,17 @@ int curve25519_public_from_base64(curve25519_public_key_t *pkey, int curve25519_public_to_base64(char *output, const curve25519_public_key_t *pkey); +int crypto_write_tagged_contents_to_file(const char *fname, + const char *typestring, + const char *tag, + const uint8_t *data, + size_t datalen); + +ssize_t crypto_read_tagged_contents_from_file(const char *fname, + const char *typestring, + char **tag_out, + uint8_t *data_out, + ssize_t data_out_len); + #endif diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index 9dedac2..b465b69 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -161,3 +161,63 @@ ed25519_checksig_batch(int *okay_out, return res; } +/** DOCDOC */ +int +ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, + const char *filename, + const char *tag) +{ + return crypto_write_tagged_contents_to_file(filename, + "ed25519v1-secret", + tag, + seckey->seckey, + sizeof(seckey->seckey)); +} + +/** DOCDOC */ +int +ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, + char **tag_out, + const char *filename) +{ + ssize_t len; + + len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-secret", + tag_out, seckey_out->seckey, + sizeof(seckey_out->seckey)); + if (len != sizeof(seckey_out->seckey)) + return -1; + + return 0; +} + +/** DOCDOC */ +int +ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, + const char *filename, + const char *tag) +{ + return crypto_write_tagged_contents_to_file(filename, + "ed25519v1-public", + tag, + pubkey->pubkey, + sizeof(pubkey->pubkey)); +} + +/** DOCDOC */ +int +ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, + char **tag_out, + const char *filename) +{ + ssize_t len; + + len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-public", + tag_out, pubkey_out->pubkey, + sizeof(pubkey_out->pubkey)); + if (len != sizeof(pubkey_out->pubkey)) + return -1; + + return 0; +} + diff --git a/src/common/crypto_ed25519.h b/src/common/crypto_ed25519.h index 35f0125..f37dd5b 100644 --- a/src/common/crypto_ed25519.h +++ b/src/common/crypto_ed25519.h @@ -76,8 +76,21 @@ int ed25519_public_from_base64(ed25519_public_key_t *pkey, int ed25519_public_to_base64(char *output, const ed25519_public_key_t *pkey); -/* XXXX write secret keys to disk, load secret keys from disk, read encrypted, - * write encrypted. */ +/* XXXX read encrypted, write encrypted. */ + +int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, + const char *filename, + const char *tag); +int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, + char **tag_out, + const char *filename); +int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, + const char *filename, + const char *tag); +int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, + char **tag_out, + const char *filename); + #endif _______________________________________________ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits