[tor-commits] [tor/master] Make curve25519_public_to_base64 output padding optional #7869

nickm at torproject.org nickm at torproject.org
Thu Jul 23 12:26:55 UTC 2020


commit 27315de590da24fe55353332c29a3a4454ee7da2
Author: Daniel Pinto <danielpinto52 at gmail.com>
Date:   Sat Jun 6 10:44:28 2020 +0100

    Make curve25519_public_to_base64 output padding optional #7869
---
 src/feature/hs/hs_descriptor.c        |  7 ++++---
 src/lib/crypt_ops/crypto_curve25519.h |  4 +++-
 src/lib/crypt_ops/crypto_format.c     | 35 ++++++++++++++++++++++-------------
 src/lib/defs/x25519_sizes.h           |  3 +++
 src/test/test_crypto.c                | 10 +++++-----
 5 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c
index 50a46fb40f..30a36030d1 100644
--- a/src/feature/hs/hs_descriptor.c
+++ b/src/feature/hs/hs_descriptor.c
@@ -55,6 +55,7 @@
 /* For unit tests.*/
 #define HS_DESCRIPTOR_PRIVATE
 
+#include <stdbool.h>
 #include "core/or/or.h"
 #include "app/config/config.h"
 #include "trunnel/ed25519_cert.h" /* Trunnel interface. */
@@ -404,7 +405,7 @@ encode_enc_key(const hs_desc_intro_point_t *ip)
   tor_assert(ip);
 
   /* Base64 encode the encryption key for the "enc-key" field. */
-  curve25519_public_to_base64(key_b64, &ip->enc_key);
+  curve25519_public_to_base64(key_b64, &ip->enc_key, true);
   if (tor_cert_encode_ed22519(ip->enc_key_cert, &encoded_cert) < 0) {
     goto done;
   }
@@ -430,7 +431,7 @@ encode_onion_key(const hs_desc_intro_point_t *ip)
   tor_assert(ip);
 
   /* Base64 encode the encryption key for the "onion-key" field. */
-  curve25519_public_to_base64(key_b64, &ip->onion_key);
+  curve25519_public_to_base64(key_b64, &ip->onion_key, true);
   tor_asprintf(&encoded, "%s ntor %s", str_ip_onion_key, key_b64);
 
   return encoded;
@@ -813,7 +814,7 @@ get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc,
     tor_assert(!fast_mem_is_zero((char *) ephemeral_pubkey->public_key,
                                 CURVE25519_PUBKEY_LEN));
 
-    curve25519_public_to_base64(ephemeral_key_base64, ephemeral_pubkey);
+    curve25519_public_to_base64(ephemeral_key_base64, ephemeral_pubkey, true);
     smartlist_add_asprintf(lines, "%s %s\n",
                            str_desc_auth_key, ephemeral_key_base64);
 
diff --git a/src/lib/crypt_ops/crypto_curve25519.h b/src/lib/crypt_ops/crypto_curve25519.h
index 154a0b94bc..f1e5d1265d 100644
--- a/src/lib/crypt_ops/crypto_curve25519.h
+++ b/src/lib/crypt_ops/crypto_curve25519.h
@@ -9,6 +9,7 @@
 #ifndef TOR_CRYPTO_CURVE25519_H
 #define TOR_CRYPTO_CURVE25519_H
 
+#include <stdbool.h>
 #include "lib/testsupport/testsupport.h"
 #include "lib/cc/torint.h"
 #include "lib/crypt_ops/crypto_digest.h"
@@ -77,7 +78,8 @@ STATIC int curve25519_basepoint_impl(uint8_t *output, const uint8_t *secret);
 int curve25519_public_from_base64(curve25519_public_key_t *pkey,
                                   const char *input);
 void curve25519_public_to_base64(char *output,
-                                 const curve25519_public_key_t *pkey);
+                                 const curve25519_public_key_t *pkey,
+                                 bool pad);
 
 void curve25519_set_impl_params(int use_ed);
 void curve25519_init(void);
diff --git a/src/lib/crypt_ops/crypto_format.c b/src/lib/crypt_ops/crypto_format.c
index 92b8b9372e..4483b7d2f5 100644
--- a/src/lib/crypt_ops/crypto_format.c
+++ b/src/lib/crypt_ops/crypto_format.c
@@ -131,9 +131,10 @@ crypto_read_tagged_contents_from_file(const char *fname,
   return r;
 }
 
