commit 78e2bc4000a9014c1762f828e15e762c359aa20e Author: David Goulet dgoulet@torproject.org Date: Wed Jul 19 13:42:35 2017 -0400
prop224: Add the introduction point onion key to descriptor
A prop224 descriptor was missing the onion key for an introduction point which is needed to extend to it by the client.
Closes #22979
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/hs_descriptor.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/or/hs_descriptor.h | 4 ++++ src/or/parsecommon.h | 1 + 3 files changed, 54 insertions(+)
diff --git a/src/or/hs_descriptor.c b/src/or/hs_descriptor.c index 2393eac25..91d0ef544 100644 --- a/src/or/hs_descriptor.c +++ b/src/or/hs_descriptor.c @@ -78,6 +78,7 @@ #define str_intro_auth_required "intro-auth-required" #define str_single_onion "single-onion-service" #define str_intro_point "introduction-point" +#define str_ip_onion_key "onion-key" #define str_ip_auth_key "auth-key" #define str_ip_enc_key "enc-key" #define str_ip_enc_key_cert "enc-key-cert" @@ -136,6 +137,7 @@ static token_rule_t hs_desc_encrypted_v3_token_table[] = { /* Descriptor ruleset for the introduction points section. */ static token_rule_t hs_desc_intro_point_v3_token_table[] = { T1_START(str_intro_point, R3_INTRODUCTION_POINT, EQ(1), NO_OBJ), + T1N(str_ip_onion_key, R3_INTRO_ONION_KEY, GE(2), OBJ_OK), T1(str_ip_auth_key, R3_INTRO_AUTH_KEY, NO_ARGS, NEED_OBJ), T1(str_ip_enc_key, R3_INTRO_ENC_KEY, GE(2), OBJ_OK), T1(str_ip_enc_key_cert, R3_INTRO_ENC_KEY_CERT, ARGS, OBJ_OK), @@ -479,6 +481,26 @@ encode_enc_key(const hs_desc_intro_point_t *ip) return encoded; }
+/* Encode an introduction point onion key. Return a newly allocated string + * with it. On failure, return NULL. */ +static char * +encode_onion_key(const hs_desc_intro_point_t *ip) +{ + char *encoded = NULL; + char key_b64[CURVE25519_BASE64_PADDED_LEN + 1]; + + 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; + } + tor_asprintf(&encoded, "%s ntor %s", str_ip_onion_key, key_b64); + + done: + return encoded; +} + /* Encode an introduction point object and return a newly allocated string * with it. On failure, return NULL. */ static char * @@ -498,6 +520,16 @@ encode_intro_point(const ed25519_public_key_t *sig_key, tor_free(ls_str); }
+ /* Onion key encoding. */ + { + char *encoded_onion_key = encode_onion_key(ip); + if (encoded_onion_key == NULL) { + goto err; + } + smartlist_add_asprintf(lines, "%s", encoded_onion_key); + tor_free(encoded_onion_key); + } + /* Authentication key encoding. */ { char *encoded_cert; @@ -1662,6 +1694,23 @@ decode_introduction_point(const hs_descriptor_t *desc, const char *start) goto err; }
+ /* "onion-key" SP ntor SP key NL */ + tok = find_by_keyword(tokens, R3_INTRO_ONION_KEY); + if (!strcmp(tok->args[0], "ntor")) { + /* This field is using GE(2) so for possible forward compatibility, we + * accept more fields but must be at least 2. */ + tor_assert(tok->n_args >= 2); + + if (curve25519_public_from_base64(&ip->onion_key, tok->args[1]) < 0) { + log_warn(LD_REND, "Introduction point ntor onion-key is invalid"); + goto err; + } + } else { + /* Unknown key type so we can't use that introduction point. */ + log_warn(LD_REND, "Introduction point onion key is unrecognized."); + goto err; + } + /* "auth-key" NL certificate NL */ tok = find_by_keyword(tokens, R3_INTRO_AUTH_KEY); tor_assert(tok->object_body); diff --git a/src/or/hs_descriptor.h b/src/or/hs_descriptor.h index 58c408979..fdf0b90b5 100644 --- a/src/or/hs_descriptor.h +++ b/src/or/hs_descriptor.h @@ -80,6 +80,10 @@ typedef struct hs_desc_intro_point_t { * contains hs_desc_link_specifier_t object. It MUST have at least one. */ smartlist_t *link_specifiers;
+ /* Onion key of the introduction point used to extend to it for the ntor + * handshake. */ + curve25519_public_key_t onion_key; + /* Authentication key used to establish the introduction point circuit and * cross-certifies the blinded public key for the replica thus signed by * the blinded key and in turn signs it. */ diff --git a/src/or/parsecommon.h b/src/or/parsecommon.h index b9f161345..a76b104fd 100644 --- a/src/or/parsecommon.h +++ b/src/or/parsecommon.h @@ -160,6 +160,7 @@ typedef enum { R3_INTRO_AUTH_REQUIRED, R3_SINGLE_ONION_SERVICE, R3_INTRODUCTION_POINT, + R3_INTRO_ONION_KEY, R3_INTRO_AUTH_KEY, R3_INTRO_ENC_KEY, R3_INTRO_ENC_KEY_CERT,