Ticket #21509: hs_descriptor.c.gcov

File hs_descriptor.c.gcov, 126.6 KB (added by nickm, 3 years ago)
Line 
1        -:    0:Source:src/or/hs_descriptor.c
2        -:    0:Graph:src/or/src_or_libtor_testing_a-hs_descriptor.gcno
3        -:    0:Data:src/or/src_or_libtor_testing_a-hs_descriptor.gcda
4        -:    0:Runs:6681
5        -:    0:Programs:1
6        -:    1:/* Copyright (c) 2016-2017, The Tor Project, Inc. */
7        -:    2:/* See LICENSE for licensing information */
8        -:    3:
9        -:    4:/**
10        -:    5: * \file hs_descriptor.c
11        -:    6: * \brief Handle hidden service descriptor encoding/decoding.
12        -:    7: *
13        -:    8: * \details
14        -:    9: * Here is a graphical depiction of an HS descriptor and its layers:
15        -:   10: *
16        -:   11: *      +------------------------------------------------------+
17        -:   12: *      |DESCRIPTOR HEADER:                                    |
18        -:   13: *      |  hs-descriptor 3                                     |
19        -:   14: *      |  descriptor-lifetime 180                             |
20        -:   15: *      |  ...                                                 |
21        -:   16: *      |  superencrypted                                      |
22        -:   17: *      |+---------------------------------------------------+ |
23        -:   18: *      ||SUPERENCRYPTED LAYER (aka OUTER ENCRYPTED LAYER):  | |
24        -:   19: *      ||  desc-auth-type x25519                            | |
25        -:   20: *      ||  desc-auth-ephemeral-key                          | |
26        -:   21: *      ||  auth-client                                      | |
27        -:   22: *      ||  auth-client                                      | |
28        -:   23: *      ||  ...                                              | |
29        -:   24: *      ||  encrypted                                        | |
30        -:   25: *      ||+-------------------------------------------------+| |
31        -:   26: *      |||ENCRYPTED LAYER (aka INNER ENCRYPTED LAYER):     || |
32        -:   27: *      |||  create2-formats                                || |
33        -:   28: *      |||  intro-auth-required                            || |
34        -:   29: *      |||  introduction-point                             || |
35        -:   30: *      |||  introduction-point                             || |
36        -:   31: *      |||  ...                                            || |
37        -:   32: *      ||+-------------------------------------------------+| |
38        -:   33: *      |+---------------------------------------------------+ |
39        -:   34: *      +------------------------------------------------------+
40        -:   35: *
41        -:   36: * The DESCRIPTOR HEADER section is completely unencrypted and contains generic
42        -:   37: * descriptor metadata.
43        -:   38: *
44        -:   39: * The SUPERENCRYPTED LAYER section is the first layer of encryption, and it's
45        -:   40: * encrypted using the blinded public key of the hidden service to protect
46        -:   41: * against entities who don't know its onion address. The clients of the hidden
47        -:   42: * service know its onion address and blinded public key, whereas third-parties
48        -:   43: * (like HSDirs) don't know it (except if it's a public hidden service).
49        -:   44: *
50        -:   45: * The ENCRYPTED LAYER section is the second layer of encryption, and it's
51        -:   46: * encrypted using the client authorization key material (if those exist). When
52        -:   47: * client authorization is enabled, this second layer of encryption protects
53        -:   48: * the descriptor content from unauthorized entities. If client authorization
54        -:   49: * is disabled, this second layer of encryption does not provide any extra
55        -:   50: * security but is still present. The plaintext of this layer contains all the
56        -:   51: * information required to connect to the hidden service like its list of
57        -:   52: * introduction points.
58        -:   53: **/
59        -:   54:
60        -:   55:/* For unit tests.*/
61        -:   56:#define HS_DESCRIPTOR_PRIVATE
62        -:   57:
63        -:   58:#include "or.h"
64        -:   59:#include "ed25519_cert.h" /* Trunnel interface. */
65        -:   60:#include "hs_descriptor.h"
66        -:   61:#include "circuitbuild.h"
67        -:   62:#include "parsecommon.h"
68        -:   63:#include "rendcache.h"
69        -:   64:#include "hs_cache.h"
70        -:   65:#include "hs_config.h"
71        -:   66:#include "torcert.h" /* tor_cert_encode_ed22519() */
72        -:   67:
73        -:   68:/* Constant string value used for the descriptor format. */
74        -:   69:#define str_hs_desc "hs-descriptor"
75        -:   70:#define str_desc_cert "descriptor-signing-key-cert"
76        -:   71:#define str_rev_counter "revision-counter"
77        -:   72:#define str_superencrypted "superencrypted"
78        -:   73:#define str_encrypted "encrypted"
79        -:   74:#define str_signature "signature"
80        -:   75:#define str_lifetime "descriptor-lifetime"
81        -:   76:/* Constant string value for the encrypted part of the descriptor. */
82        -:   77:#define str_create2_formats "create2-formats"
83        -:   78:#define str_intro_auth_required "intro-auth-required"
84        -:   79:#define str_single_onion "single-onion-service"
85        -:   80:#define str_intro_point "introduction-point"
86        -:   81:#define str_ip_onion_key "onion-key"
87        -:   82:#define str_ip_auth_key "auth-key"
88        -:   83:#define str_ip_enc_key "enc-key"
89        -:   84:#define str_ip_enc_key_cert "enc-key-cert"
90        -:   85:#define str_ip_legacy_key "legacy-key"
91        -:   86:#define str_ip_legacy_key_cert "legacy-key-cert"
92        -:   87:#define str_intro_point_start "\n" str_intro_point " "
93        -:   88:/* Constant string value for the construction to encrypt the encrypted data
94        -:   89: * section. */
95        -:   90:#define str_enc_const_superencryption "hsdir-superencrypted-data"
96        -:   91:#define str_enc_const_encryption "hsdir-encrypted-data"
97        -:   92:/* Prefix required to compute/verify HS desc signatures */
98        -:   93:#define str_desc_sig_prefix "Tor onion service descriptor sig v3"
99        -:   94:#define str_desc_auth_type "desc-auth-type"
100        -:   95:#define str_desc_auth_key "desc-auth-ephemeral-key"
101        -:   96:#define str_desc_auth_client "auth-client"
102        -:   97:#define str_encrypted "encrypted"
103        -:   98:
104        -:   99:/* Authentication supported types. */
105        -:  100:static const struct {
106        -:  101:  hs_desc_auth_type_t type;
107        -:  102:  const char *identifier;
108        -:  103:} intro_auth_types[] = {
109        -:  104:  { HS_DESC_AUTH_ED25519, "ed25519" },
110        -:  105:  /* Indicate end of array. */
111        -:  106:  { 0, NULL }
112        -:  107:};
113        -:  108:
114        -:  109:/* Descriptor ruleset. */
115        -:  110:static token_rule_t hs_desc_v3_token_table[] = {
116        -:  111:  T1_START(str_hs_desc, R_HS_DESCRIPTOR, EQ(1), NO_OBJ),
117        -:  112:  T1(str_lifetime, R3_DESC_LIFETIME, EQ(1), NO_OBJ),
118        -:  113:  T1(str_desc_cert, R3_DESC_SIGNING_CERT, NO_ARGS, NEED_OBJ),
119        -:  114:  T1(str_rev_counter, R3_REVISION_COUNTER, EQ(1), NO_OBJ),
120        -:  115:  T1(str_superencrypted, R3_SUPERENCRYPTED, NO_ARGS, NEED_OBJ),
121        -:  116:  T1_END(str_signature, R3_SIGNATURE, EQ(1), NO_OBJ),
122        -:  117:  END_OF_TABLE
123        -:  118:};
124        -:  119:
125        -:  120:/* Descriptor ruleset for the superencrypted section. */
126        -:  121:static token_rule_t hs_desc_superencrypted_v3_token_table[] = {
127        -:  122:  T1_START(str_desc_auth_type, R3_DESC_AUTH_TYPE, GE(1), NO_OBJ),
128        -:  123:  T1(str_desc_auth_key, R3_DESC_AUTH_KEY, GE(1), NO_OBJ),
129        -:  124:  T1N(str_desc_auth_client, R3_DESC_AUTH_CLIENT, GE(3), NO_OBJ),
130        -:  125:  T1(str_encrypted, R3_ENCRYPTED, NO_ARGS, NEED_OBJ),
131        -:  126:  END_OF_TABLE
132        -:  127:};
133        -:  128:
134        -:  129:/* Descriptor ruleset for the encrypted section. */
135        -:  130:static token_rule_t hs_desc_encrypted_v3_token_table[] = {
136        -:  131:  T1_START(str_create2_formats, R3_CREATE2_FORMATS, CONCAT_ARGS, NO_OBJ),
137        -:  132:  T01(str_intro_auth_required, R3_INTRO_AUTH_REQUIRED, ARGS, NO_OBJ),
138        -:  133:  T01(str_single_onion, R3_SINGLE_ONION_SERVICE, ARGS, NO_OBJ),
139        -:  134:  END_OF_TABLE
140        -:  135:};
141        -:  136:
142        -:  137:/* Descriptor ruleset for the introduction points section. */
143        -:  138:static token_rule_t hs_desc_intro_point_v3_token_table[] = {
144        -:  139:  T1_START(str_intro_point, R3_INTRODUCTION_POINT, EQ(1), NO_OBJ),
145        -:  140:  T1N(str_ip_onion_key, R3_INTRO_ONION_KEY, GE(2), OBJ_OK),
146        -:  141:  T1(str_ip_auth_key, R3_INTRO_AUTH_KEY, NO_ARGS, NEED_OBJ),
147        -:  142:  T1(str_ip_enc_key, R3_INTRO_ENC_KEY, GE(2), OBJ_OK),
148        -:  143:  T1(str_ip_enc_key_cert, R3_INTRO_ENC_KEY_CERT, ARGS, OBJ_OK),
149        -:  144:  T01(str_ip_legacy_key, R3_INTRO_LEGACY_KEY, ARGS, NEED_KEY_1024),
150        -:  145:  T01(str_ip_legacy_key_cert, R3_INTRO_LEGACY_KEY_CERT, ARGS, OBJ_OK),
151        -:  146:  END_OF_TABLE
152        -:  147:};
153        -:  148:
154        -:  149:/* Free the content of the plaintext section of a descriptor. */
155        -:  150:STATIC void
156        -:  151:desc_plaintext_data_free_contents(hs_desc_plaintext_data_t *desc)
157        -:  152:{
158      594:  153:  if (!desc) {
159        -:  154:    return;
160        -:  155:  }
161        -:  156:
162      297:  157:  if (desc->superencrypted_blob) {
163       56:  158:    tor_free(desc->superencrypted_blob);
164        -:  159:  }
165      297:  160:  tor_cert_free(desc->signing_key_cert);
166        -:  161:
167      297:  162:  memwipe(desc, 0, sizeof(*desc));
168      594:  163:}
169        -:  164:
170        -:  165:/* Free the content of the encrypted section of a descriptor. */
171        -:  166:static void
172        -:  167:desc_encrypted_data_free_contents(hs_desc_encrypted_data_t *desc)
173        -:  168:{
174      636:  169:  if (!desc) {
175        -:  170:    return;
176        -:  171:  }
177        -:  172:
178      318:  173:  if (desc->intro_auth_types) {
179    #####:  174:    SMARTLIST_FOREACH(desc->intro_auth_types, char *, a, tor_free(a));
180    #####:  175:    smartlist_free(desc->intro_auth_types);
181    #####:  176:  }
182      318:  177:  if (desc->intro_points) {
183       10:  178:    SMARTLIST_FOREACH(desc->intro_points, hs_desc_intro_point_t *, ip,
184        -:  179:                      hs_desc_intro_point_free(ip));
185        5:  180:    smartlist_free(desc->intro_points);
186        5:  181:  }
187      318:  182:  memwipe(desc, 0, sizeof(*desc));
188      636:  183:}
189        -:  184:
190        -:  185:/* Using a key, salt and encrypted payload, build a MAC and put it in mac_out.
191        -:  186: * We use SHA3-256 for the MAC computation.
192        -:  187: * This function can't fail. */
193        -:  188:static void
194        -:  189:build_mac(const uint8_t *mac_key, size_t mac_key_len,
195        -:  190:          const uint8_t *salt, size_t salt_len,
196        -:  191:          const uint8_t *encrypted, size_t encrypted_len,
197        -:  192:          uint8_t *mac_out, size_t mac_len)
198        -:  193:{
199        -:  194:  crypto_digest_t *digest;
200        -:  195:
201    #####:  196:  const uint64_t mac_len_netorder = tor_htonll(mac_key_len);
202    #####:  197:  const uint64_t salt_len_netorder = tor_htonll(salt_len);
203        -:  198:
204    #####:  199:  tor_assert(mac_key);
205    #####:  200:  tor_assert(salt);
206    #####:  201:  tor_assert(encrypted);
207    #####:  202:  tor_assert(mac_out);
208        -:  203:
209    #####:  204:  digest = crypto_digest256_new(DIGEST_SHA3_256);
210        -:  205:  /* As specified in section 2.5 of proposal 224, first add the mac key
211        -:  206:   * then add the salt first and then the encrypted section. */
212        -:  207:
213    #####:  208:  crypto_digest_add_bytes(digest, (const char *) &mac_len_netorder, 8);
214    #####:  209:  crypto_digest_add_bytes(digest, (const char *) mac_key, mac_key_len);
215    #####:  210:  crypto_digest_add_bytes(digest, (const char *) &salt_len_netorder, 8);
216    #####:  211:  crypto_digest_add_bytes(digest, (const char *) salt, salt_len);
217    #####:  212:  crypto_digest_add_bytes(digest, (const char *) encrypted, encrypted_len);
218    #####:  213:  crypto_digest_get_digest(digest, (char *) mac_out, mac_len);
219    #####:  214:  crypto_digest_free(digest);
220    #####:  215:}
221        -:  216:
222        -:  217:/* Using a given decriptor object, build the secret input needed for the
223        -:  218: * KDF and put it in the dst pointer which is an already allocated buffer
224        -:  219: * of size dstlen. */
225        -:  220:static void
226        -:  221:build_secret_input(const hs_descriptor_t *desc, uint8_t *dst, size_t dstlen)
227        -:  222:{
228        -:  223:  size_t offset = 0;
229        -:  224:
230    #####:  225:  tor_assert(desc);
231    #####:  226:  tor_assert(dst);
232    #####:  227:  tor_assert(HS_DESC_ENCRYPTED_SECRET_INPUT_LEN <= dstlen);
233        -:  228:
234        -:  229:  /* XXX use the destination length as the memcpy length */
235        -:  230:  /* Copy blinded public key. */
236    #####:  231:  memcpy(dst, desc->plaintext_data.blinded_pubkey.pubkey,
237        -:  232:         sizeof(desc->plaintext_data.blinded_pubkey.pubkey));
238        -:  233:  offset += sizeof(desc->plaintext_data.blinded_pubkey.pubkey);
239        -:  234:  /* Copy subcredential. */
240    #####:  235:  memcpy(dst + offset, desc->subcredential, sizeof(desc->subcredential));
241        -:  236:  offset += sizeof(desc->subcredential);
242        -:  237:  /* Copy revision counter value. */
243    #####:  238:  set_uint64(dst + offset, tor_htonll(desc->plaintext_data.revision_counter));
244        -:  239:  offset += sizeof(uint64_t);
245    #####:  240:  tor_assert(HS_DESC_ENCRYPTED_SECRET_INPUT_LEN == offset);
246    #####:  241:}
247        -:  242:
248        -:  243:/* Do the KDF construction and put the resulting data in key_out which is of
249        -:  244: * key_out_len length. It uses SHAKE-256 as specified in the spec. */
250        -:  245:static void
251        -:  246:build_kdf_key(const hs_descriptor_t *desc,
252        -:  247:              const uint8_t *salt, size_t salt_len,
253        -:  248:              uint8_t *key_out, size_t key_out_len,
254        -:  249:              int is_superencrypted_layer)
255        -:  250:{
256    #####:  251:  uint8_t secret_input[HS_DESC_ENCRYPTED_SECRET_INPUT_LEN];
257        -:  252:  crypto_xof_t *xof;
258        -:  253:
259    #####:  254:  tor_assert(desc);
260    #####:  255:  tor_assert(salt);
261    #####:  256:  tor_assert(key_out);
262        -:  257:
263        -:  258:  /* Build the secret input for the KDF computation. */
264    #####:  259:  build_secret_input(desc, secret_input, sizeof(secret_input));
265        -:  260:
266    #####:  261:  xof = crypto_xof_new();
267        -:  262:  /* Feed our KDF. [SHAKE it like a polaroid picture --Yawning]. */
268    #####:  263:  crypto_xof_add_bytes(xof, secret_input, sizeof(secret_input));
269    #####:  264:  crypto_xof_add_bytes(xof, salt, salt_len);
270        -:  265:
271        -:  266:  /* Feed in the right string constant based on the desc layer */
272    #####:  267:  if (is_superencrypted_layer) {
273    #####:  268:    crypto_xof_add_bytes(xof, (const uint8_t *) str_enc_const_superencryption,
274        -:  269:                         strlen(str_enc_const_superencryption));
275    #####:  270:  } else {
276    #####:  271:    crypto_xof_add_bytes(xof, (const uint8_t *) str_enc_const_encryption,
277        -:  272:                         strlen(str_enc_const_encryption));
278        -:  273:  }
279        -:  274:
280        -:  275:  /* Eat from our KDF. */
281    #####:  276:  crypto_xof_squeeze_bytes(xof, key_out, key_out_len);
282    #####:  277:  crypto_xof_free(xof);
283    #####:  278:  memwipe(secret_input,  0, sizeof(secret_input));
284    #####:  279:}
285        -:  280:
286        -:  281:/* Using the given descriptor and salt, run it through our KDF function and
287        -:  282: * then extract a secret key in key_out, the IV in iv_out and MAC in mac_out.
288        -:  283: * This function can't fail. */
289        -:  284:static void
290        -:  285:build_secret_key_iv_mac(const hs_descriptor_t *desc,
291        -:  286:                        const uint8_t *salt, size_t salt_len,
292        -:  287:                        uint8_t *key_out, size_t key_len,
293        -:  288:                        uint8_t *iv_out, size_t iv_len,
294        -:  289:                        uint8_t *mac_out, size_t mac_len,
295        -:  290:                        int is_superencrypted_layer)
296        -:  291:{
297        -:  292:  size_t offset = 0;
298    #####:  293:  uint8_t kdf_key[HS_DESC_ENCRYPTED_KDF_OUTPUT_LEN];
299        -:  294:
300    #####:  295:  tor_assert(desc);
301    #####:  296:  tor_assert(salt);
302    #####:  297:  tor_assert(key_out);
303    #####:  298:  tor_assert(iv_out);
304    #####:  299:  tor_assert(mac_out);
305        -:  300:
306    #####:  301:  build_kdf_key(desc, salt, salt_len, kdf_key, sizeof(kdf_key),
307        -:  302:                is_superencrypted_layer);
308        -:  303:  /* Copy the bytes we need for both the secret key and IV. */
309    #####:  304:  memcpy(key_out, kdf_key, key_len);
310        -:  305:  offset += key_len;
311    #####:  306:  memcpy(iv_out, kdf_key + offset, iv_len);
312    #####:  307:  offset += iv_len;
313    #####:  308:  memcpy(mac_out, kdf_key + offset, mac_len);
314        -:  309:  /* Extra precaution to make sure we are not out of bound. */
315    #####:  310:  tor_assert((offset + mac_len) == sizeof(kdf_key));
316    #####:  311:  memwipe(kdf_key, 0, sizeof(kdf_key));
317    #####:  312:}
318        -:  313:
319        -:  314:/* === ENCODING === */
320        -:  315:
321        -:  316:/* Encode the given link specifier objects into a newly allocated string.
322        -:  317: * This can't fail so caller can always assume a valid string being
323        -:  318: * returned. */
324        -:  319:STATIC char *
325        -:  320:encode_link_specifiers(const smartlist_t *specs)
326        -:  321:{
327        -:  322:  char *encoded_b64 = NULL;
328    #####:  323:  link_specifier_list_t *lslist = link_specifier_list_new();
329        -:  324:
330    #####:  325:  tor_assert(specs);
331        -:  326:  /* No link specifiers is a code flow error, can't happen. */
332    #####:  327:  tor_assert(smartlist_len(specs) > 0);
333    #####:  328:  tor_assert(smartlist_len(specs) <= UINT8_MAX);
334        -:  329:
335    #####:  330:  link_specifier_list_set_n_spec(lslist, smartlist_len(specs));
336        -:  331:
337    #####:  332:  SMARTLIST_FOREACH_BEGIN(specs, const hs_desc_link_specifier_t *,
338        -:  333:                          spec) {
339    #####:  334:    link_specifier_t *ls = hs_desc_lspec_to_trunnel(spec);
340    #####:  335:    if (ls) {
341    #####:  336:      link_specifier_list_add_spec(lslist, ls);
342    #####:  337:    }
343        -:  338:  } SMARTLIST_FOREACH_END(spec);
344        -:  339:
345        -:  340:  {
346        -:  341:    uint8_t *encoded;
347        -:  342:    ssize_t encoded_len, encoded_b64_len, ret;
348        -:  343:
349    #####:  344:    encoded_len = link_specifier_list_encoded_len(lslist);
350    #####:  345:    tor_assert(encoded_len > 0);
351    #####:  346:    encoded = tor_malloc_zero(encoded_len);
352    #####:  347:    ret = link_specifier_list_encode(encoded, encoded_len, lslist);
353    #####:  348:    tor_assert(ret == encoded_len);
354        -:  349:
355        -:  350:    /* Base64 encode our binary format. Add extra NUL byte for the base64
356        -:  351:     * encoded value. */
357    #####:  352:    encoded_b64_len = base64_encode_size(encoded_len, 0) + 1;
358    #####:  353:    encoded_b64 = tor_malloc_zero(encoded_b64_len);
359    #####:  354:    ret = base64_encode(encoded_b64, encoded_b64_len, (const char *) encoded,
360        -:  355:                        encoded_len, 0);
361    #####:  356:    tor_assert(ret == (encoded_b64_len - 1));
362    #####:  357:    tor_free(encoded);
363        -:  358:  }
364        -:  359:
365    #####:  360:  link_specifier_list_free(lslist);
366    #####:  361:  return encoded_b64;
367        -:  362:}
368        -:  363:
369        -:  364:/* Encode an introduction point legacy key and certificate. Return a newly
370        -:  365: * allocated string with it. On failure, return NULL. */
371        -:  366:static char *
372        -:  367:encode_legacy_key(const hs_desc_intro_point_t *ip)
373        -:  368:{
374    #####:  369:  char *key_str, b64_cert[256], *encoded = NULL;
375    #####:  370:  size_t key_str_len;
376        -:  371:
377    #####:  372:  tor_assert(ip);
378        -:  373:
379        -:  374:  /* Encode cross cert. */
380    #####:  375:  if (base64_encode(b64_cert, sizeof(b64_cert),
381    #####:  376:                    (const char *) ip->legacy.cert.encoded,
382    #####:  377:                    ip->legacy.cert.len, BASE64_ENCODE_MULTILINE) < 0) {
383    #####:  378:    log_warn(LD_REND, "Unable to encode legacy crosscert.");
384    #####:  379:    goto done;
385        -:  380:  }
386        -:  381:  /* Convert the encryption key to PEM format NUL terminated. */
387    #####:  382:  if (crypto_pk_write_public_key_to_string(ip->legacy.key, &key_str,
388    #####:  383:                                           &key_str_len) < 0) {
389    #####:  384:    log_warn(LD_REND, "Unable to encode legacy encryption key.");
390    #####:  385:    goto done;
391        -:  386:  }
392    #####:  387:  tor_asprintf(&encoded,
393        -:  388:               "%s \n%s"  /* Newline is added by the call above. */
394        -:  389:               "%s\n"
395        -:  390:               "-----BEGIN CROSSCERT-----\n"
396        -:  391:               "%s"
397        -:  392:               "-----END CROSSCERT-----",
398    #####:  393:               str_ip_legacy_key, key_str,
399        -:  394:               str_ip_legacy_key_cert, b64_cert);
400    #####:  395:  tor_free(key_str);
401        -:  396:
402        -:  397: done:
403    #####:  398:  return encoded;
404    #####:  399:}
405        -:  400:
406        -:  401:/* Encode an introduction point encryption key and certificate. Return a newly
407        -:  402: * allocated string with it. On failure, return NULL. */
408        -:  403:static char *
409        -:  404:encode_enc_key(const hs_desc_intro_point_t *ip)
410        -:  405:{
411    #####:  406:  char *encoded = NULL, *encoded_cert;
412    #####:  407:  char key_b64[CURVE25519_BASE64_PADDED_LEN + 1];
413        -:  408:
414    #####:  409:  tor_assert(ip);
415        -:  410:
416        -:  411:  /* Base64 encode the encryption key for the "enc-key" field. */
417    #####:  412:  if (curve25519_public_to_base64(key_b64, &ip->enc_key) < 0) {
418        -:  413:    goto done;
419        -:  414:  }
420    #####:  415:  if (tor_cert_encode_ed22519(ip->enc_key_cert, &encoded_cert) < 0) {
421        -:  416:    goto done;
422        -:  417:  }
423    #####:  418:  tor_asprintf(&encoded,
424        -:  419:               "%s ntor %s\n"
425        -:  420:               "%s\n%s",
426        -:  421:               str_ip_enc_key, key_b64,
427    #####:  422:               str_ip_enc_key_cert, encoded_cert);
428    #####:  423:  tor_free(encoded_cert);
429        -:  424:
430        -:  425: done:
431    #####:  426:  return encoded;
432    #####:  427:}
433        -:  428:
434        -:  429:/* Encode an introduction point onion key. Return a newly allocated string
435        -:  430: * with it. On failure, return NULL. */
436        -:  431:static char *
437        -:  432:encode_onion_key(const hs_desc_intro_point_t *ip)
438        -:  433:{
439    #####:  434:  char *encoded = NULL;
440    #####:  435:  char key_b64[CURVE25519_BASE64_PADDED_LEN + 1];
441        -:  436:
442    #####:  437:  tor_assert(ip);
443        -:  438:
444        -:  439:  /* Base64 encode the encryption key for the "onion-key" field. */
445    #####:  440:  if (curve25519_public_to_base64(key_b64, &ip->onion_key) < 0) {
446        -:  441:    goto done;
447        -:  442:  }
448    #####:  443:  tor_asprintf(&encoded, "%s ntor %s", str_ip_onion_key, key_b64);
449        -:  444:
450        -:  445: done:
451    #####:  446:  return encoded;
452    #####:  447:}
453        -:  448:
454        -:  449:/* Encode an introduction point object and return a newly allocated string
455        -:  450: * with it. On failure, return NULL. */
456        -:  451:static char *
457        -:  452:encode_intro_point(const ed25519_public_key_t *sig_key,
458        -:  453:                   const hs_desc_intro_point_t *ip)
459        -:  454:{
460        -:  455:  char *encoded_ip = NULL;
461    #####:  456:  smartlist_t *lines = smartlist_new();
462        -:  457:
463    #####:  458:  tor_assert(ip);
464    #####:  459:  tor_assert(sig_key);
465        -:  460:
466        -:  461:  /* Encode link specifier. */
467        -:  462:  {
468    #####:  463:    char *ls_str = encode_link_specifiers(ip->link_specifiers);
469    #####:  464:    smartlist_add_asprintf(lines, "%s %s", str_intro_point, ls_str);
470    #####:  465:    tor_free(ls_str);
471        -:  466:  }
472        -:  467:
473        -:  468:  /* Onion key encoding. */
474        -:  469:  {
475    #####:  470:    char *encoded_onion_key = encode_onion_key(ip);
476    #####:  471:    if (encoded_onion_key == NULL) {
477    #####:  472:      goto err;
478        -:  473:    }
479    #####:  474:    smartlist_add_asprintf(lines, "%s", encoded_onion_key);
480    #####:  475:    tor_free(encoded_onion_key);
481    #####:  476:  }
482        -:  477:
483        -:  478:  /* Authentication key encoding. */
484        -:  479:  {
485    #####:  480:    char *encoded_cert;
486    #####:  481:    if (tor_cert_encode_ed22519(ip->auth_key_cert, &encoded_cert) < 0) {
487    #####:  482:      goto err;
488        -:  483:    }
489    #####:  484:    smartlist_add_asprintf(lines, "%s\n%s", str_ip_auth_key, encoded_cert);
490    #####:  485:    tor_free(encoded_cert);
491    #####:  486:  }
492        -:  487:
493        -:  488:  /* Encryption key encoding. */
494        -:  489:  {
495    #####:  490:    char *encoded_enc_key = encode_enc_key(ip);
496    #####:  491:    if (encoded_enc_key == NULL) {
497    #####:  492:      goto err;
498        -:  493:    }
499    #####:  494:    smartlist_add_asprintf(lines, "%s", encoded_enc_key);
500    #####:  495:    tor_free(encoded_enc_key);
501    #####:  496:  }
502        -:  497:
503        -:  498:  /* Legacy key if any. */
504    #####:  499:  if (ip->legacy.key != NULL) {
505        -:  500:    /* Strong requirement else the IP creation was badly done. */
506    #####:  501:    tor_assert(ip->legacy.cert.encoded);
507    #####:  502:    char *encoded_legacy_key = encode_legacy_key(ip);
508    #####:  503:    if (encoded_legacy_key == NULL) {
509    #####:  504:      goto err;
510        -:  505:    }
511    #####:  506:    smartlist_add_asprintf(lines, "%s", encoded_legacy_key);
512    #####:  507:    tor_free(encoded_legacy_key);
513    #####:  508:  }
514        -:  509:
515        -:  510:  /* Join them all in one blob of text. */
516    #####:  511:  encoded_ip = smartlist_join_strings(lines, "\n", 1, NULL);
517        -:  512:
518        -:  513: err:
519    #####:  514:  SMARTLIST_FOREACH(lines, char *, l, tor_free(l));
520    #####:  515:  smartlist_free(lines);
521    #####:  516:  return encoded_ip;
522    #####:  517:}
523        -:  518:
524        -:  519:/* Given a source length, return the new size including padding for the
525        -:  520: * plaintext encryption. */
526        -:  521:static size_t
527        -:  522:compute_padded_plaintext_length(size_t plaintext_len)
528        -:  523:{
529        -:  524:  size_t plaintext_padded_len;
530        -:  525:  const int padding_block_length = HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE;
531        -:  526:
532        -:  527:  /* Make sure we won't overflow. */
533    #####:  528:  tor_assert(plaintext_len <= (SIZE_T_CEILING - padding_block_length));
534        -:  529:
535        -:  530:  /* Get the extra length we need to add. For example, if srclen is 10200
536        -:  531:   * bytes, this will expand to (2 * 10k) == 20k thus an extra 9800 bytes. */
537    #####:  532:  plaintext_padded_len = CEIL_DIV(plaintext_len, padding_block_length) *
538        -:  533:                         padding_block_length;
539        -:  534:  /* Can never be extra careful. Make sure we are _really_ padded. */
540    #####:  535:  tor_assert(!(plaintext_padded_len % padding_block_length));
541    #####:  536:  return plaintext_padded_len;
542        -:  537:}
543        -:  538:
544        -:  539:/* Given a buffer, pad it up to the encrypted section padding requirement. Set
545        -:  540: * the newly allocated string in padded_out and return the length of the
546        -:  541: * padded buffer. */
547        -:  542:STATIC size_t
548        -:  543:build_plaintext_padding(const char *plaintext, size_t plaintext_len,
549        -:  544:                        uint8_t **padded_out)
550        -:  545:{
551        -:  546:  size_t padded_len;
552        -:  547:  uint8_t *padded;
553        -:  548:
554    #####:  549:  tor_assert(plaintext);
555    #####:  550:  tor_assert(padded_out);
556        -:  551:
557        -:  552:  /* Allocate the final length including padding. */
558    #####:  553:  padded_len = compute_padded_plaintext_length(plaintext_len);
559    #####:  554:  tor_assert(padded_len >= plaintext_len);
560    #####:  555:  padded = tor_malloc_zero(padded_len);
561        -:  556:
562    #####:  557:  memcpy(padded, plaintext, plaintext_len);
563    #####:  558:  *padded_out = padded;
564    #####:  559:  return padded_len;
565        -:  560:}
566        -:  561:
567        -:  562:/* Using a key, IV and plaintext data of length plaintext_len, create the
568        -:  563: * encrypted section by encrypting it and setting encrypted_out with the
569        -:  564: * data. Return size of the encrypted data buffer. */
570        -:  565:static size_t
571        -:  566:build_encrypted(const uint8_t *key, const uint8_t *iv, const char *plaintext,
572        -:  567:                size_t plaintext_len, uint8_t **encrypted_out,
573        -:  568:                int is_superencrypted_layer)
574        -:  569:{
575        -:  570:  size_t encrypted_len;
576    #####:  571:  uint8_t *padded_plaintext, *encrypted;
577        -:  572:  crypto_cipher_t *cipher;
578        -:  573:
579    #####:  574:  tor_assert(key);
580    #####:  575:  tor_assert(iv);
581    #####:  576:  tor_assert(plaintext);
582    #####:  577:  tor_assert(encrypted_out);
583        -:  578:
584        -:  579:  /* If we are encrypting the middle layer of the descriptor, we need to first
585        -:  580:     pad the plaintext */
586    #####:  581:  if (is_superencrypted_layer) {
587    #####:  582:    encrypted_len = build_plaintext_padding(plaintext, plaintext_len,
588        -:  583:                                            &padded_plaintext);
589        -:  584:    /* Extra precautions that we have a valid padding length. */
590    #####:  585:    tor_assert(!(encrypted_len % HS_DESC_SUPERENC_PLAINTEXT_PAD_MULTIPLE));
591        -:  586:  } else { /* No padding required for inner layers */
592    #####:  587:    padded_plaintext = tor_memdup(plaintext, plaintext_len);
593        -:  588:    encrypted_len = plaintext_len;
594        -:  589:  }
595        -:  590:
596        -:  591:  /* This creates a cipher for AES. It can't fail. */
597    #####:  592:  cipher = crypto_cipher_new_with_iv_and_bits(key, iv,
598        -:  593:                                              HS_DESC_ENCRYPTED_BIT_SIZE);
599        -:  594:  /* We use a stream cipher so the encrypted length will be the same as the
600        -:  595:   * plaintext padded length. */
601    #####:  596:  encrypted = tor_malloc_zero(encrypted_len);
602        -:  597:  /* This can't fail. */
603    #####:  598:  crypto_cipher_encrypt(cipher, (char *) encrypted,
604    #####:  599:                        (const char *) padded_plaintext, encrypted_len);
605    #####:  600:  *encrypted_out = encrypted;
606        -:  601:  /* Cleanup. */
607    #####:  602:  crypto_cipher_free(cipher);
608    #####:  603:  tor_free(padded_plaintext);
609    #####:  604:  return encrypted_len;
610    #####:  605:}
611        -:  606:
612        -:  607:/* Encrypt the given <b>plaintext</b> buffer using <b>desc</b> to get the
613        -:  608: * keys. Set encrypted_out with the encrypted data and return the length of
614        -:  609: * it. <b>is_superencrypted_layer</b> is set if this is the outer encrypted
615        -:  610: * layer of the descriptor. */
616        -:  611:static size_t
617        -:  612:encrypt_descriptor_data(const hs_descriptor_t *desc, const char *plaintext,
618        -:  613:                        char **encrypted_out, int is_superencrypted_layer)
619        -:  614:{
620        -:  615:  char *final_blob;
621        -:  616:  size_t encrypted_len, final_blob_len, offset = 0;
622    #####:  617:  uint8_t *encrypted;
623    #####:  618:  uint8_t salt[HS_DESC_ENCRYPTED_SALT_LEN];
624    #####:  619:  uint8_t secret_key[HS_DESC_ENCRYPTED_KEY_LEN], secret_iv[CIPHER_IV_LEN];
625    #####:  620:  uint8_t mac_key[DIGEST256_LEN], mac[DIGEST256_LEN];
626        -:  621:
627    #####:  622:  tor_assert(desc);
628    #####:  623:  tor_assert(plaintext);
629    #####:  624:  tor_assert(encrypted_out);
630        -:  625:
631        -:  626:  /* Get our salt. The returned bytes are already hashed. */
632    #####:  627:  crypto_strongest_rand(salt, sizeof(salt));
633        -:  628:
634        -:  629:  /* KDF construction resulting in a key from which the secret key, IV and MAC
635        -:  630:   * key are extracted which is what we need for the encryption. */
636    #####:  631:  build_secret_key_iv_mac(desc, salt, sizeof(salt),
637    #####:  632:                          secret_key, sizeof(secret_key),
638    #####:  633:                          secret_iv, sizeof(secret_iv),
639    #####:  634:                          mac_key, sizeof(mac_key),
640        -:  635:                          is_superencrypted_layer);
641        -:  636:
642        -:  637:  /* Build the encrypted part that is do the actual encryption. */
643    #####:  638:  encrypted_len = build_encrypted(secret_key, secret_iv, plaintext,
644    #####:  639:                                  strlen(plaintext), &encrypted,
645        -:  640:                                  is_superencrypted_layer);
646    #####:  641:  memwipe(secret_key, 0, sizeof(secret_key));
647    #####:  642:  memwipe(secret_iv, 0, sizeof(secret_iv));
648        -:  643:  /* This construction is specified in section 2.5 of proposal 224. */
649    #####:  644:  final_blob_len = sizeof(salt) + encrypted_len + DIGEST256_LEN;
650    #####:  645:  final_blob = tor_malloc_zero(final_blob_len);
651        -:  646:
652        -:  647:  /* Build the MAC. */
653    #####:  648:  build_mac(mac_key, sizeof(mac_key), salt, sizeof(salt),
654    #####:  649:            encrypted, encrypted_len, mac, sizeof(mac));
655    #####:  650:  memwipe(mac_key, 0, sizeof(mac_key));
656        -:  651:
657        -:  652:  /* The salt is the first value. */
658    #####:  653:  memcpy(final_blob, salt, sizeof(salt));
659        -:  654:  offset = sizeof(salt);
660        -:  655:  /* Second value is the encrypted data. */
661    #####:  656:  memcpy(final_blob + offset, encrypted, encrypted_len);
662        -:  657:  offset += encrypted_len;
663        -:  658:  /* Third value is the MAC. */
664    #####:  659:  memcpy(final_blob + offset, mac, sizeof(mac));
665        -:  660:  offset += sizeof(mac);
666        -:  661:  /* Cleanup the buffers. */
667    #####:  662:  memwipe(salt, 0, sizeof(salt));
668    #####:  663:  memwipe(encrypted, 0, encrypted_len);
669    #####:  664:  tor_free(encrypted);
670        -:  665:  /* Extra precaution. */
671    #####:  666:  tor_assert(offset == final_blob_len);
672        -:  667:
673    #####:  668:  *encrypted_out = final_blob;
674    #####:  669:  return final_blob_len;
675    #####:  670:}
676        -:  671:
677        -:  672:/* Create and return a string containing a fake client-auth entry. It's the
678        -:  673: * responsibility of the caller to free the returned string. This function will
679        -:  674: * never fail. */
680        -:  675:static char *
681        -:  676:get_fake_auth_client_str(void)
682        -:  677:{
683    #####:  678:  char *auth_client_str = NULL;
684        -:  679:  /* We are gonna fill these arrays with fake base64 data. They are all double
685        -:  680:   * the size of their binary representation to fit the base64 overhead. */
686    #####:  681:  char client_id_b64[8*2];
687    #####:  682:  char iv_b64[16*2];
688    #####:  683:  char encrypted_cookie_b64[16*2];
689        -:  684:  int retval;
690        -:  685:
691        -:  686:  /* This is a macro to fill a field with random data and then base64 it. */
692        -:  687:#define FILL_WITH_FAKE_DATA_AND_BASE64(field) STMT_BEGIN         \
693        -:  688:  crypto_rand((char *)field, sizeof(field));                     \
694        -:  689:  retval = base64_encode_nopad(field##_b64, sizeof(field##_b64), \
695        -:  690:                               field, sizeof(field));            \
696        -:  691:  tor_assert(retval > 0);                                        \
697        -:  692:  STMT_END
698        -:  693:
699        -:  694:  { /* Get those fakes! */
700    #####:  695:    uint8_t client_id[8]; /* fake client-id */
701    #####:  696:    uint8_t iv[16]; /* fake IV (initialization vector) */
702    #####:  697:    uint8_t encrypted_cookie[16]; /* fake encrypted cookie */
703        -:  698:
704    #####:  699:    FILL_WITH_FAKE_DATA_AND_BASE64(client_id);
705    #####:  700:    FILL_WITH_FAKE_DATA_AND_BASE64(iv);
706    #####:  701:    FILL_WITH_FAKE_DATA_AND_BASE64(encrypted_cookie);
707    #####:  702:  }
708        -:  703:
709        -:  704:  /* Build the final string */
710    #####:  705:  tor_asprintf(&auth_client_str, "%s %s %s %s", str_desc_auth_client,
711        -:  706:               client_id_b64, iv_b64, encrypted_cookie_b64);
712        -:  707:
713        -:  708:#undef FILL_WITH_FAKE_DATA_AND_BASE64
714        -:  709:
715    #####:  710:  return auth_client_str;
716    #####:  711:}
717        -:  712:
718        -:  713:/** How many lines of "client-auth" we want in our descriptors; fake or not. */
719        -:  714:#define CLIENT_AUTH_ENTRIES_BLOCK_SIZE 16
720        -:  715:
721        -:  716:/** Create the "client-auth" part of the descriptor and return a
722        -:  717: *  newly-allocated string with it. It's the responsibility of the caller to
723        -:  718: *  free the returned string. */
724        -:  719:static char *
725        -:  720:get_fake_auth_client_lines(void)
726        -:  721:{
727        -:  722:  /* XXX: Client authorization is still not implemented, so all this function
728        -:  723:     does is make fake clients */
729        -:  724:  int i = 0;
730    #####:  725:  smartlist_t *auth_client_lines = smartlist_new();
731        -:  726:  char *auth_client_lines_str = NULL;
732        -:  727:
733        -:  728:  /* Make a line for each fake client */
734        -:  729:  const int num_fake_clients = CLIENT_AUTH_ENTRIES_BLOCK_SIZE;
735    #####:  730:  for (i = 0; i < num_fake_clients; i++) {
736    #####:  731:    char *auth_client_str = get_fake_auth_client_str();
737    #####:  732:    tor_assert(auth_client_str);
738    #####:  733:    smartlist_add(auth_client_lines, auth_client_str);
739        -:  734:  }
740        -:  735:
741        -:  736:  /* Join all lines together to form final string */
742    #####:  737:  auth_client_lines_str = smartlist_join_strings(auth_client_lines,
743        -:  738:                                                 "\n", 1, NULL);
744        -:  739:  /* Cleanup the mess */
745    #####:  740:  SMARTLIST_FOREACH(auth_client_lines, char *, a, tor_free(a));
746    #####:  741:  smartlist_free(auth_client_lines);
747        -:  742:
748    #####:  743:  return auth_client_lines_str;
749        -:  744:}
750        -:  745:
751        -:  746:/* Create the inner layer of the descriptor (which includes the intro points,
752        -:  747: * etc.). Return a newly-allocated string with the layer plaintext, or NULL if
753        -:  748: * an error occured. It's the responsibility of the caller to free the returned
754        -:  749: * string. */
755        -:  750:static char *
756        -:  751:get_inner_encrypted_layer_plaintext(const hs_descriptor_t *desc)
757        -:  752:{
758        -:  753:  char *encoded_str = NULL;
759    #####:  754:  smartlist_t *lines = smartlist_new();
760        -:  755:
761        -:  756:  /* Build the start of the section prior to the introduction points. */
762        -:  757:  {
763    #####:  758:    if (!desc->encrypted_data.create2_ntor) {
764    #####:  759:      log_err(LD_BUG, "HS desc doesn't have recognized handshake type.");
765    #####:  760:      goto err;
766        -:  761:    }
767    #####:  762:    smartlist_add_asprintf(lines, "%s %d\n", str_create2_formats,
768        -:  763:                           ONION_HANDSHAKE_TYPE_NTOR);
769        -:  764:
770    #####:  765:    if (desc->encrypted_data.intro_auth_types &&
771    #####:  766:        smartlist_len(desc->encrypted_data.intro_auth_types)) {
772        -:  767:      /* Put the authentication-required line. */
773    #####:  768:      char *buf = smartlist_join_strings(desc->encrypted_data.intro_auth_types,
774        -:  769:                                         " ", 0, NULL);
775    #####:  770:      smartlist_add_asprintf(lines, "%s %s\n", str_intro_auth_required, buf);
776    #####:  771:      tor_free(buf);
777    #####:  772:    }
778        -:  773:
779    #####:  774:    if (desc->encrypted_data.single_onion_service) {
780    #####:  775:      smartlist_add_asprintf(lines, "%s\n", str_single_onion);
781    #####:  776:    }
782        -:  777:  }
783        -:  778:
784        -:  779:  /* Build the introduction point(s) section. */
785    #####:  780:  SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
786        -:  781:                          const hs_desc_intro_point_t *, ip) {
787    #####:  782:    char *encoded_ip = encode_intro_point(&desc->plaintext_data.signing_pubkey,
788        -:  783:                                          ip);
789    #####:  784:    if (encoded_ip == NULL) {
790    #####:  785:      log_err(LD_BUG, "HS desc intro point is malformed.");
791    #####:  786:      goto err;
792        -:  787:    }
793    #####:  788:    smartlist_add(lines, encoded_ip);
794    #####:  789:  } SMARTLIST_FOREACH_END(ip);
795        -:  790:
796        -:  791:  /* Build the entire encrypted data section into one encoded plaintext and
797        -:  792:   * then encrypt it. */
798    #####:  793:  encoded_str = smartlist_join_strings(lines, "", 0, NULL);
799        -:  794:
800        -:  795: err:
801    #####:  796:  SMARTLIST_FOREACH(lines, char *, l, tor_free(l));
802    #####:  797:  smartlist_free(lines);
803        -:  798:
804    #####:  799:  return encoded_str;
805    #####:  800:}
806        -:  801:
807        -:  802:/* Create the middle layer of the descriptor, which includes the client auth
808        -:  803: * data and the encrypted inner layer (provided as a base64 string at
809        -:  804: * <b>layer2_b64_ciphertext</b>). Return a newly-allocated string with the
810        -:  805: * layer plaintext, or NULL if an error occured. It's the responsibility of the
811        -:  806: * caller to free the returned string. */
812        -:  807:static char *
813        -:  808:get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc,
814        -:  809:                                    const char *layer2_b64_ciphertext)
815        -:  810:{
816        -:  811:  char *layer1_str = NULL;
817    #####:  812:  smartlist_t *lines = smartlist_new();
818        -:  813:
819        -:  814:  /* XXX: Disclaimer: This function generates only _fake_ client auth
820        -:  815:   * data. Real client auth is not yet implemented, but client auth data MUST
821        -:  816:   * always be present in descriptors. In the future this function will be
822        -:  817:   * refactored to use real client auth data if they exist (#20700). */
823        -:  818:  (void) *desc;
824        -:  819:
825        -:  820:  /* Specify auth type */
826    #####:  821:  smartlist_add_asprintf(lines, "%s %s\n", str_desc_auth_type, "x25519");
827        -:  822:
828        -:  823:  {  /* Create fake ephemeral x25519 key */
829    #####:  824:    char fake_key_base64[CURVE25519_BASE64_PADDED_LEN + 1];
830    #####:  825:    curve25519_keypair_t fake_x25519_keypair;
831    #####:  826:    if (curve25519_keypair_generate(&fake_x25519_keypair, 0) < 0) {
832    #####:  827:      goto done;
833        -:  828:    }
834    #####:  829:    if (curve25519_public_to_base64(fake_key_base64,
835    #####:  830:                                    &fake_x25519_keypair.pubkey) < 0) {
836    #####:  831:      goto done;
837        -:  832:    }
838    #####:  833:    smartlist_add_asprintf(lines, "%s %s\n",
839        -:  834:                           str_desc_auth_key, fake_key_base64);
840        -:  835:    /* No need to memwipe any of these fake keys. They will go unused. */
841    #####:  836:  }
842        -:  837:
843        -:  838:  {  /* Create fake auth-client lines. */
844    #####:  839:    char *auth_client_lines = get_fake_auth_client_lines();
845    #####:  840:    tor_assert(auth_client_lines);
846    #####:  841:    smartlist_add(lines, auth_client_lines);
847        -:  842:  }
848        -:  843:
849        -:  844:  /* create encrypted section */
850        -:  845:  {
851    #####:  846:    smartlist_add_asprintf(lines,
852        -:  847:                           "%s\n"
853        -:  848:                           "-----BEGIN MESSAGE-----\n"
854        -:  849:                           "%s"
855        -:  850:                           "-----END MESSAGE-----",
856        -:  851:                           str_encrypted, layer2_b64_ciphertext);
857        -:  852:  }
858        -:  853:
859    #####:  854:  layer1_str = smartlist_join_strings(lines, "", 0, NULL);
860        -:  855:
861        -:  856: done:
862    #####:  857:  SMARTLIST_FOREACH(lines, char *, a, tor_free(a));
863    #####:  858:  smartlist_free(lines);
864        -:  859:
865    #####:  860:  return layer1_str;
866    #####:  861:}
867        -:  862:
868        -:  863:/* Encrypt <b>encoded_str</b> into an encrypted blob and then base64 it before
869        -:  864: * returning it. <b>desc</b> is provided to derive the encryption
870        -:  865: * keys. <b>is_superencrypted_layer</b> is set if <b>encoded_str</b> is the
871        -:  866: * middle (superencrypted) layer of the descriptor. It's the responsibility of
872        -:  867: * the caller to free the returned string. */
873        -:  868:static char *
874        -:  869:encrypt_desc_data_and_base64(const hs_descriptor_t *desc,
875        -:  870:                             const char *encoded_str,
876        -:  871:                             int is_superencrypted_layer)
877        -:  872:{
878        -:  873:  char *enc_b64;
879        -:  874:  ssize_t enc_b64_len, ret_len, enc_len;
880    #####:  875:  char *encrypted_blob = NULL;
881        -:  876:
882    #####:  877:  enc_len = encrypt_descriptor_data(desc, encoded_str, &encrypted_blob,
883        -:  878:                                    is_superencrypted_layer);
884        -:  879:  /* Get the encoded size plus a NUL terminating byte. */
885    #####:  880:  enc_b64_len = base64_encode_size(enc_len, BASE64_ENCODE_MULTILINE) + 1;
886    #####:  881:  enc_b64 = tor_malloc_zero(enc_b64_len);
887        -:  882:  /* Base64 the encrypted blob before returning it. */
888    #####:  883:  ret_len = base64_encode(enc_b64, enc_b64_len, encrypted_blob, enc_len,
889        -:  884:                          BASE64_ENCODE_MULTILINE);
890        -:  885:  /* Return length doesn't count the NUL byte. */
891    #####:  886:  tor_assert(ret_len == (enc_b64_len - 1));
892    #####:  887:  tor_free(encrypted_blob);
893        -:  888:
894    #####:  889:  return enc_b64;
895    #####:  890:}
896        -:  891:
897        -:  892:/* Generate and encode the superencrypted portion of <b>desc</b>. This also
898        -:  893: * involves generating the encrypted portion of the descriptor, and performing
899        -:  894: * the superencryption. A newly allocated NUL-terminated string pointer
900        -:  895: * containing the encrypted encoded blob is put in encrypted_blob_out. Return 0
901        -:  896: * on success else a negative value. */
902        -:  897:static int
903        -:  898:encode_superencrypted_data(const hs_descriptor_t *desc,
904        -:  899:                           char **encrypted_blob_out)
905        -:  900:{
906        -:  901:  int ret = -1;
907        -:  902:  char *layer2_str = NULL;
908        -:  903:  char *layer2_b64_ciphertext = NULL;
909        -:  904:  char *layer1_str = NULL;
910        -:  905:  char *layer1_b64_ciphertext = NULL;
911        -:  906:
912    #####:  907:  tor_assert(desc);
913    #####:  908:  tor_assert(encrypted_blob_out);
914        -:  909:
915        -:  910:  /* Func logic: We first create the inner layer of the descriptor (layer2).
916        -:  911:   * We then encrypt it and use it to create the middle layer of the descriptor
917        -:  912:   * (layer1).  Finally we superencrypt the middle layer and return it to our
918        -:  913:   * caller. */
919        -:  914:
920        -:  915:  /* Create inner descriptor layer */
921    #####:  916:  layer2_str = get_inner_encrypted_layer_plaintext(desc);
922    #####:  917:  if (!layer2_str) {
923        -:  918:    goto err;
924        -:  919:  }
925        -:  920:
926        -:  921:  /* Encrypt and b64 the inner layer */
927    #####:  922:  layer2_b64_ciphertext = encrypt_desc_data_and_base64(desc, layer2_str, 0);
928    #####:  923:  if (!layer2_b64_ciphertext) {
929        -:  924:    goto err;
930        -:  925:  }
931        -:  926:
932        -:  927:  /* Now create middle descriptor layer given the inner layer */
933    #####:  928:  layer1_str = get_outer_encrypted_layer_plaintext(desc,layer2_b64_ciphertext);
934    #####:  929:  if (!layer1_str) {
935        -:  930:    goto err;
936        -:  931:  }
937        -:  932:
938        -:  933:  /* Encrypt and base64 the middle layer */
939    #####:  934:  layer1_b64_ciphertext = encrypt_desc_data_and_base64(desc, layer1_str, 1);
940    #####:  935:  if (!layer1_b64_ciphertext) {
941        -:  936:    goto err;
942        -:  937:  }
943        -:  938:
944        -:  939:  /* Success! */
945    #####:  940:  ret = 0;
946        -:  941:
947        -:  942: err:
948    #####:  943:  tor_free(layer1_str);
949    #####:  944:  tor_free(layer2_str);
950    #####:  945:  tor_free(layer2_b64_ciphertext);
951        -:  946:
952    #####:  947:  *encrypted_blob_out = layer1_b64_ciphertext;
953    #####:  948:  return ret;
954        -:  949:}
955        -:  950:
956        -:  951:/* Encode a v3 HS descriptor. Return 0 on success and set encoded_out to the
957        -:  952: * newly allocated string of the encoded descriptor. On error, -1 is returned
958        -:  953: * and encoded_out is untouched. */
959        -:  954:static int
960        -:  955:desc_encode_v3(const hs_descriptor_t *desc,
961        -:  956:               const ed25519_keypair_t *signing_kp, char **encoded_out)
962        -:  957:{
963        -:  958:  int ret = -1;
964        -:  959:  char *encoded_str = NULL;
965    #####:  960:  size_t encoded_len;
966    #####:  961:  smartlist_t *lines = smartlist_new();
967        -:  962:
968    #####:  963:  tor_assert(desc);
969    #####:  964:  tor_assert(signing_kp);
970    #####:  965:  tor_assert(encoded_out);
971    #####:  966:  tor_assert(desc->plaintext_data.version == 3);
972        -:  967:
973    #####:  968:  if (BUG(desc->subcredential == NULL)) {
974    #####:  969:    goto err;
975        -:  970:  }
976        -:  971:
977        -:  972:  /* Build the non-encrypted values. */
978        -:  973:  {
979    #####:  974:    char *encoded_cert;
980        -:  975:    /* Encode certificate then create the first line of the descriptor. */
981    #####:  976:    if (desc->plaintext_data.signing_key_cert->cert_type
982    #####:  977:        != CERT_TYPE_SIGNING_HS_DESC) {
983    #####:  978:      log_err(LD_BUG, "HS descriptor signing key has an unexpected cert type "
984        -:  979:              "(%d)", (int) desc->plaintext_data.signing_key_cert->cert_type);
985    #####:  980:      goto err;
986        -:  981:    }
987    #####:  982:    if (tor_cert_encode_ed22519(desc->plaintext_data.signing_key_cert,
988    #####:  983:                                &encoded_cert) < 0) {
989        -:  984:      /* The function will print error logs. */
990    #####:  985:      goto err;
991        -:  986:    }
992        -:  987:    /* Create the hs descriptor line. */
993    #####:  988:    smartlist_add_asprintf(lines, "%s %" PRIu32, str_hs_desc,
994    #####:  989:                           desc->plaintext_data.version);
995        -:  990:    /* Add the descriptor lifetime line (in minutes). */
996    #####:  991:    smartlist_add_asprintf(lines, "%s %" PRIu32, str_lifetime,
997    #####:  992:                           desc->plaintext_data.lifetime_sec / 60);
998        -:  993:    /* Create the descriptor certificate line. */
999    #####:  994:    smartlist_add_asprintf(lines, "%s\n%s", str_desc_cert, encoded_cert);
1000    #####:  995:    tor_free(encoded_cert);
1001        -:  996:    /* Create the revision counter line. */
1002    #####:  997:    smartlist_add_asprintf(lines, "%s %" PRIu64, str_rev_counter,
1003    #####:  998:                           desc->plaintext_data.revision_counter);
1004    #####:  999:  }
1005        -: 1000:
1006        -: 1001:  /* Build the superencrypted data section. */
1007        -: 1002:  {
1008    #####: 1003:    char *enc_b64_blob=NULL;
1009    #####: 1004:    if (encode_superencrypted_data(desc, &enc_b64_blob) < 0) {
1010    #####: 1005:      goto err;
1011        -: 1006:    }
1012    #####: 1007:    smartlist_add_asprintf(lines,
1013        -: 1008:                           "%s\n"
1014        -: 1009:                           "-----BEGIN MESSAGE-----\n"
1015        -: 1010:                           "%s"
1016        -: 1011:                           "-----END MESSAGE-----",
1017    #####: 1012:                           str_superencrypted, enc_b64_blob);
1018    #####: 1013:    tor_free(enc_b64_blob);
1019    #####: 1014:  }
1020        -: 1015:
1021        -: 1016:  /* Join all lines in one string so we can generate a signature and append
1022        -: 1017:   * it to the descriptor. */
1023    #####: 1018:  encoded_str = smartlist_join_strings(lines, "\n", 1, &encoded_len);
1024        -: 1019:
1025        -: 1020:  /* Sign all fields of the descriptor with our short term signing key. */
1026        -: 1021:  {
1027    #####: 1022:    ed25519_signature_t sig;
1028    #####: 1023:    char ed_sig_b64[ED25519_SIG_BASE64_LEN + 1];
1029    #####: 1024:    if (ed25519_sign_prefixed(&sig,
1030    #####: 1025:                              (const uint8_t *) encoded_str, encoded_len,
1031    #####: 1026:                              str_desc_sig_prefix, signing_kp) < 0) {
1032    #####: 1027:      log_warn(LD_BUG, "Can't sign encoded HS descriptor!");
1033    #####: 1028:      tor_free(encoded_str);
1034    #####: 1029:      goto err;
1035        -: 1030:    }
1036    #####: 1031:    if (ed25519_signature_to_base64(ed_sig_b64, &sig) < 0) {
1037    #####: 1032:      log_warn(LD_BUG, "Can't base64 encode descriptor signature!");
1038    #####: 1033:      tor_free(encoded_str);
1039    #####: 1034:      goto err;
1040        -: 1035:    }
1041        -: 1036:    /* Create the signature line. */
1042    #####: 1037:    smartlist_add_asprintf(lines, "%s %s", str_signature, ed_sig_b64);
1043    #####: 1038:  }
1044        -: 1039:  /* Free previous string that we used so compute the signature. */
1045    #####: 1040:  tor_free(encoded_str);
1046    #####: 1041:  encoded_str = smartlist_join_strings(lines, "\n", 1, NULL);
1047    #####: 1042:  *encoded_out = encoded_str;
1048        -: 1043:
1049    #####: 1044:  if (strlen(encoded_str) >= hs_cache_get_max_descriptor_size()) {
1050    #####: 1045:    log_warn(LD_GENERAL, "We just made an HS descriptor that's too big (%d)."
1051        -: 1046:             "Failing.", (int)strlen(encoded_str));
1052    #####: 1047:    tor_free(encoded_str);
1053        -: 1048:    goto err;
1054        -: 1049:  }
1055        -: 1050:
1056        -: 1051:  /* XXX: Trigger a control port event. */
1057        -: 1052:
1058        -: 1053:  /* Success! */
1059    #####: 1054:  ret = 0;
1060        -: 1055:
1061        -: 1056: err:
1062    #####: 1057:  SMARTLIST_FOREACH(lines, char *, l, tor_free(l));
1063    #####: 1058:  smartlist_free(lines);
1064    #####: 1059:  return ret;
1065    #####: 1060:}
1066        -: 1061:
1067        -: 1062:/* === DECODING === */
1068        -: 1063:
1069        -: 1064:/* Given an encoded string of the link specifiers, return a newly allocated
1070        -: 1065: * list of decoded link specifiers. Return NULL on error. */
1071        -: 1066:STATIC smartlist_t *
1072        -: 1067:decode_link_specifiers(const char *encoded)
1073        -: 1068:{
1074        -: 1069:  int decoded_len;
1075        -: 1070:  size_t encoded_len, i;
1076        -: 1071:  uint8_t *decoded;
1077        -: 1072:  smartlist_t *results = NULL;
1078    #####: 1073:  link_specifier_list_t *specs = NULL;
1079        -: 1074:
1080    #####: 1075:  tor_assert(encoded);
1081        -: 1076:
1082    #####: 1077:  encoded_len = strlen(encoded);
1083    #####: 1078:  decoded = tor_malloc(encoded_len);
1084    #####: 1079:  decoded_len = base64_decode((char *) decoded, encoded_len, encoded,
1085        -: 1080:                              encoded_len);
1086    #####: 1081:  if (decoded_len < 0) {
1087        -: 1082:    goto err;
1088        -: 1083:  }
1089        -: 1084:
1090    #####: 1085:  if (link_specifier_list_parse(&specs, decoded,
1091    #####: 1086:                                (size_t) decoded_len) < decoded_len) {
1092        -: 1087:    goto err;
1093        -: 1088:  }
1094    #####: 1089:  tor_assert(specs);
1095    #####: 1090:  results = smartlist_new();
1096        -: 1091:
1097    #####: 1092:  for (i = 0; i < link_specifier_list_getlen_spec(specs); i++) {
1098        -: 1093:    hs_desc_link_specifier_t *hs_spec;
1099    #####: 1094:    link_specifier_t *ls = link_specifier_list_get_spec(specs, i);
1100    #####: 1095:    tor_assert(ls);
1101        -: 1096:
1102    #####: 1097:    hs_spec = tor_malloc_zero(sizeof(*hs_spec));
1103    #####: 1098:    hs_spec->type = link_specifier_get_ls_type(ls);
1104    #####: 1099:    switch (hs_spec->type) {
1105        -: 1100:    case LS_IPV4:
1106    #####: 1101:      tor_addr_from_ipv4h(&hs_spec->u.ap.addr,
1107        -: 1102:                          link_specifier_get_un_ipv4_addr(ls));
1108    #####: 1103:      hs_spec->u.ap.port = link_specifier_get_un_ipv4_port(ls);
1109    #####: 1104:      break;
1110        -: 1105:    case LS_IPV6:
1111    #####: 1106:      tor_addr_from_ipv6_bytes(&hs_spec->u.ap.addr, (const char *)
1112    #####: 1107:                               link_specifier_getarray_un_ipv6_addr(ls));
1113    #####: 1108:      hs_spec->u.ap.port = link_specifier_get_un_ipv6_port(ls);
1114    #####: 1109:      break;
1115        -: 1110:    case LS_LEGACY_ID:
1116        -: 1111:      /* Both are known at compile time so let's make sure they are the same
1117        -: 1112:       * else we can copy memory out of bound. */
1118    #####: 1113:      tor_assert(link_specifier_getlen_un_legacy_id(ls) ==
1119        -: 1114:                 sizeof(hs_spec->u.legacy_id));
1120    #####: 1115:      memcpy(hs_spec->u.legacy_id, link_specifier_getarray_un_legacy_id(ls),
1121        -: 1116:             sizeof(hs_spec->u.legacy_id));
1122    #####: 1117:      break;
1123        -: 1118:    case LS_ED25519_ID:
1124        -: 1119:      /* Both are known at compile time so let's make sure they are the same
1125        -: 1120:       * else we can copy memory out of bound. */
1126    #####: 1121:      tor_assert(link_specifier_getlen_un_ed25519_id(ls) ==
1127        -: 1122:                 sizeof(hs_spec->u.ed25519_id));
1128    #####: 1123:      memcpy(hs_spec->u.ed25519_id,
1129    #####: 1124:             link_specifier_getconstarray_un_ed25519_id(ls),
1130        -: 1125:             sizeof(hs_spec->u.ed25519_id));
1131    #####: 1126:      break;
1132        -: 1127:    default:
1133    #####: 1128:      goto err;
1134        -: 1129:    }
1135        -: 1130:
1136    #####: 1131:    smartlist_add(results, hs_spec);
1137    #####: 1132:  }
1138        -: 1133:
1139        -: 1134:  goto done;
1140        -: 1135: err:
1141    #####: 1136:  if (results) {
1142    #####: 1137:    SMARTLIST_FOREACH(results, hs_desc_link_specifier_t *, s, tor_free(s));
1143    #####: 1138:    smartlist_free(results);
1144        -: 1139:    results = NULL;
1145    #####: 1140:  }
1146        -: 1141: done:
1147    #####: 1142:  link_specifier_list_free(specs);
1148    #####: 1143:  tor_free(decoded);
1149    #####: 1144:  return results;
1150    #####: 1145:}
1151        -: 1146:
1152        -: 1147:/* Given a list of authentication types, decode it and put it in the encrypted
1153        -: 1148: * data section. Return 1 if we at least know one of the type or 0 if we know
1154        -: 1149: * none of them. */
1155        -: 1150:static int
1156        -: 1151:decode_auth_type(hs_desc_encrypted_data_t *desc, const char *list)
1157        -: 1152:{
1158        -: 1153:  int match = 0;
1159        -: 1154:
1160    #####: 1155:  tor_assert(desc);
1161    #####: 1156:  tor_assert(list);
1162        -: 1157:
1163    #####: 1158:  desc->intro_auth_types = smartlist_new();
1164    #####: 1159:  smartlist_split_string(desc->intro_auth_types, list, " ", 0, 0);
1165        -: 1160:
1166        -: 1161:  /* Validate the types that we at least know about one. */
1167    #####: 1162:  SMARTLIST_FOREACH_BEGIN(desc->intro_auth_types, const char *, auth) {
1168    #####: 1163:    for (int idx = 0; intro_auth_types[idx].identifier; idx++) {
1169    #####: 1164:      if (!strncmp(auth, intro_auth_types[idx].identifier,
1170    #####: 1165:                   strlen(intro_auth_types[idx].identifier))) {
1171        -: 1166:        match = 1;
1172    #####: 1167:        break;
1173        -: 1168:      }
1174        -: 1169:    }
1175        -: 1170:  } SMARTLIST_FOREACH_END(auth);
1176        -: 1171:
1177    #####: 1172:  return match;
1178        -: 1173:}
1179        -: 1174:
1180        -: 1175:/* Parse a space-delimited list of integers representing CREATE2 formats into
1181        -: 1176: * the bitfield in hs_desc_encrypted_data_t. Ignore unrecognized values. */
1182        -: 1177:static void
1183        -: 1178:decode_create2_list(hs_desc_encrypted_data_t *desc, const char *list)
1184        -: 1179:{
1185        -: 1180:  smartlist_t *tokens;
1186        -: 1181:
1187       16: 1182:  tor_assert(desc);
1188        8: 1183:  tor_assert(list);
1189        -: 1184:
1190        8: 1185:  tokens = smartlist_new();
1191        8: 1186:  smartlist_split_string(tokens, list, " ", 0, 0);
1192        -: 1187:
1193       43: 1188:  SMARTLIST_FOREACH_BEGIN(tokens, char *, s) {
1194        9: 1189:    int ok;
1195        9: 1190:    unsigned long type = tor_parse_ulong(s, 10, 1, UINT16_MAX, &ok, NULL);
1196        9: 1191:    if (!ok) {
1197        3: 1192:      log_warn(LD_REND, "Unparseable value %s in create2 list", escaped(s));
1198        3: 1193:      continue;
1199        -: 1194:    }
1200        6: 1195:    switch (type) {
1201        -: 1196:    case ONION_HANDSHAKE_TYPE_NTOR:
1202        5: 1197:      desc->create2_ntor = 1;
1203        -: 1198:      break;
1204        -: 1199:    default:
1205        -: 1200:      /* We deliberately ignore unsupported handshake types */
1206        1: 1201:      continue;
1207        -: 1202:    }
1208       19: 1203:  } SMARTLIST_FOREACH_END(s);
1209        -: 1204:
1210       52: 1205:  SMARTLIST_FOREACH(tokens, char *, s, tor_free(s));
1211        8: 1206:  smartlist_free(tokens);
1212        8: 1207:}
1213        -: 1208:
1214        -: 1209:/* Given a certificate, validate the certificate for certain conditions which
1215        -: 1210: * are if the given type matches the cert's one, if the signing key is
1216        -: 1211: * included and if the that key was actually used to sign the certificate.
1217        -: 1212: *
1218        -: 1213: * Return 1 iff if all conditions pass or 0 if one of them fails. */
1219        -: 1214:STATIC int
1220        -: 1215:cert_is_valid(tor_cert_t *cert, uint8_t type, const char *log_obj_type)
1221        -: 1216:{
1222       80: 1217:  tor_assert(log_obj_type);
1223        -: 1218:
1224       40: 1219:  if (cert == NULL) {
1225    #####: 1220:    log_warn(LD_REND, "Certificate for %s couldn't be parsed.", log_obj_type);
1226    #####: 1221:    goto err;
1227        -: 1222:  }
1228       40: 1223:  if (cert->cert_type != type) {
1229        1: 1224:    log_warn(LD_REND, "Invalid cert type %02x for %s.", cert->cert_type,
1230        -: 1225:             log_obj_type);
1231        1: 1226:    goto err;
1232        -: 1227:  }
1233        -: 1228:  /* All certificate must have its signing key included. */
1234       39: 1229:  if (!cert->signing_key_included) {
1235        6: 1230:    log_warn(LD_REND, "Signing key is NOT included for %s.", log_obj_type);
1236        6: 1231:    goto err;
1237        -: 1232:  }
1238        -: 1233:  /* The following will not only check if the signature matches but also the
1239        -: 1234:   * expiration date and overall validity. */
1240       33: 1235:  if (tor_cert_checksig(cert, &cert->signing_key, approx_time()) < 0) {
1241    #####: 1236:    log_warn(LD_REND, "Invalid signature for %s.", log_obj_type);
1242    #####: 1237:    goto err;
1243        -: 1238:  }
1244        -: 1239:
1245       33: 1240:  return 1;
1246        -: 1241: err:
1247        7: 1242:  return 0;
1248       40: 1243:}
1249        -: 1244:
1250        -: 1245:/* Given some binary data, try to parse it to get a certificate object. If we
1251        -: 1246: * have a valid cert, validate it using the given wanted type. On error, print
1252        -: 1247: * a log using the err_msg has the certificate identifier adding semantic to
1253        -: 1248: * the log and cert_out is set to NULL. On success, 0 is returned and cert_out
1254        -: 1249: * points to a newly allocated certificate object. */
1255        -: 1250:static int
1256        -: 1251:cert_parse_and_validate(tor_cert_t **cert_out, const char *data,
1257        -: 1252:                        size_t data_len, unsigned int cert_type_wanted,
1258        -: 1253:                        const char *err_msg)
1259        -: 1254:{
1260        -: 1255:  tor_cert_t *cert;
1261        -: 1256:
1262      142: 1257:  tor_assert(cert_out);
1263       71: 1258:  tor_assert(data);
1264       71: 1259:  tor_assert(err_msg);
1265        -: 1260:
1266        -: 1261:  /* Parse certificate. */
1267       71: 1262:  cert = tor_cert_parse((const uint8_t *) data, data_len);
1268       71: 1263:  if (!cert) {
1269       31: 1264:    log_warn(LD_REND, "Certificate for %s couldn't be parsed.", err_msg);
1270       31: 1265:    goto err;
1271        -: 1266:  }
1272        -: 1267:
1273        -: 1268:  /* Validate certificate. */
1274       40: 1269:  if (!cert_is_valid(cert, cert_type_wanted, err_msg)) {
1275        -: 1270:    goto err;
1276        -: 1271:  }
1277        -: 1272:
1278       33: 1273:  *cert_out = cert;
1279       33: 1274:  return 0;
1280        -: 1275:
1281        -: 1276: err:
1282       38: 1277:  tor_cert_free(cert);
1283       38: 1278:  *cert_out = NULL;
1284       38: 1279:  return -1;
1285       71: 1280:}
1286        -: 1281:
1287        -: 1282:/* Return true iff the given length of the encrypted data of a descriptor
1288        -: 1283: * passes validation. */
1289        -: 1284:STATIC int
1290        -: 1285:encrypted_data_length_is_valid(size_t len)
1291        -: 1286:{
1292        -: 1287:  /* Make sure there is enough data for the salt and the mac. The equality is
1293        -: 1288:     there to ensure that there is at least one byte of encrypted data. */
1294       80: 1289:  if (len <= HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN) {
1295        3: 1290:    log_warn(LD_REND, "Length of descriptor's encrypted data is too small. "
1296        -: 1291:                      "Got %lu but minimum value is %d",
1297        -: 1292:             (unsigned long)len, HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN);
1298        -: 1293:    goto err;
1299        -: 1294:  }
1300        -: 1295:
1301       37: 1296:  return 1;
1302        -: 1297: err:
1303        3: 1298:  return 0;
1304       40: 1299:}
1305        -: 1300:
1306        -: 1301:/** Decrypt an encrypted descriptor layer at <b>encrypted_blob</b> of size
1307        -: 1302: *  <b>encrypted_blob_size</b>. Use the descriptor object <b>desc</b> to
1308        -: 1303: *  generate the right decryption keys; set <b>decrypted_out</b> to the
1309        -: 1304: *  plaintext. If <b>is_superencrypted_layer</b> is set, this is the outter
1310        -: 1305: *  encrypted layer of the descriptor. */
1311        -: 1306:MOCK_IMPL(STATIC size_t,
1312        -: 1307:decrypt_desc_layer,(const hs_descriptor_t *desc,
1313        -: 1308:                    const uint8_t *encrypted_blob,
1314        -: 1309:                    size_t encrypted_blob_size,
1315        -: 1310:                    int is_superencrypted_layer,
1316        -: 1311:                    char **decrypted_out))
1317        -: 1312:{
1318        -: 1313:  uint8_t *decrypted = NULL;
1319    #####: 1314:  uint8_t secret_key[HS_DESC_ENCRYPTED_KEY_LEN], secret_iv[CIPHER_IV_LEN];
1320    #####: 1315:  uint8_t mac_key[DIGEST256_LEN], our_mac[DIGEST256_LEN];
1321        -: 1316:  const uint8_t *salt, *encrypted, *desc_mac;
1322        -: 1317:  size_t encrypted_len, result_len = 0;
1323        -: 1318:
1324    #####: 1319:  tor_assert(decrypted_out);
1325    #####: 1320:  tor_assert(desc);
1326    #####: 1321:  tor_assert(encrypted_blob);
1327        -: 1322:
1328        -: 1323:  /* Construction is as follow: SALT | ENCRYPTED_DATA | MAC .
1329        -: 1324:   * Make sure we have enough space for all these things. */
1330    #####: 1325:  if (!encrypted_data_length_is_valid(encrypted_blob_size)) {
1331        -: 1326:    goto err;
1332        -: 1327:  }
1333        -: 1328:
1334        -: 1329:  /* Start of the blob thus the salt. */
1335        -: 1330:  salt = encrypted_blob;
1336        -: 1331:
1337        -: 1332:  /* Next is the encrypted data. */
1338    #####: 1333:  encrypted = encrypted_blob + HS_DESC_ENCRYPTED_SALT_LEN;
1339    #####: 1334:  encrypted_len = encrypted_blob_size -
1340        -: 1335:    (HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN);
1341    #####: 1336:  tor_assert(encrypted_len > 0); /* guaranteed by the check above */
1342        -: 1337:
1343        -: 1338:  /* And last comes the MAC. */
1344    #####: 1339:  desc_mac = encrypted_blob + encrypted_blob_size - DIGEST256_LEN;
1345        -: 1340:
1346        -: 1341:  /* KDF construction resulting in a key from which the secret key, IV and MAC
1347        -: 1342:   * key are extracted which is what we need for the decryption. */
1348    #####: 1343:  build_secret_key_iv_mac(desc, salt, HS_DESC_ENCRYPTED_SALT_LEN,
1349    #####: 1344:                          secret_key, sizeof(secret_key),
1350    #####: 1345:                          secret_iv, sizeof(secret_iv),
1351    #####: 1346:                          mac_key, sizeof(mac_key),
1352        -: 1347:                          is_superencrypted_layer);
1353        -: 1348:
1354        -: 1349:  /* Build MAC. */
1355    #####: 1350:  build_mac(mac_key, sizeof(mac_key), salt, HS_DESC_ENCRYPTED_SALT_LEN,
1356    #####: 1351:            encrypted, encrypted_len, our_mac, sizeof(our_mac));
1357    #####: 1352:  memwipe(mac_key, 0, sizeof(mac_key));
1358        -: 1353:  /* Verify MAC; MAC is H(mac_key || salt || encrypted)
1359        -: 1354:   *
1360        -: 1355:   * This is a critical check that is making sure the computed MAC matches the
1361        -: 1356:   * one in the descriptor. */
1362    #####: 1357:  if (!tor_memeq(our_mac, desc_mac, sizeof(our_mac))) {
1363    #####: 1358:    log_warn(LD_REND, "Encrypted service descriptor MAC check failed");
1364    #####: 1359:    goto err;
1365        -: 1360:  }
1366        -: 1361:
1367        -: 1362:  {
1368        -: 1363:    /* Decrypt. Here we are assured that the encrypted length is valid for
1369        -: 1364:     * decryption. */
1370        -: 1365:    crypto_cipher_t *cipher;
1371        -: 1366:
1372    #####: 1367:    cipher = crypto_cipher_new_with_iv_and_bits(secret_key, secret_iv,
1373        -: 1368:                                                HS_DESC_ENCRYPTED_BIT_SIZE);
1374        -: 1369:    /* Extra byte for the NUL terminated byte. */
1375    #####: 1370:    decrypted = tor_malloc_zero(encrypted_len + 1);
1376    #####: 1371:    crypto_cipher_decrypt(cipher, (char *) decrypted,
1377        -: 1372:                          (const char *) encrypted, encrypted_len);
1378    #####: 1373:    crypto_cipher_free(cipher);
1379        -: 1374:  }
1380        -: 1375:
1381        -: 1376:  {
1382        -: 1377:    /* Adjust length to remove NUL padding bytes */
1383    #####: 1378:    uint8_t *end = memchr(decrypted, 0, encrypted_len);
1384        -: 1379:    result_len = encrypted_len;
1385    #####: 1380:    if (end) {
1386    #####: 1381:      result_len = end - decrypted;
1387    #####: 1382:    }
1388        -: 1383:  }
1389        -: 1384:
1390        -: 1385:  /* Make sure to NUL terminate the string. */
1391    #####: 1386:  decrypted[encrypted_len] = '\0';
1392    #####: 1387:  *decrypted_out = (char *) decrypted;
1393    #####: 1388:  goto done;
1394        -: 1389:
1395        -: 1390: err:
1396    #####: 1391:  if (decrypted) {
1397    #####: 1392:    tor_free(decrypted);
1398        -: 1393:  }
1399    #####: 1394:  *decrypted_out = NULL;
1400    #####: 1395:  result_len = 0;
1401        -: 1396:
1402        -: 1397: done:
1403    #####: 1398:  memwipe(secret_key, 0, sizeof(secret_key));
1404    #####: 1399:  memwipe(secret_iv, 0, sizeof(secret_iv));
1405    #####: 1400:  return result_len;
1406    #####: 1401:}
1407        -: 1402:
1408        -: 1403:/* Basic validation that the superencrypted client auth portion of the
1409        -: 1404: * descriptor is well-formed and recognized. Return True if so, otherwise
1410        -: 1405: * return False. */
1411        -: 1406:static int
1412        -: 1407:superencrypted_auth_data_is_valid(smartlist_t *tokens)
1413        -: 1408:{
1414        -: 1409:  /* XXX: This is just basic validation for now. When we implement client auth,
1415        -: 1410:     we can refactor this function so that it actually parses and saves the
1416        -: 1411:     data. */
1417        -: 1412:
1418        -: 1413:  { /* verify desc auth type */
1419        -: 1414:    const directory_token_t *tok;
1420       30: 1415:    tok = find_by_keyword(tokens, R3_DESC_AUTH_TYPE);
1421       15: 1416:    tor_assert(tok->n_args >= 1);
1422       15: 1417:    if (strcmp(tok->args[0], "x25519")) {
1423        1: 1418:      log_warn(LD_DIR, "Unrecognized desc auth type");
1424        1: 1419:      return 0;
1425        -: 1420:    }
1426       14: 1421:  }
1427        -: 1422:
1428        -: 1423:  { /* verify desc auth key */
1429        -: 1424:    const directory_token_t *tok;
1430       14: 1425:    curve25519_public_key_t k;
1431       14: 1426:    tok = find_by_keyword(tokens, R3_DESC_AUTH_KEY);
1432       14: 1427:    tor_assert(tok->n_args >= 1);
1433       14: 1428:    if (curve25519_public_from_base64(&k, tok->args[0]) < 0) {
1434        3: 1429:      log_warn(LD_DIR, "Bogus desc auth key in HS desc");
1435        3: 1430:      return 0;
1436        -: 1431:    }
1437       25: 1432:  }
1438        -: 1433:
1439        -: 1434:  /* verify desc auth client items */
1440      460: 1435:  SMARTLIST_FOREACH_BEGIN(tokens, const directory_token_t *, tok) {
1441      146: 1436:    if (tok->tp == R3_DESC_AUTH_CLIENT) {
1442      111: 1437:      tor_assert(tok->n_args >= 3);
1443        -: 1438:    }
1444        -: 1439:  } SMARTLIST_FOREACH_END(tok);
1445        -: 1440:
1446       11: 1441:  return 1;
1447       15: 1442:}
1448        -: 1443:
1449        -: 1444:/* Parse <b>message</b>, the plaintext of the superencrypted portion of an HS
1450        -: 1445: * descriptor. Set <b>encrypted_out</b> to the encrypted blob, and return its
1451        -: 1446: * size */
1452        -: 1447:STATIC size_t
1453        -: 1448:decode_superencrypted(const char *message, size_t message_len,
1454        -: 1449:                     uint8_t **encrypted_out)
1455        -: 1450:{
1456        -: 1451:  int retval = 0;
1457        -: 1452:  memarea_t *area = NULL;
1458        -: 1453:  smartlist_t *tokens = NULL;
1459        -: 1454:
1460       50: 1455:  area = memarea_new();
1461       25: 1456:  tokens = smartlist_new();
1462       50: 1457:  if (tokenize_string(area, message, message + message_len, tokens,
1463       25: 1458:                      hs_desc_superencrypted_v3_token_table, 0) < 0) {
1464       10: 1459:    log_warn(LD_REND, "Superencrypted portion is not parseable");
1465       10: 1460:    goto err;
1466        -: 1461:  }
1467        -: 1462:
1468        -: 1463:  /* Do some rudimentary validation of the authentication data */
1469       15: 1464:  if (!superencrypted_auth_data_is_valid(tokens)) {
1470        4: 1465:    log_warn(LD_REND, "Invalid auth data");
1471        4: 1466:    goto err;
1472        -: 1467:  }
1473        -: 1468:
1474        -: 1469:  /* Extract the encrypted data section. */
1475        -: 1470:  {
1476        -: 1471:    const directory_token_t *tok;
1477       11: 1472:    tok = find_by_keyword(tokens, R3_ENCRYPTED);
1478       11: 1473:    tor_assert(tok->object_body);
1479       11: 1474:    if (strcmp(tok->object_type, "MESSAGE") != 0) {
1480    #####: 1475:      log_warn(LD_REND, "Desc superencrypted data section is invalid");
1481    #####: 1476:      goto err;
1482        -: 1477:    }
1483        -: 1478:    /* Make sure the length of the encrypted blob is valid. */
1484       11: 1479:    if (!encrypted_data_length_is_valid(tok->object_size)) {
1485        2: 1480:      goto err;
1486        -: 1481:    }
1487        -: 1482:
1488        -: 1483:    /* Copy the encrypted blob to the descriptor object so we can handle it
1489        -: 1484:     * latter if needed. */
1490        9: 1485:    tor_assert(tok->object_size <= INT_MAX);
1491        9: 1486:    *encrypted_out = tor_memdup(tok->object_body, tok->object_size);
1492        9: 1487:    retval = (int) tok->object_size;
1493        9: 1488:  }
1494        -: 1489:
1495        -: 1490: err:
1496      520: 1491:  SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
1497       25: 1492:  smartlist_free(tokens);
1498       25: 1493:  if (area) {
1499       25: 1494:    memarea_drop_all(area);
1500       25: 1495:  }
1501        -: 1496:
1502       25: 1497:  return retval;
1503       25: 1498:}
1504        -: 1499:
1505        -: 1500:/* Decrypt both the superencrypted and the encrypted section of the descriptor
1506        -: 1501: * using the given descriptor object <b>desc</b>. A newly allocated NUL
1507        -: 1502: * terminated string is put in decrypted_out which contains the inner encrypted
1508        -: 1503: * layer of the descriptor. Return the length of decrypted_out on success else
1509        -: 1504: * 0 is returned and decrypted_out is set to NULL. */
1510        -: 1505:static size_t
1511        -: 1506:desc_decrypt_all(const hs_descriptor_t *desc, char **decrypted_out)
1512        -: 1507:{
1513        -: 1508:  size_t  decrypted_len = 0;
1514        -: 1509:  size_t encrypted_len = 0;
1515        -: 1510:  size_t superencrypted_len = 0;
1516       52: 1511:  char *superencrypted_plaintext = NULL;
1517       26: 1512:  uint8_t *encrypted_blob = NULL;
1518        -: 1513:
1519        -: 1514:  /** Function logic: This function takes us from the descriptor header to the
1520        -: 1515:   *  inner encrypted layer, by decrypting and decoding the middle descriptor
1521        -: 1516:   *  layer. In the end we return the contents of the inner encrypted layer to
1522        -: 1517:   *  our caller. */
1523        -: 1518:
1524        -: 1519:  /* 1. Decrypt middle layer of descriptor */
1525       52: 1520:  superencrypted_len = decrypt_desc_layer(desc,
1526       26: 1521:                                 desc->plaintext_data.superencrypted_blob,
1527       26: 1522:                                 desc->plaintext_data.superencrypted_blob_size,
1528        -: 1523:                                 1,
1529        -: 1524:                                 &superencrypted_plaintext);
1530       26: 1525:  if (!superencrypted_len) {
1531        1: 1526:    log_warn(LD_REND, "Decrypting superencrypted desc failed.");
1532        1: 1527:    goto err;
1533        -: 1528:  }
1534       25: 1529:  tor_assert(superencrypted_plaintext);
1535        -: 1530:
1536        -: 1531:  /* 2. Parse "superencrypted" */
1537       25: 1532:  encrypted_len = decode_superencrypted(superencrypted_plaintext,
1538        -: 1533:                                        superencrypted_len,
1539        -: 1534:                                        &encrypted_blob);
1540       25: 1535:  if (!encrypted_len) {
1541       16: 1536:    log_warn(LD_REND, "Decrypting encrypted desc failed.");
1542       16: 1537:    goto err;
1543        -: 1538:  }
1544        9: 1539:  tor_assert(encrypted_blob);
1545        -: 1540:
1546        -: 1541:  /* 3. Decrypt "encrypted" and set decrypted_out */
1547        -: 1542:  char *decrypted_desc;
1548        9: 1543:  decrypted_len = decrypt_desc_layer(desc,
1549        -: 1544:                                     encrypted_blob, encrypted_len,
1550        -: 1545:                                     0, &decrypted_desc);
1551        9: 1546:  if (!decrypted_len) {
1552    #####: 1547:    log_warn(LD_REND, "Decrypting encrypted desc failed.");
1553    #####: 1548:    goto err;
1554        -: 1549:  }
1555        9: 1550:  tor_assert(decrypted_desc);
1556        -: 1551:
1557        9: 1552:  *decrypted_out = decrypted_desc;
1558        -: 1553:
1559        -: 1554: err:
1560       52: 1555:  tor_free(superencrypted_plaintext);
1561       35: 1556:  tor_free(encrypted_blob);
1562        -: 1557:
1563       26: 1558:  return decrypted_len;
1564       26: 1559:}
1565        -: 1560:
1566        -: 1561:/* Given the token tok for an intro point legacy key, the list of tokens, the
1567        -: 1562: * introduction point ip being decoded and the descriptor desc from which it
1568        -: 1563: * comes from, decode the legacy key and set the intro point object. Return 0
1569        -: 1564: * on success else -1 on failure. */
1570        -: 1565:static int
1571        -: 1566:decode_intro_legacy_key(const directory_token_t *tok,
1572        -: 1567:                        smartlist_t *tokens,
1573        -: 1568:                        hs_desc_intro_point_t *ip,
1574        -: 1569:                        const hs_descriptor_t *desc)
1575        -: 1570:{
1576    #####: 1571:  tor_assert(tok);
1577    #####: 1572:  tor_assert(tokens);
1578    #####: 1573:  tor_assert(ip);
1579    #####: 1574:  tor_assert(desc);
1580        -: 1575:
1581    #####: 1576:  if (!crypto_pk_public_exponent_ok(tok->key)) {
1582    #####: 1577:    log_warn(LD_REND, "Introduction point legacy key is invalid");
1583    #####: 1578:    goto err;
1584        -: 1579:  }
1585    #####: 1580:  ip->legacy.key = crypto_pk_dup_key(tok->key);
1586        -: 1581:  /* Extract the legacy cross certification cert which MUST be present if we
1587        -: 1582:   * have a legacy key. */
1588    #####: 1583:  tok = find_opt_by_keyword(tokens, R3_INTRO_LEGACY_KEY_CERT);
1589    #####: 1584:  if (!tok) {
1590    #####: 1585:    log_warn(LD_REND, "Introduction point legacy key cert is missing");
1591    #####: 1586:    goto err;
1592        -: 1587:  }
1593    #####: 1588:  tor_assert(tok->object_body);
1594    #####: 1589:  if (strcmp(tok->object_type, "CROSSCERT")) {
1595        -: 1590:    /* Info level because this might be an unknown field that we should
1596        -: 1591:     * ignore. */
1597    #####: 1592:    log_info(LD_REND, "Introduction point legacy encryption key "
1598        -: 1593:                      "cross-certification has an unknown format.");
1599    #####: 1594:    goto err;
1600        -: 1595:  }
1601        -: 1596:  /* Keep a copy of the certificate. */
1602    #####: 1597:  ip->legacy.cert.encoded = tor_memdup(tok->object_body, tok->object_size);
1603    #####: 1598:  ip->legacy.cert.len = tok->object_size;
1604        -: 1599:  /* The check on the expiration date is for the entire lifetime of a
1605        -: 1600:   * certificate which is 24 hours. However, a descriptor has a maximum
1606        -: 1601:   * lifetime of 12 hours meaning we have a 12h difference between the two
1607        -: 1602:   * which ultimately accomodate the clock skewed client. */
1608    #####: 1603:  if (rsa_ed25519_crosscert_check(ip->legacy.cert.encoded,
1609    #####: 1604:                                  ip->legacy.cert.len, ip->legacy.key,
1610    #####: 1605:                                  &desc->plaintext_data.signing_pubkey,
1611    #####: 1606:                                  approx_time() - HS_DESC_CERT_LIFETIME)) {
1612    #####: 1607:    log_warn(LD_REND, "Unable to check cross-certification on the "
1613        -: 1608:                      "introduction point legacy encryption key.");
1614    #####: 1609:    ip->cross_certified = 0;
1615    #####: 1610:    goto err;
1616        -: 1611:  }
1617        -: 1612:
1618        -: 1613:  /* Success. */
1619    #####: 1614:  return 0;
1620        -: 1615: err:
1621    #####: 1616:  return -1;
1622    #####: 1617:}
1623        -: 1618:
1624        -: 1619:/* Dig into the descriptor <b>tokens</b> to find the onion key we should use
1625        -: 1620: * for this intro point, and set it into <b>onion_key_out</b>. Return 0 if it
1626        -: 1621: * was found and well-formed, otherwise return -1 in case of errors. */
1627        -: 1622:static int
1628        -: 1623:set_intro_point_onion_key(curve25519_public_key_t *onion_key_out,
1629        -: 1624:                          const smartlist_t *tokens)
1630        -: 1625:{
1631        -: 1626:  int retval = -1;
1632        -: 1627:  smartlist_t *onion_keys = NULL;
1633        -: 1628:
1634    #####: 1629:  tor_assert(onion_key_out);
1635        -: 1630:
1636    #####: 1631:  onion_keys = find_all_by_keyword(tokens, R3_INTRO_ONION_KEY);
1637    #####: 1632:  if (!onion_keys) {
1638    #####: 1633:    log_warn(LD_REND, "Descriptor did not contain intro onion keys");
1639    #####: 1634:    goto err;
1640        -: 1635:  }
1641        -: 1636:
1642    #####: 1637:  SMARTLIST_FOREACH_BEGIN(onion_keys, directory_token_t *, tok) {
1643        -: 1638:    /* This field is using GE(2) so for possible forward compatibility, we
1644        -: 1639:     * accept more fields but must be at least 2. */
1645    #####: 1640:    tor_assert(tok->n_args >= 2);
1646        -: 1641:
1647        -: 1642:    /* Try to find an ntor key, it's the only recognized type right now */
1648    #####: 1643:    if (!strcmp(tok->args[0], "ntor")) {
1649    #####: 1644:      if (curve25519_public_from_base64(onion_key_out, tok->args[1]) < 0) {
1650    #####: 1645:        log_warn(LD_REND, "Introduction point ntor onion-key is invalid");
1651    #####: 1646:        goto err;
1652        -: 1647:      }
1653        -: 1648:      /* Got the onion key! Set the appropriate retval */
1654        -: 1649:      retval = 0;
1655    #####: 1650:    }
1656    #####: 1651:  } SMARTLIST_FOREACH_END(tok);
1657        -: 1652:
1658        -: 1653:  /* Log an error if we didn't find it :( */
1659    #####: 1654:  if (retval < 0) {
1660    #####: 1655:    log_warn(LD_REND, "Descriptor did not contain ntor onion keys");
1661    #####: 1656:  }
1662        -: 1657:
1663        -: 1658: err:
1664    #####: 1659:  smartlist_free(onion_keys);
1665    #####: 1660:  return retval;
1666    #####: 1661:}
1667        -: 1662:
1668        -: 1663:/* Given the start of a section and the end of it, decode a single
1669        -: 1664: * introduction point from that section. Return a newly allocated introduction
1670        -: 1665: * point object containing the decoded data. Return NULL if the section can't
1671        -: 1666: * be decoded. */
1672        -: 1667:STATIC hs_desc_intro_point_t *
1673        -: 1668:decode_introduction_point(const hs_descriptor_t *desc, const char *start)
1674        -: 1669:{
1675        -: 1670:  hs_desc_intro_point_t *ip = NULL;
1676        -: 1671:  memarea_t *area = NULL;
1677        -: 1672:  smartlist_t *tokens = NULL;
1678        -: 1673:  const directory_token_t *tok;
1679        -: 1674:
1680    #####: 1675:  tor_assert(desc);
1681    #####: 1676:  tor_assert(start);
1682        -: 1677:
1683    #####: 1678:  area = memarea_new();
1684    #####: 1679:  tokens = smartlist_new();
1685    #####: 1680:  if (tokenize_string(area, start, start + strlen(start),
1686    #####: 1681:                      tokens, hs_desc_intro_point_v3_token_table, 0) < 0) {
1687    #####: 1682:    log_warn(LD_REND, "Introduction point is not parseable");
1688    #####: 1683:    goto err;
1689        -: 1684:  }
1690        -: 1685:
1691        -: 1686:  /* Ok we seem to have a well formed section containing enough tokens to
1692        -: 1687:   * parse. Allocate our IP object and try to populate it. */
1693    #####: 1688:  ip = hs_desc_intro_point_new();
1694        -: 1689:
1695        -: 1690:  /* "introduction-point" SP link-specifiers NL */
1696    #####: 1691:  tok = find_by_keyword(tokens, R3_INTRODUCTION_POINT);
1697    #####: 1692:  tor_assert(tok->n_args == 1);
1698        -: 1693:  /* Our constructor creates this list by default so free it. */
1699    #####: 1694:  smartlist_free(ip->link_specifiers);
1700    #####: 1695:  ip->link_specifiers = decode_link_specifiers(tok->args[0]);
1701    #####: 1696:  if (!ip->link_specifiers) {
1702    #####: 1697:    log_warn(LD_REND, "Introduction point has invalid link specifiers");
1703    #####: 1698:    goto err;
1704        -: 1699:  }
1705        -: 1700:
1706        -: 1701:  /* "onion-key" SP ntor SP key NL */
1707    #####: 1702:  if (set_intro_point_onion_key(&ip->onion_key, tokens) < 0) {
1708        -: 1703:    goto err;
1709        -: 1704:  }
1710        -: 1705:
1711        -: 1706:  /* "auth-key" NL certificate NL */
1712    #####: 1707:  tok = find_by_keyword(tokens, R3_INTRO_AUTH_KEY);
1713    #####: 1708:  tor_assert(tok->object_body);
1714    #####: 1709:  if (strcmp(tok->object_type, "ED25519 CERT")) {
1715    #####: 1710:    log_warn(LD_REND, "Unexpected object type for introduction auth key");
1716    #####: 1711:    goto err;
1717        -: 1712:  }
1718        -: 1713:  /* Parse cert and do some validation. */
1719    #####: 1714:  if (cert_parse_and_validate(&ip->auth_key_cert, tok->object_body,
1720    #####: 1715:                              tok->object_size, CERT_TYPE_AUTH_HS_IP_KEY,
1721    #####: 1716:                              "introduction point auth-key") < 0) {
1722        -: 1717:    goto err;
1723        -: 1718:  }
1724        -: 1719:  /* Validate authentication certificate with descriptor signing key. */
1725    #####: 1720:  if (tor_cert_checksig(ip->auth_key_cert,
1726    #####: 1721:                        &desc->plaintext_data.signing_pubkey, 0) < 0) {
1727    #####: 1722:    log_warn(LD_REND, "Invalid authentication key signature");
1728    #####: 1723:    goto err;
1729        -: 1724:  }
1730        -: 1725:
1731        -: 1726:  /* Exactly one "enc-key" SP "ntor" SP key NL */
1732    #####: 1727:  tok = find_by_keyword(tokens, R3_INTRO_ENC_KEY);
1733    #####: 1728:  if (!strcmp(tok->args[0], "ntor")) {
1734        -: 1729:    /* This field is using GE(2) so for possible forward compatibility, we
1735        -: 1730:     * accept more fields but must be at least 2. */
1736    #####: 1731:    tor_assert(tok->n_args >= 2);
1737        -: 1732:
1738    #####: 1733:    if (curve25519_public_from_base64(&ip->enc_key, tok->args[1]) < 0) {
1739    #####: 1734:      log_warn(LD_REND, "Introduction point ntor enc-key is invalid");
1740    #####: 1735:      goto err;
1741        -: 1736:    }
1742        -: 1737:  } else {
1743        -: 1738:    /* Unknown key type so we can't use that introduction point. */
1744    #####: 1739:    log_warn(LD_REND, "Introduction point encryption key is unrecognized.");
1745    #####: 1740:    goto err;
1746        -: 1741:  }
1747        -: 1742:
1748        -: 1743:  /* Exactly once "enc-key-cert" NL certificate NL */
1749    #####: 1744:  tok = find_by_keyword(tokens, R3_INTRO_ENC_KEY_CERT);
1750    #####: 1745:  tor_assert(tok->object_body);
1751        -: 1746:  /* Do the cross certification. */
1752    #####: 1747:  if (strcmp(tok->object_type, "ED25519 CERT")) {
1753    #####: 1748:      log_warn(LD_REND, "Introduction point ntor encryption key "
1754        -: 1749:                        "cross-certification has an unknown format.");
1755    #####: 1750:      goto err;
1756        -: 1751:  }
1757    #####: 1752:  if (cert_parse_and_validate(&ip->enc_key_cert, tok->object_body,
1758    #####: 1753:                              tok->object_size, CERT_TYPE_CROSS_HS_IP_KEYS,
1759    #####: 1754:                              "introduction point enc-key-cert") < 0) {
1760        -: 1755:    goto err;
1761        -: 1756:  }
1762    #####: 1757:  if (tor_cert_checksig(ip->enc_key_cert,
1763    #####: 1758:                        &desc->plaintext_data.signing_pubkey, 0) < 0) {
1764    #####: 1759:    log_warn(LD_REND, "Invalid encryption key signature");
1765    #####: 1760:    goto err;
1766        -: 1761:  }
1767        -: 1762:  /* It is successfully cross certified. Flag the object. */
1768    #####: 1763:  ip->cross_certified = 1;
1769        -: 1764:
1770        -: 1765:  /* Do we have a "legacy-key" SP key NL ?*/
1771    #####: 1766:  tok = find_opt_by_keyword(tokens, R3_INTRO_LEGACY_KEY);
1772    #####: 1767:  if (tok) {
1773    #####: 1768:    if (decode_intro_legacy_key(tok, tokens, ip, desc) < 0) {
1774        -: 1769:      goto err;
1775        -: 1770:    }
1776        -: 1771:  }
1777        -: 1772:
1778        -: 1773:  /* Introduction point has been parsed successfully. */
1779        -: 1774:  goto done;
1780        -: 1775:
1781        -: 1776: err:
1782    #####: 1777:  hs_desc_intro_point_free(ip);
1783    #####: 1778:  ip = NULL;
1784        -: 1779:
1785        -: 1780: done:
1786    #####: 1781:  SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
1787    #####: 1782:  smartlist_free(tokens);
1788    #####: 1783:  if (area) {
1789    #####: 1784:    memarea_drop_all(area);
1790    #####: 1785:  }
1791        -: 1786:
1792    #####: 1787:  return ip;
1793        -: 1788:}
1794        -: 1789:
1795        -: 1790:/* Given a descriptor string at <b>data</b>, decode all possible introduction
1796        -: 1791: * points that we can find. Add the introduction point object to desc_enc as we
1797        -: 1792: * find them. This function can't fail and it is possible that zero
1798        -: 1793: * introduction points can be decoded. */
1799        -: 1794:static void
1800        -: 1795:decode_intro_points(const hs_descriptor_t *desc,
1801        -: 1796:                    hs_desc_encrypted_data_t *desc_enc,
1802        -: 1797:                    const char *data)
1803        -: 1798:{
1804       10: 1799:  smartlist_t *chunked_desc = smartlist_new();
1805        5: 1800:  smartlist_t *intro_points = smartlist_new();
1806        -: 1801:
1807        5: 1802:  tor_assert(desc);
1808        5: 1803:  tor_assert(desc_enc);
1809        5: 1804:  tor_assert(data);
1810        5: 1805:  tor_assert(desc_enc->intro_points);
1811        -: 1806:
1812        -: 1807:  /* Take the desc string, and extract the intro point substrings out of it */
1813        -: 1808:  {
1814        -: 1809:    /* Split the descriptor string using the intro point header as delimiter */
1815        5: 1810:    smartlist_split_string(chunked_desc, data, str_intro_point_start, 0, 0);
1816        -: 1811:
1817        -: 1812:    /* Check if there are actually any intro points included. The first chunk
1818        -: 1813:     * should be other descriptor fields (e.g. create2-formats), so it's not an
1819        -: 1814:     * intro point. */
1820        5: 1815:    if (smartlist_len(chunked_desc) < 2) {
1821        -: 1816:      goto done;
1822        -: 1817:    }
1823        -: 1818:  }
1824        -: 1819:
1825        -: 1820:  /* Take the intro point substrings, and prepare them for parsing */
1826        -: 1821:  {
1827        -: 1822:    int i = 0;
1828        -: 1823:    /* Prepend the introduction-point header to all the chunks, since
1829        -: 1824:       smartlist_split_string() devoured it. */
1830    #####: 1825:    SMARTLIST_FOREACH_BEGIN(chunked_desc, char *, chunk) {
1831        -: 1826:      /* Ignore first chunk. It's other descriptor fields. */
1832    #####: 1827:      if (i++ == 0) {
1833        -: 1828:        continue;
1834        -: 1829:      }
1835        -: 1830:
1836    #####: 1831:      smartlist_add_asprintf(intro_points, "%s %s", str_intro_point, chunk);
1837    #####: 1832:    } SMARTLIST_FOREACH_END(chunk);
1838        -: 1833:  }
1839        -: 1834:
1840        -: 1835:  /* Parse the intro points! */
1841    #####: 1836:  SMARTLIST_FOREACH_BEGIN(intro_points, const char *, intro_point) {
1842    #####: 1837:    hs_desc_intro_point_t *ip = decode_introduction_point(desc, intro_point);
1843    #####: 1838:    if (!ip) {
1844        -: 1839:      /* Malformed introduction point section. We'll ignore this introduction
1845        -: 1840:       * point and continue parsing. New or unknown fields are possible for
1846        -: 1841:       * forward compatibility. */
1847    #####: 1842:      continue;
1848        -: 1843:    }
1849    #####: 1844:    smartlist_add(desc_enc->intro_points, ip);
1850    #####: 1845:  } SMARTLIST_FOREACH_END(intro_point);
1851        -: 1846:
1852        -: 1847: done:
1853       30: 1848:  SMARTLIST_FOREACH(chunked_desc, char *, a, tor_free(a));
1854        5: 1849:  smartlist_free(chunked_desc);
1855       10: 1850:  SMARTLIST_FOREACH(intro_points, char *, a, tor_free(a));
1856        5: 1851:  smartlist_free(intro_points);
1857        5: 1852:}
1858        -: 1853:/* Return 1 iff the given base64 encoded signature in b64_sig from the encoded
1859        -: 1854: * descriptor in encoded_desc validates the descriptor content. */
1860        -: 1855:STATIC int
1861        -: 1856:desc_sig_is_valid(const char *b64_sig,
1862        -: 1857:                  const ed25519_public_key_t *signing_pubkey,
1863        -: 1858:                  const char *encoded_desc, size_t encoded_len)
1864        -: 1859:{
1865        -: 1860:  int ret = 0;
1866       56: 1861:  ed25519_signature_t sig;
1867        -: 1862:  const char *sig_start;
1868        -: 1863:
1869       28: 1864:  tor_assert(b64_sig);
1870       28: 1865:  tor_assert(signing_pubkey);
1871       28: 1866:  tor_assert(encoded_desc);
1872        -: 1867:  /* Verifying nothing won't end well :). */
1873       28: 1868:  tor_assert(encoded_len > 0);
1874        -: 1869:
1875        -: 1870:  /* Signature length check. */
1876       28: 1871:  if (strlen(b64_sig) != ED25519_SIG_BASE64_LEN) {
1877        1: 1872:    log_warn(LD_REND, "Service descriptor has an invalid signature length."
1878        -: 1873:                      "Exptected %d but got %lu",
1879        -: 1874:             ED25519_SIG_BASE64_LEN, (unsigned long) strlen(b64_sig));
1880        1: 1875:    goto err;
1881        -: 1876:  }
1882        -: 1877:
1883        -: 1878:  /* First, convert base64 blob to an ed25519 signature. */
1884       27: 1879:  if (ed25519_signature_from_base64(&sig, b64_sig) != 0) {
1885        1: 1880:    log_warn(LD_REND, "Service descriptor does not contain a valid "
1886        -: 1881:                      "signature");
1887        1: 1882:    goto err;
1888        -: 1883:  }
1889        -: 1884:
1890        -: 1885:  /* Find the start of signature. */
1891       26: 1886:  sig_start = tor_memstr(encoded_desc, encoded_len, "\n" str_signature);
1892        -: 1887:  /* Getting here means the token parsing worked for the signature so if we
1893        -: 1888:   * can't find the start of the signature, we have a code flow issue. */
1894       26: 1889:  if (!sig_start) {
1895    #####: 1890:    log_warn(LD_GENERAL, "Malformed signature line. Rejecting.");
1896    #####: 1891:    goto err;
1897        -: 1892:  }
1898        -: 1893:  /* Skip newline, it has to go in the signature check. */
1899       26: 1894:  sig_start++;
1900        -: 1895:
1901        -: 1896:  /* Validate signature with the full body of the descriptor. */
1902       52: 1897:  if (ed25519_checksig_prefixed(&sig,
1903        -: 1898:                                (const uint8_t *) encoded_desc,
1904       26: 1899:                                sig_start - encoded_desc,
1905        -: 1900:                                str_desc_sig_prefix,
1906       26: 1901:                                signing_pubkey) != 0) {
1907    #####: 1902:    log_warn(LD_REND, "Invalid signature on service descriptor");
1908    #####: 1903:    goto err;
1909        -: 1904:  }
1910        -: 1905:  /* Valid signature! All is good. */
1911       26: 1906:  ret = 1;
1912        -: 1907:
1913        -: 1908: err:
1914       28: 1909:  return ret;
1915       28: 1910:}
1916        -: 1911:
1917        -: 1912:/* Decode descriptor plaintext data for version 3. Given a list of tokens, an
1918        -: 1913: * allocated plaintext object that will be populated and the encoded
1919        -: 1914: * descriptor with its length. The last one is needed for signature
1920        -: 1915: * verification. Unknown tokens are simply ignored so this won't error on
1921        -: 1916: * unknowns but requires that all v3 token be present and valid.
1922        -: 1917: *
1923        -: 1918: * Return 0 on success else a negative value. */
1924        -: 1919:static int
1925        -: 1920:desc_decode_plaintext_v3(smartlist_t *tokens,
1926        -: 1921:                         hs_desc_plaintext_data_t *desc,
1927        -: 1922:                         const char *encoded_desc, size_t encoded_len)
1928        -: 1923:{
1929      154: 1924:  int ok;
1930        -: 1925:  directory_token_t *tok;
1931        -: 1926:
1932       77: 1927:  tor_assert(tokens);
1933       77: 1928:  tor_assert(desc);
1934        -: 1929:  /* Version higher could still use this function to decode most of the
1935        -: 1930:   * descriptor and then they decode the extra part. */
1936       77: 1931:  tor_assert(desc->version >= 3);
1937        -: 1932:
1938        -: 1933:  /* Descriptor lifetime parsing. */
1939       77: 1934:  tok = find_by_keyword(tokens, R3_DESC_LIFETIME);
1940       77: 1935:  tor_assert(tok->n_args == 1);
1941       77: 1936:  desc->lifetime_sec = (uint32_t) tor_parse_ulong(tok->args[0], 10, 0,
1942        -: 1937:                                                  UINT32_MAX, &ok, NULL);
1943       77: 1938:  if (!ok) {
1944        3: 1939:    log_warn(LD_REND, "Service descriptor lifetime value is invalid");
1945        3: 1940:    goto err;
1946        -: 1941:  }
1947        -: 1942:  /* Put it from minute to second. */
1948       74: 1943:  desc->lifetime_sec *= 60;
1949       74: 1944:  if (desc->lifetime_sec > HS_DESC_MAX_LIFETIME) {
1950        2: 1945:    log_warn(LD_REND, "Service descriptor lifetime is too big. "
1951        -: 1946:                      "Got %" PRIu32 " but max is %d",
1952        -: 1947:             desc->lifetime_sec, HS_DESC_MAX_LIFETIME);
1953        2: 1948:    goto err;
1954        -: 1949:  }
1955        -: 1950:
1956        -: 1951:  /* Descriptor signing certificate. */
1957       72: 1952:  tok = find_by_keyword(tokens, R3_DESC_SIGNING_CERT);
1958       72: 1953:  tor_assert(tok->object_body);
1959        -: 1954:  /* Expecting a prop220 cert with the signing key extension, which contains
1960        -: 1955:   * the blinded public key. */
1961       72: 1956:  if (strcmp(tok->object_type, "ED25519 CERT") != 0) {
1962        1: 1957:    log_warn(LD_REND, "Service descriptor signing cert wrong type (%s)",
1963        -: 1958:             escaped(tok->object_type));
1964        1: 1959:    goto err;
1965        -: 1960:  }
1966      213: 1961:  if (cert_parse_and_validate(&desc->signing_key_cert, tok->object_body,
1967       71: 1962:                              tok->object_size, CERT_TYPE_SIGNING_HS_DESC,
1968       71: 1963:                              "service descriptor signing key") < 0) {
1969        -: 1964:    goto err;
1970        -: 1965:  }
1971        -: 1966:
1972        -: 1967:  /* Copy the public keys into signing_pubkey and blinded_pubkey */
1973       33: 1968:  memcpy(&desc->signing_pubkey, &desc->signing_key_cert->signed_key,
1974        -: 1969:         sizeof(ed25519_public_key_t));
1975       33: 1970:  memcpy(&desc->blinded_pubkey, &desc->signing_key_cert->signing_key,
1976        -: 1971:         sizeof(ed25519_public_key_t));
1977        -: 1972:
1978        -: 1973:  /* Extract revision counter value. */
1979       33: 1974:  tok = find_by_keyword(tokens, R3_REVISION_COUNTER);
1980       33: 1975:  tor_assert(tok->n_args == 1);
1981       33: 1976:  desc->revision_counter = tor_parse_uint64(tok->args[0], 10, 0,
1982        -: 1977:                                            UINT64_MAX, &ok, NULL);
1983       33: 1978:  if (!ok) {
1984        3: 1979:    log_warn(LD_REND, "Service descriptor revision-counter is invalid");
1985        3: 1980:    goto err;
1986        -: 1981:  }
1987        -: 1982:
1988        -: 1983:  /* Extract the encrypted data section. */
1989       30: 1984:  tok = find_by_keyword(tokens, R3_SUPERENCRYPTED);
1990       30: 1985:  tor_assert(tok->object_body);
1991       30: 1986:  if (strcmp(tok->object_type, "MESSAGE") != 0) {
1992        1: 1987:    log_warn(LD_REND, "Service descriptor encrypted data section is invalid");
1993        1: 1988:    goto err;
1994        -: 1989:  }
1995        -: 1990:  /* Make sure the length of the encrypted blob is valid. */
1996       29: 1991:  if (!encrypted_data_length_is_valid(tok->object_size)) {
1997        -: 1992:    goto err;
1998        -: 1993:  }
1999        -: 1994:
2000        -: 1995:  /* Copy the encrypted blob to the descriptor object so we can handle it
2001        -: 1996:   * latter if needed. */
2002       28: 1997:  desc->superencrypted_blob = tor_memdup(tok->object_body, tok->object_size);
2003       28: 1998:  desc->superencrypted_blob_size = tok->object_size;
2004        -: 1999:
2005        -: 2000:  /* Extract signature and verify it. */
2006       28: 2001:  tok = find_by_keyword(tokens, R3_SIGNATURE);
2007       28: 2002:  tor_assert(tok->n_args == 1);
2008        -: 2003:  /* First arg here is the actual encoded signature. */
2009       28: 2004:  if (!desc_sig_is_valid(tok->args[0], &desc->signing_pubkey,
2010        -: 2005:                         encoded_desc, encoded_len)) {
2011        -: 2006:    goto err;
2012        -: 2007:  }
2013        -: 2008:
2014       26: 2009:  return 0;
2015        -: 2010:
2016        -: 2011: err:
2017       51: 2012:  return -1;
2018       77: 2013:}
2019        -: 2014:
2020        -: 2015:/* Decode the version 3 encrypted section of the given descriptor desc. The
2021        -: 2016: * desc_encrypted_out will be populated with the decoded data. Return 0 on
2022        -: 2017: * success else -1. */
2023        -: 2018:static int
2024        -: 2019:desc_decode_encrypted_v3(const hs_descriptor_t *desc,
2025        -: 2020:                         hs_desc_encrypted_data_t *desc_encrypted_out)
2026        -: 2021:{
2027        -: 2022:  int result = -1;
2028       52: 2023:  char *message = NULL;
2029        -: 2024:  size_t message_len;
2030        -: 2025:  memarea_t *area = NULL;
2031        -: 2026:  directory_token_t *tok;
2032        -: 2027:  smartlist_t *tokens = NULL;
2033        -: 2028:
2034       26: 2029:  tor_assert(desc);
2035       26: 2030:  tor_assert(desc_encrypted_out);
2036        -: 2031:
2037        -: 2032:  /* Decrypt the superencrypted data that is located in the plaintext section
2038        -: 2033:   * in the descriptor as a blob of bytes. */
2039       26: 2034:  message_len = desc_decrypt_all(desc, &message);
2040       26: 2035:  if (!message_len) {
2041       17: 2036:    log_warn(LD_REND, "Service descriptor decryption failed.");
2042       17: 2037:    goto err;
2043        -: 2038:  }
2044        9: 2039:  tor_assert(message);
2045        -: 2040:
2046        9: 2041:  area = memarea_new();
2047        9: 2042:  tokens = smartlist_new();
2048       18: 2043:  if (tokenize_string(area, message, message + message_len,
2049        9: 2044:                      tokens, hs_desc_encrypted_v3_token_table, 0) < 0) {
2050        1: 2045:    log_warn(LD_REND, "Encrypted service descriptor is not parseable.");
2051        1: 2046:    goto err;
2052        -: 2047:  }
2053        -: 2048:
2054        -: 2049:  /* CREATE2 supported cell format. It's mandatory. */
2055        8: 2050:  tok = find_by_keyword(tokens, R3_CREATE2_FORMATS);
2056        8: 2051:  tor_assert(tok);
2057        8: 2052:  decode_create2_list(desc_encrypted_out, tok->args[0]);
2058        -: 2053:  /* Must support ntor according to the specification */
2059        8: 2054:  if (!desc_encrypted_out->create2_ntor) {
2060        3: 2055:    log_warn(LD_REND, "Service create2-formats does not include ntor.");
2061        3: 2056:    goto err;
2062        -: 2057:  }
2063        -: 2058:
2064        -: 2059:  /* Authentication type. It's optional but only once. */
2065        5: 2060:  tok = find_opt_by_keyword(tokens, R3_INTRO_AUTH_REQUIRED);
2066        5: 2061:  if (tok) {
2067    #####: 2062:    if (!decode_auth_type(desc_encrypted_out, tok->args[0])) {
2068    #####: 2063:      log_warn(LD_REND, "Service descriptor authentication type has "
2069        -: 2064:                        "invalid entry(ies).");
2070    #####: 2065:      goto err;
2071        -: 2066:    }
2072        -: 2067:  }
2073        -: 2068:
2074        -: 2069:  /* Is this service a single onion service? */
2075        5: 2070:  tok = find_opt_by_keyword(tokens, R3_SINGLE_ONION_SERVICE);
2076        5: 2071:  if (tok) {
2077    #####: 2072:    desc_encrypted_out->single_onion_service = 1;
2078    #####: 2073:  }
2079        -: 2074:
2080        -: 2075:  /* Initialize the descriptor's introduction point list before we start
2081        -: 2076:   * decoding. Having 0 intro point is valid. Then decode them all. */
2082        5: 2077:  desc_encrypted_out->intro_points = smartlist_new();
2083        5: 2078:  decode_intro_points(desc, desc_encrypted_out, message);
2084        -: 2079:
2085        -: 2080:  /* Validation of maximum introduction points allowed. */
2086        5: 2081:  if (smartlist_len(desc_encrypted_out->intro_points) >
2087        -: 2082:      HS_CONFIG_V3_MAX_INTRO_POINTS) {
2088    #####: 2083:    log_warn(LD_REND, "Service descriptor contains too many introduction "
2089        -: 2084:                      "points. Maximum allowed is %d but we have %d",
2090        -: 2085:             HS_CONFIG_V3_MAX_INTRO_POINTS,
2091        -: 2086:             smartlist_len(desc_encrypted_out->intro_points));
2092    #####: 2087:    goto err;
2093        -: 2088:  }
2094        -: 2089:
2095        -: 2090:  /* NOTE: Unknown fields are allowed because this function could be used to
2096        -: 2091:   * decode other descriptor version. */
2097        -: 2092:
2098        -: 2093:  result = 0;
2099        5: 2094:  goto done;
2100        -: 2095:
2101        -: 2096: err:
2102       21: 2097:  tor_assert(result < 0);
2103       21: 2098:  desc_encrypted_data_free_contents(desc_encrypted_out);
2104        -: 2099:
2105        -: 2100: done:
2106       26: 2101:  if (tokens) {
2107       38: 2102:    SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
2108        9: 2103:    smartlist_free(tokens);
2109        9: 2104:  }
2110       26: 2105:  if (area) {
2111        9: 2106:    memarea_drop_all(area);
2112        9: 2107:  }
2113       26: 2108:  if (message) {
2114       18: 2109:    tor_free(message);
2115        -: 2110:  }
2116       26: 2111:  return result;
2117       26: 2112:}
2118        -: 2113:
2119        -: 2114:/* Table of encrypted decode function version specific. The function are
2120        -: 2115: * indexed by the version number so v3 callback is at index 3 in the array. */
2121        -: 2116:static int
2122        -: 2117:  (*decode_encrypted_handlers[])(
2123        -: 2118:      const hs_descriptor_t *desc,
2124        -: 2119:      hs_desc_encrypted_data_t *desc_encrypted) =
2125        -: 2120:{
2126        -: 2121:  /* v0 */ NULL, /* v1 */ NULL, /* v2 */ NULL,
2127        -: 2122:  desc_decode_encrypted_v3,
2128        -: 2123:};
2129        -: 2124:
2130        -: 2125:/* Decode the encrypted data section of the given descriptor and store the
2131        -: 2126: * data in the given encrypted data object. Return 0 on success else a
2132        -: 2127: * negative value on error. */
2133        -: 2128:int
2134        -: 2129:hs_desc_decode_encrypted(const hs_descriptor_t *desc,
2135        -: 2130:                         hs_desc_encrypted_data_t *desc_encrypted)
2136        -: 2131:{
2137        -: 2132:  int ret;
2138        -: 2133:  uint32_t version;
2139        -: 2134:
2140       52: 2135:  tor_assert(desc);
2141        -: 2136:  /* Ease our life a bit. */
2142       26: 2137:  version = desc->plaintext_data.version;
2143       26: 2138:  tor_assert(desc_encrypted);
2144        -: 2139:  /* Calling this function without an encrypted blob to parse is a code flow
2145        -: 2140:   * error. The plaintext parsing should never succeed in the first place
2146        -: 2141:   * without an encrypted section. */
2147       26: 2142:  tor_assert(desc->plaintext_data.superencrypted_blob);
2148        -: 2143:  /* Let's make sure we have a supported version as well. By correctly parsing
2149        -: 2144:   * the plaintext, this should not fail. */
2150       26: 2145:  if (BUG(!hs_desc_is_supported_version(version))) {
2151        -: 2146:    ret = -1;
2152    #####: 2147:    goto err;
2153        -: 2148:  }
2154        -: 2149:  /* Extra precaution. Having no handler for the supported version should
2155        -: 2150:   * never happened else we forgot to add it but we bumped the version. */
2156       26: 2151:  tor_assert(ARRAY_LENGTH(decode_encrypted_handlers) >= version);
2157       26: 2152:  tor_assert(decode_encrypted_handlers[version]);
2158        -: 2153:
2159        -: 2154:  /* Run the version specific plaintext decoder. */
2160       26: 2155:  ret = decode_encrypted_handlers[version](desc, desc_encrypted);
2161        -: 2156:  if (ret < 0) {
2162       26: 2157:    goto err;
2163        -: 2158:  }
2164        -: 2159:
2165        -: 2160: err:
2166       26: 2161:  return ret;
2167        -: 2162:}
2168        -: 2163:
2169        -: 2164:/* Table of plaintext decode function version specific. The function are
2170        -: 2165: * indexed by the version number so v3 callback is at index 3 in the array. */
2171        -: 2166:static int
2172        -: 2167:  (*decode_plaintext_handlers[])(
2173        -: 2168:      smartlist_t *tokens,
2174        -: 2169:      hs_desc_plaintext_data_t *desc,
2175        -: 2170:      const char *encoded_desc,
2176        -: 2171:      size_t encoded_len) =
2177        -: 2172:{
2178        -: 2173:  /* v0 */ NULL, /* v1 */ NULL, /* v2 */ NULL,
2179        -: 2174:  desc_decode_plaintext_v3,
2180        -: 2175:};
2181        -: 2176:
2182        -: 2177:/* Fully decode the given descriptor plaintext and store the data in the
2183        -: 2178: * plaintext data object. Returns 0 on success else a negative value. */
2184        -: 2179:int
2185        -: 2180:hs_desc_decode_plaintext(const char *encoded,
2186        -: 2181:                         hs_desc_plaintext_data_t *plaintext)
2187        -: 2182:{
2188      594: 2183:  int ok = 0, ret = -1;
2189        -: 2184:  memarea_t *area = NULL;
2190        -: 2185:  smartlist_t *tokens = NULL;
2191        -: 2186:  size_t encoded_len;
2192        -: 2187:  directory_token_t *tok;
2193        -: 2188:
2194      297: 2189:  tor_assert(encoded);
2195      297: 2190:  tor_assert(plaintext);
2196        -: 2191:
2197        -: 2192:  /* Check that descriptor is within size limits. */
2198      297: 2193:  encoded_len = strlen(encoded);
2199      297: 2194:  if (encoded_len >= hs_cache_get_max_descriptor_size()) {
2200    #####: 2195:    log_warn(LD_REND, "Service descriptor is too big (%lu bytes)",
2201        -: 2196:             (unsigned long) encoded_len);
2202    #####: 2197:    goto err;
2203        -: 2198:  }
2204        -: 2199:
2205      297: 2200:  area = memarea_new();
2206      297: 2201:  tokens = smartlist_new();
2207        -: 2202:  /* Tokenize the descriptor so we can start to parse it. */
2208      594: 2203:  if (tokenize_string(area, encoded, encoded + encoded_len, tokens,
2209      297: 2204:                      hs_desc_v3_token_table, 0) < 0) {
2210      181: 2205:    log_warn(LD_REND, "Service descriptor is not parseable");
2211      181: 2206:    goto err;
2212        -: 2207:  }
2213        -: 2208:
2214        -: 2209:  /* Get the version of the descriptor which is the first mandatory field of
2215        -: 2210:   * the descriptor. From there, we'll decode the right descriptor version. */
2216      116: 2211:  tok = find_by_keyword(tokens, R_HS_DESCRIPTOR);
2217      116: 2212:  tor_assert(tok->n_args == 1);
2218      116: 2213:  plaintext->version = (uint32_t) tor_parse_ulong(tok->args[0], 10, 0,
2219        -: 2214:                                                  UINT32_MAX, &ok, NULL);
2220      116: 2215:  if (!ok) {
2221       37: 2216:    log_warn(LD_REND, "Service descriptor has unparseable version %s",
2222        -: 2217:             escaped(tok->args[0]));
2223       37: 2218:    goto err;
2224        -: 2219:  }
2225       79: 2220:  if (!hs_desc_is_supported_version(plaintext->version)) {
2226        2: 2221:    log_warn(LD_REND, "Service descriptor has unsupported version %" PRIu32,
2227        -: 2222:             plaintext->version);
2228        2: 2223:    goto err;
2229        -: 2224:  }
2230        -: 2225:  /* Extra precaution. Having no handler for the supported version should
2231        -: 2226:   * never happened else we forgot to add it but we bumped the version. */
2232       77: 2227:  tor_assert(ARRAY_LENGTH(decode_plaintext_handlers) >= plaintext->version);
2233       77: 2228:  tor_assert(decode_plaintext_handlers[plaintext->version]);
2234        -: 2229:
2235        -: 2230:  /* Run the version specific plaintext decoder. */
2236       77: 2231:  ret = decode_plaintext_handlers[plaintext->version](tokens, plaintext,
2237        -: 2232:                                                      encoded, encoded_len);
2238       77: 2233:  if (ret < 0) {
2239        -: 2234:    goto err;
2240        -: 2235:  }
2241        -: 2236:  /* Success. Descriptor has been populated with the data. */
2242        -: 2237:  ret = 0;
2243        -: 2238:
2244        -: 2239: err:
2245      297: 2240:  if (tokens) {
2246    23012: 2241:    SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
2247      297: 2242:    smartlist_free(tokens);
2248      297: 2243:  }
2249      297: 2244:  if (area) {
2250      297: 2245:    memarea_drop_all(area);
2251      297: 2246:  }
2252      297: 2247:  return ret;
2253      297: 2248:}
2254        -: 2249:
2255        -: 2250:/* Fully decode an encoded descriptor and set a newly allocated descriptor
2256        -: 2251: * object in desc_out. Subcredentials are used if not NULL else it's ignored.
2257        -: 2252: *
2258        -: 2253: * Return 0 on success. A negative value is returned on error and desc_out is
2259        -: 2254: * set to NULL. */
2260        -: 2255:int
2261        -: 2256:hs_desc_decode_descriptor(const char *encoded,
2262        -: 2257:                          const uint8_t *subcredential,
2263        -: 2258:                          hs_descriptor_t **desc_out)
2264        -: 2259:{
2265        -: 2260:  int ret = -1;
2266        -: 2261:  hs_descriptor_t *desc;
2267        -: 2262:
2268      594: 2263:  tor_assert(encoded);
2269        -: 2264:
2270      297: 2265:  desc = tor_malloc_zero(sizeof(hs_descriptor_t));
2271        -: 2266:
2272        -: 2267:  /* Subcredentials are optional. */
2273      297: 2268:  if (BUG(!subcredential)) {
2274    #####: 2269:    log_warn(LD_GENERAL, "Tried to decrypt without subcred. Impossible!");
2275    #####: 2270:    goto err;
2276        -: 2271:  }
2277        -: 2272:
2278      297: 2273:  memcpy(desc->subcredential, subcredential, sizeof(desc->subcredential));
2279        -: 2274:
2280      297: 2275:  ret = hs_desc_decode_plaintext(encoded, &desc->plaintext_data);
2281      297: 2276:  if (ret < 0) {
2282        -: 2277:    goto err;
2283        -: 2278:  }
2284        -: 2279:
2285       26: 2280:  ret = hs_desc_decode_encrypted(desc, &desc->encrypted_data);
2286       26: 2281:  if (ret < 0) {
2287        -: 2282:    goto err;
2288        -: 2283:  }
2289        -: 2284:
2290        5: 2285:  if (desc_out) {
2291        5: 2286:    *desc_out = desc;
2292        5: 2287:  } else {
2293    #####: 2288:    hs_descriptor_free(desc);
2294        -: 2289:  }
2295        5: 2290:  return ret;
2296        -: 2291:
2297        -: 2292: err:
2298      292: 2293:  hs_descriptor_free(desc);
2299      292: 2294:  if (desc_out) {
2300      292: 2295:    *desc_out = NULL;
2301      292: 2296:  }
2302        -: 2297:
2303      292: 2298:  tor_assert(ret < 0);
2304      292: 2299:  return ret;
2305      297: 2300:}
2306        -: 2301:
2307        -: 2302:/* Table of encode function version specific. The functions are indexed by the
2308        -: 2303: * version number so v3 callback is at index 3 in the array. */
2309        -: 2304:static int
2310        -: 2305:  (*encode_handlers[])(
2311        -: 2306:      const hs_descriptor_t *desc,
2312        -: 2307:      const ed25519_keypair_t *signing_kp,
2313        -: 2308:      char **encoded_out) =
2314        -: 2309:{
2315        -: 2310:  /* v0 */ NULL, /* v1 */ NULL, /* v2 */ NULL,
2316        -: 2311:  desc_encode_v3,
2317        -: 2312:};
2318        -: 2313:
2319        -: 2314:/* Encode the given descriptor desc including signing with the given key pair
2320        -: 2315: * signing_kp. On success, encoded_out points to a newly allocated NUL
2321        -: 2316: * terminated string that contains the encoded descriptor as a string.
2322        -: 2317: *
2323        -: 2318: * Return 0 on success and encoded_out is a valid pointer. On error, -1 is
2324        -: 2319: * returned and encoded_out is set to NULL. */
2325        -: 2320:MOCK_IMPL(int,
2326        -: 2321:hs_desc_encode_descriptor,(const hs_descriptor_t *desc,
2327        -: 2322:                           const ed25519_keypair_t *signing_kp,
2328        -: 2323:                           char **encoded_out))
2329        -: 2324:{
2330        -: 2325:  int ret = -1;
2331        -: 2326:  uint32_t version;
2332        -: 2327:
2333    #####: 2328:  tor_assert(desc);
2334    #####: 2329:  tor_assert(encoded_out);
2335        -: 2330:
2336        -: 2331:  /* Make sure we support the version of the descriptor format. */
2337    #####: 2332:  version = desc->plaintext_data.version;
2338    #####: 2333:  if (!hs_desc_is_supported_version(version)) {
2339        -: 2334:    goto err;
2340        -: 2335:  }
2341        -: 2336:  /* Extra precaution. Having no handler for the supported version should
2342        -: 2337:   * never happened else we forgot to add it but we bumped the version. */
2343    #####: 2338:  tor_assert(ARRAY_LENGTH(encode_handlers) >= version);
2344    #####: 2339:  tor_assert(encode_handlers[version]);
2345        -: 2340:
2346    #####: 2341:  ret = encode_handlers[version](desc, signing_kp, encoded_out);
2347    #####: 2342:  if (ret < 0) {
2348        -: 2343:    goto err;
2349        -: 2344:  }
2350        -: 2345:
2351        -: 2346:  /* Try to decode what we just encoded. Symmetry is nice! */
2352    #####: 2347:  ret = hs_desc_decode_descriptor(*encoded_out, desc->subcredential, NULL);
2353    #####: 2348:  if (BUG(ret < 0)) {
2354    #####: 2349:    goto err;
2355        -: 2350:  }
2356        -: 2351:
2357    #####: 2352:  return 0;
2358        -: 2353:
2359        -: 2354: err:
2360    #####: 2355:  *encoded_out = NULL;
2361    #####: 2356:  return ret;
2362    #####: 2357:}
2363        -: 2358:
2364        -: 2359:/* Free the descriptor plaintext data object. */
2365        -: 2360:void
2366        -: 2361:hs_desc_plaintext_data_free(hs_desc_plaintext_data_t *desc)
2367        -: 2362:{
2368    #####: 2363:  desc_plaintext_data_free_contents(desc);
2369    #####: 2364:  tor_free(desc);
2370    #####: 2365:}
2371        -: 2366:
2372        -: 2367:/* Free the descriptor encrypted data object. */
2373        -: 2368:void
2374        -: 2369:hs_desc_encrypted_data_free(hs_desc_encrypted_data_t *desc)
2375        -: 2370:{
2376    #####: 2371:  desc_encrypted_data_free_contents(desc);
2377    #####: 2372:  tor_free(desc);
2378    #####: 2373:}
2379        -: 2374:
2380        -: 2375:/* Free the given descriptor object. */
2381        -: 2376:void
2382        -: 2377:hs_descriptor_free(hs_descriptor_t *desc)
2383        -: 2378:{
2384      594: 2379:  if (!desc) {
2385        -: 2380:    return;
2386        -: 2381:  }
2387        -: 2382:
2388      297: 2383:  desc_plaintext_data_free_contents(&desc->plaintext_data);
2389      297: 2384:  desc_encrypted_data_free_contents(&desc->encrypted_data);
2390      594: 2385:  tor_free(desc);
2391      297: 2386:}
2392        -: 2387:
2393        -: 2388:/* Return the size in bytes of the given plaintext data object. A sizeof() is
2394        -: 2389: * not enough because the object contains pointers and the encrypted blob.
2395        -: 2390: * This is particularly useful for our OOM subsystem that tracks the HSDir
2396        -: 2391: * cache size for instance. */
2397        -: 2392:size_t
2398        -: 2393:hs_desc_plaintext_obj_size(const hs_desc_plaintext_data_t *data)
2399        -: 2394:{
2400    #####: 2395:  tor_assert(data);
2401    #####: 2396:  return (sizeof(*data) + sizeof(*data->signing_key_cert) +
2402    #####: 2397:          data->superencrypted_blob_size);
2403        -: 2398:}
2404        -: 2399:
2405        -: 2400:/* Return the size in bytes of the given encrypted data object. Used by OOM
2406        -: 2401: * subsystem. */
2407        -: 2402:static size_t
2408        -: 2403:hs_desc_encrypted_obj_size(const hs_desc_encrypted_data_t *data)
2409        -: 2404:{
2410    #####: 2405:  tor_assert(data);
2411        -: 2406:  size_t intro_size = 0;
2412    #####: 2407:  if (data->intro_auth_types) {
2413        -: 2408:    intro_size +=
2414    #####: 2409:      smartlist_len(data->intro_auth_types) * sizeof(intro_auth_types);
2415    #####: 2410:  }
2416    #####: 2411:  if (data->intro_points) {
2417        -: 2412:    /* XXX could follow pointers here and get more accurate size */
2418    #####: 2413:    intro_size +=
2419    #####: 2414:      smartlist_len(data->intro_points) * sizeof(hs_desc_intro_point_t);
2420    #####: 2415:  }
2421        -: 2416:
2422    #####: 2417:  return sizeof(*data) + intro_size;
2423        -: 2418:}
2424        -: 2419:
2425        -: 2420:/* Return the size in bytes of the given descriptor object. Used by OOM
2426        -: 2421: * subsystem. */
2427        -: 2422:  size_t
2428        -: 2423:hs_desc_obj_size(const hs_descriptor_t *data)
2429        -: 2424:{
2430    #####: 2425:  tor_assert(data);
2431    #####: 2426:  return (hs_desc_plaintext_obj_size(&data->plaintext_data) +
2432    #####: 2427:          hs_desc_encrypted_obj_size(&data->encrypted_data) +
2433        -: 2428:          sizeof(data->subcredential));
2434        -: 2429:}
2435        -: 2430:
2436        -: 2431:/* Return a newly allocated descriptor intro point. */
2437        -: 2432:hs_desc_intro_point_t *
2438        -: 2433:hs_desc_intro_point_new(void)
2439        -: 2434:{
2440    #####: 2435:  hs_desc_intro_point_t *ip = tor_malloc_zero(sizeof(*ip));
2441    #####: 2436:  ip->link_specifiers = smartlist_new();
2442    #####: 2437:  return ip;
2443        -: 2438:}
2444        -: 2439:
2445        -: 2440:/* Free a descriptor intro point object. */
2446        -: 2441:void
2447        -: 2442:hs_desc_intro_point_free(hs_desc_intro_point_t *ip)
2448        -: 2443:{
2449    #####: 2444:  if (ip == NULL) {
2450        -: 2445:    return;
2451        -: 2446:  }
2452    #####: 2447:  if (ip->link_specifiers) {
2453    #####: 2448:    SMARTLIST_FOREACH(ip->link_specifiers, hs_desc_link_specifier_t *,
2454        -: 2449:                      ls, hs_desc_link_specifier_free(ls));
2455    #####: 2450:    smartlist_free(ip->link_specifiers);
2456    #####: 2451:  }
2457    #####: 2452:  tor_cert_free(ip->auth_key_cert);
2458    #####: 2453:  tor_cert_free(ip->enc_key_cert);
2459    #####: 2454:  crypto_pk_free(ip->legacy.key);
2460    #####: 2455:  tor_free(ip->legacy.cert.encoded);
2461    #####: 2456:  tor_free(ip);
2462    #####: 2457:}
2463        -: 2458:
2464        -: 2459:/* Free the given descriptor link specifier. */
2465        -: 2460:void
2466        -: 2461:hs_desc_link_specifier_free(hs_desc_link_specifier_t *ls)
2467        -: 2462:{
2468    #####: 2463:  if (ls == NULL) {
2469        -: 2464:    return;
2470        -: 2465:  }
2471    #####: 2466:  tor_free(ls);
2472    #####: 2467:}
2473        -: 2468:
2474        -: 2469:/* Return a newly allocated descriptor link specifier using the given extend
2475        -: 2470: * info and requested type. Return NULL on error. */
2476        -: 2471:hs_desc_link_specifier_t *
2477        -: 2472:hs_desc_link_specifier_new(const extend_info_t *info, uint8_t type)
2478        -: 2473:{
2479        -: 2474:  hs_desc_link_specifier_t *ls = NULL;
2480        -: 2475:
2481    #####: 2476:  tor_assert(info);
2482        -: 2477:
2483    #####: 2478:  ls = tor_malloc_zero(sizeof(*ls));
2484    #####: 2479:  ls->type = type;
2485    #####: 2480:  switch (ls->type) {
2486        -: 2481:  case LS_IPV4:
2487    #####: 2482:    if (info->addr.family != AF_INET) {
2488        -: 2483:      goto err;
2489        -: 2484:    }
2490    #####: 2485:    tor_addr_copy(&ls->u.ap.addr, &info->addr);
2491    #####: 2486:    ls->u.ap.port = info->port;
2492    #####: 2487:    break;
2493        -: 2488:  case LS_IPV6:
2494    #####: 2489:    if (info->addr.family != AF_INET6) {
2495        -: 2490:      goto err;
2496        -: 2491:    }
2497    #####: 2492:    tor_addr_copy(&ls->u.ap.addr, &info->addr);
2498    #####: 2493:    ls->u.ap.port = info->port;
2499    #####: 2494:    break;
2500        -: 2495:  case LS_LEGACY_ID:
2501        -: 2496:    /* Bug out if the identity digest is not set */
2502    #####: 2497:    if (BUG(tor_mem_is_zero(info->identity_digest,
2503        -: 2498:                            sizeof(info->identity_digest)))) {
2504    #####: 2499:      goto err;
2505        -: 2500:    }
2506    #####: 2501:    memcpy(ls->u.legacy_id, info->identity_digest, sizeof(ls->u.legacy_id));
2507    #####: 2502:    break;
2508        -: 2503:  case LS_ED25519_ID:
2509        -: 2504:    /* ed25519 keys are optional for intro points */
2510    #####: 2505:    if (ed25519_public_key_is_zero(&info->ed_identity)) {
2511        -: 2506:      goto err;
2512        -: 2507:    }
2513    #####: 2508:    memcpy(ls->u.ed25519_id, info->ed_identity.pubkey,
2514        -: 2509:           sizeof(ls->u.ed25519_id));
2515    #####: 2510:    break;
2516        -: 2511:  default:
2517        -: 2512:    /* Unknown type is code flow error. */
2518    #####: 2513:    tor_assert(0);
2519        -: 2514:  }
2520        -: 2515:
2521    #####: 2516:  return ls;
2522        -: 2517: err:
2523    #####: 2518:  tor_free(ls);
2524    #####: 2519:  return NULL;
2525    #####: 2520:}
2526        -: 2521:
2527        -: 2522:/* From the given descriptor, remove and free every introduction point. */
2528        -: 2523:void
2529        -: 2524:hs_descriptor_clear_intro_points(hs_descriptor_t *desc)
2530        -: 2525:{
2531        -: 2526:  smartlist_t *ips;
2532        -: 2527:
2533    #####: 2528:  tor_assert(desc);
2534        -: 2529:
2535    #####: 2530:  ips = desc->encrypted_data.intro_points;
2536    #####: 2531:  if (ips) {
2537    #####: 2532:    SMARTLIST_FOREACH(ips, hs_desc_intro_point_t *,
2538        -: 2533:                      ip, hs_desc_intro_point_free(ip));
2539    #####: 2534:    smartlist_clear(ips);
2540    #####: 2535:  }
2541    #####: 2536:}
2542        -: 2537:
2543        -: 2538:/* From a descriptor link specifier object spec, returned a newly allocated
2544        -: 2539: * link specifier object that is the encoded representation of spec. Return
2545        -: 2540: * NULL on error. */
2546        -: 2541:link_specifier_t *
2547        -: 2542:hs_desc_lspec_to_trunnel(const hs_desc_link_specifier_t *spec)
2548        -: 2543:{
2549    #####: 2544:  tor_assert(spec);
2550        -: 2545:
2551    #####: 2546:  link_specifier_t *ls = link_specifier_new();
2552    #####: 2547:  link_specifier_set_ls_type(ls, spec->type);
2553        -: 2548:
2554    #####: 2549:  switch (spec->type) {
2555        -: 2550:  case LS_IPV4:
2556    #####: 2551:    link_specifier_set_un_ipv4_addr(ls,
2557    #####: 2552:                                    tor_addr_to_ipv4h(&spec->u.ap.addr));
2558    #####: 2553:    link_specifier_set_un_ipv4_port(ls, spec->u.ap.port);
2559        -: 2554:    /* Four bytes IPv4 and two bytes port. */
2560    #####: 2555:    link_specifier_set_ls_len(ls, sizeof(spec->u.ap.addr.addr.in_addr) +
2561        -: 2556:                                  sizeof(spec->u.ap.port));
2562    #####: 2557:    break;
2563        -: 2558:  case LS_IPV6:
2564        -: 2559:  {
2565    #####: 2560:    size_t addr_len = link_specifier_getlen_un_ipv6_addr(ls);
2566    #####: 2561:    const uint8_t *in6_addr = tor_addr_to_in6_addr8(&spec->u.ap.addr);
2567    #####: 2562:    uint8_t *ipv6_array = link_specifier_getarray_un_ipv6_addr(ls);
2568    #####: 2563:    memcpy(ipv6_array, in6_addr, addr_len);
2569    #####: 2564:    link_specifier_set_un_ipv6_port(ls, spec->u.ap.port);
2570        -: 2565:    /* Sixteen bytes IPv6 and two bytes port. */
2571    #####: 2566:    link_specifier_set_ls_len(ls, addr_len + sizeof(spec->u.ap.port));
2572        -: 2567:    break;
2573        -: 2568:  }
2574        -: 2569:  case LS_LEGACY_ID:
2575        -: 2570:  {
2576    #####: 2571:    size_t legacy_id_len = link_specifier_getlen_un_legacy_id(ls);
2577    #####: 2572:    uint8_t *legacy_id_array = link_specifier_getarray_un_legacy_id(ls);
2578    #####: 2573:    memcpy(legacy_id_array, spec->u.legacy_id, legacy_id_len);
2579    #####: 2574:    link_specifier_set_ls_len(ls, legacy_id_len);
2580        -: 2575:    break;
2581        -: 2576:  }
2582        -: 2577:  case LS_ED25519_ID:
2583        -: 2578:  {
2584    #####: 2579:    size_t ed25519_id_len = link_specifier_getlen_un_ed25519_id(ls);
2585    #####: 2580:    uint8_t *ed25519_id_array = link_specifier_getarray_un_ed25519_id(ls);
2586    #####: 2581:    memcpy(ed25519_id_array, spec->u.ed25519_id, ed25519_id_len);
2587    #####: 2582:    link_specifier_set_ls_len(ls, ed25519_id_len);
2588        -: 2583:    break;
2589        -: 2584:  }
2590        -: 2585:  default:
2591    #####: 2586:    tor_assert_nonfatal_unreached();
2592    #####: 2587:    link_specifier_free(ls);
2593        -: 2588:    ls = NULL;
2594    #####: 2589:  }
2595        -: 2590:
2596    #####: 2591:  return ls;
2597        -: 2592:}
2598        -: 2593: