[tor-commits] [tor/master] Make the = at the end of ntor-onion-key optional.

nickm at torproject.org nickm at torproject.org
Mon Jan 14 17:32:33 UTC 2013


commit 31d888c834b135d8f36ceec181f3d1ea7af62267
Author: Nick Mathewson <nickm at torproject.org>
Date:   Sat Jan 5 22:53:32 2013 -0500

    Make the = at the end of ntor-onion-key optional.
    
    Makes bug 7869 more easily fixable if we ever choose to do so.
---
 src/common/crypto_curve25519.c |   30 ++++++++++++++++++++++++++++++
 src/common/crypto_curve25519.h |    7 +++++++
 src/or/routerparse.c           |   25 ++++++++-----------------
 src/test/test_crypto.c         |   37 +++++++++++++++++++++++++++++++++++++
 4 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c
index a4ab65c..aead4f8 100644
--- a/src/common/crypto_curve25519.c
+++ b/src/common/crypto_curve25519.c
@@ -178,3 +178,33 @@ curve25519_handshake(uint8_t *output,
   curve25519_impl(output, skey->secret_key, pkey->public_key);
 }
 
+int
+curve25519_public_to_base64(char *output,
+                            const curve25519_public_key_t *pkey)
+{
+  char buf[128];
+  base64_encode(buf, sizeof(buf),
+                (const char*)pkey->public_key, CURVE25519_PUBKEY_LEN);
+  buf[CURVE25519_BASE64_PADDED_LEN] = '\0';
+  memcpy(output, buf, CURVE25519_BASE64_PADDED_LEN+1);
+  return 0;
+}
+
+int
+curve25519_public_from_base64(curve25519_public_key_t *pkey,
+                              const char *input)
+{
+  size_t len = strlen(input);
+  if (len == CURVE25519_BASE64_PADDED_LEN - 1) {
+    /* not padded */
+    return digest256_from_base64((char*)pkey->public_key, input);
+  } else if (len == CURVE25519_BASE64_PADDED_LEN) {
+    char buf[128];
+    if (base64_decode(buf, sizeof(buf), input, len) != CURVE25519_PUBKEY_LEN)
+      return -1;
+    memcpy(pkey->public_key, buf, CURVE25519_PUBKEY_LEN);
+    return 0;
+  } else {
+    return -1;
+  }
+}
diff --git a/src/common/crypto_curve25519.h b/src/common/crypto_curve25519.h
index e768b8c..9c732b9 100644
--- a/src/common/crypto_curve25519.h
+++ b/src/common/crypto_curve25519.h
@@ -51,6 +51,13 @@ int curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
                                       char **tag_out,
                                       const char *fname);
 
+#define CURVE25519_BASE64_PADDED_LEN 44
+
+int curve25519_public_from_base64(curve25519_public_key_t *pkey,
+                                  const char *input);
+int curve25519_public_to_base64(char *output,
+                                const curve25519_public_key_t *pkey);
+
 #ifdef CRYPTO_CURVE25519_PRIVATE
 int curve25519_impl(uint8_t *output, const uint8_t *secret,
                     const uint8_t *basepoint);
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index c873784..dca4176 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1288,18 +1288,14 @@ router_parse_entry_from_string(const char *s, const char *end,
   tok->key = NULL; /* Prevent free */
 
   if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) {
-    uint8_t k[CURVE25519_PUBKEY_LEN+32];
-    int r;
+    curve25519_public_key_t k;
     tor_assert(tok->n_args >= 1);
-    r = base64_decode((char*)k, sizeof(k), tok->args[0], strlen(tok->args[0]));
-    if (r != CURVE25519_PUBKEY_LEN) {
-      log_warn(LD_DIR, "Bogus onion-key-ntor in routerinfo");
+    if (curve25519_public_from_base64(&k, tok->args[0]) < 0) {
+      log_warn(LD_DIR, "Bogus ntor-onion-key in routerinfo");
       goto err;
     }
     router->onion_curve25519_pkey =
-      tor_malloc(sizeof(curve25519_public_key_t));
-    memcpy(router->onion_curve25519_pkey->public_key,
-           k, CURVE25519_PUBKEY_LEN);
+      tor_memdup(&k, sizeof(curve25519_public_key_t));
   }
 
   tok = find_by_keyword(tokens, K_SIGNING_KEY);
@@ -4264,19 +4260,14 @@ microdescs_parse_from_string(const char *s, const char *eos,
     tok->key = NULL;
 
     if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) {
-      uint8_t k[CURVE25519_PUBKEY_LEN+32];
-      int r;
+      curve25519_public_key_t k;
       tor_assert(tok->n_args >= 1);
-      r = base64_decode((char*)k, sizeof(k),
-                        tok->args[0], strlen(tok->args[0]));
-      if (r != CURVE25519_PUBKEY_LEN) {
-        log_warn(LD_DIR, "Bogus onion-key-ntor in microdesc");
+      if (curve25519_public_from_base64(&k, tok->args[0]) < 0) {
+        log_warn(LD_DIR, "Bogus ntor-onion-key in microdesc");
         goto next;
       }
       md->onion_curve25519_pkey =
-        tor_malloc(sizeof(curve25519_public_key_t));
-      memcpy(md->onion_curve25519_pkey->public_key,
-             k, CURVE25519_PUBKEY_LEN);
+        tor_memdup(&k, sizeof(curve25519_public_key_t));
     }
 
     {
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 67d2b83..0c846b6 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -1008,6 +1008,42 @@ test_crypto_curve25519_wrappers(void *arg)
 }
 
 static void
+test_crypto_curve25519_encode(void *arg)
+{
+  curve25519_secret_key_t seckey;
+  curve25519_public_key_t key1, key2, key3;
+  char buf[64];
+
+  (void)arg;
+
+  curve25519_secret_key_generate(&seckey, 0);
+  curve25519_public_key_generate(&key1, &seckey);
+  tt_int_op(0, ==, curve25519_public_to_base64(buf, &key1));
+  tt_int_op(CURVE25519_BASE64_PADDED_LEN, ==, strlen(buf));
+
+  tt_int_op(0, ==, curve25519_public_from_base64(&key2, buf));
+  test_memeq(key1.public_key, key2.public_key, CURVE25519_PUBKEY_LEN);
+
+  buf[CURVE25519_BASE64_PADDED_LEN - 1] = '\0';
+  tt_int_op(CURVE25519_BASE64_PADDED_LEN-1, ==, strlen(buf));
+  tt_int_op(0, ==, curve25519_public_from_base64(&key3, buf));
+  test_memeq(key1.public_key, key3.public_key, CURVE25519_PUBKEY_LEN);
+
+  /* Now try bogus parses. */
+  strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$=", sizeof(buf));
+  tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));
+
+  strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", sizeof(buf));
+  tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));
+
+  strlcpy(buf, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", sizeof(buf));
+  tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));
+
+ done:
+  ;
+}
+
+static void
 test_crypto_curve25519_persist(void *arg)
 {
   curve25519_keypair_t keypair, keypair2;
@@ -1100,6 +1136,7 @@ struct testcase_t crypto_tests[] = {
 #ifdef CURVE25519_ENABLED
   { "curve25519_impl", test_crypto_curve25519_impl, 0, NULL, NULL },
   { "curve25519_wrappers", test_crypto_curve25519_wrappers, 0, NULL, NULL },
+  { "curve25519_encode", test_crypto_curve25519_encode, 0, NULL, NULL },
   { "curve25519_persist", test_crypto_curve25519_persist, 0, NULL, NULL },
 #endif
   END_OF_TESTCASES





More information about the tor-commits mailing list