Browse Source

Move curve25519 keypair type to src/common; give it functions

This patch moves curve25519_keypair_t from src/or/onion_ntor.h to
src/common/crypto_curve25519.h, and adds new functions to generate,
load, and store keypairs.
Nick Mathewson 11 years ago
parent
commit
6c883bc638
3 changed files with 100 additions and 8 deletions
  1. 82 0
      src/common/crypto_curve25519.c
  2. 18 0
      src/common/crypto_curve25519.h
  3. 0 8
      src/or/onion_ntor.h

+ 82 - 0
src/common/crypto_curve25519.c

@@ -5,9 +5,13 @@
 
 #define CRYPTO_CURVE25519_PRIVATE
 #include "orconfig.h"
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
 #include "crypto.h"
 #include "crypto_curve25519.h"
 #include "util.h"
+#include "torlog.h"
 
 /* ==============================
    Part 1: wrap a suitable curve25519 implementation as curve25519_impl
@@ -85,6 +89,84 @@ curve25519_public_key_generate(curve25519_public_key_t *key_out,
   curve25519_impl(key_out->public_key, seckey->secret_key, basepoint);
 }
 
+void
+curve25519_keypair_generate(curve25519_keypair_t *keypair_out,
+                            int extra_strong)
+{
+  curve25519_secret_key_generate(&keypair_out->seckey, extra_strong);
+  curve25519_public_key_generate(&keypair_out->pubkey, &keypair_out->seckey);
+}
+
+int
+curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair,
+                                 const char *fname,
+                                 const char *tag)
+{
+  char contents[32 + CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
+  int r;
+
+  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);
+
+  r = write_bytes_to_file(fname, contents, sizeof(contents), 1);
+
+  memwipe(contents, 0, sizeof(contents));
+  return r;
+}
+
+int
+curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
+                                  char **tag_out,
+                                  const char *fname)
+{
+  char prefix[33];
+  char *content;
+  struct stat st;
+  int 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)
+    goto end;
+
+  memcpy(prefix, content, 32);
+  prefix[32] = '\0';
+  if (strcmpstart(prefix, "== c25519v1: ") ||
+      strcmpend(prefix, " =="))
+    goto end;
+
+  *tag_out = tor_strndup(prefix+strlen("== c25519v1: "),
+                         strlen(prefix) - strlen("== c25519v1:  =="));
+
+  memcpy(keypair_out->seckey.secret_key, content+32, 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,
+                 CURVE25519_PUBKEY_LEN))
+    goto end;
+
+  r = 0;
+
+ end:
+  if (content) {
+    memwipe(content, 0, st.st_size);
+    tor_free(content);
+  }
+  if (r != 0) {
+    memset(keypair_out, 0, sizeof(*keypair_out));
+    tor_free(*tag_out);
+  }
+  return r;
+}
+
 /** Perform the curve25519 ECDH handshake with <b>skey</b> and <b>pkey</b>,
  * writing CURVE25519_OUTPUT_LEN bytes of output into <b>output</b>. */
 void

+ 18 - 0
src/common/crypto_curve25519.h

@@ -23,21 +23,39 @@ typedef struct curve25519_secret_key_t {
   uint8_t secret_key[CURVE25519_SECKEY_LEN];
 } curve25519_secret_key_t;
 
+/** A paired public and private key for curve25519. **/
+typedef struct curve25519_keypair_t {
+  curve25519_public_key_t pubkey;
+  curve25519_secret_key_t seckey;
+} curve25519_keypair_t;
+
+#ifdef CURVE25519_ENABLED
 int curve25519_public_key_is_ok(const curve25519_public_key_t *);
 
 void curve25519_secret_key_generate(curve25519_secret_key_t *key_out,
                                     int extra_strong);
 void curve25519_public_key_generate(curve25519_public_key_t *key_out,
                                     const curve25519_secret_key_t *seckey);
+void curve25519_keypair_generate(curve25519_keypair_t *keypair_out,
+                                 int extra_strong);
 
 void curve25519_handshake(uint8_t *output,
                           const curve25519_secret_key_t *,
                           const curve25519_public_key_t *);
 
+int curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair,
+                                     const char *fname,
+                                     const char *tag);
+
+int curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
+                                      char **tag_out,
+                                      const char *fname);
+
 #ifdef CRYPTO_CURVE25519_PRIVATE
 int curve25519_impl(uint8_t *output, const uint8_t *secret,
                     const uint8_t *basepoint);
 #endif
+#endif
 
 #endif
 

+ 0 - 8
src/or/onion_ntor.h

@@ -17,14 +17,6 @@ typedef struct ntor_handshake_state_t ntor_handshake_state_t;
 /** Length of an ntor reply, as sent from server to client. */
 #define NTOR_REPLY_LEN 64
 
-/** A paired public and private key for curve25519.
- * XXXX024 move this structure somewhere smarter.
- **/
-typedef struct curve25519_keypair_t {
-  curve25519_public_key_t pubkey;
-  curve25519_secret_key_t seckey;
-} curve25519_keypair_t;
-
 void ntor_handshake_state_free(ntor_handshake_state_t *state);
 
 int onion_skin_ntor_create(const uint8_t *router_id,