[tor-commits] [tor/master] Sign extrainfo documents with ed25519

nickm at torproject.org nickm at torproject.org
Thu May 28 15:06:55 UTC 2015


commit 79db24b3d5cb845b18d737bbc63510154f6a87c7
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu May 28 10:42:22 2015 -0400

    Sign extrainfo documents with ed25519
    
    Extrainfo documents are now ed-signed just as are router
    descriptors, according to proposal 220.  This patch also includes
    some more tests for successful/failing parsing, and fixes a crash
    bug in ed25519 descriptor parsing.
---
 scripts/codegen/makedesc.py      |   34 +-
 src/or/or.h                      |    6 +
 src/or/router.c                  |   90 +++-
 src/or/router.h                  |    3 +-
 src/or/routerlist.c              |    1 +
 src/or/routerparse.c             |   95 ++++-
 src/test/example_extrainfo.inc   |  233 +++++++++++
 src/test/failing_routerdescs.inc |  855 ++++++++++++++++++++++++++++++++++++++
 src/test/test_dir.c              |   43 ++
 9 files changed, 1318 insertions(+), 42 deletions(-)

diff --git a/scripts/codegen/makedesc.py b/scripts/codegen/makedesc.py
index 0ed1f7e..d4ba21e 100644
--- a/scripts/codegen/makedesc.py
+++ b/scripts/codegen/makedesc.py
@@ -16,6 +16,7 @@ import ctypes.util
 import hashlib
 import optparse
 import os
+import re
 import struct
 import time
 import UserDict
@@ -297,7 +298,7 @@ def signdesc(body, args_out=None):
     return body.rstrip()
 
 def print_c_string(ident, body):
-    print "static const char EX %s[] =" % ident
+    print "static const char %s[] =" % ident
     for line in body.split("\n"):
         print '  "%s\\n"' %(line)
     print "  ;"
@@ -314,9 +315,9 @@ def emit_ei(name, body):
     body = info.sign_desc(body)
     print_c_string("EX_EI_%s"%name.upper(), body)
 
