Make curve25519_public_to_base64 output padding optional #7869

This commit is contained in:
Daniel Pinto 2020-06-06 10:44:28 +01:00
parent 1d32c3114f
commit 27315de590
5 changed files with 37 additions and 22 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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. */

View File

@ -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. */