-/** Encode <b>pkey</b> as a base64-encoded string, including trailing "="
- * characters, in the buffer <b>output</b>, which must have at least
- * CURVE25519_BASE64_PADDED_LEN+1 bytes available.
+/** Encode <b>pkey</b> as a base64-encoded string in the buffer <b>output</b>.
+ * If <b>pad</b> is false do not include trailing "=" characters, otherwise
+ * include them. <b>output</b> must have at least
+ * CURVE25519_BASE64_PADDED_LEN+1 bytes available, even if <b>pad</b> is false.
  * Can not fail.
  *
  * Careful! CURVE25519_BASE64_PADDED_LEN is one byte longer than
@@ -141,17 +142,25 @@ crypto_read_tagged_contents_from_file(const char *fname,
  */
 void
 curve25519_public_to_base64(char *output,
-                            const curve25519_public_key_t *pkey)
+                            const curve25519_public_key_t *pkey, bool pad)
 {
-  char buf[128];
-  int n = base64_encode(buf, sizeof(buf),
-                        (const char*)pkey->public_key,
-                        CURVE25519_PUBKEY_LEN, 0);
+  int n, expected_len;
+  if (pad) {
+    n = base64_encode(output, CURVE25519_BASE64_PADDED_LEN+1,
+                      (const char*)pkey->public_key,
+                      CURVE25519_PUBKEY_LEN, 0);
+    expected_len = CURVE25519_BASE64_PADDED_LEN;
+  } else {
+    n = base64_encode_nopad(output, CURVE25519_BASE64_PADDED_LEN+1,
+                            (const uint8_t*)pkey->public_key,
+                            CURVE25519_PUBKEY_LEN);
+    expected_len = CURVE25519_BASE64_LEN;
+  }
+
   /* These asserts should always succeed, unless there is a bug in
    * base64_encode(). */
-  tor_assert(n == CURVE25519_BASE64_PADDED_LEN);
-  tor_assert(buf[CURVE25519_BASE64_PADDED_LEN] == '\0');
-  memcpy(output, buf, CURVE25519_BASE64_PADDED_LEN+1);
+  tor_assert(n == expected_len);
+  tor_assert(output[expected_len] == '\0');
 }
 
 /** Try to decode a base64-encoded curve25519 public key from <b>input</b>
@@ -162,11 +171,11 @@ curve25519_public_from_base64(curve25519_public_key_t *pkey,
                               const char *input)
 {
   size_t len = strlen(input);
-  if (len == CURVE25519_BASE64_PADDED_LEN - 1) {
+  if (len == CURVE25519_BASE64_LEN) {
     /* not padded */
     return digest256_from_base64((char*)pkey->public_key, input);
   } else if (len == CURVE25519_BASE64_PADDED_LEN) {
-    char buf[128];
+    char buf[CURVE25519_BASE64_PADDED_LEN+1];
     if (base64_decode(buf, sizeof(buf), input, len) != CURVE25519_PUBKEY_LEN)
       return -1;
     memcpy(pkey->public_key, buf, CURVE25519_PUBKEY_LEN);
diff --git a/src/lib/defs/x25519_sizes.h b/src/lib/defs/x25519_sizes.h
index acb08c5e6a..e650f5a350 100644
--- a/src/lib/defs/x25519_sizes.h
+++ b/src/lib/defs/x25519_sizes.h
@@ -36,6 +36,9 @@
 /** Length of a Curve25519 key when encoded in base 64, with padding. */
 #define CURVE25519_BASE64_PADDED_LEN 44
 
+/** Length of a Curve25519 key when encoded in base 64, without padding. */
+#define CURVE25519_BASE64_LEN 43
+
 /** Length of a Ed25519 key when encoded in base 64, without padding. */
 #define ED25519_BASE64_LEN 43
 /** Length of a Ed25519 signature when encoded in base 64, without padding. */
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 0d75a212e9..ffd6a25bd5 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -2107,21 +2107,21 @@ test_crypto_curve25519_encode(void *arg)
 {
   curve25519_secret_key_t seckey;
   curve25519_public_key_t key1, key2, key3;
-  char buf[64];
+  char buf[64], buf_nopad[64];
 
   (void)arg;
 
   curve25519_secret_key_generate(&seckey, 0);
   curve25519_public_key_generate(&key1, &seckey);
-  curve25519_public_to_base64(buf, &key1);
+  curve25519_public_to_base64(buf, &key1, true);
   tt_int_op(CURVE25519_BASE64_PADDED_LEN, OP_EQ, strlen(buf));
 
   tt_int_op(0, OP_EQ, curve25519_public_from_base64(&key2, buf));
   tt_mem_op(key1.public_key,OP_EQ, key2.public_key, CURVE25519_PUBKEY_LEN);
 
-  buf[CURVE25519_BASE64_PADDED_LEN - 1] = '\0';
-  tt_int_op(CURVE25519_BASE64_PADDED_LEN-1, OP_EQ, strlen(buf));
-  tt_int_op(0, OP_EQ, curve25519_public_from_base64(&key3, buf));
+  curve25519_public_to_base64(buf_nopad, &key1, false);
+  tt_int_op(CURVE25519_BASE64_LEN, OP_EQ, strlen(buf_nopad));
+  tt_int_op(0, OP_EQ, curve25519_public_from_base64(&key3, buf_nopad));
   tt_mem_op(key1.public_key,OP_EQ, key3.public_key, CURVE25519_PUBKEY_LEN);
 
   /* Now try bogus parses. */





More information about the tor-commits mailing list