-    print 'const char {NAME}_FP[] = "{d.RSA_FINGERPRINT_NOSPACE}";'.format(
+    print 'const char EX_EI_{NAME}_FP[] = "{d.RSA_FINGERPRINT_NOSPACE}";'.format(
         d=info, NAME=name.upper())
-    prnit_c_string("%s_KEY"%name.upper(), d.RSA_IDENTITY)
+    print_c_string("EX_EI_%s_KEY"%name.upper(), info.RSA_IDENTITY)
 
 def analyze(s):
     fields = {}
@@ -330,6 +331,7 @@ def analyze(s):
     return fields, s
 
 def process_file(s):
+    fields, s = analyze(s)
     try:
         name = fields['name']
         tp = fields['type']
@@ -343,25 +345,7 @@ def process_file(s):
     else:
         raise ValueError("unrecognized type")
 
-if 0:
-    emit_ri("minimal_ed",
-     """\
-router fred 127.0.0.1 9001 0 9002
-identity-ed25519
-{d.ED_CERT}
-signing-key
-{d.RSA_IDENTITY}
-onion-key
-{d.RSA_ONION_KEY}
-ntor-onion-key {d.NTOR_ONION_KEY}
-ntor-onion-key-crosscert {d.NTOR_CROSSCERT_SIGN}
-{d.NTOR_CROSSCERT}
-onion-key-crosscert
-{d.RSA_CROSSCERT_ED}
-published 2014-10-05 12:00:00
-bandwidth 1000 1000 1000
-reject *:*
-router-sig-ed25519 {d.ED_SIGNATURE}
-router-signature
-{d.RSA_SIGNATURE}
-""")
+if __name__ == '__main__':
+    import sys
+    for fn in sys.argv[1:]:
+        process_file(open(fn).read())
diff --git a/src/or/or.h b/src/or/or.h
index ba36ad8..714b1c6 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2004,6 +2004,8 @@ typedef int16_t country_t;
 /** Information about another onion router in the network. */
 typedef struct {
   signed_descriptor_t cache_info;
+  /** A SHA256-digest of the extrainfo (if any) */
+  char extra_info_digest256[DIGEST256_LEN];
   char *nickname; /**< Human-readable OR name. */
 
   uint32_t addr; /**< IPv4 address of OR, in host order. */
@@ -2085,8 +2087,12 @@ typedef struct {
 /** Information needed to keep and cache a signed extra-info document. */
 typedef struct extrainfo_t {
   signed_descriptor_t cache_info;
+  /** SHA256 digest of this document */
+  uint8_t digest256[DIGEST256_LEN];
   /** The router's nickname. */
   char nickname[MAX_NICKNAME_LEN+1];
+  /** Certificate for ed25519 signing key */
+  struct tor_cert_st *signing_key_cert;
   /** True iff we found the right key for this extra-info, verified the
    * signature, and found it to be bad. */
   unsigned int bad_sig : 1;
diff --git a/src/or/router.c b/src/or/router.c
index 242ec05..c94667a 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1974,10 +1974,12 @@ router_rebuild_descriptor(int force)
   ei->cache_info.is_extrainfo = 1;
   strlcpy(ei->nickname, get_options()->Nickname, sizeof(ei->nickname));
   ei->cache_info.published_on = ri->cache_info.published_on;
+  ei->signing_key_cert = tor_cert_dup(get_master_signing_key_cert());
   memcpy(ei->cache_info.identity_digest, ri->cache_info.identity_digest,
          DIGEST_LEN);
   if (extrainfo_dump_to_string(&ei->cache_info.signed_descriptor_body,
-                               ei, get_server_identity_key()) < 0) {
+                               ei, get_server_identity_key(),
+                               get_master_signing_keypair()) < 0) {
     log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
     extrainfo_free(ei);
     ei = NULL;
@@ -1987,6 +1989,10 @@ router_rebuild_descriptor(int force)
     router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
                               ei->cache_info.signed_descriptor_len,
                               ei->cache_info.signed_descriptor_digest);
+    crypto_digest256((char*) ei->digest256,
+                     ei->cache_info.signed_descriptor_body,
+                     ei->cache_info.signed_descriptor_len,
+                     DIGEST_SHA256);
   }
 
   /* Now finish the router descriptor. */
@@ -1994,6 +2000,9 @@ router_rebuild_descriptor(int force)
     memcpy(ri->cache_info.extra_info_digest,
            ei->cache_info.signed_descriptor_digest,
            DIGEST_LEN);
+    memcpy(ri->extra_info_digest256,
+           ei->digest256,
+           DIGEST256_LEN);
   } else {
     /* ri was allocated with tor_malloc_zero, so there is no need to
      * zero ri->cache_info.extra_info_digest here. */
@@ -2319,8 +2328,7 @@ router_dump_router_to_string(routerinfo_t *router,
   char digest[DIGEST256_LEN];
   char published[ISO_TIME_LEN+1];
   char fingerprint[FINGERPRINT_LEN+1];
-  int has_extra_info_digest;
-  char extra_info_digest[HEX_DIGEST_LEN+1];
+  char *extra_info_line = NULL;
   size_t onion_pkeylen, identity_pkeylen;
   char *family_line = NULL;
   char *extra_or_address = NULL;
@@ -2457,12 +2465,19 @@ router_dump_router_to_string(routerinfo_t *router,
     family_line = tor_strdup("");
   }
 
-  has_extra_info_digest =
-    ! tor_digest_is_zero(router->cache_info.extra_info_digest);
-
-  if (has_extra_info_digest) {
+  if (!tor_digest_is_zero(router->cache_info.extra_info_digest)) {
+    char extra_info_digest[HEX_DIGEST_LEN+1];
     base16_encode(extra_info_digest, sizeof(extra_info_digest),
                   router->cache_info.extra_info_digest, DIGEST_LEN);
+    if (!tor_digest256_is_zero(router->extra_info_digest256)) {
+      char d256_64[BASE64_DIGEST256_LEN+1];
+      digest256_to_base64(d256_64, router->extra_info_digest256);
+      tor_asprintf(&extra_info_line, "extra-info-digest %s %s\n",
+                   extra_info_digest, d256_64);
+    } else {
+      tor_asprintf(&extra_info_line, "extra-info-digest %s\n",
+                   extra_info_digest);
+    }
   }
 
   if (router->ipv6_orport &&
@@ -2491,7 +2506,7 @@ router_dump_router_to_string(routerinfo_t *router,
                     "fingerprint %s\n"
                     "uptime %ld\n"
                     "bandwidth %d %d %d\n"
-                    "%s%s%s%s"
+                    "%s%s"
                     "onion-key\n%s"
                     "signing-key\n%s"
                     "%s%s"
@@ -2509,9 +2524,7 @@ router_dump_router_to_string(routerinfo_t *router,
     (int) router->bandwidthrate,
     (int) router->bandwidthburst,
     (int) router->bandwidthcapacity,
-    has_extra_info_digest ? "extra-info-digest " : "",
-    has_extra_info_digest ? extra_info_digest : "",
-    has_extra_info_digest ? "\n" : "",
+    extra_info_line ? extra_info_line : "",
     (options->DownloadExtraInfo || options->V3AuthoritativeDir) ?
                          "caches-extra-info\n" : "",
     onion_pkey, identity_pkey,
@@ -2631,6 +2644,7 @@ router_dump_router_to_string(routerinfo_t *router,
   tor_free(ed_cert_line);
   tor_free(rsa_tap_cc_line);
   tor_free(ntor_cc_line);
+  tor_free(extra_info_line);
 
   return output;
 }
@@ -2774,7 +2788,8 @@ load_stats_file(const char *filename, const char *end_line, time_t now,
  * success, negative on failure. */
 int
 extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
-                         crypto_pk_t *ident_key)
+                         crypto_pk_t *ident_key,
+                         const ed25519_keypair_t *signing_keypair)
 {
   const or_options_t *options = get_options();
   char identity[HEX_DIGEST_LEN+1];
@@ -2784,18 +2799,44 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
   int result;
   static int write_stats_to_extrainfo = 1;
   char sig[DIROBJ_MAX_SIG_LEN+1];
-  char *s, *pre, *contents, *cp, *s_dup = NULL;
+  char *s = NULL, *pre, *contents, *cp, *s_dup = NULL;
   time_t now = time(NULL);
   smartlist_t *chunks = smartlist_new();
   extrainfo_t *ei_tmp = NULL;
+  const int emit_ed_sigs = signing_keypair && extrainfo->signing_key_cert;
+  char *ed_cert_line = NULL;
 
   base16_encode(identity, sizeof(identity),
                 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) {
+      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);
@@ -2855,6 +2896,23 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
     }
   }
 
+  if (emit_ed_sigs) {
+    char digest[DIGEST256_LEN];
+    smartlist_add(chunks, tor_strdup("router-sig-ed25519 "));
+    crypto_digest_smartlist_prefix(digest, DIGEST256_LEN,
+                                   ED_DESC_SIGNATURE_PREFIX,
+                                   chunks, "", DIGEST_SHA256);
+    ed25519_signature_t sig;
+    char buf[ED25519_SIG_BASE64_LEN+1];
+    if (ed25519_sign(&sig, (const uint8_t*)digest, DIGEST256_LEN,
+                     signing_keypair) < 0)
+      goto err;
+    if (ed25519_signature_to_base64(buf, &sig) < 0)
+      goto err;
+
+    smartlist_add_asprintf(chunks, "%s\n", buf);
+  }
+
   smartlist_add(chunks, tor_strdup("router-signature\n"));
   s = smartlist_join_strings(chunks, "", 0, NULL);
 
@@ -2903,7 +2961,8 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
                            "adding statistics to this or any future "
                            "extra-info descriptors.");
       write_stats_to_extrainfo = 0;
-      result = extrainfo_dump_to_string(s_out, extrainfo, ident_key);
+      result = extrainfo_dump_to_string(s_out, extrainfo, ident_key,
+                                        signing_keypair);
       goto done;
     } else {
       log_warn(LD_BUG, "We just generated an extrainfo descriptor we "
@@ -2925,6 +2984,7 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
   SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
   smartlist_free(chunks);
   tor_free(s_dup);
+  tor_free(ed_cert_line);
   extrainfo_free(ei_tmp);
 
   return result;
diff --git a/src/or/router.h b/src/or/router.h
index cb813c6..695cfd3 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -109,7 +109,8 @@ int router_has_addr(const routerinfo_t *router, const tor_addr_t *addr);
 int router_has_orport(const routerinfo_t *router,
                       const tor_addr_port_t *orport);
 int extrainfo_dump_to_string(char **s, extrainfo_t *extrainfo,
-                             crypto_pk_t *ident_key);
+                             crypto_pk_t *ident_key,
+                             const ed25519_keypair_t *signing_keypair);
 int is_legal_nickname(const char *s);
 int is_legal_nickname_or_hexdigest(const char *s);
 int is_legal_hexdigest(const char *s);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index dbb93e4..b2784ae 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -2684,6 +2684,7 @@ extrainfo_free(extrainfo_t *extrainfo)
 {
   if (!extrainfo)
     return;
+  tor_cert_free(extrainfo->signing_key_cert);
   tor_free(extrainfo->cache_info.signed_descriptor_body);
   tor_free(extrainfo->pending_sig);
 
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index e1bc295..03a5eaf 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -324,6 +324,8 @@ static token_rule_t routerdesc_token_table[] = {
 static token_rule_t extrainfo_token_table[] = {
   T1_END( "router-signature",    K_ROUTER_SIGNATURE,    NO_ARGS, NEED_OBJ ),
   T1( "published",           K_PUBLISHED,       CONCAT_ARGS, NO_OBJ ),
+  T01("identity-ed25519",    K_IDENTITY_ED25519,    NO_ARGS, NEED_OBJ ),
+  T01("router-sig-ed25519",  K_ROUTER_SIG_ED25519,  GE(1),   NO_OBJ ),
   T0N("opt",                 K_OPT,             CONCAT_ARGS, OBJ_OK ),
   T01("read-history",        K_READ_HISTORY,        ARGS,    NO_OBJ ),
   T01("write-history",       K_WRITE_HISTORY,       ARGS,    NO_OBJ ),
@@ -1398,7 +1400,7 @@ router_parse_entry_from_string(const char *s, const char *end,
 
       ntor_cc_cert = tor_cert_parse((const uint8_t*)cc_ntor_tok->object_body,
                                     cc_ntor_tok->object_size);
-      if (!cc_ntor_tok) {
+      if (!ntor_cc_cert) {
         log_warn(LD_DIR, "Couldn't parse ntor-onion-key-crosscert cert");
         goto err;
       }
@@ -1564,6 +1566,14 @@ router_parse_entry_from_string(const char *s, const char *end,
     } else {
       log_warn(LD_DIR, "Invalid extra info digest %s", escaped(tok->args[0]));
     }
+
+    if (tok->n_args >= 2) {
+      if (digest256_from_base64(router->extra_info_digest256, tok->args[1])
+          < 0) {
+        log_warn(LD_DIR, "Invalid extra info digest256 %s",
+                 escaped(tok->args[1]));
+      }
+    }
   }
 
   if (find_opt_by_keyword(tokens, K_HIDDEN_SERVICE_DIR)) {
@@ -1666,6 +1676,7 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
     goto err;
   }
 
+  /* XXXX Accept this in position 1 too, and ed identity in position 0. */
   tok = smartlist_get(tokens,0);
   if (tok->tp != K_EXTRA_INFO) {
     log_warn(LD_DIR,"Entry does not start with \"extra-info\"");
@@ -1678,6 +1689,7 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
     extrainfo->cache_info.signed_descriptor_body = tor_memdup_nulterm(s,end-s);
   extrainfo->cache_info.signed_descriptor_len = end-s;
   memcpy(extrainfo->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
+  crypto_digest256((char*)extrainfo->digest256, s, end-s, DIGEST_SHA256);
 
   tor_assert(tok->n_args >= 2);
   if (!is_legal_nickname(tok->args[0])) {
@@ -1700,6 +1712,87 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
     goto err;
   }
 
+  {
+    directory_token_t *ed_sig_tok, *ed_cert_tok;
+    ed_sig_tok = find_opt_by_keyword(tokens, K_ROUTER_SIG_ED25519);
+    ed_cert_tok = find_opt_by_keyword(tokens, K_IDENTITY_ED25519);
+    int n_ed_toks = !!ed_sig_tok + !!ed_cert_tok;
+    if (n_ed_toks != 0 && n_ed_toks != 2) {
+      log_warn(LD_DIR, "Router descriptor with only partial ed25519/"
+               "cross-certification support");
+      goto err;
+    }
+    if (ed_sig_tok) {
+      tor_assert(ed_cert_tok);
+      const int ed_cert_token_pos = smartlist_pos(tokens, ed_cert_tok);
+      if (ed_cert_token_pos != 1) {
+        /* Accept this in position 0 XXXX */
+        log_warn(LD_DIR, "Ed25519 certificate in wrong position");
+        goto err;
+      }
+      if (ed_sig_tok != smartlist_get(tokens, smartlist_len(tokens)-2)) {
+        log_warn(LD_DIR, "Ed25519 signature in wrong position");
+        goto err;
+      }
+      if (strcmp(ed_cert_tok->object_type, "ED25519 CERT")) {
+        log_warn(LD_DIR, "Wrong object type on identity-ed25519 in decriptor");
+        goto err;
+      }
+
+      uint8_t d256[DIGEST256_LEN];
+      const char *signed_start, *signed_end;
+      tor_cert_t *cert = tor_cert_parse(
+                       (const uint8_t*)ed_cert_tok->object_body,
+                       ed_cert_tok->object_size);
+      if (! cert) {
+        log_warn(LD_DIR, "Couldn't parse ed25519 cert");
+        goto err;
+      }
+      extrainfo->signing_key_cert = cert; /* makes sure it gets freed. */
+      if (cert->cert_type != CERT_TYPE_ID_SIGNING ||
+          ! cert->signing_key_included) {
+        log_warn(LD_DIR, "Invalid form for ed25519 cert");
+        goto err;
+      }
+
+      if (router_get_hash_impl_helper(s, end-s, "extra-info ",
+                                      "\nrouter-sig-ed25519",
+                                      ' ', &signed_start, &signed_end) < 0) {
+        log_warn(LD_DIR, "Can't find ed25519-signed portion of extrainfo");
+        goto err;
+      }
+      crypto_digest_t *d = crypto_digest256_new(DIGEST_SHA256);
+      crypto_digest_add_bytes(d, ED_DESC_SIGNATURE_PREFIX,
+        strlen(ED_DESC_SIGNATURE_PREFIX));
+      crypto_digest_add_bytes(d, signed_start, signed_end-signed_start);
+      crypto_digest_get_digest(d, (char*)d256, sizeof(d256));
+      crypto_digest_free(d);
+
+      ed25519_checkable_t check[2];
+      int check_ok[2];
+      if (tor_cert_get_checkable_sig(&check[0], cert, NULL) < 0) {
+        log_err(LD_BUG, "Couldn't create 'checkable' for cert.");
+        goto err;
+      }
+
+      if (ed25519_signature_from_base64(&check[1].signature,
+                                        ed_sig_tok->args[0])<0) {
+        log_warn(LD_DIR, "Couldn't decode ed25519 signature");
+        goto err;
+      }
+      check[1].pubkey = &cert->signed_key;
+      check[1].msg = d256;
+      check[1].len = DIGEST256_LEN;
+
+      if (ed25519_checksig_batch(check_ok, check, 2) < 0) {
+        log_warn(LD_DIR, "Incorrect ed25519 signature(s)");
+        goto err;
+      }
+      /* We don't check the certificate expiration time: checking that it
+       * matches the cert in the router descriptor is adequate. */
+    }
+  }
+
   /* We've checked everything that's covered by the hash. */
   can_dl_again = 1;
 
diff --git a/src/test/example_extrainfo.inc b/src/test/example_extrainfo.inc
index 606279a..e096afd 100644
--- a/src/test/example_extrainfo.inc
+++ b/src/test/example_extrainfo.inc
@@ -190,3 +190,236 @@ static const char EX_EI_BAD_PUBLISHED_KEY[] =
   "BvG6303md3INygg+KP49RvWEJR/cU4RZ9QfHpORxH2OocMyRedw2rLex2E7jNNSi\n"
   "52yd1sHFYI8ZQ4aff+ZHUjJUGKRyqpbc8okVbq/Rl7vug0dd12eHAgMBAAE=\n"
   "-----END RSA PUBLIC KEY-----\n";
+
+static const char EX_EI_GOOD_ED_EI[] =
+  "extra-info emma A692FE045C32B5E3A54B52882EF678A9DAC46A73\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AYgHn/OKR8GHBlscN5VkO73wA9jSci8QgTM30615ZT44AQAgBAC08woT\n"
+  "MBZpKzRcaoEJhEG7+RmuYtnB2+nODk9IRIs8ZoyYPTZ6dLzI+MLMmtzUuo/Wmvw0\n"
+  "PflTyCb2RlWitOEhAErWH3Z9UmYGnzM/COId0Fe3ScSriyvRoFnJY1+GVAQ=\n"
+  "-----END ED25519 CERT-----\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-sig-ed25519 a7K8nwfg+HrdlSGQwr9rnLBq0qozkyZZs6d6aiLEiXGdhV1r9KJncmlQ5SNoY/zMQlyQm8EV5rCyBiVliKQ1Bw\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "GvmCmIGgbC1DeawRyRuChy62VmBOG0EviryG/a2qSZiFy0iPPwqSp5ZyZDQEIEId\n"
+  "kkk1zPzK1+S3fmgOAXyXGH0r4YFkoLGnhMk07BoEwi6HEXzjJsabmcNkOHfaOWgs\n"
+  "/5nvnLfcmxL4c6FstZ7t9VQpE06y3GU0zwBeIy1qjp0=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  ;
+const char EX_EI_GOOD_ED_EI_FP[] = "A692FE045C32B5E3A54B52882EF678A9DAC46A73";
+static const char EX_EI_GOOD_ED_EI_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAM3jdYwjwGxDWYj/vyFkQT7RgeCNIn89Ei6D2+L/fdtFnqrMXOreFFHL\n"
+  "C7CK2v2uN3v+uXxfb5lADz3NcalxJrCfGTGtaBk7PwMZraTSh2luFKOvSRBQCmB1\n"
+  "yD5N0QqnIhBJoGr6NITpbWyiTKWvYLjl9PZd9af8e8jQCAa5P1j1AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+
+static const char EX_EI_ED_MISSING_SIG[] =
+  "extra-info rachel 2A7521497B91A8437021515308A47491164EDBA1\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AT2/T71LFYHiI1ppwNiuaewIu2Hq+GWWQ85O8gpWcUxeAQAgBAC2dgYu\n"
+  "moxhtuip7GVlthT9iomZKba1IllVa7uE1u2uO9BUYZQWXciFt7OnNzMH5mlffwxB\n"
+  "1dWCl+G5nbOsV5jYLbfhrF5afZotf+EQTfob4cCH79AV223LPcySbTHTtQ4=\n"
+  "-----END ED25519 CERT-----\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "oypRD2IZQ5EttOE8dvofrW80nnBfijSkvYzBrM6H4KVeayRYvWfmi96dYO6ybMqm\n"
+  "Yp7Gs3ngqeeNdfHtkRPuQVUXUGYZgBTvYItuagnFlFgRqaHy0knwUIVOL35eqWYx\n"
+  "xSbQKA7fglxEDMFs/RK7FRP4dWc731ZMt5wzzfJHZ8E=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  ;
+const char EX_EI_ED_MISSING_SIG_FP[] = "2A7521497B91A8437021515308A47491164EDBA1";
+static const char EX_EI_ED_MISSING_SIG_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAOOB8ccxbtk2dB5FuKFhGndDcO6STNjB6KiG0b9X2QwKrOZMfmXSigto\n"
+  "mtC1JfPTxECayRjLSiP/9UD8iTVvlcnc8mMWBGM12Pa/KoCZRn7McHI3JJ7n9lfn\n"
+  "qw9+iZ9b/rBimzOb3W6k3uxzg9r8secdq4jJwTnwSjTObgxZtC8/AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+
+static const char EX_EI_ED_MISSING_CERT[] =
+  "extra-info lynne E88E43E86015345A323D93D825C33E4AD1028F65\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-sig-ed25519 H4gKIKm5K9Pfkriy7SlMUD6BdYVp6B5mXKzR/rTyYlpH0tEZ4Fx2hlHNfNNdWXJieXzKZQZo8e7SOVzvrAC3CQ\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "dIrbQjK5T9t5KM8CpsMF85hh2i060oPIxzYQMgE1q4j99dtb/n7SE8nhj1Sjij4D\n"
+  "7JvTjGdLHi3bFSxXaSmla0wxD9PUYFN7VsBQmwSaDrqrzJFb1SGwZuzW1IEZ7BBi\n"
+  "H0czsxEteg5hcNRwISj5WVthuWmau9v13MijtZGSK40=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  "\n"
+  ;
+const char EX_EI_ED_MISSING_CERT_FP[] = "E88E43E86015345A323D93D825C33E4AD1028F65";
+static const char EX_EI_ED_MISSING_CERT_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALjA/geb0TR9rp/UPvLhABQpB0XUDYuZAnLkrv+i7AAV7FemTDveEGnc\n"
+  "XdXNSusO1mHOquvr0YYKPhwauInxD56S8QOzLYiWWajGq8XHARQ33b4/9K2TUrAx\n"
+  "W9HTHV1U1zrPlCJtrkbjxsYoHpUg5ljzM7FGYGY5xuvyHu18SQvzAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+static const char EX_EI_ED_BAD_CERT1[] =
+  "extra-info marcie F78D8A655607D32281D02144817A4F1D26AE520F\n"
+  "identity-ed25519\n"
+  "-----BEGIN PLAGICAL SPELL-----\n"
+  "aaaa\n"
+  "-----END PLAGICAL SPELL\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-sig-ed25519 KQJ+2AH7EkkjrD0RtDtUAIr+Vc7wndwILYnoUxFLSJiTP+5fMi54eFF/f1OgkG8gYyTh8phMij9WOxK/dsOpBg\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "XWD+P25AH6moi79j20Si3hqKGcJDws+FORL1MTu+GeJLV1mp5CR9N83UH4ffulcL\n"
+  "CpSSBDL/j74HqapzW7QvBx3FilaNT55GvcobZDFK4TKkCEyEmcuWKpEceBS7JTTV\n"
+  "SvwZeOObTjWPafELbsc/gI9Rh5Idwu7mZt3ZVntCGaQ=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+const char EX_EI_ED_BAD_CERT1_FP[] = "F78D8A655607D32281D02144817A4F1D26AE520F";
+static const char EX_EI_ED_BAD_CERT1_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMlR46JhxsCmWYtmIB/JjTV2TUYIhJLmHy+X7FfkK3ZVQvvl9/3GSXFL\n"
+  "3USfyf3j34XLh8An7pJBi9LAHkIXgnRbglCud7dXoexabmC+c2mSbw5RnuxDGEwz\n"
+  "krXUph/r2b+2UY1CgEt28nFigaHrIQbCmF4szFX/2GPYCLi5SrRNAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+static const char EX_EI_ED_BAD_CERT2[] =
+  "extra-info jaeger 7C2B42E783C4E0EB0CC3BDB37385D16737BACFBD\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55Acpw27GZBdwGCgawCj2F/DPadt8F/9DnEWywEew1Yi3qAOtLpCB8KXL7\n"
+  "4w5deFW2RBg8qTondNSUvAmwYLbLjNXMmgA3+nkoJOP3fcmQMHz1jm5xzgs2lCVP\n"
+  "t5txApaBIA4=\n"
+  "-----END ED25519 CERT-----\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-sig-ed25519 DRQ4MLOGosBbW8M+17klNu8uWVkPxErmmEYoSo6OuH2Tzrcs6sUY+8Xi2qLoV1SbOugJ214Htl0I+6ceag+vBA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "DfdA+DbuN9nVJNujuSY5wNCDLk7Hfzkrde/sK0hVmZRvivtpF/Fy/dVQHHGNFY5i\n"
+  "L1cESAgq9HLdbHU+hcc08XXxTIaGwvoklcJClcG3ENVBWkTXbJNT+ifr7chEagIi\n"
+  "cVrtU6RVmzldSbyir8V/Z4S/Cm67gYAgjM5gfoFUqDs=\n"
+  "-----END SIGNATURE-----\n"
+  ;
+const char EX_EI_ED_BAD_CERT2_FP[] = "7C2B42E783C4E0EB0CC3BDB37385D16737BACFBD";
+static const char EX_EI_ED_BAD_CERT2_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALAM1F/0XJEsbxIQqb3+ObX/yGVnq9of8Q9sLsmxffD6hwVpCqnV3lTg\n"
+  "iC6+xZ/bSlTGLPi0k8QLCaTmYxgKwmlMPpbQZ4kpZUrsb9flKdChMN7w8hd48pY9\n"
+  "lu8QiAEgErsl5rCCJIHHjrxxM/Cnd0TnedRnj/Z2YqpNx/ggsmsRAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+static const char EX_EI_ED_BAD_SIG1[] =
+  "extra-info vary 5AC3A538FEEFC6F9FCC5FA0CE64704396C30D62A\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AbPp++GrRb6WphSu+PkMaYsqY/beiLBmtiV3YP5i2JkKAQAgBABKXjg1\n"
+  "aiz2JfQpNOG308i2EojnUAZEk0C0x9g2BAAXGL63sv3eO/qrlytsG1x2hkcamxFn\n"
+  "LmfZBb/prqe1Vy4wABuhqWHAUtM29vXR6lpiCJeddt9Pa8XVy/tgWLX6TAw=\n"
+  "-----END ED25519 CERT-----\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-sig-ed25519 a7K8nwfg+HrdlSGQwr9rnLBq0qozkyZZs6d6aiLEiXGdhV1r9KJncmlQ5SNoY/zMQlyQm8EV5rCyBiVliKQ1Bw\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "xhZX8Qmgft51NJ7eMd4vrESzf/VdxDrBz7hgn8K+5bLtZUksG0s6s7IyGRYWQtp4\n"
+  "/7oc9sYe3lcQiUN2K7DkeBDlL8Pcsl8aIlKuujWomCE3j0TIu+8XK6oJeo7eYic+\n"
+  "IA7EwVbdZsKsW5/eJVzbX2eO0a5zyJ5RIYotFNYNCSE=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+const char EX_EI_ED_BAD_SIG1_FP[] = "5AC3A538FEEFC6F9FCC5FA0CE64704396C30D62A";
+static const char EX_EI_ED_BAD_SIG1_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMvb6SuoIkPfBkJgQuo5aQDepAs1kEETZ9VXotMlhB0JJikrqBrAAz+7\n"
+  "rjIJ4JsBaeQuN0Z5ksXk2ebxtef7oMIUs37NfekLQHbNR0VsXkFXPEGmOAqpZjW0\n"
+  "P524eHqybWYZTckvZtUvKI3xYGD6kEEkz4qmV6dcExU1OiAYO9jrAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+static const char EX_EI_ED_BAD_SIG2[] =
+  "extra-info coward 7F1D4DD477E340C6D6B389FAC26EDC746113082F\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf56AZkSDiFZ1QaiLJhcKdFDE5Kei/sPaPEIEoPMGP4BvOVXAQAgBAAlRLzx\n"
+  "U029tgIL9BRe47MVgcPJGy48db6ntzhjil7iOnWKT70z2LorUD5CZoLJs72TjB6r\n"
+  "8+HYNyFLEM6dvytWZf9NA5gLdhogbFcUk/R3gbNepmCF7XoZjbhPIp8zOwg=\n"
+  "-----END ED25519 CERT-----\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-sig-ed25519 yfV+GySMIP1fw1oVa1C1de4XOWBqT4pUtEmSHq1h+WrLBNCh3/HZWvNC/denf2YVntuQrMLCJEv5ZaFKU+AIDQ\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "g+BWq69i9CP19va2cYMAXCQ6jK3IG0VmNYspjjUFgmFpJKGG6bHeOkuy1GXp47fG\n"
+  "LzZ3OPfJLptxU5AOQDUUYf25hu9uSl6gyknCzsszFs5n6ticuNejvcpzw6UfO1LP\n"
+  "5u+mGJlgpcMtmSraImDZrRipmZ3oRWvEULltlvzGQcQ=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+const char EX_EI_ED_BAD_SIG2_FP[] = "7F1D4DD477E340C6D6B389FAC26EDC746113082F";
+static const char EX_EI_ED_BAD_SIG2_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALzOyfCEUZnvCyhlyMctPkdXg/XRE3Cr6QgyzdKf5kQbUiu2n0FgSHOX\n"
+  "iP5gfq8sO9eVeTPZtjE7/+KiR8aQJECy+eoye+lpsfm3tXpLxnpOIgL4DlURxlo/\n"
+  "rfCyv30SYBN9j62qgU9m6U2ydI0tH7/9Ep8yIY/QL8me8VAjLbf/AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+
+static const char EX_EI_ED_MISPLACED_CERT[] =
+  "extra-info msselene 3B788BD0CE348BC5CED48313307C78175EB6D0F3\n"
+  "published 2014-10-05 20:07:00\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AWBcqjzLESDuLNGsqQ/tHn32XueXwj2fDlgEy/kQNVf/AQAgBAAFOegg\n"
+  "XY1LR82xE9ohAYJxYpwJJw0YfXsBhGHqfakEoBtSgFJ3cQAUXZQX4lX6G8IxAlQB\n"
+  "7Rj7dPQuQRUmqD1yyKb/ScBgCa8esxlhNlATz47kRNR38A3TcoJ4c1Zv6AE=\n"
+  "-----END ED25519 CERT-----\n"
+  "router-sig-ed25519 Q52JKH9/iMsr1jIPlWHHxakSBvyqjT1gzL944vad4OhzCZuNuAYGWyWSGzTb1DVmBqqbAUq73TiZKAz77YLNCQ\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "YplvAIwExGf5/L8AoroVQXtGm+26EffrxKBArMKn0zS1NOOie1p0oF/+qJg+rNWU\n"
+  "6cv3Anf188EXGlkUOddavgVH8CQbvve2nHSfIAPxjgEX9QNXbM5CiaMwgpCewXnF\n"
+  "UoNBVo5tydeLHVns15MBg/JNIxUQMd6svMoPp2WqmaE=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+const char EX_EI_ED_MISPLACED_CERT_FP[] = "3B788BD0CE348BC5CED48313307C78175EB6D0F3";
+static const char EX_EI_ED_MISPLACED_CERT_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALTwNqhTprg1oC6bEbDqwIYBoER6prqUXQFbwbFDn+ekXhZj8vltgGwp\n"
+  "aDGl9ceZWDKfi+reR6rZXjAJGctmv0VHkfe7maUX4FC/d2T8N8DvS+3IvJzFMpbT\n"
+  "O0fFrDTrCSnPikqFfQWnlP8yoF5vO7wo0jRRY432fLRXg9WqVzdrAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+static const char EX_EI_ED_MISPLACED_SIG[] =
+  "extra-info grazie 384E40A5DEED4AB1D8A74F1FCBDB18B7C24A8284\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AcGuIBoa6TBqD8Gg5atcwp/+r9ThxIBkULmPv9OSGhv+AQAgBACXH13y\n"
+  "mUvdpcN6oRN1nX6mnH40LyfYR5um8xogJZk3oINse5cRNrfMgVWiBpDlJZAwlDDa\n"
+  "lx99hzuZBong+CiOcnEvLMsBaVJmNTm5mpdetYclZpl0g8QEXznXXeRBMgM=\n"
+  "-----END ED25519 CERT-----\n"
+  "router-sig-ed25519 TxuO86dQ3pUaIY2raQ3hoDBmh4TTPC0OVgY98T5cf6Y+sHyiELCkkKQ3lqqXCjqnbTLr1/4riH980JoWPpR+Dw\n"
+  "published 2014-10-05 20:07:00\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "kV2CtArl1VF1nUSyHL00mO3nEdNxlQU5N7/hZNTd+45lej5Veb+6vb4ujelsFERJ\n"
+  "YoxwIs6SuKAR4orQytCL0e+GgZsrg8zGTveEtMX/+u//OcCwQBYEevR5duBZjVw/\n"
+  "yzpEHwdIdB2PPyDBLkf1VKnP7uDj059tXiQRWl7LXgE=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+const char EX_EI_ED_MISPLACED_SIG_FP[] = "384E40A5DEED4AB1D8A74F1FCBDB18B7C24A8284";
+static const char EX_EI_ED_MISPLACED_SIG_KEY[] =
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAK0HgOCG/6433VCrwz/vhk3cKmyOfenCp0GZ4DIUwPWt4DeyP4nTbN6T\n"
+  "1HJ1H8+hXC9bMuI4m43IWrzgLycQ9UaskUn372ZjHP9InPqHMJU6GQ7vZUe9Tgza\n"
+  "qnBdRPoxnrZzUOzlvatGrePt0hDiOZaMtDAkeEojFp9Wp2ZN7+tZAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  ;
+
diff --git a/src/test/failing_routerdescs.inc b/src/test/failing_routerdescs.inc
index db3fd70..e2b72c5 100644
--- a/src/test/failing_routerdescs.inc
+++ b/src/test/failing_routerdescs.inc
@@ -712,3 +712,858 @@ static const char EX_RI_MINIMAL_ED[] =
   "-----END SIGNATURE-----\n"
   "\n"
   ;
+
+static const char EX_RI_ED_MISSING_CROSSCERT[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf54AfsyyHhGluzfESzL4LP8AhFEm83+GkFoHbe1KnssVngHAQAgBABNzJRw\n"
+  "BLXT3QMlic0QZ4eG612wkfSRS4yzONIbATKLHIgyzgGiGl4gaSX0JTeHeGfIlu7P\n"
+  "5SKocZVNxm1mp55PG+tgBqHObDRJRSgbOyUbUgfOtcbQGUeVgUlFKWZ9FAY=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMqT7K8cEzWIaPNXbNgvoZ5ejavoszI2OjW9XXetPD/S2f+N7TfQXHBW\n"
+  "bnjpgj87gmk59w0OXTMCv+XofZ0xOy2YR/jG5l1VJIvqgJhhFJ8oSEGVzy+97Ekn\n"
+  "Lb1FEYuVfVxSxnU2jhHW6KPtee/gvuyRI/TvZuwmYWxLRpikVn4pAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAM4nITNe8UykgsIuo5czSSSl3Okr1K+UVWTzDGLznDg77MkLy7mydmk9\n"
+  "vf51OB+ogQhozYKIh9uHvecOzY4EhSIuKhui4hNyQklD9juGoW7RVTSpGdYT1ymp\n"
+  "dDYS30JBPwCZ7KjdMtXiU8ch2WgbzYBuI+JfjwOhfcsuNC9QPfbfAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key lx8o212IYw5Ly2KbH2ua1+fr4YvDq5nKd7LHMdPzTGo=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf54AU3MlHAEtdPdAyWJzRBnh4brXbCR9JFLjLM40hsBMoscAJ8cHMIc71+p\n"
+  "Qa+lg5JiYb551mLgtPWLy12xdhog7SXiJl3NvnMgbMZXHDqkU2YZCidnVz+xqMdh\n"
+  "mjQFK4AtRwg=\n"
+  "-----END ED25519 CERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 4DSdPePrToNx3WQ+4GfFelB8IyHu5Z9vTbbLZ02vfYEsCF9QeaeHbYagY/yjdt+9e71jmfM+W5MfRQd8FJ1+Dg\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "cv1yL8HhQzQfjzkSosziu2kMecNUQGle4d103h6tVMoZS1ua1xiDpVKeuWPl9Z0+\n"
+  "wpFwRkOmK0HpNeOXCNHJwfJaWBGQXunB3WQ6Oi1BLilwLtWQixGTYG0hZ6xYLTnX\n"
+  "PdSQIbsohSgCzo9HLTAgTnkyBgklIO1PHJBJsaNOwfI=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+
+static const char EX_RI_ED_MISSING_CROSSCERT2[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf54AXXgm0CUWQr+rxvgdIslqaFdBiwosT+9PaC8zOxYGIsZAQAgBAA6yeH7\n"
+  "3AfGIGuDpVihVUUo0QwguWDPwk2dBJan7B0qgPWF5Y4YL5XDh2nMatskUrtUGCr1\n"
+  "abLYlJPozmYd6QBSv6eyBfITS/oNOMyZpjDiIjcLQD08tVQ2Jho+WmN64wc=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMdyTK/VPZloLUaLsvj1+NOFs33/E9HmA0VgvZ1nNUrR+PxSR71QF7Tw\n"
+  "DKz+/p2rJE+MPfQ/Na3dH0vH4CDZ+FH2m4A8SB9emF8aKxdc/7KCjQNDQCNlEQYn\n"
+  "O9WvZJhbNPHUmX0z4OotI+Sk3qBzVHu0BGDsPYC9gwszIumDUILxAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAL8o6CJiLfW4vdRFvJ2nFt/H/ei0ov83rilOuwSmNORmL9lvnHY++HrD\n"
+  "dmEEvBv74xqWJxGbJ6OQ3VOwRpf2X/cb4gAvsQDqDmNwpJsrPYRQVXp/KY/8z7bJ\n"
+  "dM4CjcsuJHHmj3yc3iCzgqt/Xr6vR24X4bee12/bP7R8IETvWoiHAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key qpNEGrLMVn28Odonk/nDtZq1ljy0fBshwgoAm4X1yzQ=\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "i4RKGIeaUrO6nzfdtb6j+ijYJh1Vgc9bsHMpW9cVCOjoJKFW9xljgl9xp6LytviN\n"
+  "ppKYCt9/JflbZUZjny34ESltPGrdquvHe8TtdQazjiZBWQok/kKnx2i+PioRF/xI\n"
+  "P8D0512kbJjXSuuq9tGl94RKPM/ySGjkTJPevN4TaJE=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 pMAOpepn5Q9MxcV9+Yiftu50oBzBsItQcBV9qdZCIt3lvSFqFY9+wJjaShvW3N9ICHkunrC0h/w5VEfx4SQdDA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "Du5fJYDzvEeGqKTJwgaQsJJgz39K/J4qEM2TZ3Mh0XuDM1ZWDtjyzP03PaPQqbJ1\n"
+  "FsN5IStjOqN3O1IWuLzGaZGpGVuqcyYOxjs7REkGQn2LfqCjpzjaAdcsL0fI4ain\n"
+  "o/in8GQ6S/qhsx8enKlN0tffTmWmH9bmmVz0+yYmBSo=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_ED_MISSING_CROSSCERT_SIGN[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf54AfoVFYuJnDNBWbjbTqfXACUtXWPipmqEYC++Ok/+4VoFAQAgBADH7JzI\n"
+  "fjSMV158AMiftgNY+KyHYIECuL9SnV3CSO+8+I7+r9n+A3DQQmGLULo/uZnkbteJ\n"
+  "+uy6uRG4kW0fnuBlKhseJQm9hjNGWzC8hmebp1M+bxwG41EGI7BZvnTrRgM=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALEqlijoFIDX1y1i5zfei8DuDIsFtSw56PGgnMRGcybwD1PRQCheCUZM\n"
+  "erQgFCWjgLgvGJERBK/oILW1dFXp4MAR5RgnrPGTfWTinCj32obMLN1gIczpq6a9\n"
+  "P9uv6Cz0ApSxpA/AuvjyAZwQKbUXuMvIY4aTprAKSqqVohk6E+E1AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMZbbBjGV7xPri4XNmejq4add93p+XsWlsfbM930bcC2JZiwg4g4cq6W\n"
+  "idl8VDmCXeaWg5y3kb82Ch/Q9vPG0QYQbXxUA3JxQKKbcEK3QsEvqQh8Nb7krILK\n"
+  "YnSGAnLG2Nc3PnKb7Wpb8M3rAysC5O99Gq1mSfm8ntj3zlIM7NSHAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key CYcpfIF4T9PJcfROfVJTUYl0zNd4Ia5u0L9eng/EBSo=\n"
+  "ntor-onion-key-crosscert\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf54AcfsnMh+NIxXXnwAyJ+2A1j4rIdggQK4v1KdXcJI77z4AMRc2LxiKbyr\n"
+  "fqRVynHuB031C4TN/HAlNPBjVoRvQRgzpiyyoyCqMDxLZdM8KtzdLLeqZJOXtWod\n"
+  "UXbYG3L70go=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "BRwRAK2lWxWGS49k8gXFHLEQ/h4k8gOQxM0WgCaN4LjAOilLHFjsjXkmKgttVpHl\n"
+  "f0V9ebSf+HgkpQnDSD8ittnr/0QaohUbD4lzslW4e/tQYEiM46soSoFft85J6U3G\n"
+  "D3D63+GmaOfIaa4nv7CD0Rw/Jz0zTuyEuARsdJIr1IY=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 7XfV5r7FXbXPEvrxlecWmAJxat/6VT+/4tE5cHrQnvLM4zslysstWH6/AfIfcmUuDlQ0watmfg1MvVnjavcfDA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "eigLL3S/oMGL2tJULt9bl3S0iY+YIxdKeGFCcKZci59zD786m+n+BpGM3yPpvrXr\n"
+  "bGvl4IBqCa1I+TqPP1rM9lIEcUWaBT7Zo5uMcL1o+zZl1ZWPWVVKP5hC5ehDueu8\n"
+  "/blzNhTEFAp23ftDK9PnFf+bXxqbgKkEoZsxnd3e9Ns=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+
+static const char EX_RI_ED_BAD_SIG1[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf54AR8QC+SNBpPOTVY198IQBANNwZjy+SBqQNxfzjEmo204AQAgBABjz4FP\n"
+  "zW/G+fu7YirvANvvqJeb7S1YYJnf6IrPaPsPRzDqJcO3/sTzFC5OSb9iJmzQAWnn\n"
+  "ADPOl+nOJC58XJnJ7CUJdPtyoVdMvUiUT/Jtg4RuCN1iDaDYaTh2VavImAY=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAKuLC0kzCBTV6+WPZcAOQPKjqbjvMIyaehIQS1o90dYM+Tosrhtk3bw8\n"
+  "QBLMaiWL3kfIWPZuWi2ai40dmqAXMrXH3yBgKRNZ6zZSbUUuJ1IknqmrQ2PKjC/p\n"
+  "sIW2awC6Tq+zrZ7vntDb02zY857vP59j8eolTDg1Vvn6l2ieL+WhAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMnBQPOJBQLZ3NAa70n6lGZGvS3DYZFNOZ2QnHVeVvOSFIFsuvHtnUdX\n"
+  "svDafznYAuRFRVqJS2xtKKGu0cmy6ulEbBF+4uAEMwQY7dGRPMgVF1Z33U0CSd08\n"
+  "ChCJGPTE7tGGuoeSIGN3mfC4z2v9SP3McBdAiLHisPzaUjfRTcwRAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key W8fUvBpKBoePmqb70rdJUcRT0NhELDWH7/BSXJtkXS0=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf54AWPPgU/Nb8b5+7tiKu8A2++ol5vtLVhgmd/ois9o+w9HAAPwWqmL0HXa\n"
+  "bYKrKPWQYnpQHQ3Ty0MmCgj3ABF940JURnV161RlN8CRAOJaeQ0Z8wBRLFC1NqLT\n"
+  "+GVdtewGeQA=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "x0vT5Wv7Guc0/Vu2BqomWwenh8oda9+8K/7ILi5GQL/WC29Tj51i0EE7PVSnSMJ7\n"
+  "33I/V+N5neauqWnbg7TxYaLsPfr6SpPTpBL1Xt0OiwT1//PvPYZ1gCcF3ig3KcfI\n"
+  "mreQd5C5Vri6ukWkMtz/zNDaDpDanzaNXTdaUXmFHF4=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 4DSdPePrToNx3WQ+4GfFelB8IyHu5Z9vTbbLZ02vfYEsCF9QeaeHbYagY/yjdt+9e71jmfM+W5MfRQd8FJ1+Dg\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "Hci/Br1+NNymDZBmQy1QWMlCeLe8Z1vtZ2ZTj42jDhWg1OC/v72ptI072x4x5cmi\n"
+  "X3EONy8wQUvTNowkfG6/V/B768C7FYJYBId1GAFZZymXnON9zUYnE3z1J20eu6l6\n"
+  "QepmmdvRmteIHMQ7HLSrBuDuXZUDJD0yXm6g8bMT+Ek=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_SIG2[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf54AW8fyx54c7vQQA/AmShAitFP7XI1CLdifEVPSrFKwYq6AQAgBAChqjVA\n"
+  "/wKKJZ30BIQoXe5+QMiPR6meNxF1lBttQ2t5AhauZbH5XzRhZkdGo114wuyPNEM9\n"
+  "PrBwp5akTtari9doVy6gs3McqdoIbRdWevpaGj5g5oOEOtA9b5UNWQSwUAs=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALp0Croi9zhpGxi9sUj54jr/flZdzxVVS+8VNldJG2c1soSx8kwlwotu\n"
+  "7mGGudJDAzDHGo5F5CCPEfQov2OmDehpefYUz/AaMLly6PrLRJlcUcpLogGf1+KU\n"
+  "1lLwE8kanXUkgvDhVQiFvNjy2Dxxuv3AHH4WdZZfbMbm8FJRGoHzAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMoI9vQT4g2sV2dViGOWOzxckk367T9sMjVwcYfJCmnixGxjWeKScQFB\n"
+  "K9v1uK73cfZR8AxiUGK4/iOX/9en14mJOGF7fftAqypFLAt1TBvb07IgXljOBoHc\n"
+  "Paw4oZoJQzEoazt0Oa181LyNnNIoaZpHVZd1+a1Gs1gKoM4xDBv1AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key KjyvXYkMcpke5ZsUYf2gZAUNeEoz8NAwYoQvvbcDGiw=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf54AaGqNUD/AoolnfQEhChd7n5AyI9HqZ43EXWUG21Da3kCAI6MRHm7GpCF\n"
+  "/3zDGR/6jKe625uFZX9HpLt6FgAdGSJeMQ9W4Np9VkrFXAB3gvh7xxRzSgZ1rXgR\n"
+  "lUomgi7N1gc=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "xJXvCCpP4ExBuT3OTsdn2HJB0HidupmQq5zBh8fx/ox6+047ZBOM7+hVxxWapcMg\n"
+  "PMXbcLD4L/FCBpA/rjnFUE/9kztdq7FH/rOdi0nB6FZWhwDcsZuyfvbnDTxz5iHJ\n"
+  "87gd5nXA5PE649SRCxW5LX0OtSiPFPazu4KyyBgnTIM=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 4DSdPePrToNx3WQ+4GfFelB8IyHu5Z9vTbbLZ02vfYEsCF9QeaeHbYagY/yjdt+9e71jmfM+W5MfRQd8FJ1+Dgxx\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "tk4kBNYqB8utOmX30HrV8YfnwBXYODIiL3M/juRS6nPn0uvbW7pjoZ3ck/ahgW+6\n"
+  "FNQsgTJnEADCWS1r6v7PcvzQjtrOUUpNxGJxYw1r8yZkvmIxSQD6GMzuTxq7o1VA\n"
+  "/wZYDLonLhCWRdPjxnrl12+z92NdyISJCHMLRVqs2QY=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_SIG3[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf54AYYiKZrFWZ/Cj5mZbfK11MZHYbwchllsUl4qPqY9gfi6AQAgBAB4irxT\n"
+  "86FYA0NbZssSTmfyG6Edcf0ge61OwB4QD35kHCrvuZk2HnmL+63Tj4QoFqIVnwVC\n"
+  "3wRGJGcmS7y+vS64GUXbuyTgqgpl/KuoHo5Aqe6IxJlVWYtU6W0M6FV9tAM=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMUEvXTVTl5xkQ2MTEsB4sXQ3MQkz8sQrU63rlqglpi1yUv24fotjzvE\n"
+  "oJpeKJBwwg5WBW/fW0bUDJF2cOHRHkj/R4Is3m+2PR1Kn3UbYfxNkFkTE11l099V\n"
+  "H6xlsi0TJOJKlgrcbSuB7se2QctZVhwsdsJvFRptC9Qd+klAPb7tAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMooTeSUX7GPoyklSd1/6cF1u8e2LbjOLIpZrMon0Xt7c/aNwlrG9rVo\n"
+  "TSokHs3AQ2H2XIceySVRRWR4AdX9KApO4CX0gGTuVUmq6hFJWMnHdAs2mKL0kt1w\n"
+  "I+YWzjUqn4jIVa2nMbyHVQWzIysWwWiO4yduIjAYpBbWd9Biew4BAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key BN0I+pLmFkDQD5iRsdkcped4eZwGIuXnLiX2K0Zoi2I=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf54AXiKvFPzoVgDQ1tmyxJOZ/IboR1x/SB7rU7AHhAPfmQcAOrIvaG/xJqe\n"
+  "adM6mai+FlV8Dbt6QrXTcNHJU1m+CUDthA9TPTAYz9D8W0mTEQ6KEAKGfQrNLy2r\n"
+  "G1B+9wWSpA4=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "BpLBsl6Yo64QzczJn0TjdcXC1Jv9IhUG2m/Re3v0voCELOP+t5vkZXXLoVL23oKv\n"
+  "JheSkWiuAIEPsatb4afXZ8wZxPcQjwy3zTOBM7p9CG5fA+KYpqKTxAi+dhVYlcDo\n"
+  "M7S5nMV63FclkZIT70FFTHwWed1sAKwEO3/Ny24eppc=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 abcdvEzGFYMcJ/Ea7sbessW1qRJmnNNo2Khkkl0rEEgtLX0b4L4MMhK/ktS52Y6jX3PRQWK5PZc6gjV7Jaldh+g0Aw\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "Vyj7g3eQ3K4+tm49fJkAtsAYnYHcEiMnlucYCEPeKojzYStNfZwQO2SG5gsoBIif\n"
+  "urgQZ/heaF4uiGFg64UFw08doXqQkd5SHO3B4astslITvmq0jyaqzSXhdB5uUzvp\n"
+  "QCR0fqGLVS1acUiqGbRr4PiZ9G7OJkm230N3rGdet+0=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_SIG4[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AaEnncX/t0cbLm1xrtlUpkXghaA8fVuV7g1VF3YNfCaIAQAgBAC7Ki3S\n"
+  "zzH9Aezz5X4fbwHeF+BQEDfVasfyTxTI4fhRi7t3RxHzBJd60uEMXy2FchD8VO5d\n"
+  "j4Dl7R4btrohPVSVBQZuemBQSW6g3ufNl0txpFWu0R7vBPTFH6oyXYfY9gQ=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALGKwzhOui2/jJPjU1ngW5IZRPcoDk7RAfGDO4xaef4VfAFHCV9CQO1c\n"
+  "/wQ09CcRdggTvUcv9hJTGJhSObUUooCkxw4/35f/A6/NoW1Gi0JqF9EsQWHpuAfr\n"
+  "n/ATlJQ9oGdTCNDq/BXSPWXhoI6UhUe0wiD4P4x4QwaYHcZh+lE5AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAOKrizVm2h5/jE/HqqLCBLWJZVVoGspasCtDDqHhSqsPzyjpqa52iMKi\n"
+  "q/deJ92le3J2NJRGKxPmPQqWxwhIjnMS5kUMoW182iLpO/G9qyPZ0dh6jXB0NBLF\n"
+  "ySfW6V2s3h4G4D2P+fqnsnzQnAX7YufkvgDau/qTWi2CqD0CjavDAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key A9h8jY9dPbhHTDbIc/NYWXmRP65wwSMrkY1MN8dV3BM=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AbsqLdLPMf0B7PPlfh9vAd4X4FAQN9Vqx/JPFMjh+FGLAN8xr/w3KFVi\n"
+  "yXoP/az6hIbJh0HYCwH8D1rPoQLcdpe8XVwFSrHGarZesdslIwc9dZa/D1dx3OGO\n"
+  "UhJOrdv51QY=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "bLmdO7ME5vq+c9y/Hd8EyBviMBTeo85sHZF/z6Pehc3Wg3i1BJ8DHSd1cK24Pg48\n"
+  "4WUrGTfonewuzJBDd3MLkKe6epXmvUgvuQN5wQszq1+u9ap/mRf6b3nEG0MHxMlO\n"
+  "FLx5MBsScuo+Q+pwXZa8vPuKTtEjqbVZivdKExJuIX0=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  " router-sig-ed25519 4DSdPePrToNx3WQ+4GfFelB8IyHu5Z9vTbbLZ02vfYEsCF9QeaeHbYagY/yjdt+9e71jmfM+W5MfRQd8FJ1+Dgxx\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "LqNGEa10zwSPeomBXTfgvBnnWAdWyiR7KYZq9T++jK4ctR6hUaWngH8qSteUrkMx\n"
+  "gyWb6UMmlxdfOG0sdcU463HsqV7zObaKya8/WwQ9elj3FfsToswUCeOaLR/Rg7wC\n"
+  "zcUjI5VsneQoXT2WVZbZBLsLB3+7QfezVHRMB377GAY=\n"
+  "-----END SIGNATURE-----\n"
+  ;
+
+static const char EX_RI_ED_BAD_CROSSCERT1[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AV1AfOvQWKlWsbzoBdJc5m72ShIJuA8eNV15basjhXYdAQAgBABy+KQK\n"
+  "3oLDGtqL5kwRmjAsls/+C6SAoAALll7U7wNSH7en5RVBal4RUzCf57ea/KG0c9V8\n"
+  "2DmZ3PdOt2aY/M2bWGmmH/tyyapOoV98dhDwFU7zcx/pMfRnJTDRSDwl8QE=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMP6xbqbj+x1mq5XImjeT0rUzqKZTgBd5zvK4Xcy9IifJuFC9+mMzrY4\n"
+  "WhYbdClxKUkDMkit9MVhek+P/w5TSHKl6AuqGaO09ID+hZpoUSdoBUYktynxfGsx\n"
+  "kIDu0XvgtAeSyJaVvoV1SKVChY0IBbzUqbHt4O2Q1BhzFCKEJTEzAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBANwWlBh7e/eSLlhto5YUdj1iGYOq+yAmlosDItVfYrSPJuUfM2ocMBAn\n"
+  "udbRbWiADoqsbKn/gwwHCC/f1HX2FkRXxxnOlJKLo+NEi8tGmOlcQXSQol1pCpvK\n"
+  "sA9TxtYr+Ft4LRpxNrexF+pIBxqzwetqQrZbKYr0CFJi8q1qlMynAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key cs1AP+xF5cXTLuKeOeItdoDAzfALTJkwk9lB4mtC4QI=\n"
+  "ntor-onion-key-crosscert 3\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AXL4pAregsMa2ovmTBGaMCyWz/4LpICgAAuWXtTvA1IfAKo6ANUq+hi+\n"
+  "xb3J4aYafnszlj87oi/DR+SDf29wzwNw8gmaqGzJ5GbfISfABuTUCzlilZyVnLxi\n"
+  "BHcCH6PWiAQ=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "qC9Kph/kGtONR2DxZDoIFFgnDFC+/7H07EgCiYQdIFIROc+gGK9qBOgeFEptrkXF\n"
+  "XdE35xxox5xSASQvp7hjFwxUtJRGOtf2O98regqeeaz6O9VPXHkLf51uqX3bVgq8\n"
+  "KvFAsFFS66GxhtbrVjpyRgIwHAYvse1WVESfLuZZTn0=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 3uW8Q1aetIQLOsqSco128ZUaHlhqdYiBvrxV7x75BGNS5RzIMTEwYDNtEX1LNPFJ5N0YOV0HEEOLhrJUV9QCBA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "WuD7S/saTYBxKvItITbHRi8n+e6g/oVbosicfbRbafYPzPp4Prb+RK03UTafzXrV\n"
+  "QEQIzDNhfePcIMH8qX+qrogLMXFqiXx6TVQ0GqNvqirokk8ar3AgtRtewhChAuAj\n"
+  "8pmQTj2JpZn/iB3PCE2l/93O9LHZfp44hc8QOWKs6BE=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CROSSCERT4[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AW5TTGF9jCMl7aALZzqypD9Bj8WYnAPIrKCoIJdgMbY0AQAgBAB7eCn8\n"
+  "rukx7t/egZUdqU7+FYqsnO4wdmOkLZkp0+gpF3jjk6N1Q0037NNVNZBjONB0Nm2F\n"
+  "CpB3nWSJliSSKr5tOYsuBPFy5VVGYeKPakpOoxanQ1UcqevMBAQy0zf9hwA=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBALeS5YbeDuKQ5iiuUvh3REoyJ47/YU9lslWmTrVBf9b66pMnYJv/awPu\n"
+  "m2HredUAJ3VzwQ38VJA39w3fQXUhQDnQ0OPpKzeAmIiuG+6WdW/mBSK7uKcezC23\n"
+  "LA1d6Afyl79LjZz/n+ENXqNMlJk4QPcPHuRnAvwBl3t8YVRPJmxhAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAPprokY7utWuO/0252dBB5MCxmVD/dROaIBDyFtpdH+YVv04rkOlDzYD\n"
+  "W4mgHVBMxEm/cspTgQmJ4exRHJPpcSe1RYHt1ONZdLYr6D7OOWf0y1IUrVSzF6K4\n"
+  "lqlmNuH1H4+TKGbkvixYc5GU/2ZmAy6gFEuphYnBbsN2Ywc38mnfAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key Cgo6xniGfEiuYoLSPUdE4Vb2D4zj2NQzC1lRjysRRXs=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf54AU3MlHAEtdPdAyWJzRBnh4brXbCR9JFLjLM40hsBMoscAJ8cHMIc71+p\n"
+  "Qa+lg5JiYb551mLgtPWLy12xdhog7SXiJl3NvnMgbMZXHDqkU2YZCidnVz+xqMdh\n"
+  "mjQFK4AtRwg=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "bi4M/AJLZF7/vSNmOj4uhrgKBQA/KfcZy5e58mhGL4owxd9vaWfl3aelvb9jf9zN\n"
+  "Q7FMv8f9aXzeVIoXIpRJxSKIJgBtG2wnMumIc80pqBvTyGInharszb6njfm0bg1u\n"
+  "PfJkbQYyf/dA5l5UwCrjFs06ImDmjFTAdsSWf6DfZ/k=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 4DSdPePrToNx3WQ+4GfFelB8IyHu5Z9vTbbLZ02vfYEsCF9QeaeHbYagY/yjdt+9e71jmfM+W5MfRQd8FJ1+Dgxx\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "io16v+e0pK3sbFzPGnkQrAjrRgIOJHrVZ1RXcxZ1+UNXagWM/MOLhQpkU/cw49Wd\n"
+  "4rQeZD3JQh16330eXbxc97AyDgp0b30He846SI0MfW/DnmGI8ZNeYfLbMv2bmbs9\n"
+  "QULzyIH8C+5mnMI1arcuiAua+Dpa34F79vgqPuvw5fU=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CROSSCERT3[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AVB+j+B2yPgGywvp7nvejyhMh9ejKmw7LCwufV83Zl9eAQAgBAConA3B\n"
+  "jJ3X2tES40jd94rRUFS2/s/Yv7E4LEQ9z0+jz8horNivzK3O/t7IGxJggi+b41/9\n"
+  "Uaqt+wqtVuKj0xJ9jwBlCXFt28G2P9s4ZyXYgGZqo7MlJlboybnOMvmoTQA=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAPWuEWckT4aYAVNrZzLA8xVwfXp0wzfXeTWBztLS8VzssN6w/+cwXdeY\n"
+  "N1YNc2DiD3u8f+7kmuZIqL1EFQUwTvRwEzQXm2dqGM7qkm5ZGNMb5FKu+QwO2ImI\n"
+  "FLNiO5zO/LqP3cf/2L8/DuvruLenUrhRtecGFaHmhDYl+2brHIiPAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMtHTfk0gDvp9+PtIG8Ks7rgCiJZ2aihSvr6WaKHYuIprgspFuga98cg\n"
+  "D//J80CrgH5Dw68YnkG+gU40IxP7YzhQ4glFlJGu3s2y7Qazcv5ww1XtHur+GDoA\n"
+  "cY0zCLhltNQFxIsoVUepY97XA6Y2ejYJjyqNXQcAmoPNoVhnTdkhAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key ibZf57LptdOK3WpVFXkYMatEEqPhuVWxsnkwF6638V4=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AaicDcGMndfa0RLjSN33itFQVLb+z9i/sTgsRD3PT6PPAEbkxCdI/bH/\n"
+  "B06DAjRuoDiv1HKsGuW+UN1iGEiWu2ieFzf3m0Z7BL9p2u2zIbHYkP50b3T3sebD\n"
+  "1AksemmMdA0=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "BpLBsl6Yo64QzczJn0TjdcXC1Jv9IhUG2m/Re3v0voCELOP+t5vkZXXLoVL23oKv\n"
+  "JheSkWiuAIEPsatb4afXZ8wZxPcQjwy3zTOBM7p9CG5fA+KYpqKTxAi+dhVYlcDo\n"
+  "M7S5nMV63FclkZIT70FFTHwWed1sAKwEO3/Ny24eppc=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 XS4zVi46Xl3xKhuozPCDlW0QRFD4qUhJmkefonQNsRlMVsrPkALnP2tfnfdfTc69hbNa22pOjJNf6Gm505EnAw\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "Q+R3OpO8VhfvFbXuE5qolhVbgosBHy2A5QS91TMzCbsxa8pBA6Li4QdPR37wvdLq\n"
+  "KayfmmNCMKU5qiZMyXqJZm4fdpxiSi50Z0tYlXM3b2OVfza3+pSOEBl89fN6G4Qc\n"
+  "pAmM14eEo1UzXrqZw76tMS2CwOYF5vR2xFGCYC0b5hM=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CROSSCERT5[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AaCfOaispi7dJhK0c8HXJHIwoBkMgRpmmHu+3Zce/soMAQAgBAB5bAIo\n"
+  "5i4TSY/bV2KQAyziRwvgJm+nEiECClflPbP9Um+zOzOgxtDmNnR5UFQj+VWNG4uf\n"
+  "5lnaryN+PfUXZMTcs8AARof3fFz9tVPINHDrsGvKt8gpzgZEHkVioAXOFwg=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAL3Fr/ovZ9SMGYrAM24taKBm/NpemZaXdD/JeBXFYm5Zs3szLwJC4Etm\n"
+  "zjNL6tVy+I21O1g3cs16TkflcidsjPXNx//PHAn7bqWMekjrt3SQdkHW2gDPgT2c\n"
+  "zYJ/hBR96JYG796jP3pkfJz6Iz5uT/ci3A/cdaVbzM1uZbMUgYGzAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMHB+1dWa8BBrKE94vTqfbkSEuysG5LyyZF/WrqHq/3W+ocDLz795k8O\n"
+  "2Zvgr9im/Ib4hD7IyrtRexcuBdwujdG7cBALdCcWiUTGAMkl96HNETSX+lUVIpJ9\n"
+  "pMsc9O7+yz+/0Cl2RpILZCdE/7I96qHpZl3tzlRKSu15WeIm5U77AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key GXi0a2VLcRHQMMYys85zu3IPqOn5ZTsOixYyQvTGnQs=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN BUTTERED CRUMPET-----\n"
+  "AQoABf54AU3MlHAEtdPdAyWJzRBnh4brXbCR9JFLjLM40hsBMoscAJ8cHMIc71+p\n"
+  "Qa+lg5JiYb551mLgtPWLy12xdhog7SXiJl3NvnMgbMZXHDqkU2YZCidnVz+xqMdh\n"
+  "mjQFK4AtRwg=\n"
+  "-----END BUTTERED CRUMPET-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "T9NHMBhuJo+TlfU3TztNgCc9fK1naNRwPOyoqr5R6lJvJ40jkHnIVOFuvuzvZ35O\n"
+  "QgPbyFcMjv6leV5xcW+/I9tWaBUFXiRGI27qjCFth4Gxq2B6B2dIcQliLXSvW9b+\n"
+  "CMTgDwVa4h2R2PMh18TRx1596ywE09YhCgBF3CwYsiM=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 sRpiP9kyW/DGOphp4V2VCtcKNA8i7zGuv2tnljNIPTB7r7KsTvdUk/Ha9ArRQEivO4nC2HHENtknDl3GtWIPCA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "DtORw3+gO/yUUIp70xDaWSOgQZrJAAoZTNCB7q5WCoZOngeaCiC1Gtc+Fmdn7tER\n"
+  "uPqQC5H/Kh3Mi82PCj0JxvNivnNTNY1AZVaIX5YoioXVOkWF0B2pqMvFuDSdm2oJ\n"
+  "29PqSVcklquu19EjJRTopIHvYn3sFhQL4LarMsYY11c=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  "\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CROSSCERT6[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55ARMMCtQ8pObC5bq02AUE9Lx2bqsZBBkeOsDZVaEq6JavAQAgBABtV0xF\n"
+  "CsWXL/uFIBnoEsnXBeU1MvYRFrj1vR7QHdWXnxywXvBYUAC8lu/uyc8qqLp+aQSJ\n"
+  "5JzpDYlg3hp1fl5k97iv5F9WrR6s554YpmgYy9agFaxZ4LmRgz7n0UJ8mwM=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAO5qd1TndKD2pEs1ZLWsHlvfO/E7cA0H7NKGLSioGpBf4P0rtkueX4ci\n"
+  "kJNa/4Fn/QsLECqEF2lUjkIc8YL+HMS6qteKvN8+nn16DfvnIhPDNZWTJjLl1bOI\n"
+  "sWSSiduhanoWQnhRtl3Rxg3opdNd9ApO0DLUNy4Qy18Ai6SgksfHAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAJkMYNpK7eJJyGwD/xG/iNg6gzzbIwrOSvmtoP7Rot42qtBiQ9A9kdsy\n"
+  "sazwkWkM93U1+1OaAADPYxeHoyHnuia95Cnc5y2lFSH3I7gnGGSPKSTwXtdyvDWZ\n"
+  "P1LbmQ4Bnh5leTCNZ/eFC4/GjNVzqHxjbb8a11dQhA8dOk8PrUq9AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key HdSQOqvLr4YnJE1XzzVIddgKgnjaHKJqnq0GqF4wXDg=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AW1XTEUKxZcv+4UgGegSydcF5TUy9hEWuPW9HtAd1ZefACVwif1deQry\n"
+  "K5GeemRa32sGzujVDDe75WRiPKFT3l/EtjTq3oeVq2xwbVJklnG3ASejKTr3YcHt\n"
+  "ov0jOl0jywc=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN NAUGHTY MARMOSET-----\n"
+  "BpLBsl6Yo64QzczJn0TjdcXC1Jv9IhUG2m/Re3v0voCELOP+t5vkZXXLoVL23oKv\n"
+  "JheSkWiuAIEPsatb4afXZ8wZxPcQjwy3zTOBM7p9CG5fA+KYpqKTxAi+dhVYlcDo\n"
+  "M7S5nMV63FclkZIT70FFTHwWed1sAKwEO3/Ny24eppc=\n"
+  "-----END NAUGHTY MARMOSET-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 lNY8TRX/FZdH5eFbsBkFHuRi8bPDsE5P+v7zExyD/IXnKS/ffYlP8qw1XIPdEDOIzGQ14+kyPX0SotaAqHRtBA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "BHamS+epF77iozo5cBt+tbs22m9GhwY55DRXpEWAtvn67jsMnmn7qCOLONigK1RT\n"
+  "adZNezIydcCxXltgHTdKaZw4lcqv3s0KL8kI8frbBmm7PjXtWnrdXBYY+YK54MN/\n"
+  "t4N3162o9hzzKSwye0gPjgzpQ1xtEIkzWhBcmE9Vw5s=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CROSSCERT7[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AfVmH2ReTyatl4VnS5YREtCM2dwikWuAPffq6M5bysZxAQAgBAAXoqE7\n"
+  "taqwLDXLZrZukpF1eBkCwYQK9uzctHTuMdqOHChguvkfX7V4H3O76Ayqvz+Z1ut1\n"
+  "KYRdgiArn3viRaBv3ZKT4Z75suMI3bjqGOSGLAKfOa0uLkOmKblHHhSUkwQ=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAOLNugzUezzzw+N1SuQWzILJYkUJyQDoVXSZjT0dzBplHCjlrv0WZCUP\n"
+  "/pbonE7SlCChIovHcdiASaLj7MVaGgYDq3M1Vtgt5vhgGl10/+evBAD1QEt8AVfr\n"
+  "5+PH/sbZvOWucAhNUhOlqFKAn4vdRY39VEEXC5/Jz5fsk1E/DBu5AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAKxzg1hsYMS+0zAIrgYxSGO0GbKRrL/VhdlMEGu7ACaoqlGnmGQS3B4B\n"
+  "gLk8xDdx9N//8+YTx0hUIxP38w08lubPl1WXMq8s7wAiFd06Nklf65mHs0sXVtS1\n"
+  "EG3f97PQqmBpEJOwYBATNcA9e6F62P8SXNkpSjOzNaE0h9wHNKk7AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key msdr3O4W4bm/xdmZLzj35363ZSFex8yQxLWsV3wRCAQ=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "VQoABx54AU3MlHAEtgPdAyWJzRBnh4brXbCR9JFLjLM40hsBMoscAJ8cHMIc71+p\n"
+  "Qa+lg5JiYb551mLgtPWLy12xdhog7SXiJl3NvnMgbMZXHDqkU2YZCidnVz+xqMdh\n"
+  "mjQFK4AtRwg=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "RJJRiU0vjVtRi3bVZru3aTvV5l56X/WOOp/ii316yPAS3aAMpOm1+piFVR5MNqcB\n"
+  "ZGyrA2Kx0hawdL2buU47iZ12GOCi4f1Es4V4N0TQgJICsKX38DsRdct9c1qMcqpp\n"
+  "1aENSRuaw0szTIr9OgR7/8stqR5c3iF1H5fOhmTi6xM=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 4DSdPePrToNx3WQ+4GfFelB8IyHu5Z9vTbbLZ02vfYEsCF9QeaeHbYagY/yjdt+9e71jmfM+W5MfRQd8FJ1+Dgxx\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "F3ZqvsyL6RRhPEnNFFIZY4WJM7LK082rseWzRkGNXjwoEwOWUK8enQ4Wjit+wozW\n"
+  "4HVIY1F+vP7gm6IiOEAFgEpB4C8FGuyoFw2q0ONA2tqTcvBJDDnqbx08FO7v2Dij\n"
+  "d3ucfc5gf7YNaoFCMMuyAzC56eyNk4U+6cSKy6wnJds=\n"
+  "-----END SIGNATURE-----\n"
+  ;
+
+static const char EX_RI_ED_MISPLACED1[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAKT6OIN6TsDB+xcp1uLeE0K3aiHGqa7hdxMBGpvcD0UFSyzpVv1A/fJa\n"
+  "tClDCwTpfTGbyK2L7AO75Ci0c7jf6Pq+V7L6R7o12g6WBTMrgsceC4YqXSKpXNhi\n"
+  "oudJyPfVzBfKcJUSynv89FUQOyul/WRRqWTfv0xUsJ3yjuOESfCNAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AbBV9NVz0Hdl0Uiv87LiXaTAoeSXE+bheNG4Dju1GzQHAQAgBAD16h+T\n"
+  "ygzSgPN4Qat5ITthvm+lvMwMVGbVNWMxNy9i33NGhgp8kqMp2iPAY+LhX8It2b+X\n"
+  "8H9cBmYLO5G7AlMPj7GsuWdCdP/M/ldMvFfznlqeE3pCpRas6W48CFJ+9Ao=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBANMO/MepK3uCkKTLRCwIWc/8URVza2gEmDx6mDTJIB/Mw8U8VRDuu4iJ\n"
+  "v+LL3D8/HGLvT9a8OXbl5525Zszt8XueF3uePBF0Qp0fjGBL8GFqmrmFe6plurPJ\n"
+  "TfrS/m3q+KhXAUowmghciVGDY0kMiDG9X/t/zKLMKWVDYRZk+fupAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key I8yDO62Flx5O/QsFvgb2ArIRqwJLWetHMeZdxngRl2A=\n"
+  "ntor-onion-key-crosscert 1\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AfXqH5PKDNKA83hBq3khO2G+b6W8zAxUZtU1YzE3L2LfAGC1uXxN2KwW\n"
+  "w4PqRidM1UPZ5jVOHceZYNQcTzzzArfBpr9OraOO2up4TGte8GVqjJNxrZc1gfjn\n"
+  "CwPW5WxpFg0=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "jLg3D3VO4i0sN8p2qtB6+5C3tai/K4M89mP7z2abQnUTbynOacPoNXIk4o64DjBJ\n"
+  "kaR42yfA7yQZ8Rj8abwgz0Zz6zbd+JjE+s/EklrEEtOl+jZAl3i+92FaHROJojXq\n"
+  "hw+ZEPOb9zgb1UQ7S1Fo+GoqA5bdGm/Wg1kSQielkNE=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 TRKvIl/wIIRD4Xcmd6HYmy7tD0KhVGgoStpWPtX0zmXGZ7+jugItrY0frDu9n82syiruuA45ZOs1Rfi4CbOSCg\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "NYpRfurB1YhFmDAdRc2Sd77S7By2V/0kgEHpJhtySb7efiQsyOA4ZBr1zEFPAXdp\n"
+  "TviKzyS9kN2fnz3hORoqFul33BDZbiLMNLtt5tzp62TYtmIg9IZdjjczbJUgbVLt\n"
+  "KCJL0vM7fdbXkZX61GIBbMYwzwIiHvVxG7F/AS5RbtE=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_ED_MISPLACED2[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55AfJo9FIePrxeDNnWT6SWkoz0/L27018XjUNWEHfaR06MAQAgBAAMgolK\n"
+  "nLg3ZnVv0skzHCfmX+ZR9Ttwj7FNXfhXCsyr860S79OW5LD0/m1GcS9JflWhP+FO\n"
+  "ng5cRb+aqNc8Ul+/4sQudZRx8w4U3d5rOuMGCqhQXnktH9AFzQHFq0jpAAU=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAPeK/znKLRvSUmCIUiZOgfhiRFt7XGN//C2GFuey4xkKiIr9LWMuVe9m\n"
+  "Wx39Ea2UGEtNGCEVvZdJMDVRl7heFTfJTN4L1YeyWx6iNRWlpAmgQOKII7slHwlq\n"
+  "seEULOLOXc9AsU/v9ba9G54DFbHfe2k44ZOwEmaQZW5VF/I0YMMdAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAKFRzlrqPPxEW0nboAJ1qzKFb/vFtvRW0xNVb8RtbOY/NY5FV1hS8yfH\n"
+  "igtugkrOBmWah7cmJhiON2j+TKeBxEoXwJMZeyV+HLbr7nY/mFhad4BQ3Frkl8d6\n"
+  "1kQMhOJswMdwnnVHPNGUob4YAX0SpFA6MpBVj92zmMBeaihqUS9VAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key br8svioLcJCAQxoo3KvlT288p8rb4lQIZNLlplkIKkw=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AQyCiUqcuDdmdW/SyTMcJ+Zf5lH1O3CPsU1d+FcKzKvzAG9XqwmRm0uJ\n"
+  "E49NoHcWr9IzdIwSGo+PJSkVpk95a5p2s065BetCWxEEBJQniajQf2hZ36zmV9rq\n"
+  "a6puqkEAKAM=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "d6QGIVAJL5JjHUyV+aicLIdBYyxHwviKpPcp7uldRF8vfDGFpu0qFgJ5KT+3t36w\n"
+  "QY1r75bvUMG/ZzGKDg95dcK0X2AK6GFlcrYyCoQEVOsuPc1QEUeK9P2s7viNQE4V\n"
+  "tRwG/CvJhPfcnxErzVGfXIeYRL1r/hPNFDZSeSxPPM0=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "router-sig-ed25519 ts9pFk8PnDWtXgQad09XC/ZCbruSx1U1pNOMWF9fyoNG0CodxdDH9Vglg+BOS7Nd9fmsINfPWKCVdVuSSM7zCA\n"
+  "reject *:*\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "YMl6mpQm7UCsPQhZKMm0aZ7fzGevWzRbQO+de20HTn7fVqMWQf2hBDJe9QTN/uDK\n"
+  "/VKYT8SnIBexbrSMy1N5q8kNFKxxUtwA9GRtz620Vvc4m+lz/tnT9qucIKCDL5iJ\n"
+  "eRpnls0JoAMIHKl99zdUioYubmOZuqUaRAdT8ulWy+Y=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CERT1[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AYf+rX8a5rzdTBGPvLdQIP8XcElDDQnJIruGqfDTj+tjAP+3XOL2UTmn\n"
+  "Hu39PbLZV+m9DIj/DvG38M0hP4MmHUjP/iZG5PaCX6/aMe+nQSNuTl0IDGpIo1l8\n"
+  "dZToQTFSzAQ=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAM4o2DrTwn3wrvUMm41S/hFL5ZtRHGRDh26o8htn14AKMC65vpygKFY7\n"
+  "fUQVClAiJthAs5fD/8sE5XDtQrLnFv5OegQx8kSPuwyS/+5pI1bdxRJvKMOUl2Tc\n"
+  "fAUhzeNBmPvW3lMi9Fksw5sCSAKQ5VH/+DlYvBGZIO49pTnOAty1AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAMzIsJeEWWjN3Lp6qrzaJGn8uhJPJyjy2Wt3sp7z7iD/yBWW6Q7Jku3e\n"
+  "C5QfKmSmNi2pNjS0SqPjqZZNsbcxpq/bEOcZdysZG1lqi/QgxUevk57RWjh3EFsG\n"
+  "TwK3ougKWB5Q6/3m32dNsnnnDqzVapgZo7Zd3V/aCo0BVtL5VXZbAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key W28nwT/5FJ818M78y/5sNOkxhQ7ENBhjVhGG2j6KvFY=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AYf+rX8a5rzdTBGPvLdQIP8XcElDDQnJIruGqfDTj+tjAP+3XOL2UTmn\n"
+  "Hu39PbLZV+m9DIj/DvG38M0hP4MmHUjP/iZG5PaCX6/aMe+nQSNuTl0IDGpIo1l8\n"
+  "dZToQTFSzAQ=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "FWnEjvFob0ObgqohMT7miwGsAuioCT7Urz6tyWaGWph/TP9hbFWj4MPK5mt998mn\n"
+  "xA8zHSF5n/edu7wVX+rtnPrYPBmg+qN8+Pq6XMg64CwtWu+sqigsi6vtz/TfAIDL\n"
+  "mypENmSY32sWPvy/CA8dAZ2ASh57EH9a+WcFModpXkM=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 88YqJdGJS4O6XiUCNrc9xbOHxujvcN/TkCoRuQQeKfZGHM+4IhI6AcXFlPIfDYq0SAavMhVmzsDDw0ROl7vyCQ\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "cU4WDO3w9ZfVRbNUgxOQMbwS2xWXvaL+cZmIV6AAjAZVWkLEpif4g6uYu+jJUZOS\n"
+  "NUT7lNOMwTu4tE4b1YJpnD9T8iW0DlOXxlvRBMQYmKwhQuYk898BDGTSk+0AY0HJ\n"
+  "vv8wRVewDajNhW7tFY907IdHvPXG0u83GANxkYrRyUg=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CERT2[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN WOBBLY RUTABAGA-----\n"
+  "helo\n"
+  "-----END WOBBLY RUTABAGA-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBANZvqyqFeiekh8ApqIGK4ZtOqjaX87EzDestvAWwamVOXiPoUrzXgM3O\n"
+  "l8uuTnMA4TfnjLyyA2TnaMzJylOI1OMHuW/D9B/liWDstSxWNNIlKgLQ/Dh9xBS7\n"
+  "uQb2PYlI+iMkPKPyJQSTDdGHE7cdFPewUfhRtJU3F5ztm/3FLBFvAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBANZl8U/Z8KCPS7EBDzt8i9kNETXS7vnp9gnw3BQNXfjiDtDg9eO7ChxY\n"
+  "NBwuOTXmRxfX3W9kvZ0op9Hno6hixIhHzDql+vZ+hN7yPanVVDglSUXcr31yBm5K\n"
+  "kA+ZnRvH3oVQ97E4rRzpi09dtI13Pzu7JS5jRMtH+JF1kQBoNC0dAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key lUrEL+TVXpjjHQ2BIKk34vblyDmoyMro1a6/9hJ4VRc=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55Abm5E7FBdd3F8N1xuz/vdv03zh2lABrmGjzPQ3AFJtntALNeQTgjv0JL\n"
+  "jON4+SPNi0B2Bva3yKaSsdxiHQ1rIwQqIUVkzXmmX4jmsvJK/9gERAdD7GafTKZQ\n"
+  "BaZbNXBvmQw=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "OxkqFsw1vHUQ9iPYcKC/MHUBtbLPK6JY2i81ccAai2eW118UXcTbeCRccrXyqSkl\n"
+  "RLcooZyli1D6wg9x7O8+2+HXIbUa6WcTOD1Qi7Z9wKZfk4sDUy7QHKENMRfAXwX3\n"
+  "U/gqd4BflMPp4+XrYfPzz+6yQPWp0t9wXbFv5hZ9F3k=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 fW6Bt4R3xVk5KMDyOcYg8n5ANP0OrQq2PQFK2cW0lTAdi+eX+oT/BeWnkrn0uSWOC/t4omCmH4Rdl8M9xtpfBA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "DHxiQXuLxZR0ylqwUGGePgN4KF4ItlOV/DuGmmszCO/Ut0p+5s4FP2v6Mm9M92Wj\n"
+  "75rS9xF/Ts0Kf49dvgc+c5VTvhX5I5SwGQkRk0RNJtNoP0t+qXBHaFV8BlAeaWF6\n"
+  "Lg3O+GUK325fQv9uDPCe37mFQV9jafAzsZUrO/ggb1U=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_ED_BAD_CERT3[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "BVVVnf55AW5TTGF9jCMl7aALZzqypD9Bj8WYnAPIrKCoIJdgMbY0AQAgBAB7eCn8\n"
+  "rukx7t/egZUdqU7+FYqsnO4wdmOkLZkp0+gpF3jjk6N1Q0037NNVNZBjONB0Nm2F\n"
+  "CpB3nWSJliSSKr5tOYsuBPFy5VVGYeKPakpOoxanQ1UcqevMBAQy0zf9hwA=\n"
+  "-----END ED25519 CERT-----\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAPgeQNbKwpnTU+qW/2djh66hptS9rcy1B4vdyWkDTdREao2ECuCv691Y\n"
+  "oIw3MpTWvpC1qHIKorunusR0FKgwXw3xQTikXbDq/1ptsekzoIA1R/hltQV3UuGH\n"
+  "zdzHuQXAMX7Fdll2gyya03c3Yq5s+xSDvGdkEeaIoctKjwxp4SdNAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAOzWuH4cPW9rIrfi8MrruMUg4IUVHz4BxfY4/szMIUvzeEAdHn4FYkWy\n"
+  "Vt7MDtUELZsmZeFNmkn72kLxnrdZ5XhxZBriq1Fzq11cSWRBF+SyE1MdcouY4GyG\n"
+  "drw6T8xb8ty19q0eO6C/gw27iqXPAp1clvkroLg6Nv9lGZvsedVDAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key /vYZ+9yLqG7yUnutoI57s96JBl36GTz0IDWE244rbzE=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AZ4zVBWP/fIYEgWmyj0WpO6CkXRJjtrWXtiT02k3IddiAMpYgMemGIpN\n"
+  "xj7TQRULsHHYvo4fLcKrSgndQbUUhfLTUuVhIzbnE2TBLMVOEkpxKU6mTuvTT/3h\n"
+  "MJugrwTWVg4=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "c/Vqu3wtsTsYMdnhTS9Tn1Pq6jDmH4uRD5WmbaCKKrkin2DjuYSMVpypndkdlZDE\n"
+  "He7uF7SUO3QG/UcRIXYOsg9MSLUmvn2kIwef8ykyqlRh95Csjo5DyattUhL2w4QF\n"
+  "tJkJBQAnXWaAVW1O8XimGCAvJ84cxbmZEcpN6WKjrXI=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 Ue7bkPpOoc8ca7cyQj/Vq3BP5X4vwLA5QmpLGw/WfRNVRPojJRxU3RVqWMi3JbsJFRTe6pH6ZHyXER33G5aAAA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "ifKUtbxmqHVs8A0oT5n7Te0c6D/XqWQTc0RxX9OKGspzh6wNX26h0Xa2vpK1Q9Zu\n"
+  "sj61I7vbHuZN6rxiWs9IzJgb//XaNJasX1pd9tbGSXW+yYzc9G9kaa7vp3HcnhIP\n"
+  "XVWzzS8WmOiVNGcF65j6f7yGloTgN7cHMptgJG7pWes=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
+static const char EX_RI_BAD_EI_DIGEST2[] =
+  "router fred 127.0.0.1 9001 0 9002\n"
+  "identity-ed25519\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQQABf55ATrK8IVBWLO2yXKCqXLXJOTu89W2b+hREPO+tCrxjVqWAQAgBACG/vVx\n"
+  "NK8wKVZvf34d75ZObSR0ge1N2RrAIKNslNXBq/tcllIrNE4S0ZNcMpA+hxXoVFeo\n"
+  "jbxifYX7nTs5N3GrGPmkiuo82v2X6ZwoIXJGFnvWMxCjsYsUVDDxoT6h/w8=\n"
+  "-----END ED25519 CERT-----\n"
+  "extra-info-digest E5FAC29E766D63F96AD175069640E803F2723765 99oo\n"
+  "signing-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAK9wHSdRalxkuAybrSCA3dlEC1ZGc7oHOzXRGLg+z6batuiCdQtus1Rk\n"
+  "LP821eZJtEMAE56aewCIHDcTiCxVa6DMqmxRjm5pfW4G5H5QCPYT6Fu0RoYck3Ef\n"
+  "vkgits5/fNYGPPVC7k8AdGax5dKj5oFVGq+JWolYFRv6tyR9AThvAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAKxjxTQ/T/MHpFbk7/zwA7l5b3IW3yVcyVe6eIGFoYun8FI0fbYRmR4M\n"
+  "G5Asu07gP9Bbgt3AFPuEqrjg4u+lIkgqTcCgKWJbAgm7fslwaDTXQ36A7I1M95PD\n"
+  "GJ10Dk5v4dVbrqwoF7MSrQPFtMO91RP11nGPSvDqXZJ4XpwqwdxpAgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "ntor-onion-key LuVmHxpj4F5mPXGNi4MtxbIbLMav6frJRBsRgAvpdzo=\n"
+  "ntor-onion-key-crosscert 0\n"
+  "-----BEGIN ED25519 CERT-----\n"
+  "AQoABf55AYb+9XE0rzApVm9/fh3vlk5tJHSB7U3ZGsAgo2yU1cGrAKBcSzwi4lY/\n"
+  "salCELOLdeZzOjDNnBd6cKp2WJg7Yz5zFlbVbyNk0iwfGmucHk8vQZe5BS0Oq/Pz\n"
+  "B1u/BcJv8gk=\n"
+  "-----END ED25519 CERT-----\n"
+  "onion-key-crosscert\n"
+  "-----BEGIN CROSSCERT-----\n"
+  "QsAQVdDVHtasDbhrZG4ZxImdTTMY7fz3vouAiGyZx6/jCCB5v0gHwTn4xo6pgLEW\n"
+  "LQfMhQZIr76Ky67c0hAN2hihuDlfvhfVe9c2c5UOH1BOhq3llE3Hc3xGyEy3rw7r\n"
+  "5y38YGi759CvsP2/L8JfXMuBg89OcgJYFa27Q6e6MdQ=\n"
+  "-----END CROSSCERT-----\n"
+  "published 2014-10-05 12:00:00\n"
+  "bandwidth 1000 1000 1000\n"
+  "reject *:*\n"
+  "router-sig-ed25519 5zoQ0dufeeOJ/tE/BgcWgM8JpfW1ELSXLz4dI+K8YRH/gUtaPmYJgU2QfeUHD0oy1iwv4Qvl8Ferga7aBk1+DA\n"
+  "router-signature\n"
+  "-----BEGIN SIGNATURE-----\n"
+  "D6KRMwkb6JmVEnpZ825SD3LMB84UmVy0i94xk44OwhoWNKLXhaSTWJgf6AqnPG5o\n"
+  "QrCypSb44bYLn+VaDN5LVUl36jeZqCT4xd+4ZwIRdPOUj7vcVmyUDg3lXcAIk97Q\n"
+  "E5PrQY1mQuLSIjjKInAR2NRBumNJtRw31Y/DTB7tODU=\n"
+  "-----END SIGNATURE-----\n"
+  "\n"
+  ;
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 20863bf..5f68c34 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -437,8 +437,28 @@ test_dir_routerinfo_parsing(void *arg)
   CHECK_FAIL(EX_RI_BAD_FAMILY, 0);
   CHECK_FAIL(EX_RI_ZERO_ORPORT, 0);
 
+  CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT, 0);
+  CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT2, 0);
+  CHECK_FAIL(EX_RI_ED_MISSING_CROSSCERT_SIGN, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_SIG1, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_SIG2, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_SIG3, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_SIG4, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT1, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT3, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT4, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT5, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT6, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CROSSCERT7, 0);
+  CHECK_FAIL(EX_RI_ED_MISPLACED1, 0);
+  CHECK_FAIL(EX_RI_ED_MISPLACED2, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CERT1, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CERT2, 0);
+  CHECK_FAIL(EX_RI_ED_BAD_CERT3, 0);
+
   /* This is allowed; we just ignore it. */
   CHECK_OK(EX_RI_BAD_EI_DIGEST);
+  CHECK_OK(EX_RI_BAD_EI_DIGEST2);
 
 #undef CHECK_FAIL
 #undef CHECK_OK
@@ -494,20 +514,34 @@ test_dir_extrainfo_parsing(void *arg)
   tt_assert(ei->pending_sig);
   CHECK_OK(EX_EI_MAXIMAL);
   tt_assert(ei->pending_sig);
+  CHECK_OK(EX_EI_GOOD_ED_EI);
+  tt_assert(ei->pending_sig);
 
   map = (struct digest_ri_map_t *)digestmap_new();
   ADD(EX_EI_MINIMAL);
   ADD(EX_EI_MAXIMAL);
+  ADD(EX_EI_GOOD_ED_EI);
   ADD(EX_EI_BAD_FP);
   ADD(EX_EI_BAD_NICKNAME);
   ADD(EX_EI_BAD_TOKENS);
   ADD(EX_EI_BAD_START);
   ADD(EX_EI_BAD_PUBLISHED);
 
+  ADD(EX_EI_ED_MISSING_SIG);
+  ADD(EX_EI_ED_MISSING_CERT);
+  ADD(EX_EI_ED_BAD_CERT1);
+  ADD(EX_EI_ED_BAD_CERT2);
+  ADD(EX_EI_ED_BAD_SIG1);
+  ADD(EX_EI_ED_BAD_SIG2);
+  ADD(EX_EI_ED_MISPLACED_CERT);
+  ADD(EX_EI_ED_MISPLACED_SIG);
+
   CHECK_OK(EX_EI_MINIMAL);
   tt_assert(!ei->pending_sig);
   CHECK_OK(EX_EI_MAXIMAL);
   tt_assert(!ei->pending_sig);
+  CHECK_OK(EX_EI_GOOD_ED_EI);
+  tt_assert(!ei->pending_sig);
 
   CHECK_FAIL(EX_EI_BAD_SIG1,1);
   CHECK_FAIL(EX_EI_BAD_SIG2,1);
@@ -518,6 +552,15 @@ test_dir_extrainfo_parsing(void *arg)
   CHECK_FAIL(EX_EI_BAD_START,0);
   CHECK_FAIL(EX_EI_BAD_PUBLISHED,0);
 
+  CHECK_FAIL(EX_EI_ED_MISSING_SIG,0);
+  CHECK_FAIL(EX_EI_ED_MISSING_CERT,0);
+  CHECK_FAIL(EX_EI_ED_BAD_CERT1,0);
+  CHECK_FAIL(EX_EI_ED_BAD_CERT2,0);
+  CHECK_FAIL(EX_EI_ED_BAD_SIG1,0);
+  CHECK_FAIL(EX_EI_ED_BAD_SIG2,0);
+  CHECK_FAIL(EX_EI_ED_MISPLACED_CERT,0);
+  CHECK_FAIL(EX_EI_ED_MISPLACED_SIG,0);
+
 #undef CHECK_OK
 #undef CHECK_FAIL
 





More information about the tor-commits mailing list