diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c
index 8f7bdf86ef..2793597028 100644
--- a/src/feature/hs/hs_descriptor.c
+++ b/src/feature/hs/hs_descriptor.c
@@ -403,9 +403,7 @@ encode_enc_key(const hs_desc_intro_point_t *ip)
tor_assert(ip);
/* Base64 encode the encryption key for the "enc-key" field. */
- if (curve25519_public_to_base64(key_b64, &ip->enc_key) < 0) {
- goto done;
- }
+ curve25519_public_to_base64(key_b64, &ip->enc_key);
if (tor_cert_encode_ed22519(ip->enc_key_cert, &encoded_cert) < 0) {
goto done;
}
@@ -421,7 +419,7 @@ encode_enc_key(const hs_desc_intro_point_t *ip)
}
/* Encode an introduction point onion key. Return a newly allocated string
- * with it. On failure, return NULL. */
+ * with it. Can not fail. */
static char *
encode_onion_key(const hs_desc_intro_point_t *ip)
{
@@ -431,12 +429,9 @@ encode_onion_key(const hs_desc_intro_point_t *ip)
tor_assert(ip);
/* Base64 encode the encryption key for the "onion-key" field. */
- if (curve25519_public_to_base64(key_b64, &ip->onion_key) < 0) {
- goto done;
- }
+ curve25519_public_to_base64(key_b64, &ip->onion_key);
tor_asprintf(&encoded, "%s ntor %s", str_ip_onion_key, key_b64);
- done:
return encoded;
}
@@ -797,8 +792,8 @@ get_inner_encrypted_layer_plaintext(const hs_descriptor_t *desc)
/* Create the middle layer of the descriptor, which includes the client auth
* data and the encrypted inner layer (provided as a base64 string at
* layer2_b64_ciphertext). Return a newly-allocated string with the
- * layer plaintext, or NULL if an error occurred. It's the responsibility of
- * the caller to free the returned string. */
+ * layer plaintext. It's the responsibility of the caller to free the returned
+ * string. Can not fail. */
static char *
get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc,
const char *layer2_b64_ciphertext)
@@ -817,10 +812,7 @@ get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc,
tor_assert(!tor_mem_is_zero((char *) ephemeral_pubkey->public_key,
CURVE25519_PUBKEY_LEN));
- if (curve25519_public_to_base64(ephemeral_key_base64,
- ephemeral_pubkey) < 0) {
- goto done;
- }
+ curve25519_public_to_base64(ephemeral_key_base64, ephemeral_pubkey);
smartlist_add_asprintf(lines, "%s %s\n",
str_desc_auth_key, ephemeral_key_base64);
@@ -845,7 +837,6 @@ get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc,
layer1_str = smartlist_join_strings(lines, "", 0, NULL);
- done:
/* We need to memwipe all lines because it contains the ephemeral key */
SMARTLIST_FOREACH(lines, char *, a, memwipe(a, 0, strlen(a)));
SMARTLIST_FOREACH(lines, char *, a, tor_free(a));
diff --git a/src/lib/crypt_ops/crypto_curve25519.h b/src/lib/crypt_ops/crypto_curve25519.h
index 061a7a3505..cd23169cd5 100644
--- a/src/lib/crypt_ops/crypto_curve25519.h
+++ b/src/lib/crypt_ops/crypto_curve25519.h
@@ -76,8 +76,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);
-int curve25519_public_to_base64(char *output,
- const curve25519_public_key_t *pkey);
+void curve25519_public_to_base64(char *output,
+ const curve25519_public_key_t *pkey);
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 217ac8959c..800f4ad5bc 100644
--- a/src/lib/crypt_ops/crypto_format.c
+++ b/src/lib/crypt_ops/crypto_format.c
@@ -131,20 +131,27 @@ crypto_read_tagged_contents_from_file(const char *fname,
return r;
}
-/** Encode pkey as a base64-encoded string, without trailing "="
+/** Encode pkey as a base64-encoded string, including trailing "="
* characters, in the buffer output, which must have at least
- * CURVE25519_BASE64_PADDED_LEN+1 bytes available. Return 0 on success, -1 on
- * failure. */
-int
+ * CURVE25519_BASE64_PADDED_LEN+1 bytes available.
+ * Can not fail.
+ *
+ * Careful! CURVE25519_BASE64_PADDED_LEN is one byte longer than
+ * ED25519_BASE64_LEN.
+ */
+void
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, 0);
- buf[CURVE25519_BASE64_PADDED_LEN] = '\0';
+ int n = base64_encode(buf, sizeof(buf),
+ (const char*)pkey->public_key,
+ CURVE25519_PUBKEY_LEN, 0);
+ /* 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);
- return 0;
}
/** Try to decode a base64-encoded curve25519 public key from input
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index fb8046fd22..5f53ba688e 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -2075,7 +2075,7 @@ test_crypto_curve25519_encode(void *arg)
curve25519_secret_key_generate(&seckey, 0);
curve25519_public_key_generate(&key1, &seckey);
- tt_int_op(0, OP_EQ, curve25519_public_to_base64(buf, &key1));
+ curve25519_public_to_base64(buf, &key1);
tt_int_op(CURVE25519_BASE64_PADDED_LEN, OP_EQ, strlen(buf));
tt_int_op(0, OP_EQ, curve25519_public_from_base64(&key2, buf));