[tor-commits] [tor/master] Support for writing ed25519 public/private components to disk.

nickm at torproject.org nickm at torproject.org
Thu Sep 25 19:12:41 UTC 2014


commit ed48b0fe56df2f719cd7cd274c664f7037f98b75
Author: Nick Mathewson <nickm at 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
 





More information about the tor-commits mailing list