commit 1b52e95028e0d84b7a112e4b8f2e393261dbb19c Merge: 0989ba3 5eb584e Author: Nick Mathewson nickm@torproject.org Date: Thu May 28 11:04:33 2015 -0400
Merge branch '12498_ed25519_keys_v6'
Fixed numerous conflicts, and ported code to use new base64 api.
doc/tor.1.txt | 24 + scripts/codegen/makedesc.py | 355 ++++--- scripts/codegen/run_trunnel.sh | 4 +- src/common/container.c | 13 + src/common/container.h | 1 + src/common/crypto.c | 102 +- src/common/crypto.h | 20 +- src/common/crypto_ed25519.c | 21 + src/common/crypto_ed25519.h | 19 +- src/common/crypto_format.c | 39 + src/common/tortls.c | 76 +- src/common/tortls.h | 29 +- src/or/channel.c | 8 +- src/or/channel.h | 5 +- src/or/channeltls.c | 161 ++- src/or/channeltls.h | 10 + src/or/config.c | 20 + src/or/config.h | 4 + src/or/connection_or.c | 180 ++-- src/or/connection_or.h | 12 +- src/or/dircollate.c | 257 +++++ src/or/dircollate.h | 49 + src/or/dirserv.c | 79 ++ src/or/dirvote.c | 87 +- src/or/dirvote.h | 9 +- src/or/include.am | 20 +- src/or/keypin.c | 419 ++++++++ src/or/keypin.h | 46 + src/or/main.c | 38 +- src/or/microdesc.c | 1 + src/or/or.h | 41 +- src/or/router.c | 242 ++++- src/or/router.h | 8 +- src/or/routerkeys.c | 648 +++++++++++++ src/or/routerkeys.h | 67 ++ src/or/routerlist.c | 27 +- src/or/routerlist.h | 7 +- src/or/routerparse.c | 310 +++++- src/or/routerparse.h | 4 +- src/or/torcert.c | 280 ++++++ src/or/torcert.h | 76 ++ src/test/example_extrainfo.inc | 233 +++++ src/test/failing_routerdescs.inc | 901 +++++++++++++++++ src/test/include.am | 6 +- src/test/test.c | 4 + src/test/test_containers.c | 38 + src/test/test_crypto.c | 20 +- src/test/test_dir.c | 133 ++- src/test/test_keypin.c | 255 +++++ src/test/test_link_handshake.c | 914 +++++++++++++++++ src/test/test_microdesc.c | 93 ++ src/test/test_routerkeys.c | 540 ++++++++++- src/trunnel/ed25519_cert.c | 887 +++++++++++++++++ src/trunnel/ed25519_cert.h | 288 ++++++ src/trunnel/ed25519_cert.trunnel | 76 ++ src/trunnel/include.am | 21 +- src/trunnel/link_handshake.c | 1885 ++++++++++++++++++++++++++++++++++++ src/trunnel/link_handshake.h | 654 +++++++++++++ src/trunnel/link_handshake.trunnel | 57 ++ 59 files changed, 10365 insertions(+), 458 deletions(-)
diff --cc src/common/crypto.c index fcd862f,2ccff80..d77d5e2 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@@ -2588,93 -2711,76 +2607,152 @@@ base64_encode(char *dest, size_t destle return -1; if (destlen > SIZE_T_CEILING) return -1; - if (destlen) - *dest = 0; /* Ensure we always initialize the buffer */ - - EVP_EncodeInit(&ctx); - EVP_EncodeUpdate(&ctx, (unsigned char*)dest, &len, - (unsigned char*)src, (int)srclen); - EVP_EncodeFinal(&ctx, (unsigned char*)(dest+len), &ret); - ret += len; - return ret; + if (enclen > INT_MAX) + return -1; + + memset(dest, 0, enclen); + + /* XXX/Yawning: If this ends up being too slow, this can be sped up + * by separating the multiline format case and the normal case, and + * processing 48 bytes of input at a time when newlines are desired. + */ +#define ENCODE_CHAR(ch) \ + STMT_BEGIN \ + *d++ = ch; \ + if (flags & BASE64_ENCODE_MULTILINE) { \ + if (++linelen % BASE64_OPENSSL_LINELEN == 0) { \ + linelen = 0; \ + *d++ = '\n'; \ + } \ + } \ + STMT_END + +#define ENCODE_N(idx) \ + ENCODE_CHAR(base64_encode_table[(n >> ((3 - idx) * 6)) & 0x3f]) + +#define ENCODE_PAD() ENCODE_CHAR('=') + + /* Iterate over all the bytes in src. Each one will add 8 bits to the + * value we're encoding. Accumulate bits in <b>n</b>, and whenever we + * have 24 bits, batch them into 4 bytes and flush those bytes to dest. + */ + for ( ; usrc < eous; ++usrc) { + n = (n << 8) | *usrc; + if ((++n_idx) == 3) { + ENCODE_N(0); + ENCODE_N(1); + ENCODE_N(2); + ENCODE_N(3); + n_idx = 0; + n = 0; + } + } + switch (n_idx) { + case 0: + /* 0 leftover bits, no pading to add. */ + break; + case 1: + /* 8 leftover bits, pad to 12 bits, write the 2 6-bit values followed + * by 2 padding characters. + */ + n <<= 4; + ENCODE_N(2); + ENCODE_N(3); + ENCODE_PAD(); + ENCODE_PAD(); + break; + case 2: + /* 16 leftover bits, pad to 18 bits, write the 3 6-bit values followed + * by 1 padding character. + */ + n <<= 2; + ENCODE_N(1); + ENCODE_N(2); + ENCODE_N(3); + ENCODE_PAD(); + break; + default: + /* Something went catastrophically wrong. */ + tor_fragile_assert(); + return -1; + } + +#undef ENCODE_N +#undef ENCODE_PAD +#undef ENCODE_CHAR + + /* Multiline output always includes at least one newline. */ + if (flags & BASE64_ENCODE_MULTILINE && linelen != 0) + *d++ = '\n'; + + tor_assert(d - dest == (ptrdiff_t)enclen); + + *d++ = '\0'; /* NUL terminate the output. */ + + return (int) enclen; }
+ /** As base64_encode, but do not add any internal spaces or external padding + * to the output stream. */ + int + base64_encode_nopad(char *dest, size_t destlen, + const uint8_t *src, size_t srclen) + { - int n = base64_encode(dest, destlen, (const char*) src, srclen); ++ int n = base64_encode(dest, destlen, (const char*) src, srclen, 0); + if (n <= 0) + return n; + tor_assert((size_t)n < destlen && dest[n] == 0); + char *in, *out; + in = out = dest; + while (*in) { + if (*in == '=' || *in == '\n') { + ++in; + } else { + *out++ = *in++; + } + } + *out = 0; + + tor_assert(out - dest <= INT_MAX); + + return (int)(out - dest); + } + + /** As base64_decode, but do not require any padding on the input */ + int + base64_decode_nopad(uint8_t *dest, size_t destlen, + const char *src, size_t srclen) + { + if (srclen > SIZE_T_CEILING - 4) + return -1; + char *buf = tor_malloc(srclen + 4); + memcpy(buf, src, srclen+1); + size_t buflen; + switch (srclen % 4) + { + case 0: + default: + buflen = srclen; + break; + case 1: + tor_free(buf); + return -1; + case 2: + memcpy(buf+srclen, "==", 3); + buflen = srclen + 2; + break; + case 3: + memcpy(buf+srclen, "=", 2); + buflen = srclen + 1; + break; + } + int n = base64_decode((char*)dest, destlen, buf, buflen); + tor_free(buf); + return n; + } + +#undef BASE64_OPENSSL_LINELEN + /** @{ */ /** Special values used for the base64_decode_table */ #define X 255 @@@ -2795,8 -2922,9 +2873,9 @@@ base64_decode(char *dest, size_t destle #undef PAD
/** Base64 encode DIGEST_LINE bytes from <b>digest</b>, remove the trailing = - * and newline characters, and store the nul-terminated result in the first + * characters, and store the nul-terminated result in the first * BASE64_DIGEST_LEN+1 bytes of <b>d64</b>. */ + /* XXXX unify with crypto_format.c code */ int digest_to_base64(char *d64, const char *digest) { @@@ -2820,8 -2961,10 +2900,9 @@@ digest_from_base64(char *digest, const }
/** Base64 encode DIGEST256_LINE bytes from <b>digest</b>, remove the - * trailing = and newline characters, and store the nul-terminated result in - * the first BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */ -/* XXXX unify with crypto_format.c code */ + * trailing = characters, and store the nul-terminated result in the first - * BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */ ++ * BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */ ++ /* XXXX unify with crypto_format.c code */ int digest256_to_base64(char *d64, const char *digest) { diff --cc src/common/crypto.h index 05572f4,15d1f6e..b953ab9 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@@ -273,11 -273,13 +278,16 @@@ struct smartlist_t void *smartlist_choose(const struct smartlist_t *sl); void smartlist_shuffle(struct smartlist_t *sl);
-int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen); +#define BASE64_ENCODE_MULTILINE 1 +size_t base64_encode_size(size_t srclen, int flags); +int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen, + int flags); int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen); + int base64_encode_nopad(char *dest, size_t destlen, + const uint8_t *src, size_t srclen); + int base64_decode_nopad(uint8_t *dest, size_t destlen, + const char *src, size_t srclen); + /** Characters that can appear (case-insensitively) in a base32 encoding. */ #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); diff --cc src/common/tortls.c index 2b8daaa,e498b2a..098df9d --- a/src/common/tortls.c +++ b/src/common/tortls.c @@@ -116,8 -114,15 +116,8 @@@ #define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0010 #endif
-/** Does the run-time openssl version look like we need - * SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION? */ -static int use_unsafe_renegotiation_op = 0; -/** Does the run-time openssl version look like we need - * SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION? */ -static int use_unsafe_renegotiation_flag = 0; - /** Structure that we use for a single certificate. */ - struct tor_cert_t { + struct tor_x509_cert_t { X509 *cert; uint8_t *encoded; size_t encoded_len; diff --cc src/or/channeltls.c index 1cf697c,0376e74..ecf0218 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@@ -22,8 -24,8 +24,9 @@@ #include "connection.h" #include "connection_or.h" #include "control.h" + #include "link_handshake.h" #include "relay.h" +#include "rephist.h" #include "router.h" #include "routerlist.h" #include "scheduler.h" diff --cc src/or/include.am index 0ce3cdc,9245ade..6bbf788 --- a/src/or/include.am +++ b/src/or/include.am @@@ -77,18 -80,19 +80,14 @@@ LIBTOR_A_SOURCES = src/or/scheduler.c \ src/or/statefile.c \ src/or/status.c \ + src/or/torcert.c \ src/or/onion_ntor.c \ $(evdns_source) \ - $(tor_platform_source) \ - src/or/config_codedigest.c + $(tor_platform_source)
src_or_libtor_a_SOURCES = $(LIBTOR_A_SOURCES) src_or_libtor_testing_a_SOURCES = $(LIBTOR_A_SOURCES)
- #libtor_a_LIBADD = $(top_builddir)/common/libor.a \ - # $(top_builddir)/common/libor-crypto.a \ - # $(top_builddir)/common/libor-event.a - - -#libtor_a_LIBADD = ../common/libor.a ../common/libor-crypto.a \ -# ../common/libor-event.a -#src_or_libtor_a_LIBADD = src/trunnel/libor-trunnel.a - src_or_tor_SOURCES = src/or/tor_main.c AM_CPPFLAGS += -I$(srcdir)/src/or -Isrc/or
@@@ -120,12 -124,12 +119,12 @@@ src_or_tor_cov_CFLAGS = $(AM_CFLAGS) $( src_or_tor_cov_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@ src_or_tor_cov_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \ src/common/libor-crypto-testing.a $(LIBDONNA) \ - src/common/libor-event-testing.a \ + src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ -TESTING_TOR_BINARY = ./src/or/tor-cov +TESTING_TOR_BINARY = $(top_builddir)/src/or/tor-cov else -TESTING_TOR_BINARY = ./src/or/tor +TESTING_TOR_BINARY = $(top_builddir)/src/or/tor endif
ORHEADERS = \ diff --cc src/or/main.c index 74e6b33,4fac17a..bbee8e0 --- a/src/or/main.c +++ b/src/or/main.c @@@ -1200,46 -1205,7 +1202,49 @@@ get_signewnym_epoch(void return newnym_epoch; }
-static time_t time_to_check_descriptor = 0; +typedef struct { + time_t last_rotated_x509_certificate; + time_t check_v3_certificate; + time_t check_listeners; + time_t download_networkstatus; + time_t try_getting_descriptors; + time_t reset_descriptor_failures; + time_t add_entropy; + time_t write_bridge_status_file; + time_t downrate_stability; + time_t save_stability; + time_t clean_caches; + time_t recheck_bandwidth; + time_t check_for_expired_networkstatus; + time_t write_stats_files; + time_t write_bridge_stats; + time_t check_port_forwarding; + time_t launch_reachability_tests; + time_t retry_dns_init; + time_t next_heartbeat; + time_t check_descriptor; + /** When do we next launch DNS wildcarding checks? */ + time_t check_for_correct_dns; ++ /** When do we next make sure our Ed25519 keys aren't about to expire? */ ++ time_t check_ed_keys; ++ +} time_to_t; + +static time_to_t time_to = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** Reset all the time_to's so we'll do all our actions again as if we + * just started up. + * Useful if our clock just moved back a long time from the future, + * so we don't wait until that future arrives again before acting. + */ +void +reset_all_main_loop_timers(void) +{ + memset(&time_to, 0, sizeof(time_to)); +} + /** * Update our schedule so that we'll check whether we need to update our * descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL @@@ -1297,8 -1282,20 +1302,20 @@@ run_scheduled_events(time_t now router_upload_dir_desc_to_dirservers(0); }
- if (is_server && time_to_check_ed_keys < now) { ++ if (is_server && time_to.check_ed_keys < now) { + if (should_make_new_ed_keys(options, now)) { + if (load_ed_keys(options, now) < 0 || + generate_ed_link_cert(options, now)) { + log_err(LD_OR, "Unable to update Ed25519 keys! Exiting."); + tor_cleanup(); + exit(0); + } + } - time_to_check_ed_keys = now + 30; ++ time_to.check_ed_keys = now + 30; + } + if (!should_delay_dir_fetches(options, NULL) && - time_to_try_getting_descriptors < now) { + time_to.try_getting_descriptors < now) { update_all_descriptor_downloads(now); update_extrainfo_downloads(now); if (router_have_minimum_dir_info()) diff --cc src/or/router.c index 24b7c75,00cd057..6532f97 --- a/src/or/router.c +++ b/src/or/router.c @@@ -2358,6 -2372,21 +2403,22 @@@ router_dump_router_to_string(routerinfo goto err; }
+ if (emit_ed_sigs) { + /* Encode ed25519 signing cert */ + char ed_cert_base64[256]; + if (base64_encode(ed_cert_base64, sizeof(ed_cert_base64), + (const char*)router->signing_key_cert->encoded, - router->signing_key_cert->encoded_len) < 0) { ++ router->signing_key_cert->encoded_len, ++ BASE64_ENCODE_MULTILINE) < 0) { + log_err(LD_BUG,"Couldn't base64-encode signing key certificate!"); + goto err; + } + tor_asprintf(&ed_cert_line, "identity-ed25519\n" + "-----BEGIN ED25519 CERT-----\n" + "%s" + "-----END ED25519 CERT-----\n", ed_cert_base64); + } + /* PEM-encode the onion key */ if (crypto_pk_write_public_key_to_string(router->onion_pkey, &onion_pkey,&onion_pkeylen)<0) { @@@ -2372,6 -2401,67 +2433,69 @@@ goto err; }
+ /* Cross-certify with RSA key */ + if (tap_key && router->signing_key_cert && + router->signing_key_cert->signing_key_included) { + char buf[256]; + int tap_cc_len = 0; + uint8_t *tap_cc = + make_tap_onion_key_crosscert(tap_key, + &router->signing_key_cert->signing_key, + router->identity_pkey, + &tap_cc_len); + if (!tap_cc) { + log_warn(LD_BUG,"make_tap_onion_key_crosscert failed!"); + goto err; + } + - if (base64_encode(buf, sizeof(buf), (const char*)tap_cc, tap_cc_len) < 0) { ++ if (base64_encode(buf, sizeof(buf), (const char*)tap_cc, tap_cc_len, ++ BASE64_ENCODE_MULTILINE) < 0) { + log_warn(LD_BUG,"base64_encode(rsa_crosscert) failed!"); + tor_free(tap_cc); + goto err; + } + tor_free(tap_cc); + + tor_asprintf(&rsa_tap_cc_line, + "onion-key-crosscert\n" + "-----BEGIN CROSSCERT-----\n" + "%s" + "-----END CROSSCERT-----\n", buf); + } + + /* Cross-certify with onion keys */ + if (ntor_keypair && router->signing_key_cert && + router->signing_key_cert->signing_key_included) { + int sign = 0; + char buf[256]; + /* XXXX Base the expiration date on the actual onion key expiration time?*/ + tor_cert_t *cert = + make_ntor_onion_key_crosscert(ntor_keypair, + &router->signing_key_cert->signing_key, + router->cache_info.published_on, + MIN_ONION_KEY_LIFETIME, &sign); + if (!cert) { + log_warn(LD_BUG,"make_ntor_onion_key_crosscert failed!"); + goto err; + } + tor_assert(sign == 0 || sign == 1); + + if (base64_encode(buf, sizeof(buf), - (const char*)cert->encoded, cert->encoded_len)<0) { ++ (const char*)cert->encoded, cert->encoded_len, ++ BASE64_ENCODE_MULTILINE)<0) { + log_warn(LD_BUG,"base64_encode(ntor_crosscert) failed!"); + tor_cert_free(cert); + goto err; + } + tor_cert_free(cert); + + tor_asprintf(&ntor_cc_line, + "ntor-onion-key-crosscert %d\n" + "-----BEGIN ED25519 CERT-----\n" + "%s" + "-----END ED25519 CERT-----\n", sign, buf); + } + /* Encode the publication time. */ format_iso_time(published, router->cache_info.published_on);
@@@ -2695,9 -2819,33 +2853,34 @@@ extrainfo_dump_to_string(char **s_out, extrainfo->cache_info.identity_digest, DIGEST_LEN); format_iso_time(published, extrainfo->cache_info.published_on); bandwidth_usage = rep_hist_get_bandwidth_lines(); + if (emit_ed_sigs) { + if (!extrainfo->signing_key_cert->signing_key_included || + !ed25519_pubkey_eq(&extrainfo->signing_key_cert->signed_key, + &signing_keypair->pubkey)) { + log_warn(LD_BUG, "Tried to sign a extrainfo descriptor with a " + "mismatched ed25519 key chain %d", + extrainfo->signing_key_cert->signing_key_included); + goto err; + } + char ed_cert_base64[256]; + if (base64_encode(ed_cert_base64, sizeof(ed_cert_base64), + (const char*)extrainfo->signing_key_cert->encoded, - extrainfo->signing_key_cert->encoded_len) < 0) { ++ extrainfo->signing_key_cert->encoded_len, ++ BASE64_ENCODE_MULTILINE) < 0) { + log_err(LD_BUG,"Couldn't base64-encode signing key certificate!"); + goto err; + } + tor_asprintf(&ed_cert_line, "identity-ed25519\n" + "-----BEGIN ED25519 CERT-----\n" + "%s" + "-----END ED25519 CERT-----\n", ed_cert_base64); + } else { + ed_cert_line = tor_strdup(""); + }
- tor_asprintf(&pre, "extra-info %s %s\npublished %s\n%s", + tor_asprintf(&pre, "extra-info %s %s\n%spublished %s\n%s", extrainfo->nickname, identity, + ed_cert_line, published, bandwidth_usage); tor_free(bandwidth_usage); smartlist_add(chunks, pre); diff --cc src/or/router.h index 73b43bc,695cfd3..61b35d6 --- a/src/or/router.h +++ b/src/or/router.h @@@ -89,10 -89,12 +89,13 @@@ const uint8_t *router_get_my_id_digest( int router_extrainfo_digest_is_me(const char *digest); int router_is_me(const routerinfo_t *router); int router_pick_published_address(const or_options_t *options, uint32_t *addr); +int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e); int router_rebuild_descriptor(int force); char *router_dump_router_to_string(routerinfo_t *router, - crypto_pk_t *ident_key); + const crypto_pk_t *ident_key, + const crypto_pk_t *tap_key, + const curve25519_keypair_t *ntor_keypair, + const ed25519_keypair_t *signing_keypair); char *router_dump_exit_policy_to_string(const routerinfo_t *router, int include_ipv4, int include_ipv6); diff --cc src/or/routerlist.c index fd09679,a531051..7eba13a --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@@ -37,7 -38,8 +38,9 @@@ #include "routerlist.h" #include "routerparse.h" #include "routerset.h" -#include "../common/sandbox.h" +#include "sandbox.h" + #include "torcert.h" ++ // #define DEBUG_ROUTERLIST
/****************************************************************************/ diff --cc src/test/test_crypto.c index 7944864,15ba14b..6cba850 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@@ -696,8 -618,9 +696,9 @@@ test_crypto_formats(void *arg /* Base64 tests */ memset(data1, 6, 1024); for (idx = 0; idx < 10; ++idx) { - i = base64_encode(data2, 1024, data1, idx); + i = base64_encode(data2, 1024, data1, idx, 0); tt_int_op(i, OP_GE, 0); + tt_int_op(i, OP_EQ, strlen(data2)); j = base64_decode(data3, 1024, data2, i); tt_int_op(j,OP_EQ, idx); tt_mem_op(data3,OP_EQ, data1, idx); diff --cc src/test/test_dir.c index a949f5d,5f68c34..3e9e955 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@@ -127,6 -133,22 +133,23 @@@ test_dir_formats(void *arg ex2->prt_min = ex2->prt_max = 24; r2 = tor_malloc_zero(sizeof(routerinfo_t)); r2->addr = 0x0a030201u; /* 10.3.2.1 */ + ed25519_keypair_t kp1, kp2; + ed25519_secret_key_from_seed(&kp1.seckey, + (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"); + ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey); + ed25519_secret_key_from_seed(&kp2.seckey, + (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey); + r2->signing_key_cert = tor_cert_create(&kp1, + CERT_TYPE_ID_SIGNING, + &kp2.pubkey, + now, 86400, + CERT_FLAG_INCLUDE_SIGNING_KEY); + char cert_buf[256]; + base64_encode(cert_buf, sizeof(cert_buf), + (const char*)r2->signing_key_cert->encoded, - r2->signing_key_cert->encoded_len); ++ r2->signing_key_cert->encoded_len, ++ BASE64_ENCODE_MULTILINE); r2->platform = tor_strdup(platform); r2->cache_info.published_on = 5; r2->or_port = 9005; @@@ -215,19 -243,49 +244,52 @@@ strlcat(buf2, pk2_str, sizeof(buf2)); strlcat(buf2, "signing-key\n", sizeof(buf2)); strlcat(buf2, pk1_str, sizeof(buf2)); + int rsa_cc_len; + rsa_cc = make_tap_onion_key_crosscert(pk2, + &kp1.pubkey, + pk1, + &rsa_cc_len); + tt_assert(rsa_cc); - base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len); ++ base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len, ++ BASE64_ENCODE_MULTILINE); + strlcat(buf2, "onion-key-crosscert\n" + "-----BEGIN CROSSCERT-----\n", sizeof(buf2)); + strlcat(buf2, cert_buf, sizeof(buf2)); + strlcat(buf2, "-----END CROSSCERT-----\n", sizeof(buf2)); + int ntor_cc_sign; + ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair, + &kp1.pubkey, + r2->cache_info.published_on, + MIN_ONION_KEY_LIFETIME, + &ntor_cc_sign); + tt_assert(ntor_cc); + base64_encode(cert_buf, sizeof(cert_buf), - (char*)ntor_cc->encoded, ntor_cc->encoded_len); ++ (char*)ntor_cc->encoded, ntor_cc->encoded_len, ++ BASE64_ENCODE_MULTILINE); + tor_snprintf(buf2+strlen(buf2), sizeof(buf2)-strlen(buf2), + "ntor-onion-key-crosscert %d\n" + "-----BEGIN ED25519 CERT-----\n" + "%s" + "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf); + strlcat(buf2, "hidden-service-dir\n", sizeof(buf2)); - strlcat(buf2, "ntor-onion-key " - "skyinAnvardNostarsNomoonNowindormistsorsnow=\n", sizeof(buf2)); + strlcat(buf2, "ntor-onion-key ", sizeof(buf2)); + base64_encode(cert_buf, sizeof(cert_buf), - (const char*)r2_onion_keypair.pubkey.public_key, 32); ++ (const char*)r2_onion_keypair.pubkey.public_key, 32, ++ BASE64_ENCODE_MULTILINE); + strlcat(buf2, cert_buf, sizeof(buf2)); strlcat(buf2, "accept *:80\nreject 18.0.0.0/8:24\n", sizeof(buf2)); - strlcat(buf2, "router-signature\n", sizeof(buf2)); + strlcat(buf2, "router-sig-ed25519 ", sizeof(buf2));
- buf = router_dump_router_to_string(r2, pk1); + buf = router_dump_router_to_string(r2, pk1, pk2, &r2_onion_keypair, &kp2); + tt_assert(buf); buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same * twice */ - tt_str_op(buf,OP_EQ, buf2); + + tt_str_op(buf, OP_EQ, buf2); tor_free(buf);
- buf = router_dump_router_to_string(r2, pk1); + buf = router_dump_router_to_string(r2, pk1, NULL, NULL, NULL); cp = buf; rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL); tt_assert(rp2);