]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Trunnel: remove support for pre-ed25519 auth.
authorNick Mathewson <nickm@torproject.org>
Mon, 17 Mar 2025 14:02:21 +0000 (10:02 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 18 Mar 2025 15:58:23 +0000 (11:58 -0400)
This involves a more-than-usual bit of code churn in the generated C,
since the context argument is now gone.

src/feature/relay/relay_handshake.c
src/test/test_link_handshake.c
src/trunnel/link_handshake.c
src/trunnel/link_handshake.h
src/trunnel/link_handshake.trunnel

index a35725ddbc5eca28be821d9007802dd2fcdfb97d..7cfa2cbfa534b08d54888e41176cbc3fddead826 100644 (file)
@@ -285,7 +285,6 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
                                       int server)
 {
   auth1_t *auth = NULL;
-  auth_ctx_t *ctx = auth_ctx_new();
   var_cell_t *result = NULL;
   const char *authtype_str = NULL;
 
@@ -306,7 +305,6 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
   }
 
   auth = auth1_new();
-  ctx->is_ed = 1;
 
   /* Type: 8 bytes. */
   memcpy(auth1_getarray_type(auth), authtype_str, 8);
@@ -347,8 +345,8 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
     const uint8_t *cid_ed = (server ? their_ed_id : my_ed_id)->pubkey;
     const uint8_t *sid_ed = (server ? my_ed_id : their_ed_id)->pubkey;
 
-    memcpy(auth->u1_cid_ed, cid_ed, ED25519_PUBKEY_LEN);
-    memcpy(auth->u1_sid_ed, sid_ed, ED25519_PUBKEY_LEN);
+    memcpy(auth->cid_ed, cid_ed, ED25519_PUBKEY_LEN);
+    memcpy(auth->sid_ed, sid_ed, ED25519_PUBKEY_LEN);
   }
 
   {
@@ -409,7 +407,7 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
    * checks it.  That's followed by 16 bytes of nonce. */
   crypto_rand((char*)auth->rand, 24);
 
-  ssize_t maxlen = auth1_encoded_len(auth, ctx);
+  ssize_t maxlen = auth1_encoded_len(auth);
   if (ed_signing_key) {
     maxlen += ED25519_SIG_LEN;
   }
@@ -423,7 +421,7 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
   result->command = CELL_AUTHENTICATE;
   set_uint16(result->payload, htons(authtype));
 
-  if ((len = auth1_encode(out, outlen, auth, ctx)) < 0) {
+  if ((len = auth1_encode(out, outlen, auth)) < 0) {
     /* LCOV_EXCL_START */
     log_warn(LD_BUG, "Unable to encode signed part of AUTH1 data.");
     goto err;
@@ -432,7 +430,7 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
 
   if (server) {
     auth1_t *tmp = NULL;
-    ssize_t len2 = auth1_parse(&tmp, out, len, ctx);
+    ssize_t len2 = auth1_parse(&tmp, out, len);
     if (!tmp) {
       /* LCOV_EXCL_START */
       log_warn(LD_BUG, "Unable to parse signed part of AUTH1 data that "
@@ -464,7 +462,7 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
     memcpy(auth1_getarray_sig(auth), sig.sig, ED25519_SIG_LEN);
   }
 
-  len = auth1_encode(out, outlen, auth, ctx);
+  len = auth1_encode(out, outlen, auth);
   if (len < 0) {
     /* LCOV_EXCL_START */
     log_warn(LD_BUG, "Unable to encode signed AUTH1 data.");
@@ -482,7 +480,6 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
   result = NULL;
  done:
   auth1_free(auth);
-  auth_ctx_free(ctx);
   return result;
 }
 
index ff7bc6bccd47985c2f74a2c26fd3149eaa96ef32..6a156c3c2f97f4e4abd005d37fb63d9fb38dbea3 100644 (file)
@@ -1301,11 +1301,9 @@ test_link_handshake_auth_cell(void *arg)
             d->cell->payload_len - 4);
 
   /* Check it out for plausibility... */
-  auth_ctx_t ctx;
-  ctx.is_ed = 1;
   tt_int_op(d->cell->payload_len-4, OP_EQ, auth1_parse(&auth1,
                                              d->cell->payload+4,
-                                             d->cell->payload_len - 4, &ctx));
+                                             d->cell->payload_len - 4));
   tt_assert(auth1);
 
   tt_mem_op(auth1->type, OP_EQ, "AUTH0003", 8);
index 76db4b0e292881736bb33080a6c12e6d1a06afc1..558073438e10651281d83a00bcf48bb06c4960ac 100644 (file)
@@ -28,10 +28,10 @@ int linkhandshake_deadcode_dummy__ = 0;
     }                                                            \
   } while (0)
 
-auth_challenge_cell_t *
-auth_challenge_cell_new(void)
+auth1_t *
+auth1_new(void)
 {
-  auth_challenge_cell_t *val = trunnel_calloc(1, sizeof(auth_challenge_cell_t));
+  auth1_t *val = trunnel_calloc(1, sizeof(auth1_t));
   if (NULL == val)
     return NULL;
   return val;
@@ -40,535 +40,608 @@ auth_challenge_cell_new(void)
 /** Release all storage held inside 'obj', but do not free 'obj'.
  */
 static void
-auth_challenge_cell_clear(auth_challenge_cell_t *obj)
+auth1_clear(auth1_t *obj)
 {
   (void) obj;
-  TRUNNEL_DYNARRAY_WIPE(&obj->methods);
-  TRUNNEL_DYNARRAY_CLEAR(&obj->methods);
+  TRUNNEL_DYNARRAY_WIPE(&obj->sig);
+  TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
 }
 
 void
-auth_challenge_cell_free(auth_challenge_cell_t *obj)
+auth1_free(auth1_t *obj)
 {
   if (obj == NULL)
     return;
-  auth_challenge_cell_clear(obj);
-  trunnel_memwipe(obj, sizeof(auth_challenge_cell_t));
+  auth1_clear(obj);
+  trunnel_memwipe(obj, sizeof(auth1_t));
   trunnel_free_(obj);
 }
 
 size_t
-auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t *inp)
+auth1_getlen_type(const auth1_t *inp)
+{
+  (void)inp;  return 8;
+}
+
+uint8_t
+auth1_get_type(auth1_t *inp, size_t idx)
+{
+  trunnel_assert(idx < 8);
+  return inp->type[idx];
+}
+
+uint8_t
+auth1_getconst_type(const auth1_t *inp, size_t idx)
+{
+  return auth1_get_type((auth1_t*)inp, idx);
+}
+int
+auth1_set_type(auth1_t *inp, size_t idx, uint8_t elt)
+{
+  trunnel_assert(idx < 8);
+  inp->type[idx] = elt;
+  return 0;
+}
+
+uint8_t *
+auth1_getarray_type(auth1_t *inp)
+{
+  return inp->type;
+}
+const uint8_t  *
+auth1_getconstarray_type(const auth1_t *inp)
+{
+  return (const uint8_t  *)auth1_getarray_type((auth1_t*)inp);
+}
+size_t
+auth1_getlen_cid(const auth1_t *inp)
 {
   (void)inp;  return 32;
 }
 
 uint8_t
-auth_challenge_cell_get_challenge(auth_challenge_cell_t *inp, size_t idx)
+auth1_get_cid(auth1_t *inp, size_t idx)
 {
   trunnel_assert(idx < 32);
-  return inp->challenge[idx];
+  return inp->cid[idx];
 }
 
 uint8_t
-auth_challenge_cell_getconst_challenge(const auth_challenge_cell_t *inp, size_t idx)
+auth1_getconst_cid(const auth1_t *inp, size_t idx)
 {
-  return auth_challenge_cell_get_challenge((auth_challenge_cell_t*)inp, idx);
+  return auth1_get_cid((auth1_t*)inp, idx);
 }
 int
-auth_challenge_cell_set_challenge(auth_challenge_cell_t *inp, size_t idx, uint8_t elt)
+auth1_set_cid(auth1_t *inp, size_t idx, uint8_t elt)
 {
   trunnel_assert(idx < 32);
-  inp->challenge[idx] = elt;
+  inp->cid[idx] = elt;
   return 0;
 }
 
 uint8_t *
-auth_challenge_cell_getarray_challenge(auth_challenge_cell_t *inp)
+auth1_getarray_cid(auth1_t *inp)
 {
-  return inp->challenge;
+  return inp->cid;
 }
 const uint8_t  *
-auth_challenge_cell_getconstarray_challenge(const auth_challenge_cell_t *inp)
+auth1_getconstarray_cid(const auth1_t *inp)
 {
-  return (const uint8_t  *)auth_challenge_cell_getarray_challenge((auth_challenge_cell_t*)inp);
+  return (const uint8_t  *)auth1_getarray_cid((auth1_t*)inp);
 }
-uint16_t
-auth_challenge_cell_get_n_methods(const auth_challenge_cell_t *inp)
+size_t
+auth1_getlen_sid(const auth1_t *inp)
 {
-  return inp->n_methods;
+  (void)inp;  return 32;
+}
+
+uint8_t
+auth1_get_sid(auth1_t *inp, size_t idx)
+{
+  trunnel_assert(idx < 32);
+  return inp->sid[idx];
+}
+
+uint8_t
+auth1_getconst_sid(const auth1_t *inp, size_t idx)
+{
+  return auth1_get_sid((auth1_t*)inp, idx);
 }
 int
-auth_challenge_cell_set_n_methods(auth_challenge_cell_t *inp, uint16_t val)
+auth1_set_sid(auth1_t *inp, size_t idx, uint8_t elt)
 {
-  inp->n_methods = val;
+  trunnel_assert(idx < 32);
+  inp->sid[idx] = elt;
   return 0;
 }
+
+uint8_t *
+auth1_getarray_sid(auth1_t *inp)
+{
+  return inp->sid;
+}
+const uint8_t  *
+auth1_getconstarray_sid(const auth1_t *inp)
+{
+  return (const uint8_t  *)auth1_getarray_sid((auth1_t*)inp);
+}
 size_t
-auth_challenge_cell_getlen_methods(const auth_challenge_cell_t *inp)
+auth1_getlen_cid_ed(const auth1_t *inp)
 {
-  return TRUNNEL_DYNARRAY_LEN(&inp->methods);
+  (void)inp;  return 32;
 }
 
-uint16_t
-auth_challenge_cell_get_methods(auth_challenge_cell_t *inp, size_t idx)
+uint8_t
+auth1_get_cid_ed(auth1_t *inp, size_t idx)
 {
-  return TRUNNEL_DYNARRAY_GET(&inp->methods, idx);
+  trunnel_assert(idx < 32);
+  return inp->cid_ed[idx];
 }
 
-uint16_t
-auth_challenge_cell_getconst_methods(const auth_challenge_cell_t *inp, size_t idx)
+uint8_t
+auth1_getconst_cid_ed(const auth1_t *inp, size_t idx)
 {
-  return auth_challenge_cell_get_methods((auth_challenge_cell_t*)inp, idx);
+  return auth1_get_cid_ed((auth1_t*)inp, idx);
 }
 int
-auth_challenge_cell_set_methods(auth_challenge_cell_t *inp, size_t idx, uint16_t elt)
+auth1_set_cid_ed(auth1_t *inp, size_t idx, uint8_t elt)
 {
-  TRUNNEL_DYNARRAY_SET(&inp->methods, idx, elt);
+  trunnel_assert(idx < 32);
+  inp->cid_ed[idx] = elt;
   return 0;
 }
-int
-auth_challenge_cell_add_methods(auth_challenge_cell_t *inp, uint16_t elt)
+
+uint8_t *
+auth1_getarray_cid_ed(auth1_t *inp)
 {
-#if SIZE_MAX >= UINT16_MAX
-  if (inp->methods.n_ == UINT16_MAX)
-    goto trunnel_alloc_failed;
-#endif
-  TRUNNEL_DYNARRAY_ADD(uint16_t, &inp->methods, elt, {});
-  return 0;
- trunnel_alloc_failed:
-  TRUNNEL_SET_ERROR_CODE(inp);
-  return -1;
+  return inp->cid_ed;
+}
+const uint8_t  *
+auth1_getconstarray_cid_ed(const auth1_t *inp)
+{
+  return (const uint8_t  *)auth1_getarray_cid_ed((auth1_t*)inp);
+}
+size_t
+auth1_getlen_sid_ed(const auth1_t *inp)
+{
+  (void)inp;  return 32;
 }
 
-uint16_t *
-auth_challenge_cell_getarray_methods(auth_challenge_cell_t *inp)
+uint8_t
+auth1_get_sid_ed(auth1_t *inp, size_t idx)
 {
-  return inp->methods.elts_;
+  trunnel_assert(idx < 32);
+  return inp->sid_ed[idx];
 }
-const uint16_t  *
-auth_challenge_cell_getconstarray_methods(const auth_challenge_cell_t *inp)
+
+uint8_t
+auth1_getconst_sid_ed(const auth1_t *inp, size_t idx)
 {
-  return (const uint16_t  *)auth_challenge_cell_getarray_methods((auth_challenge_cell_t*)inp);
+  return auth1_get_sid_ed((auth1_t*)inp, idx);
 }
 int
-auth_challenge_cell_setlen_methods(auth_challenge_cell_t *inp, size_t newlen)
+auth1_set_sid_ed(auth1_t *inp, size_t idx, uint8_t elt)
 {
-  uint16_t *newptr;
-#if UINT16_MAX < SIZE_MAX
-  if (newlen > UINT16_MAX)
-    goto trunnel_alloc_failed;
-#endif
-  newptr = trunnel_dynarray_setlen(&inp->methods.allocated_,
-                 &inp->methods.n_, inp->methods.elts_, newlen,
-                 sizeof(inp->methods.elts_[0]), (trunnel_free_fn_t) NULL,
-                 &inp->trunnel_error_code_);
-  if (newlen != 0 && newptr == NULL)
-    goto trunnel_alloc_failed;
-  inp->methods.elts_ = newptr;
+  trunnel_assert(idx < 32);
+  inp->sid_ed[idx] = elt;
   return 0;
- trunnel_alloc_failed:
-  TRUNNEL_SET_ERROR_CODE(inp);
-  return -1;
 }
-const char *
-auth_challenge_cell_check(const auth_challenge_cell_t *obj)
+
+uint8_t *
+auth1_getarray_sid_ed(auth1_t *inp)
 {
-  if (obj == NULL)
-    return "Object was NULL";
-  if (obj->trunnel_error_code_)
-    return "A set function failed on this object";
-  if (TRUNNEL_DYNARRAY_LEN(&obj->methods) != obj->n_methods)
-    return "Length mismatch for methods";
-  return NULL;
+  return inp->sid_ed;
 }
-
-ssize_t
-auth_challenge_cell_encoded_len(const auth_challenge_cell_t *obj)
+const uint8_t  *
+auth1_getconstarray_sid_ed(const auth1_t *inp)
 {
-  ssize_t result = 0;
+  return (const uint8_t  *)auth1_getarray_sid_ed((auth1_t*)inp);
+}
+size_t
+auth1_getlen_slog(const auth1_t *inp)
+{
+  (void)inp;  return 32;
+}
 
-  if (NULL != auth_challenge_cell_check(obj))
-     return -1;
+uint8_t
+auth1_get_slog(auth1_t *inp, size_t idx)
+{
+  trunnel_assert(idx < 32);
+  return inp->slog[idx];
+}
 
+uint8_t
+auth1_getconst_slog(const auth1_t *inp, size_t idx)
+{
+  return auth1_get_slog((auth1_t*)inp, idx);
+}
+int
+auth1_set_slog(auth1_t *inp, size_t idx, uint8_t elt)
+{
+  trunnel_assert(idx < 32);
+  inp->slog[idx] = elt;
+  return 0;
+}
 
-  /* Length of u8 challenge[32] */
-  result += 32;
+uint8_t *
+auth1_getarray_slog(auth1_t *inp)
+{
+  return inp->slog;
+}
+const uint8_t  *
+auth1_getconstarray_slog(const auth1_t *inp)
+{
+  return (const uint8_t  *)auth1_getarray_slog((auth1_t*)inp);
+}
+size_t
+auth1_getlen_clog(const auth1_t *inp)
+{
+  (void)inp;  return 32;
+}
 
-  /* Length of u16 n_methods */
-  result += 2;
+uint8_t
+auth1_get_clog(auth1_t *inp, size_t idx)
+{
+  trunnel_assert(idx < 32);
+  return inp->clog[idx];
+}
 
-  /* Length of u16 methods[n_methods] */
-  result += 2 * TRUNNEL_DYNARRAY_LEN(&obj->methods);
-  return result;
+uint8_t
+auth1_getconst_clog(const auth1_t *inp, size_t idx)
+{
+  return auth1_get_clog((auth1_t*)inp, idx);
 }
 int
-auth_challenge_cell_clear_errors(auth_challenge_cell_t *obj)
+auth1_set_clog(auth1_t *inp, size_t idx, uint8_t elt)
 {
-  int r = obj->trunnel_error_code_;
-  obj->trunnel_error_code_ = 0;
-  return r;
-}
-ssize_t
-auth_challenge_cell_encode(uint8_t *output, const size_t avail, const auth_challenge_cell_t *obj)
-{
-  ssize_t result = 0;
-  size_t written = 0;
-  uint8_t *ptr = output;
-  const char *msg;
-#ifdef TRUNNEL_CHECK_ENCODED_LEN
-  const ssize_t encoded_len = auth_challenge_cell_encoded_len(obj);
-#endif
-
-  if (NULL != (msg = auth_challenge_cell_check(obj)))
-    goto check_failed;
-
-#ifdef TRUNNEL_CHECK_ENCODED_LEN
-  trunnel_assert(encoded_len >= 0);
-#endif
-
-  /* Encode u8 challenge[32] */
-  trunnel_assert(written <= avail);
-  if (avail - written < 32)
-    goto truncated;
-  memcpy(ptr, obj->challenge, 32);
-  written += 32; ptr += 32;
-
-  /* Encode u16 n_methods */
-  trunnel_assert(written <= avail);
-  if (avail - written < 2)
-    goto truncated;
-  trunnel_set_uint16(ptr, trunnel_htons(obj->n_methods));
-  written += 2; ptr += 2;
-
-  /* Encode u16 methods[n_methods] */
-  {
-
-    unsigned idx;
-    for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->methods); ++idx) {
-      trunnel_assert(written <= avail);
-      if (avail - written < 2)
-        goto truncated;
-      trunnel_set_uint16(ptr, trunnel_htons(TRUNNEL_DYNARRAY_GET(&obj->methods, idx)));
-      written += 2; ptr += 2;
-    }
-  }
-
-
-  trunnel_assert(ptr == output + written);
-#ifdef TRUNNEL_CHECK_ENCODED_LEN
-  {
-    trunnel_assert(encoded_len >= 0);
-    trunnel_assert((size_t)encoded_len == written);
-  }
-
-#endif
-
-  return written;
-
- truncated:
-  result = -2;
-  goto fail;
- check_failed:
-  (void)msg;
-  result = -1;
-  goto fail;
- fail:
-  trunnel_assert(result < 0);
-  return result;
-}
-
-/** As auth_challenge_cell_parse(), but do not allocate the output
- * object.
- */
-static ssize_t
-auth_challenge_cell_parse_into(auth_challenge_cell_t *obj, const uint8_t *input, const size_t len_in)
-{
-  const uint8_t *ptr = input;
-  size_t remaining = len_in;
-  ssize_t result = 0;
-  (void)result;
-
-  /* Parse u8 challenge[32] */
-  CHECK_REMAINING(32, truncated);
-  memcpy(obj->challenge, ptr, 32);
-  remaining -= 32; ptr += 32;
-
-  /* Parse u16 n_methods */
-  CHECK_REMAINING(2, truncated);
-  obj->n_methods = trunnel_ntohs(trunnel_get_uint16(ptr));
-  remaining -= 2; ptr += 2;
-
-  /* Parse u16 methods[n_methods] */
-  TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj->methods, obj->n_methods, {});
-  {
-    uint16_t elt;
-    unsigned idx;
-    for (idx = 0; idx < obj->n_methods; ++idx) {
-      CHECK_REMAINING(2, truncated);
-      elt = trunnel_ntohs(trunnel_get_uint16(ptr));
-      remaining -= 2; ptr += 2;
-      TRUNNEL_DYNARRAY_ADD(uint16_t, &obj->methods, elt, {});
-    }
-  }
-  trunnel_assert(ptr + remaining == input + len_in);
-  return len_in - remaining;
-
- truncated:
-  return -2;
- trunnel_alloc_failed:
-  return -1;
+  trunnel_assert(idx < 32);
+  inp->clog[idx] = elt;
+  return 0;
 }
 
-ssize_t
-auth_challenge_cell_parse(auth_challenge_cell_t **output, const uint8_t *input, const size_t len_in)
+uint8_t *
+auth1_getarray_clog(auth1_t *inp)
 {
-  ssize_t result;
-  *output = auth_challenge_cell_new();
-  if (NULL == *output)
-    return -1;
-  result = auth_challenge_cell_parse_into(*output, input, len_in);
-  if (result < 0) {
-    auth_challenge_cell_free(*output);
-    *output = NULL;
-  }
-  return result;
+  return inp->clog;
 }
-auth_ctx_t *
-auth_ctx_new(void)
+const uint8_t  *
+auth1_getconstarray_clog(const auth1_t *inp)
 {
-  auth_ctx_t *val = trunnel_calloc(1, sizeof(auth_ctx_t));
-  if (NULL == val)
-    return NULL;
-  return val;
+  return (const uint8_t  *)auth1_getarray_clog((auth1_t*)inp);
 }
-
-/** Release all storage held inside 'obj', but do not free 'obj'.
- */
-static void
-auth_ctx_clear(auth_ctx_t *obj)
+size_t
+auth1_getlen_scert(const auth1_t *inp)
 {
-  (void) obj;
+  (void)inp;  return 32;
 }
 
-void
-auth_ctx_free(auth_ctx_t *obj)
+uint8_t
+auth1_get_scert(auth1_t *inp, size_t idx)
 {
-  if (obj == NULL)
-    return;
-  auth_ctx_clear(obj);
-  trunnel_memwipe(obj, sizeof(auth_ctx_t));
-  trunnel_free_(obj);
+  trunnel_assert(idx < 32);
+  return inp->scert[idx];
 }
 
 uint8_t
-auth_ctx_get_is_ed(const auth_ctx_t *inp)
+auth1_getconst_scert(const auth1_t *inp, size_t idx)
 {
-  return inp->is_ed;
+  return auth1_get_scert((auth1_t*)inp, idx);
 }
 int
-auth_ctx_set_is_ed(auth_ctx_t *inp, uint8_t val)
+auth1_set_scert(auth1_t *inp, size_t idx, uint8_t elt)
 {
-  inp->is_ed = val;
+  trunnel_assert(idx < 32);
+  inp->scert[idx] = elt;
   return 0;
 }
-certs_cell_cert_t *
-certs_cell_cert_new(void)
+
+uint8_t *
+auth1_getarray_scert(auth1_t *inp)
 {
-  certs_cell_cert_t *val = trunnel_calloc(1, sizeof(certs_cell_cert_t));
-  if (NULL == val)
-    return NULL;
-  return val;
+  return inp->scert;
 }
-
-/** Release all storage held inside 'obj', but do not free 'obj'.
- */
-static void
-certs_cell_cert_clear(certs_cell_cert_t *obj)
+const uint8_t  *
+auth1_getconstarray_scert(const auth1_t *inp)
 {
-  (void) obj;
-  TRUNNEL_DYNARRAY_WIPE(&obj->body);
-  TRUNNEL_DYNARRAY_CLEAR(&obj->body);
+  return (const uint8_t  *)auth1_getarray_scert((auth1_t*)inp);
+}
+size_t
+auth1_getlen_tlssecrets(const auth1_t *inp)
+{
+  (void)inp;  return 32;
 }
 
-void
-certs_cell_cert_free(certs_cell_cert_t *obj)
+uint8_t
+auth1_get_tlssecrets(auth1_t *inp, size_t idx)
 {
-  if (obj == NULL)
-    return;
-  certs_cell_cert_clear(obj);
-  trunnel_memwipe(obj, sizeof(certs_cell_cert_t));
-  trunnel_free_(obj);
+  trunnel_assert(idx < 32);
+  return inp->tlssecrets[idx];
 }
 
 uint8_t
-certs_cell_cert_get_cert_type(const certs_cell_cert_t *inp)
+auth1_getconst_tlssecrets(const auth1_t *inp, size_t idx)
 {
-  return inp->cert_type;
+  return auth1_get_tlssecrets((auth1_t*)inp, idx);
 }
 int
-certs_cell_cert_set_cert_type(certs_cell_cert_t *inp, uint8_t val)
+auth1_set_tlssecrets(auth1_t *inp, size_t idx, uint8_t elt)
 {
-  inp->cert_type = val;
+  trunnel_assert(idx < 32);
+  inp->tlssecrets[idx] = elt;
   return 0;
 }
-uint16_t
-certs_cell_cert_get_cert_len(const certs_cell_cert_t *inp)
+
+uint8_t *
+auth1_getarray_tlssecrets(auth1_t *inp)
 {
-  return inp->cert_len;
+  return inp->tlssecrets;
 }
-int
-certs_cell_cert_set_cert_len(certs_cell_cert_t *inp, uint16_t val)
+const uint8_t  *
+auth1_getconstarray_tlssecrets(const auth1_t *inp)
 {
-  inp->cert_len = val;
-  return 0;
+  return (const uint8_t  *)auth1_getarray_tlssecrets((auth1_t*)inp);
+}
+const uint8_t *
+auth1_get_end_of_fixed_part(const auth1_t *inp)
+{
+  return inp->end_of_fixed_part;
 }
 size_t
-certs_cell_cert_getlen_body(const certs_cell_cert_t *inp)
+auth1_getlen_rand(const auth1_t *inp)
 {
-  return TRUNNEL_DYNARRAY_LEN(&inp->body);
+  (void)inp;  return 24;
 }
 
 uint8_t
-certs_cell_cert_get_body(certs_cell_cert_t *inp, size_t idx)
+auth1_get_rand(auth1_t *inp, size_t idx)
 {
-  return TRUNNEL_DYNARRAY_GET(&inp->body, idx);
+  trunnel_assert(idx < 24);
+  return inp->rand[idx];
 }
 
 uint8_t
-certs_cell_cert_getconst_body(const certs_cell_cert_t *inp, size_t idx)
-{
-  return certs_cell_cert_get_body((certs_cell_cert_t*)inp, idx);
-}
-int
-certs_cell_cert_set_body(certs_cell_cert_t *inp, size_t idx, uint8_t elt)
+auth1_getconst_rand(const auth1_t *inp, size_t idx)
 {
-  TRUNNEL_DYNARRAY_SET(&inp->body, idx, elt);
-  return 0;
+  return auth1_get_rand((auth1_t*)inp, idx);
 }
 int
-certs_cell_cert_add_body(certs_cell_cert_t *inp, uint8_t elt)
+auth1_set_rand(auth1_t *inp, size_t idx, uint8_t elt)
 {
-#if SIZE_MAX >= UINT16_MAX
-  if (inp->body.n_ == UINT16_MAX)
-    goto trunnel_alloc_failed;
-#endif
-  TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->body, elt, {});
+  trunnel_assert(idx < 24);
+  inp->rand[idx] = elt;
   return 0;
- trunnel_alloc_failed:
-  TRUNNEL_SET_ERROR_CODE(inp);
-  return -1;
 }
 
 uint8_t *
-certs_cell_cert_getarray_body(certs_cell_cert_t *inp)
+auth1_getarray_rand(auth1_t *inp)
 {
-  return inp->body.elts_;
+  return inp->rand;
 }
 const uint8_t  *
-certs_cell_cert_getconstarray_body(const certs_cell_cert_t *inp)
+auth1_getconstarray_rand(const auth1_t *inp)
 {
-  return (const uint8_t  *)certs_cell_cert_getarray_body((certs_cell_cert_t*)inp);
+  return (const uint8_t  *)auth1_getarray_rand((auth1_t*)inp);
 }
-int
-certs_cell_cert_setlen_body(certs_cell_cert_t *inp, size_t newlen)
+const uint8_t *
+auth1_get_end_of_signed(const auth1_t *inp)
+{
+  return inp->end_of_signed;
+}
+size_t
+auth1_getlen_sig(const auth1_t *inp)
+{
+  return TRUNNEL_DYNARRAY_LEN(&inp->sig);
+}
+
+uint8_t
+auth1_get_sig(auth1_t *inp, size_t idx)
+{
+  return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
+}
+
+uint8_t
+auth1_getconst_sig(const auth1_t *inp, size_t idx)
+{
+  return auth1_get_sig((auth1_t*)inp, idx);
+}
+int
+auth1_set_sig(auth1_t *inp, size_t idx, uint8_t elt)
+{
+  TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
+  return 0;
+}
+int
+auth1_add_sig(auth1_t *inp, uint8_t elt)
+{
+  TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
+  return 0;
+ trunnel_alloc_failed:
+  TRUNNEL_SET_ERROR_CODE(inp);
+  return -1;
+}
+
+uint8_t *
+auth1_getarray_sig(auth1_t *inp)
+{
+  return inp->sig.elts_;
+}
+const uint8_t  *
+auth1_getconstarray_sig(const auth1_t *inp)
+{
+  return (const uint8_t  *)auth1_getarray_sig((auth1_t*)inp);
+}
+int
+auth1_setlen_sig(auth1_t *inp, size_t newlen)
 {
   uint8_t *newptr;
-#if UINT16_MAX < SIZE_MAX
-  if (newlen > UINT16_MAX)
-    goto trunnel_alloc_failed;
-#endif
-  newptr = trunnel_dynarray_setlen(&inp->body.allocated_,
-                 &inp->body.n_, inp->body.elts_, newlen,
-                 sizeof(inp->body.elts_[0]), (trunnel_free_fn_t) NULL,
+  newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
+                 &inp->sig.n_, inp->sig.elts_, newlen,
+                 sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
                  &inp->trunnel_error_code_);
   if (newlen != 0 && newptr == NULL)
     goto trunnel_alloc_failed;
-  inp->body.elts_ = newptr;
+  inp->sig.elts_ = newptr;
   return 0;
  trunnel_alloc_failed:
   TRUNNEL_SET_ERROR_CODE(inp);
   return -1;
 }
 const char *
-certs_cell_cert_check(const certs_cell_cert_t *obj)
+auth1_check(const auth1_t *obj)
 {
   if (obj == NULL)
     return "Object was NULL";
   if (obj->trunnel_error_code_)
     return "A set function failed on this object";
-  if (TRUNNEL_DYNARRAY_LEN(&obj->body) != obj->cert_len)
-    return "Length mismatch for body";
   return NULL;
 }
 
 ssize_t
-certs_cell_cert_encoded_len(const certs_cell_cert_t *obj)
+auth1_encoded_len(const auth1_t *obj)
 {
   ssize_t result = 0;
 
-  if (NULL != certs_cell_cert_check(obj))
+  if (NULL != auth1_check(obj))
      return -1;
 
 
-  /* Length of u8 cert_type */
-  result += 1;
+  /* Length of u8 type[8] */
+  result += 8;
 
-  /* Length of u16 cert_len */
-  result += 2;
+  /* Length of u8 cid[32] */
+  result += 32;
 
-  /* Length of u8 body[cert_len] */
-  result += TRUNNEL_DYNARRAY_LEN(&obj->body);
+  /* Length of u8 sid[32] */
+  result += 32;
+
+  /* Length of u8 cid_ed[32] */
+  result += 32;
+
+  /* Length of u8 sid_ed[32] */
+  result += 32;
+
+  /* Length of u8 slog[32] */
+  result += 32;
+
+  /* Length of u8 clog[32] */
+  result += 32;
+
+  /* Length of u8 scert[32] */
+  result += 32;
+
+  /* Length of u8 tlssecrets[32] */
+  result += 32;
+
+  /* Length of u8 rand[24] */
+  result += 24;
+
+  /* Length of u8 sig[] */
+  result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
   return result;
 }
 int
-certs_cell_cert_clear_errors(certs_cell_cert_t *obj)
+auth1_clear_errors(auth1_t *obj)
 {
   int r = obj->trunnel_error_code_;
   obj->trunnel_error_code_ = 0;
   return r;
 }
 ssize_t
-certs_cell_cert_encode(uint8_t *output, const size_t avail, const certs_cell_cert_t *obj)
+auth1_encode(uint8_t *output, const size_t avail, const auth1_t *obj)
 {
   ssize_t result = 0;
   size_t written = 0;
   uint8_t *ptr = output;
   const char *msg;
 #ifdef TRUNNEL_CHECK_ENCODED_LEN
-  const ssize_t encoded_len = certs_cell_cert_encoded_len(obj);
+  const ssize_t encoded_len = auth1_encoded_len(obj);
 #endif
 
-  if (NULL != (msg = certs_cell_cert_check(obj)))
+  if (NULL != (msg = auth1_check(obj)))
     goto check_failed;
 
 #ifdef TRUNNEL_CHECK_ENCODED_LEN
   trunnel_assert(encoded_len >= 0);
 #endif
 
-  /* Encode u8 cert_type */
+  /* Encode u8 type[8] */
   trunnel_assert(written <= avail);
-  if (avail - written < 1)
+  if (avail - written < 8)
     goto truncated;
-  trunnel_set_uint8(ptr, (obj->cert_type));
-  written += 1; ptr += 1;
+  memcpy(ptr, obj->type, 8);
+  written += 8; ptr += 8;
 
-  /* Encode u16 cert_len */
+  /* Encode u8 cid[32] */
   trunnel_assert(written <= avail);
-  if (avail - written < 2)
+  if (avail - written < 32)
     goto truncated;
-  trunnel_set_uint16(ptr, trunnel_htons(obj->cert_len));
-  written += 2; ptr += 2;
+  memcpy(ptr, obj->cid, 32);
+  written += 32; ptr += 32;
 
-  /* Encode u8 body[cert_len] */
+  /* Encode u8 sid[32] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 32)
+    goto truncated;
+  memcpy(ptr, obj->sid, 32);
+  written += 32; ptr += 32;
+
+  /* Encode u8 cid_ed[32] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 32)
+    goto truncated;
+  memcpy(ptr, obj->cid_ed, 32);
+  written += 32; ptr += 32;
+
+  /* Encode u8 sid_ed[32] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 32)
+    goto truncated;
+  memcpy(ptr, obj->sid_ed, 32);
+  written += 32; ptr += 32;
+
+  /* Encode u8 slog[32] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 32)
+    goto truncated;
+  memcpy(ptr, obj->slog, 32);
+  written += 32; ptr += 32;
+
+  /* Encode u8 clog[32] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 32)
+    goto truncated;
+  memcpy(ptr, obj->clog, 32);
+  written += 32; ptr += 32;
+
+  /* Encode u8 scert[32] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 32)
+    goto truncated;
+  memcpy(ptr, obj->scert, 32);
+  written += 32; ptr += 32;
+
+  /* Encode u8 tlssecrets[32] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 32)
+    goto truncated;
+  memcpy(ptr, obj->tlssecrets, 32);
+  written += 32; ptr += 32;
+
+  /* Encode u8 rand[24] */
+  trunnel_assert(written <= avail);
+  if (avail - written < 24)
+    goto truncated;
+  memcpy(ptr, obj->rand, 24);
+  written += 24; ptr += 24;
+
+  /* Encode u8 sig[] */
   {
-    size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->body);
-    trunnel_assert(obj->cert_len == elt_len);
+    size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
     trunnel_assert(written <= avail);
     if (avail - written < elt_len)
       goto truncated;
     if (elt_len)
-      memcpy(ptr, obj->body.elts_, elt_len);
+      memcpy(ptr, obj->sig.elts_, elt_len);
     written += elt_len; ptr += elt_len;
   }
 
@@ -596,33 +669,74 @@ certs_cell_cert_encode(uint8_t *output, const size_t avail, const certs_cell_cer
   return result;
 }
 
-/** As certs_cell_cert_parse(), but do not allocate the output object.
+/** As auth1_parse(), but do not allocate the output object.
  */
 static ssize_t
-certs_cell_cert_parse_into(certs_cell_cert_t *obj, const uint8_t *input, const size_t len_in)
+auth1_parse_into(auth1_t *obj, const uint8_t *input, const size_t len_in)
 {
   const uint8_t *ptr = input;
   size_t remaining = len_in;
   ssize_t result = 0;
   (void)result;
 
-  /* Parse u8 cert_type */
-  CHECK_REMAINING(1, truncated);
-  obj->cert_type = (trunnel_get_uint8(ptr));
-  remaining -= 1; ptr += 1;
+  /* Parse u8 type[8] */
+  CHECK_REMAINING(8, truncated);
+  memcpy(obj->type, ptr, 8);
+  remaining -= 8; ptr += 8;
 
-  /* Parse u16 cert_len */
-  CHECK_REMAINING(2, truncated);
-  obj->cert_len = trunnel_ntohs(trunnel_get_uint16(ptr));
-  remaining -= 2; ptr += 2;
+  /* Parse u8 cid[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->cid, ptr, 32);
+  remaining -= 32; ptr += 32;
 
-  /* Parse u8 body[cert_len] */
-  CHECK_REMAINING(obj->cert_len, truncated);
-  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->body, obj->cert_len, {});
-  obj->body.n_ = obj->cert_len;
-  if (obj->cert_len)
-    memcpy(obj->body.elts_, ptr, obj->cert_len);
-  ptr += obj->cert_len; remaining -= obj->cert_len;
+  /* Parse u8 sid[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->sid, ptr, 32);
+  remaining -= 32; ptr += 32;
+
+  /* Parse u8 cid_ed[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->cid_ed, ptr, 32);
+  remaining -= 32; ptr += 32;
+
+  /* Parse u8 sid_ed[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->sid_ed, ptr, 32);
+  remaining -= 32; ptr += 32;
+
+  /* Parse u8 slog[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->slog, ptr, 32);
+  remaining -= 32; ptr += 32;
+
+  /* Parse u8 clog[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->clog, ptr, 32);
+  remaining -= 32; ptr += 32;
+
+  /* Parse u8 scert[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->scert, ptr, 32);
+  remaining -= 32; ptr += 32;
+
+  /* Parse u8 tlssecrets[32] */
+  CHECK_REMAINING(32, truncated);
+  memcpy(obj->tlssecrets, ptr, 32);
+  remaining -= 32; ptr += 32;
+  obj->end_of_fixed_part = ptr;
+
+  /* Parse u8 rand[24] */
+  CHECK_REMAINING(24, truncated);
+  memcpy(obj->rand, ptr, 24);
+  remaining -= 24; ptr += 24;
+  obj->end_of_signed = ptr;
+
+  /* Parse u8 sig[] */
+  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, remaining, {});
+  obj->sig.n_ = remaining;
+  if (remaining)
+    memcpy(obj->sig.elts_, ptr, remaining);
+  ptr += remaining; remaining -= remaining;
   trunnel_assert(ptr + remaining == input + len_in);
   return len_in - remaining;
 
@@ -633,23 +747,23 @@ certs_cell_cert_parse_into(certs_cell_cert_t *obj, const uint8_t *input, const s
 }
 
 ssize_t
-certs_cell_cert_parse(certs_cell_cert_t **output, const uint8_t *input, const size_t len_in)
+auth1_parse(auth1_t **output, const uint8_t *input, const size_t len_in)
 {
   ssize_t result;
-  *output = certs_cell_cert_new();
+  *output = auth1_new();
   if (NULL == *output)
     return -1;
-  result = certs_cell_cert_parse_into(*output, input, len_in);
+  result = auth1_parse_into(*output, input, len_in);
   if (result < 0) {
-    certs_cell_cert_free(*output);
+    auth1_free(*output);
     *output = NULL;
   }
   return result;
 }
-rsa_ed_crosscert_t *
-rsa_ed_crosscert_new(void)
+auth_challenge_cell_t *
+auth_challenge_cell_new(void)
 {
-  rsa_ed_crosscert_t *val = trunnel_calloc(1, sizeof(rsa_ed_crosscert_t));
+  auth_challenge_cell_t *val = trunnel_calloc(1, sizeof(auth_challenge_cell_t));
   if (NULL == val)
     return NULL;
   return val;
@@ -658,243 +772,218 @@ rsa_ed_crosscert_new(void)
 /** Release all storage held inside 'obj', but do not free 'obj'.
  */
 static void
-rsa_ed_crosscert_clear(rsa_ed_crosscert_t *obj)
+auth_challenge_cell_clear(auth_challenge_cell_t *obj)
 {
   (void) obj;
-  TRUNNEL_DYNARRAY_WIPE(&obj->sig);
-  TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
+  TRUNNEL_DYNARRAY_WIPE(&obj->methods);
+  TRUNNEL_DYNARRAY_CLEAR(&obj->methods);
 }
 
 void
-rsa_ed_crosscert_free(rsa_ed_crosscert_t *obj)
+auth_challenge_cell_free(auth_challenge_cell_t *obj)
 {
   if (obj == NULL)
     return;
-  rsa_ed_crosscert_clear(obj);
-  trunnel_memwipe(obj, sizeof(rsa_ed_crosscert_t));
+  auth_challenge_cell_clear(obj);
+  trunnel_memwipe(obj, sizeof(auth_challenge_cell_t));
   trunnel_free_(obj);
 }
 
 size_t
-rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t *inp)
+auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t *inp)
 {
   (void)inp;  return 32;
 }
 
 uint8_t
-rsa_ed_crosscert_get_ed_key(rsa_ed_crosscert_t *inp, size_t idx)
+auth_challenge_cell_get_challenge(auth_challenge_cell_t *inp, size_t idx)
 {
   trunnel_assert(idx < 32);
-  return inp->ed_key[idx];
+  return inp->challenge[idx];
 }
 
 uint8_t
-rsa_ed_crosscert_getconst_ed_key(const rsa_ed_crosscert_t *inp, size_t idx)
+auth_challenge_cell_getconst_challenge(const auth_challenge_cell_t *inp, size_t idx)
 {
-  return rsa_ed_crosscert_get_ed_key((rsa_ed_crosscert_t*)inp, idx);
+  return auth_challenge_cell_get_challenge((auth_challenge_cell_t*)inp, idx);
 }
 int
-rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
+auth_challenge_cell_set_challenge(auth_challenge_cell_t *inp, size_t idx, uint8_t elt)
 {
   trunnel_assert(idx < 32);
-  inp->ed_key[idx] = elt;
+  inp->challenge[idx] = elt;
   return 0;
 }
 
 uint8_t *
-rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t *inp)
+auth_challenge_cell_getarray_challenge(auth_challenge_cell_t *inp)
 {
-  return inp->ed_key;
+  return inp->challenge;
 }
 const uint8_t  *
-rsa_ed_crosscert_getconstarray_ed_key(const rsa_ed_crosscert_t *inp)
-{
-  return (const uint8_t  *)rsa_ed_crosscert_getarray_ed_key((rsa_ed_crosscert_t*)inp);
-}
-uint32_t
-rsa_ed_crosscert_get_expiration(const rsa_ed_crosscert_t *inp)
-{
-  return inp->expiration;
-}
-int
-rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t *inp, uint32_t val)
-{
-  inp->expiration = val;
-  return 0;
-}
-const uint8_t *
-rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t *inp)
+auth_challenge_cell_getconstarray_challenge(const auth_challenge_cell_t *inp)
 {
-  return inp->end_of_signed;
+  return (const uint8_t  *)auth_challenge_cell_getarray_challenge((auth_challenge_cell_t*)inp);
 }
-uint8_t
-rsa_ed_crosscert_get_sig_len(const rsa_ed_crosscert_t *inp)
+uint16_t
+auth_challenge_cell_get_n_methods(const auth_challenge_cell_t *inp)
 {
-  return inp->sig_len;
+  return inp->n_methods;
 }
 int
-rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t *inp, uint8_t val)
+auth_challenge_cell_set_n_methods(auth_challenge_cell_t *inp, uint16_t val)
 {
-  inp->sig_len = val;
+  inp->n_methods = val;
   return 0;
 }
 size_t
-rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t *inp)
+auth_challenge_cell_getlen_methods(const auth_challenge_cell_t *inp)
 {
-  return TRUNNEL_DYNARRAY_LEN(&inp->sig);
+  return TRUNNEL_DYNARRAY_LEN(&inp->methods);
 }
 
-uint8_t
-rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t *inp, size_t idx)
+uint16_t
+auth_challenge_cell_get_methods(auth_challenge_cell_t *inp, size_t idx)
 {
-  return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
+  return TRUNNEL_DYNARRAY_GET(&inp->methods, idx);
 }
 
-uint8_t
-rsa_ed_crosscert_getconst_sig(const rsa_ed_crosscert_t *inp, size_t idx)
+uint16_t
+auth_challenge_cell_getconst_methods(const auth_challenge_cell_t *inp, size_t idx)
 {
-  return rsa_ed_crosscert_get_sig((rsa_ed_crosscert_t*)inp, idx);
+  return auth_challenge_cell_get_methods((auth_challenge_cell_t*)inp, idx);
 }
 int
-rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
+auth_challenge_cell_set_methods(auth_challenge_cell_t *inp, size_t idx, uint16_t elt)
 {
-  TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
+  TRUNNEL_DYNARRAY_SET(&inp->methods, idx, elt);
   return 0;
 }
 int
-rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t *inp, uint8_t elt)
+auth_challenge_cell_add_methods(auth_challenge_cell_t *inp, uint16_t elt)
 {
-#if SIZE_MAX >= UINT8_MAX
-  if (inp->sig.n_ == UINT8_MAX)
+#if SIZE_MAX >= UINT16_MAX
+  if (inp->methods.n_ == UINT16_MAX)
     goto trunnel_alloc_failed;
 #endif
-  TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
+  TRUNNEL_DYNARRAY_ADD(uint16_t, &inp->methods, elt, {});
   return 0;
  trunnel_alloc_failed:
   TRUNNEL_SET_ERROR_CODE(inp);
   return -1;
 }
 
-uint8_t *
-rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t *inp)
+uint16_t *
+auth_challenge_cell_getarray_methods(auth_challenge_cell_t *inp)
 {
-  return inp->sig.elts_;
+  return inp->methods.elts_;
 }
-const uint8_t  *
-rsa_ed_crosscert_getconstarray_sig(const rsa_ed_crosscert_t *inp)
+const uint16_t  *
+auth_challenge_cell_getconstarray_methods(const auth_challenge_cell_t *inp)
 {
-  return (const uint8_t  *)rsa_ed_crosscert_getarray_sig((rsa_ed_crosscert_t*)inp);
+  return (const uint16_t  *)auth_challenge_cell_getarray_methods((auth_challenge_cell_t*)inp);
 }
 int
-rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t *inp, size_t newlen)
+auth_challenge_cell_setlen_methods(auth_challenge_cell_t *inp, size_t newlen)
 {
-  uint8_t *newptr;
-#if UINT8_MAX < SIZE_MAX
-  if (newlen > UINT8_MAX)
+  uint16_t *newptr;
+#if UINT16_MAX < SIZE_MAX
+  if (newlen > UINT16_MAX)
     goto trunnel_alloc_failed;
 #endif
-  newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
-                 &inp->sig.n_, inp->sig.elts_, newlen,
-                 sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
+  newptr = trunnel_dynarray_setlen(&inp->methods.allocated_,
+                 &inp->methods.n_, inp->methods.elts_, newlen,
+                 sizeof(inp->methods.elts_[0]), (trunnel_free_fn_t) NULL,
                  &inp->trunnel_error_code_);
   if (newlen != 0 && newptr == NULL)
     goto trunnel_alloc_failed;
-  inp->sig.elts_ = newptr;
+  inp->methods.elts_ = newptr;
   return 0;
  trunnel_alloc_failed:
   TRUNNEL_SET_ERROR_CODE(inp);
   return -1;
 }
 const char *
-rsa_ed_crosscert_check(const rsa_ed_crosscert_t *obj)
+auth_challenge_cell_check(const auth_challenge_cell_t *obj)
 {
   if (obj == NULL)
     return "Object was NULL";
   if (obj->trunnel_error_code_)
     return "A set function failed on this object";
-  if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len)
-    return "Length mismatch for sig";
+  if (TRUNNEL_DYNARRAY_LEN(&obj->methods) != obj->n_methods)
+    return "Length mismatch for methods";
   return NULL;
 }
 
 ssize_t
-rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t *obj)
+auth_challenge_cell_encoded_len(const auth_challenge_cell_t *obj)
 {
   ssize_t result = 0;
 
-  if (NULL != rsa_ed_crosscert_check(obj))
+  if (NULL != auth_challenge_cell_check(obj))
      return -1;
 
 
-  /* Length of u8 ed_key[32] */
+  /* Length of u8 challenge[32] */
   result += 32;
 
-  /* Length of u32 expiration */
-  result += 4;
-
-  /* Length of u8 sig_len */
-  result += 1;
+  /* Length of u16 n_methods */
+  result += 2;
 
-  /* Length of u8 sig[sig_len] */
-  result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
+  /* Length of u16 methods[n_methods] */
+  result += 2 * TRUNNEL_DYNARRAY_LEN(&obj->methods);
   return result;
 }
 int
-rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t *obj)
+auth_challenge_cell_clear_errors(auth_challenge_cell_t *obj)
 {
   int r = obj->trunnel_error_code_;
   obj->trunnel_error_code_ = 0;
   return r;
 }
 ssize_t
-rsa_ed_crosscert_encode(uint8_t *output, const size_t avail, const rsa_ed_crosscert_t *obj)
+auth_challenge_cell_encode(uint8_t *output, const size_t avail, const auth_challenge_cell_t *obj)
 {
   ssize_t result = 0;
   size_t written = 0;
   uint8_t *ptr = output;
   const char *msg;
 #ifdef TRUNNEL_CHECK_ENCODED_LEN
-  const ssize_t encoded_len = rsa_ed_crosscert_encoded_len(obj);
+  const ssize_t encoded_len = auth_challenge_cell_encoded_len(obj);
 #endif
 
-  if (NULL != (msg = rsa_ed_crosscert_check(obj)))
+  if (NULL != (msg = auth_challenge_cell_check(obj)))
     goto check_failed;
 
 #ifdef TRUNNEL_CHECK_ENCODED_LEN
   trunnel_assert(encoded_len >= 0);
 #endif
 
-  /* Encode u8 ed_key[32] */
+  /* Encode u8 challenge[32] */
   trunnel_assert(written <= avail);
   if (avail - written < 32)
     goto truncated;
-  memcpy(ptr, obj->ed_key, 32);
+  memcpy(ptr, obj->challenge, 32);
   written += 32; ptr += 32;
 
-  /* Encode u32 expiration */
-  trunnel_assert(written <= avail);
-  if (avail - written < 4)
-    goto truncated;
-  trunnel_set_uint32(ptr, trunnel_htonl(obj->expiration));
-  written += 4; ptr += 4;
-
-  /* Encode u8 sig_len */
+  /* Encode u16 n_methods */
   trunnel_assert(written <= avail);
-  if (avail - written < 1)
+  if (avail - written < 2)
     goto truncated;
-  trunnel_set_uint8(ptr, (obj->sig_len));
-  written += 1; ptr += 1;
+  trunnel_set_uint16(ptr, trunnel_htons(obj->n_methods));
+  written += 2; ptr += 2;
 
-  /* Encode u8 sig[sig_len] */
+  /* Encode u16 methods[n_methods] */
   {
-    size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
-    trunnel_assert(obj->sig_len == elt_len);
-    trunnel_assert(written <= avail);
-    if (avail - written < elt_len)
-      goto truncated;
-    if (elt_len)
-      memcpy(ptr, obj->sig.elts_, elt_len);
-    written += elt_len; ptr += elt_len;
+
+    unsigned idx;
+    for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->methods); ++idx) {
+      trunnel_assert(written <= avail);
+      if (avail - written < 2)
+        goto truncated;
+      trunnel_set_uint16(ptr, trunnel_htons(TRUNNEL_DYNARRAY_GET(&obj->methods, idx)));
+      written += 2; ptr += 2;
+    }
   }
 
 
@@ -921,40 +1010,39 @@ rsa_ed_crosscert_encode(uint8_t *output, const size_t avail, const rsa_ed_crossc
   return result;
 }
 
-/** As rsa_ed_crosscert_parse(), but do not allocate the output
+/** As auth_challenge_cell_parse(), but do not allocate the output
  * object.
  */
 static ssize_t
-rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t *obj, const uint8_t *input, const size_t len_in)
+auth_challenge_cell_parse_into(auth_challenge_cell_t *obj, const uint8_t *input, const size_t len_in)
 {
   const uint8_t *ptr = input;
   size_t remaining = len_in;
   ssize_t result = 0;
   (void)result;
 
-  /* Parse u8 ed_key[32] */
+  /* Parse u8 challenge[32] */
   CHECK_REMAINING(32, truncated);
-  memcpy(obj->ed_key, ptr, 32);
+  memcpy(obj->challenge, ptr, 32);
   remaining -= 32; ptr += 32;
 
-  /* Parse u32 expiration */
-  CHECK_REMAINING(4, truncated);
-  obj->expiration = trunnel_ntohl(trunnel_get_uint32(ptr));
-  remaining -= 4; ptr += 4;
-  obj->end_of_signed = ptr;
-
-  /* Parse u8 sig_len */
-  CHECK_REMAINING(1, truncated);
-  obj->sig_len = (trunnel_get_uint8(ptr));
-  remaining -= 1; ptr += 1;
+  /* Parse u16 n_methods */
+  CHECK_REMAINING(2, truncated);
+  obj->n_methods = trunnel_ntohs(trunnel_get_uint16(ptr));
+  remaining -= 2; ptr += 2;
 
-  /* Parse u8 sig[sig_len] */
-  CHECK_REMAINING(obj->sig_len, truncated);
-  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {});
-  obj->sig.n_ = obj->sig_len;
-  if (obj->sig_len)
-    memcpy(obj->sig.elts_, ptr, obj->sig_len);
-  ptr += obj->sig_len; remaining -= obj->sig_len;
+  /* Parse u16 methods[n_methods] */
+  TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj->methods, obj->n_methods, {});
+  {
+    uint16_t elt;
+    unsigned idx;
+    for (idx = 0; idx < obj->n_methods; ++idx) {
+      CHECK_REMAINING(2, truncated);
+      elt = trunnel_ntohs(trunnel_get_uint16(ptr));
+      remaining -= 2; ptr += 2;
+      TRUNNEL_DYNARRAY_ADD(uint16_t, &obj->methods, elt, {});
+    }
+  }
   trunnel_assert(ptr + remaining == input + len_in);
   return len_in - remaining;
 
@@ -965,23 +1053,23 @@ rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t *obj, const uint8_t *input, const
 }
 
 ssize_t
-rsa_ed_crosscert_parse(rsa_ed_crosscert_t **output, const uint8_t *input, const size_t len_in)
+auth_challenge_cell_parse(auth_challenge_cell_t **output, const uint8_t *input, const size_t len_in)
 {
   ssize_t result;
-  *output = rsa_ed_crosscert_new();
+  *output = auth_challenge_cell_new();
   if (NULL == *output)
     return -1;
-  result = rsa_ed_crosscert_parse_into(*output, input, len_in);
+  result = auth_challenge_cell_parse_into(*output, input, len_in);
   if (result < 0) {
-    rsa_ed_crosscert_free(*output);
+    auth_challenge_cell_free(*output);
     *output = NULL;
   }
   return result;
 }
-auth1_t *
-auth1_new(void)
+certs_cell_cert_t *
+certs_cell_cert_new(void)
 {
-  auth1_t *val = trunnel_calloc(1, sizeof(auth1_t));
+  certs_cell_cert_t *val = trunnel_calloc(1, sizeof(certs_cell_cert_t));
   if (NULL == val)
     return NULL;
   return val;
@@ -990,419 +1078,390 @@ auth1_new(void)
 /** Release all storage held inside 'obj', but do not free 'obj'.
  */
 static void
-auth1_clear(auth1_t *obj)
+certs_cell_cert_clear(certs_cell_cert_t *obj)
 {
   (void) obj;
-  TRUNNEL_DYNARRAY_WIPE(&obj->sig);
-  TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
+  TRUNNEL_DYNARRAY_WIPE(&obj->body);
+  TRUNNEL_DYNARRAY_CLEAR(&obj->body);
 }
 
 void
-auth1_free(auth1_t *obj)
+certs_cell_cert_free(certs_cell_cert_t *obj)
 {
   if (obj == NULL)
     return;
-  auth1_clear(obj);
-  trunnel_memwipe(obj, sizeof(auth1_t));
+  certs_cell_cert_clear(obj);
+  trunnel_memwipe(obj, sizeof(certs_cell_cert_t));
   trunnel_free_(obj);
 }
 
-size_t
-auth1_getlen_type(const auth1_t *inp)
-{
-  (void)inp;  return 8;
-}
-
-uint8_t
-auth1_get_type(auth1_t *inp, size_t idx)
-{
-  trunnel_assert(idx < 8);
-  return inp->type[idx];
-}
-
 uint8_t
-auth1_getconst_type(const auth1_t *inp, size_t idx)
+certs_cell_cert_get_cert_type(const certs_cell_cert_t *inp)
 {
-  return auth1_get_type((auth1_t*)inp, idx);
+  return inp->cert_type;
 }
 int
-auth1_set_type(auth1_t *inp, size_t idx, uint8_t elt)
+certs_cell_cert_set_cert_type(certs_cell_cert_t *inp, uint8_t val)
 {
-  trunnel_assert(idx < 8);
-  inp->type[idx] = elt;
+  inp->cert_type = val;
   return 0;
 }
-
-uint8_t *
-auth1_getarray_type(auth1_t *inp)
+uint16_t
+certs_cell_cert_get_cert_len(const certs_cell_cert_t *inp)
 {
-  return inp->type;
+  return inp->cert_len;
 }
-const uint8_t  *
-auth1_getconstarray_type(const auth1_t *inp)
+int
+certs_cell_cert_set_cert_len(certs_cell_cert_t *inp, uint16_t val)
 {
-  return (const uint8_t  *)auth1_getarray_type((auth1_t*)inp);
+  inp->cert_len = val;
+  return 0;
 }
 size_t
-auth1_getlen_cid(const auth1_t *inp)
+certs_cell_cert_getlen_body(const certs_cell_cert_t *inp)
 {
-  (void)inp;  return 32;
+  return TRUNNEL_DYNARRAY_LEN(&inp->body);
 }
 
 uint8_t
-auth1_get_cid(auth1_t *inp, size_t idx)
+certs_cell_cert_get_body(certs_cell_cert_t *inp, size_t idx)
 {
-  trunnel_assert(idx < 32);
-  return inp->cid[idx];
+  return TRUNNEL_DYNARRAY_GET(&inp->body, idx);
 }
 
 uint8_t
-auth1_getconst_cid(const auth1_t *inp, size_t idx)
+certs_cell_cert_getconst_body(const certs_cell_cert_t *inp, size_t idx)
 {
-  return auth1_get_cid((auth1_t*)inp, idx);
+  return certs_cell_cert_get_body((certs_cell_cert_t*)inp, idx);
 }
 int
-auth1_set_cid(auth1_t *inp, size_t idx, uint8_t elt)
+certs_cell_cert_set_body(certs_cell_cert_t *inp, size_t idx, uint8_t elt)
 {
-  trunnel_assert(idx < 32);
-  inp->cid[idx] = elt;
+  TRUNNEL_DYNARRAY_SET(&inp->body, idx, elt);
   return 0;
 }
-
-uint8_t *
-auth1_getarray_cid(auth1_t *inp)
-{
-  return inp->cid;
-}
-const uint8_t  *
-auth1_getconstarray_cid(const auth1_t *inp)
-{
-  return (const uint8_t  *)auth1_getarray_cid((auth1_t*)inp);
-}
-size_t
-auth1_getlen_sid(const auth1_t *inp)
-{
-  (void)inp;  return 32;
-}
-
-uint8_t
-auth1_get_sid(auth1_t *inp, size_t idx)
-{
-  trunnel_assert(idx < 32);
-  return inp->sid[idx];
-}
-
-uint8_t
-auth1_getconst_sid(const auth1_t *inp, size_t idx)
-{
-  return auth1_get_sid((auth1_t*)inp, idx);
-}
 int
-auth1_set_sid(auth1_t *inp, size_t idx, uint8_t elt)
+certs_cell_cert_add_body(certs_cell_cert_t *inp, uint8_t elt)
 {
-  trunnel_assert(idx < 32);
-  inp->sid[idx] = elt;
+#if SIZE_MAX >= UINT16_MAX
+  if (inp->body.n_ == UINT16_MAX)
+    goto trunnel_alloc_failed;
+#endif
+  TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->body, elt, {});
   return 0;
+ trunnel_alloc_failed:
+  TRUNNEL_SET_ERROR_CODE(inp);
+  return -1;
 }
 
 uint8_t *
-auth1_getarray_sid(auth1_t *inp)
+certs_cell_cert_getarray_body(certs_cell_cert_t *inp)
 {
-  return inp->sid;
+  return inp->body.elts_;
 }
 const uint8_t  *
-auth1_getconstarray_sid(const auth1_t *inp)
-{
-  return (const uint8_t  *)auth1_getarray_sid((auth1_t*)inp);
-}
-size_t
-auth1_getlen_u1_cid_ed(const auth1_t *inp)
-{
-  (void)inp;  return 32;
-}
-
-uint8_t
-auth1_get_u1_cid_ed(auth1_t *inp, size_t idx)
-{
-  trunnel_assert(idx < 32);
-  return inp->u1_cid_ed[idx];
-}
-
-uint8_t
-auth1_getconst_u1_cid_ed(const auth1_t *inp, size_t idx)
+certs_cell_cert_getconstarray_body(const certs_cell_cert_t *inp)
 {
-  return auth1_get_u1_cid_ed((auth1_t*)inp, idx);
+  return (const uint8_t  *)certs_cell_cert_getarray_body((certs_cell_cert_t*)inp);
 }
 int
-auth1_set_u1_cid_ed(auth1_t *inp, size_t idx, uint8_t elt)
+certs_cell_cert_setlen_body(certs_cell_cert_t *inp, size_t newlen)
 {
-  trunnel_assert(idx < 32);
-  inp->u1_cid_ed[idx] = elt;
+  uint8_t *newptr;
+#if UINT16_MAX < SIZE_MAX
+  if (newlen > UINT16_MAX)
+    goto trunnel_alloc_failed;
+#endif
+  newptr = trunnel_dynarray_setlen(&inp->body.allocated_,
+                 &inp->body.n_, inp->body.elts_, newlen,
+                 sizeof(inp->body.elts_[0]), (trunnel_free_fn_t) NULL,
+                 &inp->trunnel_error_code_);
+  if (newlen != 0 && newptr == NULL)
+    goto trunnel_alloc_failed;
+  inp->body.elts_ = newptr;
   return 0;
+ trunnel_alloc_failed:
+  TRUNNEL_SET_ERROR_CODE(inp);
+  return -1;
 }
-
-uint8_t *
-auth1_getarray_u1_cid_ed(auth1_t *inp)
-{
-  return inp->u1_cid_ed;
-}
-const uint8_t  *
-auth1_getconstarray_u1_cid_ed(const auth1_t *inp)
-{
-  return (const uint8_t  *)auth1_getarray_u1_cid_ed((auth1_t*)inp);
-}
-size_t
-auth1_getlen_u1_sid_ed(const auth1_t *inp)
+const char *
+certs_cell_cert_check(const certs_cell_cert_t *obj)
 {
-  (void)inp;  return 32;
+  if (obj == NULL)
+    return "Object was NULL";
+  if (obj->trunnel_error_code_)
+    return "A set function failed on this object";
+  if (TRUNNEL_DYNARRAY_LEN(&obj->body) != obj->cert_len)
+    return "Length mismatch for body";
+  return NULL;
 }
 
-uint8_t
-auth1_get_u1_sid_ed(auth1_t *inp, size_t idx)
+ssize_t
+certs_cell_cert_encoded_len(const certs_cell_cert_t *obj)
 {
-  trunnel_assert(idx < 32);
-  return inp->u1_sid_ed[idx];
-}
+  ssize_t result = 0;
 
-uint8_t
-auth1_getconst_u1_sid_ed(const auth1_t *inp, size_t idx)
-{
-  return auth1_get_u1_sid_ed((auth1_t*)inp, idx);
-}
-int
-auth1_set_u1_sid_ed(auth1_t *inp, size_t idx, uint8_t elt)
-{
-  trunnel_assert(idx < 32);
-  inp->u1_sid_ed[idx] = elt;
-  return 0;
-}
+  if (NULL != certs_cell_cert_check(obj))
+     return -1;
 
-uint8_t *
-auth1_getarray_u1_sid_ed(auth1_t *inp)
-{
-  return inp->u1_sid_ed;
-}
-const uint8_t  *
-auth1_getconstarray_u1_sid_ed(const auth1_t *inp)
-{
-  return (const uint8_t  *)auth1_getarray_u1_sid_ed((auth1_t*)inp);
-}
-size_t
-auth1_getlen_slog(const auth1_t *inp)
-{
-  (void)inp;  return 32;
-}
 
-uint8_t
-auth1_get_slog(auth1_t *inp, size_t idx)
-{
-  trunnel_assert(idx < 32);
-  return inp->slog[idx];
-}
+  /* Length of u8 cert_type */
+  result += 1;
 
-uint8_t
-auth1_getconst_slog(const auth1_t *inp, size_t idx)
-{
-  return auth1_get_slog((auth1_t*)inp, idx);
-}
-int
-auth1_set_slog(auth1_t *inp, size_t idx, uint8_t elt)
-{
-  trunnel_assert(idx < 32);
-  inp->slog[idx] = elt;
-  return 0;
-}
+  /* Length of u16 cert_len */
+  result += 2;
 
-uint8_t *
-auth1_getarray_slog(auth1_t *inp)
-{
-  return inp->slog;
+  /* Length of u8 body[cert_len] */
+  result += TRUNNEL_DYNARRAY_LEN(&obj->body);
+  return result;
 }
-const uint8_t  *
-auth1_getconstarray_slog(const auth1_t *inp)
+int
+certs_cell_cert_clear_errors(certs_cell_cert_t *obj)
 {
-  return (const uint8_t  *)auth1_getarray_slog((auth1_t*)inp);
+  int r = obj->trunnel_error_code_;
+  obj->trunnel_error_code_ = 0;
+  return r;
 }
-size_t
-auth1_getlen_clog(const auth1_t *inp)
+ssize_t
+certs_cell_cert_encode(uint8_t *output, const size_t avail, const certs_cell_cert_t *obj)
 {
-  (void)inp;  return 32;
-}
+  ssize_t result = 0;
+  size_t written = 0;
+  uint8_t *ptr = output;
+  const char *msg;
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+  const ssize_t encoded_len = certs_cell_cert_encoded_len(obj);
+#endif
 
-uint8_t
-auth1_get_clog(auth1_t *inp, size_t idx)
-{
-  trunnel_assert(idx < 32);
-  return inp->clog[idx];
-}
+  if (NULL != (msg = certs_cell_cert_check(obj)))
+    goto check_failed;
 
-uint8_t
-auth1_getconst_clog(const auth1_t *inp, size_t idx)
-{
-  return auth1_get_clog((auth1_t*)inp, idx);
-}
-int
-auth1_set_clog(auth1_t *inp, size_t idx, uint8_t elt)
-{
-  trunnel_assert(idx < 32);
-  inp->clog[idx] = elt;
-  return 0;
-}
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+  trunnel_assert(encoded_len >= 0);
+#endif
 
-uint8_t *
-auth1_getarray_clog(auth1_t *inp)
-{
-  return inp->clog;
-}
-const uint8_t  *
-auth1_getconstarray_clog(const auth1_t *inp)
-{
-  return (const uint8_t  *)auth1_getarray_clog((auth1_t*)inp);
-}
-size_t
-auth1_getlen_scert(const auth1_t *inp)
-{
-  (void)inp;  return 32;
+  /* Encode u8 cert_type */
+  trunnel_assert(written <= avail);
+  if (avail - written < 1)
+    goto truncated;
+  trunnel_set_uint8(ptr, (obj->cert_type));
+  written += 1; ptr += 1;
+
+  /* Encode u16 cert_len */
+  trunnel_assert(written <= avail);
+  if (avail - written < 2)
+    goto truncated;
+  trunnel_set_uint16(ptr, trunnel_htons(obj->cert_len));
+  written += 2; ptr += 2;
+
+  /* Encode u8 body[cert_len] */
+  {
+    size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->body);
+    trunnel_assert(obj->cert_len == elt_len);
+    trunnel_assert(written <= avail);
+    if (avail - written < elt_len)
+      goto truncated;
+    if (elt_len)
+      memcpy(ptr, obj->body.elts_, elt_len);
+    written += elt_len; ptr += elt_len;
+  }
+
+
+  trunnel_assert(ptr == output + written);
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+  {
+    trunnel_assert(encoded_len >= 0);
+    trunnel_assert((size_t)encoded_len == written);
+  }
+
+#endif
+
+  return written;
+
+ truncated:
+  result = -2;
+  goto fail;
+ check_failed:
+  (void)msg;
+  result = -1;
+  goto fail;
+ fail:
+  trunnel_assert(result < 0);
+  return result;
 }
 
-uint8_t
-auth1_get_scert(auth1_t *inp, size_t idx)
+/** As certs_cell_cert_parse(), but do not allocate the output object.
+ */
+static ssize_t
+certs_cell_cert_parse_into(certs_cell_cert_t *obj, const uint8_t *input, const size_t len_in)
 {
-  trunnel_assert(idx < 32);
-  return inp->scert[idx];
+  const uint8_t *ptr = input;
+  size_t remaining = len_in;
+  ssize_t result = 0;
+  (void)result;
+
+  /* Parse u8 cert_type */
+  CHECK_REMAINING(1, truncated);
+  obj->cert_type = (trunnel_get_uint8(ptr));
+  remaining -= 1; ptr += 1;
+
+  /* Parse u16 cert_len */
+  CHECK_REMAINING(2, truncated);
+  obj->cert_len = trunnel_ntohs(trunnel_get_uint16(ptr));
+  remaining -= 2; ptr += 2;
+
+  /* Parse u8 body[cert_len] */
+  CHECK_REMAINING(obj->cert_len, truncated);
+  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->body, obj->cert_len, {});
+  obj->body.n_ = obj->cert_len;
+  if (obj->cert_len)
+    memcpy(obj->body.elts_, ptr, obj->cert_len);
+  ptr += obj->cert_len; remaining -= obj->cert_len;
+  trunnel_assert(ptr + remaining == input + len_in);
+  return len_in - remaining;
+
+ truncated:
+  return -2;
+ trunnel_alloc_failed:
+  return -1;
 }
 
-uint8_t
-auth1_getconst_scert(const auth1_t *inp, size_t idx)
+ssize_t
+certs_cell_cert_parse(certs_cell_cert_t **output, const uint8_t *input, const size_t len_in)
 {
-  return auth1_get_scert((auth1_t*)inp, idx);
+  ssize_t result;
+  *output = certs_cell_cert_new();
+  if (NULL == *output)
+    return -1;
+  result = certs_cell_cert_parse_into(*output, input, len_in);
+  if (result < 0) {
+    certs_cell_cert_free(*output);
+    *output = NULL;
+  }
+  return result;
 }
-int
-auth1_set_scert(auth1_t *inp, size_t idx, uint8_t elt)
+rsa_ed_crosscert_t *
+rsa_ed_crosscert_new(void)
 {
-  trunnel_assert(idx < 32);
-  inp->scert[idx] = elt;
-  return 0;
+  rsa_ed_crosscert_t *val = trunnel_calloc(1, sizeof(rsa_ed_crosscert_t));
+  if (NULL == val)
+    return NULL;
+  return val;
 }
 
-uint8_t *
-auth1_getarray_scert(auth1_t *inp)
+/** Release all storage held inside 'obj', but do not free 'obj'.
+ */
+static void
+rsa_ed_crosscert_clear(rsa_ed_crosscert_t *obj)
 {
-  return inp->scert;
+  (void) obj;
+  TRUNNEL_DYNARRAY_WIPE(&obj->sig);
+  TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
 }
-const uint8_t  *
-auth1_getconstarray_scert(const auth1_t *inp)
+
+void
+rsa_ed_crosscert_free(rsa_ed_crosscert_t *obj)
 {
-  return (const uint8_t  *)auth1_getarray_scert((auth1_t*)inp);
+  if (obj == NULL)
+    return;
+  rsa_ed_crosscert_clear(obj);
+  trunnel_memwipe(obj, sizeof(rsa_ed_crosscert_t));
+  trunnel_free_(obj);
 }
+
 size_t
-auth1_getlen_tlssecrets(const auth1_t *inp)
+rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t *inp)
 {
   (void)inp;  return 32;
 }
 
 uint8_t
-auth1_get_tlssecrets(auth1_t *inp, size_t idx)
+rsa_ed_crosscert_get_ed_key(rsa_ed_crosscert_t *inp, size_t idx)
 {
   trunnel_assert(idx < 32);
-  return inp->tlssecrets[idx];
+  return inp->ed_key[idx];
 }
 
 uint8_t
-auth1_getconst_tlssecrets(const auth1_t *inp, size_t idx)
+rsa_ed_crosscert_getconst_ed_key(const rsa_ed_crosscert_t *inp, size_t idx)
 {
-  return auth1_get_tlssecrets((auth1_t*)inp, idx);
+  return rsa_ed_crosscert_get_ed_key((rsa_ed_crosscert_t*)inp, idx);
 }
 int
-auth1_set_tlssecrets(auth1_t *inp, size_t idx, uint8_t elt)
+rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
 {
   trunnel_assert(idx < 32);
-  inp->tlssecrets[idx] = elt;
+  inp->ed_key[idx] = elt;
   return 0;
 }
 
 uint8_t *
-auth1_getarray_tlssecrets(auth1_t *inp)
+rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t *inp)
 {
-  return inp->tlssecrets;
+  return inp->ed_key;
 }
 const uint8_t  *
-auth1_getconstarray_tlssecrets(const auth1_t *inp)
-{
-  return (const uint8_t  *)auth1_getarray_tlssecrets((auth1_t*)inp);
-}
-const uint8_t *
-auth1_get_end_of_fixed_part(const auth1_t *inp)
-{
-  return inp->end_of_fixed_part;
-}
-size_t
-auth1_getlen_rand(const auth1_t *inp)
-{
-  (void)inp;  return 24;
-}
-
-uint8_t
-auth1_get_rand(auth1_t *inp, size_t idx)
+rsa_ed_crosscert_getconstarray_ed_key(const rsa_ed_crosscert_t *inp)
 {
-  trunnel_assert(idx < 24);
-  return inp->rand[idx];
+  return (const uint8_t  *)rsa_ed_crosscert_getarray_ed_key((rsa_ed_crosscert_t*)inp);
 }
-
-uint8_t
-auth1_getconst_rand(const auth1_t *inp, size_t idx)
+uint32_t
+rsa_ed_crosscert_get_expiration(const rsa_ed_crosscert_t *inp)
 {
-  return auth1_get_rand((auth1_t*)inp, idx);
+  return inp->expiration;
 }
 int
-auth1_set_rand(auth1_t *inp, size_t idx, uint8_t elt)
+rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t *inp, uint32_t val)
 {
-  trunnel_assert(idx < 24);
-  inp->rand[idx] = elt;
+  inp->expiration = val;
   return 0;
 }
-
-uint8_t *
-auth1_getarray_rand(auth1_t *inp)
+const uint8_t *
+rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t *inp)
 {
-  return inp->rand;
+  return inp->end_of_signed;
 }
-const uint8_t  *
-auth1_getconstarray_rand(const auth1_t *inp)
+uint8_t
+rsa_ed_crosscert_get_sig_len(const rsa_ed_crosscert_t *inp)
 {
-  return (const uint8_t  *)auth1_getarray_rand((auth1_t*)inp);
+  return inp->sig_len;
 }
-const uint8_t *
-auth1_get_end_of_signed(const auth1_t *inp)
+int
+rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t *inp, uint8_t val)
 {
-  return inp->end_of_signed;
+  inp->sig_len = val;
+  return 0;
 }
 size_t
-auth1_getlen_sig(const auth1_t *inp)
+rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t *inp)
 {
   return TRUNNEL_DYNARRAY_LEN(&inp->sig);
 }
 
 uint8_t
-auth1_get_sig(auth1_t *inp, size_t idx)
+rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t *inp, size_t idx)
 {
   return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
 }
 
 uint8_t
-auth1_getconst_sig(const auth1_t *inp, size_t idx)
+rsa_ed_crosscert_getconst_sig(const rsa_ed_crosscert_t *inp, size_t idx)
 {
-  return auth1_get_sig((auth1_t*)inp, idx);
+  return rsa_ed_crosscert_get_sig((rsa_ed_crosscert_t*)inp, idx);
 }
 int
-auth1_set_sig(auth1_t *inp, size_t idx, uint8_t elt)
+rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
 {
   TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
   return 0;
 }
 int
-auth1_add_sig(auth1_t *inp, uint8_t elt)
+rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t *inp, uint8_t elt)
 {
+#if SIZE_MAX >= UINT8_MAX
+  if (inp->sig.n_ == UINT8_MAX)
+    goto trunnel_alloc_failed;
+#endif
   TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
   return 0;
  trunnel_alloc_failed:
@@ -1411,19 +1470,23 @@ auth1_add_sig(auth1_t *inp, uint8_t elt)
 }
 
 uint8_t *
-auth1_getarray_sig(auth1_t *inp)
+rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t *inp)
 {
   return inp->sig.elts_;
 }
 const uint8_t  *
-auth1_getconstarray_sig(const auth1_t *inp)
+rsa_ed_crosscert_getconstarray_sig(const rsa_ed_crosscert_t *inp)
 {
-  return (const uint8_t  *)auth1_getarray_sig((auth1_t*)inp);
+  return (const uint8_t  *)rsa_ed_crosscert_getarray_sig((rsa_ed_crosscert_t*)inp);
 }
 int
-auth1_setlen_sig(auth1_t *inp, size_t newlen)
+rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t *inp, size_t newlen)
 {
   uint8_t *newptr;
+#if UINT8_MAX < SIZE_MAX
+  if (newlen > UINT8_MAX)
+    goto trunnel_alloc_failed;
+#endif
   newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
                  &inp->sig.n_, inp->sig.elts_, newlen,
                  sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
@@ -1437,197 +1500,89 @@ auth1_setlen_sig(auth1_t *inp, size_t newlen)
   return -1;
 }
 const char *
-auth1_check(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
+rsa_ed_crosscert_check(const rsa_ed_crosscert_t *obj)
 {
   if (obj == NULL)
     return "Object was NULL";
   if (obj->trunnel_error_code_)
     return "A set function failed on this object";
-  if (auth_ctx_ctx == NULL)
-    return "Context was NULL";
-  switch (auth_ctx_ctx->is_ed) {
-
-    case 0:
-      break;
-
-    case 1:
-      break;
-
-    default:
-        return "Bad tag for union";
-      break;
-  }
+  if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len)
+    return "Length mismatch for sig";
   return NULL;
 }
 
 ssize_t
-auth1_encoded_len(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
+rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t *obj)
 {
   ssize_t result = 0;
 
-  if (NULL != auth1_check(obj, auth_ctx_ctx))
+  if (NULL != rsa_ed_crosscert_check(obj))
      return -1;
 
 
-  /* Length of u8 type[8] */
-  result += 8;
-
-  /* Length of u8 cid[32] */
-  result += 32;
-
-  /* Length of u8 sid[32] */
-  result += 32;
-  switch (auth_ctx_ctx->is_ed) {
-
-    case 0:
-      break;
-
-    case 1:
-
-      /* Length of u8 u1_cid_ed[32] */
-      result += 32;
-
-      /* Length of u8 u1_sid_ed[32] */
-      result += 32;
-      break;
-
-    default:
-      trunnel_assert(0);
-      break;
-  }
-
-  /* Length of u8 slog[32] */
-  result += 32;
-
-  /* Length of u8 clog[32] */
-  result += 32;
-
-  /* Length of u8 scert[32] */
+  /* Length of u8 ed_key[32] */
   result += 32;
 
-  /* Length of u8 tlssecrets[32] */
-  result += 32;
+  /* Length of u32 expiration */
+  result += 4;
 
-  /* Length of u8 rand[24] */
-  result += 24;
+  /* Length of u8 sig_len */
+  result += 1;
 
-  /* Length of u8 sig[] */
+  /* Length of u8 sig[sig_len] */
   result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
   return result;
 }
 int
-auth1_clear_errors(auth1_t *obj)
+rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t *obj)
 {
   int r = obj->trunnel_error_code_;
   obj->trunnel_error_code_ = 0;
   return r;
 }
 ssize_t
-auth1_encode(uint8_t *output, const size_t avail, const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
+rsa_ed_crosscert_encode(uint8_t *output, const size_t avail, const rsa_ed_crosscert_t *obj)
 {
   ssize_t result = 0;
   size_t written = 0;
   uint8_t *ptr = output;
   const char *msg;
 #ifdef TRUNNEL_CHECK_ENCODED_LEN
-  const ssize_t encoded_len = auth1_encoded_len(obj, auth_ctx_ctx);
+  const ssize_t encoded_len = rsa_ed_crosscert_encoded_len(obj);
 #endif
 
-  if (NULL != (msg = auth1_check(obj, auth_ctx_ctx)))
+  if (NULL != (msg = rsa_ed_crosscert_check(obj)))
     goto check_failed;
 
 #ifdef TRUNNEL_CHECK_ENCODED_LEN
   trunnel_assert(encoded_len >= 0);
 #endif
 
-  /* Encode u8 type[8] */
-  trunnel_assert(written <= avail);
-  if (avail - written < 8)
-    goto truncated;
-  memcpy(ptr, obj->type, 8);
-  written += 8; ptr += 8;
-
-  /* Encode u8 cid[32] */
-  trunnel_assert(written <= avail);
-  if (avail - written < 32)
-    goto truncated;
-  memcpy(ptr, obj->cid, 32);
-  written += 32; ptr += 32;
-
-  /* Encode u8 sid[32] */
-  trunnel_assert(written <= avail);
-  if (avail - written < 32)
-    goto truncated;
-  memcpy(ptr, obj->sid, 32);
-  written += 32; ptr += 32;
-
-  /* Encode union u1[auth_ctx.is_ed] */
-  trunnel_assert(written <= avail);
-  switch (auth_ctx_ctx->is_ed) {
-
-    case 0:
-      break;
-
-    case 1:
-
-      /* Encode u8 u1_cid_ed[32] */
-      trunnel_assert(written <= avail);
-      if (avail - written < 32)
-        goto truncated;
-      memcpy(ptr, obj->u1_cid_ed, 32);
-      written += 32; ptr += 32;
-
-      /* Encode u8 u1_sid_ed[32] */
-      trunnel_assert(written <= avail);
-      if (avail - written < 32)
-        goto truncated;
-      memcpy(ptr, obj->u1_sid_ed, 32);
-      written += 32; ptr += 32;
-      break;
-
-    default:
-      trunnel_assert(0);
-      break;
-  }
-
-  /* Encode u8 slog[32] */
-  trunnel_assert(written <= avail);
-  if (avail - written < 32)
-    goto truncated;
-  memcpy(ptr, obj->slog, 32);
-  written += 32; ptr += 32;
-
-  /* Encode u8 clog[32] */
-  trunnel_assert(written <= avail);
-  if (avail - written < 32)
-    goto truncated;
-  memcpy(ptr, obj->clog, 32);
-  written += 32; ptr += 32;
-
-  /* Encode u8 scert[32] */
+  /* Encode u8 ed_key[32] */
   trunnel_assert(written <= avail);
   if (avail - written < 32)
     goto truncated;
-  memcpy(ptr, obj->scert, 32);
+  memcpy(ptr, obj->ed_key, 32);
   written += 32; ptr += 32;
 
-  /* Encode u8 tlssecrets[32] */
+  /* Encode u32 expiration */
   trunnel_assert(written <= avail);
-  if (avail - written < 32)
+  if (avail - written < 4)
     goto truncated;
-  memcpy(ptr, obj->tlssecrets, 32);
-  written += 32; ptr += 32;
+  trunnel_set_uint32(ptr, trunnel_htonl(obj->expiration));
+  written += 4; ptr += 4;
 
-  /* Encode u8 rand[24] */
+  /* Encode u8 sig_len */
   trunnel_assert(written <= avail);
-  if (avail - written < 24)
+  if (avail - written < 1)
     goto truncated;
-  memcpy(ptr, obj->rand, 24);
-  written += 24; ptr += 24;
+  trunnel_set_uint8(ptr, (obj->sig_len));
+  written += 1; ptr += 1;
 
-  /* Encode u8 sig[] */
+  /* Encode u8 sig[sig_len] */
   {
     size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
+    trunnel_assert(obj->sig_len == elt_len);
     trunnel_assert(written <= avail);
     if (avail - written < elt_len)
       goto truncated;
@@ -1660,90 +1615,40 @@ auth1_encode(uint8_t *output, const size_t avail, const auth1_t *obj, const auth
   return result;
 }
 
-/** As auth1_parse(), but do not allocate the output object.
+/** As rsa_ed_crosscert_parse(), but do not allocate the output
+ * object.
  */
 static ssize_t
-auth1_parse_into(auth1_t *obj, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx)
+rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t *obj, const uint8_t *input, const size_t len_in)
 {
   const uint8_t *ptr = input;
   size_t remaining = len_in;
   ssize_t result = 0;
   (void)result;
-  if (auth_ctx_ctx == NULL)
-    return -1;
-
-  /* Parse u8 type[8] */
-  CHECK_REMAINING(8, truncated);
-  memcpy(obj->type, ptr, 8);
-  remaining -= 8; ptr += 8;
-
-  /* Parse u8 cid[32] */
-  CHECK_REMAINING(32, truncated);
-  memcpy(obj->cid, ptr, 32);
-  remaining -= 32; ptr += 32;
-
-  /* Parse u8 sid[32] */
-  CHECK_REMAINING(32, truncated);
-  memcpy(obj->sid, ptr, 32);
-  remaining -= 32; ptr += 32;
-
-  /* Parse union u1[auth_ctx.is_ed] */
-  switch (auth_ctx_ctx->is_ed) {
-
-    case 0:
-      break;
-
-    case 1:
-
-      /* Parse u8 u1_cid_ed[32] */
-      CHECK_REMAINING(32, truncated);
-      memcpy(obj->u1_cid_ed, ptr, 32);
-      remaining -= 32; ptr += 32;
-
-      /* Parse u8 u1_sid_ed[32] */
-      CHECK_REMAINING(32, truncated);
-      memcpy(obj->u1_sid_ed, ptr, 32);
-      remaining -= 32; ptr += 32;
-      break;
-
-    default:
-      goto fail;
-      break;
-  }
-
-  /* Parse u8 slog[32] */
-  CHECK_REMAINING(32, truncated);
-  memcpy(obj->slog, ptr, 32);
-  remaining -= 32; ptr += 32;
-
-  /* Parse u8 clog[32] */
-  CHECK_REMAINING(32, truncated);
-  memcpy(obj->clog, ptr, 32);
-  remaining -= 32; ptr += 32;
-
-  /* Parse u8 scert[32] */
-  CHECK_REMAINING(32, truncated);
-  memcpy(obj->scert, ptr, 32);
-  remaining -= 32; ptr += 32;
 
-  /* Parse u8 tlssecrets[32] */
+  /* Parse u8 ed_key[32] */
   CHECK_REMAINING(32, truncated);
-  memcpy(obj->tlssecrets, ptr, 32);
+  memcpy(obj->ed_key, ptr, 32);
   remaining -= 32; ptr += 32;
-  obj->end_of_fixed_part = ptr;
 
-  /* Parse u8 rand[24] */
-  CHECK_REMAINING(24, truncated);
-  memcpy(obj->rand, ptr, 24);
-  remaining -= 24; ptr += 24;
+  /* Parse u32 expiration */
+  CHECK_REMAINING(4, truncated);
+  obj->expiration = trunnel_ntohl(trunnel_get_uint32(ptr));
+  remaining -= 4; ptr += 4;
   obj->end_of_signed = ptr;
 
-  /* Parse u8 sig[] */
-  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, remaining, {});
-  obj->sig.n_ = remaining;
-  if (remaining)
-    memcpy(obj->sig.elts_, ptr, remaining);
-  ptr += remaining; remaining -= remaining;
+  /* Parse u8 sig_len */
+  CHECK_REMAINING(1, truncated);
+  obj->sig_len = (trunnel_get_uint8(ptr));
+  remaining -= 1; ptr += 1;
+
+  /* Parse u8 sig[sig_len] */
+  CHECK_REMAINING(obj->sig_len, truncated);
+  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {});
+  obj->sig.n_ = obj->sig_len;
+  if (obj->sig_len)
+    memcpy(obj->sig.elts_, ptr, obj->sig_len);
+  ptr += obj->sig_len; remaining -= obj->sig_len;
   trunnel_assert(ptr + remaining == input + len_in);
   return len_in - remaining;
 
@@ -1751,21 +1656,18 @@ auth1_parse_into(auth1_t *obj, const uint8_t *input, const size_t len_in, const
   return -2;
  trunnel_alloc_failed:
   return -1;
- fail:
-  result = -1;
-  return result;
 }
 
 ssize_t
-auth1_parse(auth1_t **output, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx)
+rsa_ed_crosscert_parse(rsa_ed_crosscert_t **output, const uint8_t *input, const size_t len_in)
 {
   ssize_t result;
-  *output = auth1_new();
+  *output = rsa_ed_crosscert_new();
   if (NULL == *output)
     return -1;
-  result = auth1_parse_into(*output, input, len_in, auth_ctx_ctx);
+  result = rsa_ed_crosscert_parse_into(*output, input, len_in);
   if (result < 0) {
-    auth1_free(*output);
+    rsa_ed_crosscert_free(*output);
     *output = NULL;
   }
   return result;
index 0c7ac36b1b949a74a122797a682cfc76066def14..b385ce74d5f24d5fdeba85e05884b4f48a49cf20 100644 (file)
 #define CERTTYPE_ED_SIGN_LINK 5
 #define CERTTYPE_ED_SIGN_AUTH 6
 #define CERTTYPE_RSA1024_ID_EDID 7
+#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_AUTH1)
+struct auth1_st {
+  uint8_t type[8];
+  uint8_t cid[32];
+  uint8_t sid[32];
+  uint8_t cid_ed[32];
+  uint8_t sid_ed[32];
+  uint8_t slog[32];
+  uint8_t clog[32];
+  uint8_t scert[32];
+  uint8_t tlssecrets[32];
+  const uint8_t *end_of_fixed_part;
+  uint8_t rand[24];
+  const uint8_t *end_of_signed;
+  TRUNNEL_DYNARRAY_HEAD(, uint8_t) sig;
+  uint8_t trunnel_error_code_;
+};
+#endif
+typedef struct auth1_st auth1_t;
 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_AUTH_CHALLENGE_CELL)
 struct auth_challenge_cell_st {
   uint8_t challenge[32];
@@ -24,13 +43,6 @@ struct auth_challenge_cell_st {
 };
 #endif
 typedef struct auth_challenge_cell_st auth_challenge_cell_t;
-#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_AUTH_CTX)
-struct auth_ctx_st {
-  uint8_t is_ed;
-  uint8_t trunnel_error_code_;
-};
-#endif
-typedef struct auth_ctx_st auth_ctx_t;
 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_CERTS_CELL_CERT)
 struct certs_cell_cert_st {
   uint8_t cert_type;
@@ -51,25 +63,6 @@ struct rsa_ed_crosscert_st {
 };
 #endif
 typedef struct rsa_ed_crosscert_st rsa_ed_crosscert_t;
-#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_AUTH1)
-struct auth1_st {
-  uint8_t type[8];
-  uint8_t cid[32];
-  uint8_t sid[32];
-  uint8_t u1_cid_ed[32];
-  uint8_t u1_sid_ed[32];
-  uint8_t slog[32];
-  uint8_t clog[32];
-  uint8_t scert[32];
-  uint8_t tlssecrets[32];
-  const uint8_t *end_of_fixed_part;
-  uint8_t rand[24];
-  const uint8_t *end_of_signed;
-  TRUNNEL_DYNARRAY_HEAD(, uint8_t) sig;
-  uint8_t trunnel_error_code_;
-};
-#endif
-typedef struct auth1_st auth1_t;
 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_CERTS_CELL)
 struct certs_cell_st {
   uint8_t n_certs;
@@ -78,475 +71,160 @@ struct certs_cell_st {
 };
 #endif
 typedef struct certs_cell_st certs_cell_t;
-/** Return a newly allocated auth_challenge_cell with all elements set
- * to zero.
+/** Return a newly allocated auth1 with all elements set to zero.
  */
-auth_challenge_cell_t *auth_challenge_cell_new(void);
-/** Release all storage held by the auth_challenge_cell in 'victim'.
- * (Do nothing if 'victim' is NULL.)
+auth1_t *auth1_new(void);
+/** Release all storage held by the auth1 in 'victim'. (Do nothing if
+ * 'victim' is NULL.)
  */
-void auth_challenge_cell_free(auth_challenge_cell_t *victim);
-/** Try to parse a auth_challenge_cell from the buffer in 'input',
- * using up to 'len_in' bytes from the input buffer. On success,
- * return the number of bytes consumed and set *output to the newly
- * allocated auth_challenge_cell_t. On failure, return -2 if the input
- * appears truncated, and -1 if the input is otherwise invalid.
+void auth1_free(auth1_t *victim);
+/** Try to parse a auth1 from the buffer in 'input', using up to
+ * 'len_in' bytes from the input buffer. On success, return the number
+ * of bytes consumed and set *output to the newly allocated auth1_t.
+ * On failure, return -2 if the input appears truncated, and -1 if the
+ * input is otherwise invalid.
  */
-ssize_t auth_challenge_cell_parse(auth_challenge_cell_t **output, const uint8_t *input, const size_t len_in);
-/** Return the number of bytes we expect to need to encode the
- * auth_challenge_cell in 'obj'. On failure, return a negative value.
- * Note that this value may be an overestimate, and can even be an
- * underestimate for certain unencodeable objects.
+ssize_t auth1_parse(auth1_t **output, const uint8_t *input, const size_t len_in);
+/** Return the number of bytes we expect to need to encode the auth1
+ * in 'obj'. On failure, return a negative value. Note that this value
+ * may be an overestimate, and can even be an underestimate for
+ * certain unencodeable objects.
  */
-ssize_t auth_challenge_cell_encoded_len(const auth_challenge_cell_t *obj);
-/** Try to encode the auth_challenge_cell from 'input' into the buffer
- * at 'output', using up to 'avail' bytes of the output buffer. On
- * success, return the number of bytes used. On failure, return -2 if
- * the buffer was not long enough, and -1 if the input was invalid.
+ssize_t auth1_encoded_len(const auth1_t *obj);
+/** Try to encode the auth1 from 'input' into the buffer at 'output',
+ * using up to 'avail' bytes of the output buffer. On success, return
+ * the number of bytes used. On failure, return -2 if the buffer was
+ * not long enough, and -1 if the input was invalid.
  */
-ssize_t auth_challenge_cell_encode(uint8_t *output, size_t avail, const auth_challenge_cell_t *input);
-/** Check whether the internal state of the auth_challenge_cell in
- * 'obj' is consistent. Return NULL if it is, and a short message if
- * it is not.
+ssize_t auth1_encode(uint8_t *output, size_t avail, const auth1_t *input);
+/** Check whether the internal state of the auth1 in 'obj' is
+ * consistent. Return NULL if it is, and a short message if it is not.
  */
-const char *auth_challenge_cell_check(const auth_challenge_cell_t *obj);
+const char *auth1_check(const auth1_t *obj);
 /** Clear any errors that were set on the object 'obj' by its setter
  * functions. Return true iff errors were cleared.
  */
-int auth_challenge_cell_clear_errors(auth_challenge_cell_t *obj);
-/** Return the (constant) length of the array holding the challenge
- * field of the auth_challenge_cell_t in 'inp'.
- */
-size_t auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t *inp);
-/** Return the element at position 'idx' of the fixed array field
- * challenge of the auth_challenge_cell_t in 'inp'.
+int auth1_clear_errors(auth1_t *obj);
+/** Return the (constant) length of the array holding the type field
+ * of the auth1_t in 'inp'.
  */
-uint8_t auth_challenge_cell_get_challenge(auth_challenge_cell_t *inp, size_t idx);
-/** As auth_challenge_cell_get_challenge, but take and return a const
- * pointer
+size_t auth1_getlen_type(const auth1_t *inp);
+/** Return the element at position 'idx' of the fixed array field type
+ * of the auth1_t in 'inp'.
  */
-uint8_t auth_challenge_cell_getconst_challenge(const auth_challenge_cell_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field
- * challenge of the auth_challenge_cell_t in 'inp', so that it will
- * hold the value 'elt'.
+uint8_t auth1_get_type(auth1_t *inp, size_t idx);
+/** As auth1_get_type, but take and return a const pointer
  */
-int auth_challenge_cell_set_challenge(auth_challenge_cell_t *inp, size_t idx, uint8_t elt);
-/** Return a pointer to the 32-element array field challenge of 'inp'.
+uint8_t auth1_getconst_type(const auth1_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field type
+ * of the auth1_t in 'inp', so that it will hold the value 'elt'.
  */
-uint8_t * auth_challenge_cell_getarray_challenge(auth_challenge_cell_t *inp);
-/** As auth_challenge_cell_get_challenge, but take and return a const
- * pointer
+int auth1_set_type(auth1_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 8-element array field type of 'inp'.
  */
-const uint8_t  * auth_challenge_cell_getconstarray_challenge(const auth_challenge_cell_t *inp);
-/** Return the value of the n_methods field of the
- * auth_challenge_cell_t in 'inp'
+uint8_t * auth1_getarray_type(auth1_t *inp);
+/** As auth1_get_type, but take and return a const pointer
  */
-uint16_t auth_challenge_cell_get_n_methods(const auth_challenge_cell_t *inp);
-/** Set the value of the n_methods field of the auth_challenge_cell_t
- * in 'inp' to 'val'. Return 0 on success; return -1 and set the error
- * code on 'inp' on failure.
+const uint8_t  * auth1_getconstarray_type(const auth1_t *inp);
+/** Return the (constant) length of the array holding the cid field of
+ * the auth1_t in 'inp'.
  */
-int auth_challenge_cell_set_n_methods(auth_challenge_cell_t *inp, uint16_t val);
-/** Return the length of the dynamic array holding the methods field
- * of the auth_challenge_cell_t in 'inp'.
+size_t auth1_getlen_cid(const auth1_t *inp);
+/** Return the element at position 'idx' of the fixed array field cid
+ * of the auth1_t in 'inp'.
  */
-size_t auth_challenge_cell_getlen_methods(const auth_challenge_cell_t *inp);
-/** Return the element at position 'idx' of the dynamic array field
- * methods of the auth_challenge_cell_t in 'inp'.
+uint8_t auth1_get_cid(auth1_t *inp, size_t idx);
+/** As auth1_get_cid, but take and return a const pointer
  */
-uint16_t auth_challenge_cell_get_methods(auth_challenge_cell_t *inp, size_t idx);
-/** As auth_challenge_cell_get_methods, but take and return a const
- * pointer
+uint8_t auth1_getconst_cid(const auth1_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field cid
+ * of the auth1_t in 'inp', so that it will hold the value 'elt'.
  */
-uint16_t auth_challenge_cell_getconst_methods(const auth_challenge_cell_t *inp, size_t idx);
-/** Change the element at position 'idx' of the dynamic array field
- * methods of the auth_challenge_cell_t in 'inp', so that it will hold
- * the value 'elt'.
+int auth1_set_cid(auth1_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 32-element array field cid of 'inp'.
  */
-int auth_challenge_cell_set_methods(auth_challenge_cell_t *inp, size_t idx, uint16_t elt);
-/** Append a new element 'elt' to the dynamic array field methods of
- * the auth_challenge_cell_t in 'inp'.
+uint8_t * auth1_getarray_cid(auth1_t *inp);
+/** As auth1_get_cid, but take and return a const pointer
  */
-int auth_challenge_cell_add_methods(auth_challenge_cell_t *inp, uint16_t elt);
-/** Return a pointer to the variable-length array field methods of
- * 'inp'.
+const uint8_t  * auth1_getconstarray_cid(const auth1_t *inp);
+/** Return the (constant) length of the array holding the sid field of
+ * the auth1_t in 'inp'.
  */
-uint16_t * auth_challenge_cell_getarray_methods(auth_challenge_cell_t *inp);
-/** As auth_challenge_cell_get_methods, but take and return a const
- * pointer
+size_t auth1_getlen_sid(const auth1_t *inp);
+/** Return the element at position 'idx' of the fixed array field sid
+ * of the auth1_t in 'inp'.
  */
-const uint16_t  * auth_challenge_cell_getconstarray_methods(const auth_challenge_cell_t *inp);
-/** Change the length of the variable-length array field methods of
- * 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success;
- * return -1 and set the error code on 'inp' on failure.
+uint8_t auth1_get_sid(auth1_t *inp, size_t idx);
+/** As auth1_get_sid, but take and return a const pointer
  */
-int auth_challenge_cell_setlen_methods(auth_challenge_cell_t *inp, size_t newlen);
-/** Return a newly allocated auth_ctx with all elements set to zero.
+uint8_t auth1_getconst_sid(const auth1_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field sid
+ * of the auth1_t in 'inp', so that it will hold the value 'elt'.
  */
-auth_ctx_t *auth_ctx_new(void);
-/** Release all storage held by the auth_ctx in 'victim'. (Do nothing
- * if 'victim' is NULL.)
+int auth1_set_sid(auth1_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 32-element array field sid of 'inp'.
  */
-void auth_ctx_free(auth_ctx_t *victim);
-/** Return the value of the is_ed field of the auth_ctx_t in 'inp'
+uint8_t * auth1_getarray_sid(auth1_t *inp);
+/** As auth1_get_sid, but take and return a const pointer
  */
-uint8_t auth_ctx_get_is_ed(const auth_ctx_t *inp);
-/** Set the value of the is_ed field of the auth_ctx_t in 'inp' to
- * 'val'. Return 0 on success; return -1 and set the error code on
- * 'inp' on failure.
+const uint8_t  * auth1_getconstarray_sid(const auth1_t *inp);
+/** Return the (constant) length of the array holding the cid_ed field
+ * of the auth1_t in 'inp'.
  */
-int auth_ctx_set_is_ed(auth_ctx_t *inp, uint8_t val);
-/** Return a newly allocated certs_cell_cert with all elements set to
- * zero.
+size_t auth1_getlen_cid_ed(const auth1_t *inp);
+/** Return the element at position 'idx' of the fixed array field
+ * cid_ed of the auth1_t in 'inp'.
  */
-certs_cell_cert_t *certs_cell_cert_new(void);
-/** Release all storage held by the certs_cell_cert in 'victim'. (Do
- * nothing if 'victim' is NULL.)
+uint8_t auth1_get_cid_ed(auth1_t *inp, size_t idx);
+/** As auth1_get_cid_ed, but take and return a const pointer
  */
-void certs_cell_cert_free(certs_cell_cert_t *victim);
-/** Try to parse a certs_cell_cert from the buffer in 'input', using
- * up to 'len_in' bytes from the input buffer. On success, return the
- * number of bytes consumed and set *output to the newly allocated
- * certs_cell_cert_t. On failure, return -2 if the input appears
- * truncated, and -1 if the input is otherwise invalid.
+uint8_t auth1_getconst_cid_ed(const auth1_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field
+ * cid_ed of the auth1_t in 'inp', so that it will hold the value
+ * 'elt'.
  */
-ssize_t certs_cell_cert_parse(certs_cell_cert_t **output, const uint8_t *input, const size_t len_in);
-/** Return the number of bytes we expect to need to encode the
- * certs_cell_cert in 'obj'. On failure, return a negative value. Note
- * that this value may be an overestimate, and can even be an
- * underestimate for certain unencodeable objects.
+int auth1_set_cid_ed(auth1_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 32-element array field cid_ed of 'inp'.
  */
-ssize_t certs_cell_cert_encoded_len(const certs_cell_cert_t *obj);
-/** Try to encode the certs_cell_cert from 'input' into the buffer at
- * 'output', using up to 'avail' bytes of the output buffer. On
- * success, return the number of bytes used. On failure, return -2 if
- * the buffer was not long enough, and -1 if the input was invalid.
+uint8_t * auth1_getarray_cid_ed(auth1_t *inp);
+/** As auth1_get_cid_ed, but take and return a const pointer
  */
-ssize_t certs_cell_cert_encode(uint8_t *output, size_t avail, const certs_cell_cert_t *input);
-/** Check whether the internal state of the certs_cell_cert in 'obj'
- * is consistent. Return NULL if it is, and a short message if it is
- * not.
+const uint8_t  * auth1_getconstarray_cid_ed(const auth1_t *inp);
+/** Return the (constant) length of the array holding the sid_ed field
+ * of the auth1_t in 'inp'.
  */
-const char *certs_cell_cert_check(const certs_cell_cert_t *obj);
-/** Clear any errors that were set on the object 'obj' by its setter
- * functions. Return true iff errors were cleared.
+size_t auth1_getlen_sid_ed(const auth1_t *inp);
+/** Return the element at position 'idx' of the fixed array field
+ * sid_ed of the auth1_t in 'inp'.
  */
-int certs_cell_cert_clear_errors(certs_cell_cert_t *obj);
-/** Return the value of the cert_type field of the certs_cell_cert_t
- * in 'inp'
+uint8_t auth1_get_sid_ed(auth1_t *inp, size_t idx);
+/** As auth1_get_sid_ed, but take and return a const pointer
  */
-uint8_t certs_cell_cert_get_cert_type(const certs_cell_cert_t *inp);
-/** Set the value of the cert_type field of the certs_cell_cert_t in
- * 'inp' to 'val'. Return 0 on success; return -1 and set the error
- * code on 'inp' on failure.
+uint8_t auth1_getconst_sid_ed(const auth1_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field
+ * sid_ed of the auth1_t in 'inp', so that it will hold the value
+ * 'elt'.
  */
-int certs_cell_cert_set_cert_type(certs_cell_cert_t *inp, uint8_t val);
-/** Return the value of the cert_len field of the certs_cell_cert_t in
- * 'inp'
+int auth1_set_sid_ed(auth1_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 32-element array field sid_ed of 'inp'.
  */
-uint16_t certs_cell_cert_get_cert_len(const certs_cell_cert_t *inp);
-/** Set the value of the cert_len field of the certs_cell_cert_t in
- * 'inp' to 'val'. Return 0 on success; return -1 and set the error
- * code on 'inp' on failure.
+uint8_t * auth1_getarray_sid_ed(auth1_t *inp);
+/** As auth1_get_sid_ed, but take and return a const pointer
  */
-int certs_cell_cert_set_cert_len(certs_cell_cert_t *inp, uint16_t val);
-/** Return the length of the dynamic array holding the body field of
- * the certs_cell_cert_t in 'inp'.
+const uint8_t  * auth1_getconstarray_sid_ed(const auth1_t *inp);
+/** Return the (constant) length of the array holding the slog field
+ * of the auth1_t in 'inp'.
  */
-size_t certs_cell_cert_getlen_body(const certs_cell_cert_t *inp);
-/** Return the element at position 'idx' of the dynamic array field
- * body of the certs_cell_cert_t in 'inp'.
+size_t auth1_getlen_slog(const auth1_t *inp);
+/** Return the element at position 'idx' of the fixed array field slog
+ * of the auth1_t in 'inp'.
  */
-uint8_t certs_cell_cert_get_body(certs_cell_cert_t *inp, size_t idx);
-/** As certs_cell_cert_get_body, but take and return a const pointer
+uint8_t auth1_get_slog(auth1_t *inp, size_t idx);
+/** As auth1_get_slog, but take and return a const pointer
  */
-uint8_t certs_cell_cert_getconst_body(const certs_cell_cert_t *inp, size_t idx);
-/** Change the element at position 'idx' of the dynamic array field
- * body of the certs_cell_cert_t in 'inp', so that it will hold the
- * value 'elt'.
- */
-int certs_cell_cert_set_body(certs_cell_cert_t *inp, size_t idx, uint8_t elt);
-/** Append a new element 'elt' to the dynamic array field body of the
- * certs_cell_cert_t in 'inp'.
- */
-int certs_cell_cert_add_body(certs_cell_cert_t *inp, uint8_t elt);
-/** Return a pointer to the variable-length array field body of 'inp'.
- */
-uint8_t * certs_cell_cert_getarray_body(certs_cell_cert_t *inp);
-/** As certs_cell_cert_get_body, but take and return a const pointer
- */
-const uint8_t  * certs_cell_cert_getconstarray_body(const certs_cell_cert_t *inp);
-/** Change the length of the variable-length array field body of 'inp'
- * to 'newlen'.Fill extra elements with 0. Return 0 on success; return
- * -1 and set the error code on 'inp' on failure.
- */
-int certs_cell_cert_setlen_body(certs_cell_cert_t *inp, size_t newlen);
-/** Return a newly allocated rsa_ed_crosscert with all elements set to
- * zero.
- */
-rsa_ed_crosscert_t *rsa_ed_crosscert_new(void);
-/** Release all storage held by the rsa_ed_crosscert in 'victim'. (Do
- * nothing if 'victim' is NULL.)
- */
-void rsa_ed_crosscert_free(rsa_ed_crosscert_t *victim);
-/** Try to parse a rsa_ed_crosscert from the buffer in 'input', using
- * up to 'len_in' bytes from the input buffer. On success, return the
- * number of bytes consumed and set *output to the newly allocated
- * rsa_ed_crosscert_t. On failure, return -2 if the input appears
- * truncated, and -1 if the input is otherwise invalid.
- */
-ssize_t rsa_ed_crosscert_parse(rsa_ed_crosscert_t **output, const uint8_t *input, const size_t len_in);
-/** Return the number of bytes we expect to need to encode the
- * rsa_ed_crosscert in 'obj'. On failure, return a negative value.
- * Note that this value may be an overestimate, and can even be an
- * underestimate for certain unencodeable objects.
- */
-ssize_t rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t *obj);
-/** Try to encode the rsa_ed_crosscert from 'input' into the buffer at
- * 'output', using up to 'avail' bytes of the output buffer. On
- * success, return the number of bytes used. On failure, return -2 if
- * the buffer was not long enough, and -1 if the input was invalid.
- */
-ssize_t rsa_ed_crosscert_encode(uint8_t *output, size_t avail, const rsa_ed_crosscert_t *input);
-/** Check whether the internal state of the rsa_ed_crosscert in 'obj'
- * is consistent. Return NULL if it is, and a short message if it is
- * not.
- */
-const char *rsa_ed_crosscert_check(const rsa_ed_crosscert_t *obj);
-/** Clear any errors that were set on the object 'obj' by its setter
- * functions. Return true iff errors were cleared.
- */
-int rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t *obj);
-/** Return the (constant) length of the array holding the ed_key field
- * of the rsa_ed_crosscert_t in 'inp'.
- */
-size_t rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t *inp);
-/** Return the element at position 'idx' of the fixed array field
- * ed_key of the rsa_ed_crosscert_t in 'inp'.
- */
-uint8_t rsa_ed_crosscert_get_ed_key(rsa_ed_crosscert_t *inp, size_t idx);
-/** As rsa_ed_crosscert_get_ed_key, but take and return a const
- * pointer
- */
-uint8_t rsa_ed_crosscert_getconst_ed_key(const rsa_ed_crosscert_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field
- * ed_key of the rsa_ed_crosscert_t in 'inp', so that it will hold the
- * value 'elt'.
- */
-int rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt);
-/** Return a pointer to the 32-element array field ed_key of 'inp'.
- */
-uint8_t * rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t *inp);
-/** As rsa_ed_crosscert_get_ed_key, but take and return a const
- * pointer
- */
-const uint8_t  * rsa_ed_crosscert_getconstarray_ed_key(const rsa_ed_crosscert_t *inp);
-/** Return the value of the expiration field of the rsa_ed_crosscert_t
- * in 'inp'
- */
-uint32_t rsa_ed_crosscert_get_expiration(const rsa_ed_crosscert_t *inp);
-/** Set the value of the expiration field of the rsa_ed_crosscert_t in
- * 'inp' to 'val'. Return 0 on success; return -1 and set the error
- * code on 'inp' on failure.
- */
-int rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t *inp, uint32_t val);
-/** Return the position for end_of_signed when we parsed this object
- */
-const uint8_t * rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t *inp);
-/** Return the value of the sig_len field of the rsa_ed_crosscert_t in
- * 'inp'
- */
-uint8_t rsa_ed_crosscert_get_sig_len(const rsa_ed_crosscert_t *inp);
-/** Set the value of the sig_len field of the rsa_ed_crosscert_t in
- * 'inp' to 'val'. Return 0 on success; return -1 and set the error
- * code on 'inp' on failure.
- */
-int rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t *inp, uint8_t val);
-/** Return the length of the dynamic array holding the sig field of
- * the rsa_ed_crosscert_t in 'inp'.
- */
-size_t rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t *inp);
-/** Return the element at position 'idx' of the dynamic array field
- * sig of the rsa_ed_crosscert_t in 'inp'.
- */
-uint8_t rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t *inp, size_t idx);
-/** As rsa_ed_crosscert_get_sig, but take and return a const pointer
- */
-uint8_t rsa_ed_crosscert_getconst_sig(const rsa_ed_crosscert_t *inp, size_t idx);
-/** Change the element at position 'idx' of the dynamic array field
- * sig of the rsa_ed_crosscert_t in 'inp', so that it will hold the
- * value 'elt'.
- */
-int rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt);
-/** Append a new element 'elt' to the dynamic array field sig of the
- * rsa_ed_crosscert_t in 'inp'.
- */
-int rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t *inp, uint8_t elt);
-/** Return a pointer to the variable-length array field sig of 'inp'.
- */
-uint8_t * rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t *inp);
-/** As rsa_ed_crosscert_get_sig, but take and return a const pointer
- */
-const uint8_t  * rsa_ed_crosscert_getconstarray_sig(const rsa_ed_crosscert_t *inp);
-/** Change the length of the variable-length array field sig of 'inp'
- * to 'newlen'.Fill extra elements with 0. Return 0 on success; return
- * -1 and set the error code on 'inp' on failure.
- */
-int rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t *inp, size_t newlen);
-/** Return a newly allocated auth1 with all elements set to zero.
- */
-auth1_t *auth1_new(void);
-/** Release all storage held by the auth1 in 'victim'. (Do nothing if
- * 'victim' is NULL.)
- */
-void auth1_free(auth1_t *victim);
-/** Try to parse a auth1 from the buffer in 'input', using up to
- * 'len_in' bytes from the input buffer. On success, return the number
- * of bytes consumed and set *output to the newly allocated auth1_t.
- * On failure, return -2 if the input appears truncated, and -1 if the
- * input is otherwise invalid.
- */
-ssize_t auth1_parse(auth1_t **output, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx);
-/** Return the number of bytes we expect to need to encode the auth1
- * in 'obj'. On failure, return a negative value. Note that this value
- * may be an overestimate, and can even be an underestimate for
- * certain unencodeable objects.
- */
-ssize_t auth1_encoded_len(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx);
-/** Try to encode the auth1 from 'input' into the buffer at 'output',
- * using up to 'avail' bytes of the output buffer. On success, return
- * the number of bytes used. On failure, return -2 if the buffer was
- * not long enough, and -1 if the input was invalid.
- */
-ssize_t auth1_encode(uint8_t *output, size_t avail, const auth1_t *input, const auth_ctx_t *auth_ctx_ctx);
-/** Check whether the internal state of the auth1 in 'obj' is
- * consistent. Return NULL if it is, and a short message if it is not.
- */
-const char *auth1_check(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx);
-/** Clear any errors that were set on the object 'obj' by its setter
- * functions. Return true iff errors were cleared.
- */
-int auth1_clear_errors(auth1_t *obj);
-/** Return the (constant) length of the array holding the type field
- * of the auth1_t in 'inp'.
- */
-size_t auth1_getlen_type(const auth1_t *inp);
-/** Return the element at position 'idx' of the fixed array field type
- * of the auth1_t in 'inp'.
- */
-uint8_t auth1_get_type(auth1_t *inp, size_t idx);
-/** As auth1_get_type, but take and return a const pointer
- */
-uint8_t auth1_getconst_type(const auth1_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field type
- * of the auth1_t in 'inp', so that it will hold the value 'elt'.
- */
-int auth1_set_type(auth1_t *inp, size_t idx, uint8_t elt);
-/** Return a pointer to the 8-element array field type of 'inp'.
- */
-uint8_t * auth1_getarray_type(auth1_t *inp);
-/** As auth1_get_type, but take and return a const pointer
- */
-const uint8_t  * auth1_getconstarray_type(const auth1_t *inp);
-/** Return the (constant) length of the array holding the cid field of
- * the auth1_t in 'inp'.
- */
-size_t auth1_getlen_cid(const auth1_t *inp);
-/** Return the element at position 'idx' of the fixed array field cid
- * of the auth1_t in 'inp'.
- */
-uint8_t auth1_get_cid(auth1_t *inp, size_t idx);
-/** As auth1_get_cid, but take and return a const pointer
- */
-uint8_t auth1_getconst_cid(const auth1_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field cid
- * of the auth1_t in 'inp', so that it will hold the value 'elt'.
- */
-int auth1_set_cid(auth1_t *inp, size_t idx, uint8_t elt);
-/** Return a pointer to the 32-element array field cid of 'inp'.
- */
-uint8_t * auth1_getarray_cid(auth1_t *inp);
-/** As auth1_get_cid, but take and return a const pointer
- */
-const uint8_t  * auth1_getconstarray_cid(const auth1_t *inp);
-/** Return the (constant) length of the array holding the sid field of
- * the auth1_t in 'inp'.
- */
-size_t auth1_getlen_sid(const auth1_t *inp);
-/** Return the element at position 'idx' of the fixed array field sid
- * of the auth1_t in 'inp'.
- */
-uint8_t auth1_get_sid(auth1_t *inp, size_t idx);
-/** As auth1_get_sid, but take and return a const pointer
- */
-uint8_t auth1_getconst_sid(const auth1_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field sid
- * of the auth1_t in 'inp', so that it will hold the value 'elt'.
- */
-int auth1_set_sid(auth1_t *inp, size_t idx, uint8_t elt);
-/** Return a pointer to the 32-element array field sid of 'inp'.
- */
-uint8_t * auth1_getarray_sid(auth1_t *inp);
-/** As auth1_get_sid, but take and return a const pointer
- */
-const uint8_t  * auth1_getconstarray_sid(const auth1_t *inp);
-/** Return the (constant) length of the array holding the u1_cid_ed
- * field of the auth1_t in 'inp'.
- */
-size_t auth1_getlen_u1_cid_ed(const auth1_t *inp);
-/** Return the element at position 'idx' of the fixed array field
- * u1_cid_ed of the auth1_t in 'inp'.
- */
-uint8_t auth1_get_u1_cid_ed(auth1_t *inp, size_t idx);
-/** As auth1_get_u1_cid_ed, but take and return a const pointer
- */
-uint8_t auth1_getconst_u1_cid_ed(const auth1_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field
- * u1_cid_ed of the auth1_t in 'inp', so that it will hold the value
- * 'elt'.
- */
-int auth1_set_u1_cid_ed(auth1_t *inp, size_t idx, uint8_t elt);
-/** Return a pointer to the 32-element array field u1_cid_ed of 'inp'.
- */
-uint8_t * auth1_getarray_u1_cid_ed(auth1_t *inp);
-/** As auth1_get_u1_cid_ed, but take and return a const pointer
- */
-const uint8_t  * auth1_getconstarray_u1_cid_ed(const auth1_t *inp);
-/** Return the (constant) length of the array holding the u1_sid_ed
- * field of the auth1_t in 'inp'.
- */
-size_t auth1_getlen_u1_sid_ed(const auth1_t *inp);
-/** Return the element at position 'idx' of the fixed array field
- * u1_sid_ed of the auth1_t in 'inp'.
- */
-uint8_t auth1_get_u1_sid_ed(auth1_t *inp, size_t idx);
-/** As auth1_get_u1_sid_ed, but take and return a const pointer
- */
-uint8_t auth1_getconst_u1_sid_ed(const auth1_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field
- * u1_sid_ed of the auth1_t in 'inp', so that it will hold the value
- * 'elt'.
- */
-int auth1_set_u1_sid_ed(auth1_t *inp, size_t idx, uint8_t elt);
-/** Return a pointer to the 32-element array field u1_sid_ed of 'inp'.
- */
-uint8_t * auth1_getarray_u1_sid_ed(auth1_t *inp);
-/** As auth1_get_u1_sid_ed, but take and return a const pointer
- */
-const uint8_t  * auth1_getconstarray_u1_sid_ed(const auth1_t *inp);
-/** Return the (constant) length of the array holding the slog field
- * of the auth1_t in 'inp'.
- */
-size_t auth1_getlen_slog(const auth1_t *inp);
-/** Return the element at position 'idx' of the fixed array field slog
- * of the auth1_t in 'inp'.
- */
-uint8_t auth1_get_slog(auth1_t *inp, size_t idx);
-/** As auth1_get_slog, but take and return a const pointer
- */
-uint8_t auth1_getconst_slog(const auth1_t *inp, size_t idx);
-/** Change the element at position 'idx' of the fixed array field slog
- * of the auth1_t in 'inp', so that it will hold the value 'elt'.
+uint8_t auth1_getconst_slog(const auth1_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field slog
+ * of the auth1_t in 'inp', so that it will hold the value 'elt'.
  */
 int auth1_set_slog(auth1_t *inp, size_t idx, uint8_t elt);
 /** Return a pointer to the 32-element array field slog of 'inp'.
@@ -679,6 +357,306 @@ const uint8_t  * auth1_getconstarray_sig(const auth1_t *inp);
  * -1 and set the error code on 'inp' on failure.
  */
 int auth1_setlen_sig(auth1_t *inp, size_t newlen);
+/** Return a newly allocated auth_challenge_cell with all elements set
+ * to zero.
+ */
+auth_challenge_cell_t *auth_challenge_cell_new(void);
+/** Release all storage held by the auth_challenge_cell in 'victim'.
+ * (Do nothing if 'victim' is NULL.)
+ */
+void auth_challenge_cell_free(auth_challenge_cell_t *victim);
+/** Try to parse a auth_challenge_cell from the buffer in 'input',
+ * using up to 'len_in' bytes from the input buffer. On success,
+ * return the number of bytes consumed and set *output to the newly
+ * allocated auth_challenge_cell_t. On failure, return -2 if the input
+ * appears truncated, and -1 if the input is otherwise invalid.
+ */
+ssize_t auth_challenge_cell_parse(auth_challenge_cell_t **output, const uint8_t *input, const size_t len_in);
+/** Return the number of bytes we expect to need to encode the
+ * auth_challenge_cell in 'obj'. On failure, return a negative value.
+ * Note that this value may be an overestimate, and can even be an
+ * underestimate for certain unencodeable objects.
+ */
+ssize_t auth_challenge_cell_encoded_len(const auth_challenge_cell_t *obj);
+/** Try to encode the auth_challenge_cell from 'input' into the buffer
+ * at 'output', using up to 'avail' bytes of the output buffer. On
+ * success, return the number of bytes used. On failure, return -2 if
+ * the buffer was not long enough, and -1 if the input was invalid.
+ */
+ssize_t auth_challenge_cell_encode(uint8_t *output, size_t avail, const auth_challenge_cell_t *input);
+/** Check whether the internal state of the auth_challenge_cell in
+ * 'obj' is consistent. Return NULL if it is, and a short message if
+ * it is not.
+ */
+const char *auth_challenge_cell_check(const auth_challenge_cell_t *obj);
+/** Clear any errors that were set on the object 'obj' by its setter
+ * functions. Return true iff errors were cleared.
+ */
+int auth_challenge_cell_clear_errors(auth_challenge_cell_t *obj);
+/** Return the (constant) length of the array holding the challenge
+ * field of the auth_challenge_cell_t in 'inp'.
+ */
+size_t auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t *inp);
+/** Return the element at position 'idx' of the fixed array field
+ * challenge of the auth_challenge_cell_t in 'inp'.
+ */
+uint8_t auth_challenge_cell_get_challenge(auth_challenge_cell_t *inp, size_t idx);
+/** As auth_challenge_cell_get_challenge, but take and return a const
+ * pointer
+ */
+uint8_t auth_challenge_cell_getconst_challenge(const auth_challenge_cell_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field
+ * challenge of the auth_challenge_cell_t in 'inp', so that it will
+ * hold the value 'elt'.
+ */
+int auth_challenge_cell_set_challenge(auth_challenge_cell_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 32-element array field challenge of 'inp'.
+ */
+uint8_t * auth_challenge_cell_getarray_challenge(auth_challenge_cell_t *inp);
+/** As auth_challenge_cell_get_challenge, but take and return a const
+ * pointer
+ */
+const uint8_t  * auth_challenge_cell_getconstarray_challenge(const auth_challenge_cell_t *inp);
+/** Return the value of the n_methods field of the
+ * auth_challenge_cell_t in 'inp'
+ */
+uint16_t auth_challenge_cell_get_n_methods(const auth_challenge_cell_t *inp);
+/** Set the value of the n_methods field of the auth_challenge_cell_t
+ * in 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int auth_challenge_cell_set_n_methods(auth_challenge_cell_t *inp, uint16_t val);
+/** Return the length of the dynamic array holding the methods field
+ * of the auth_challenge_cell_t in 'inp'.
+ */
+size_t auth_challenge_cell_getlen_methods(const auth_challenge_cell_t *inp);
+/** Return the element at position 'idx' of the dynamic array field
+ * methods of the auth_challenge_cell_t in 'inp'.
+ */
+uint16_t auth_challenge_cell_get_methods(auth_challenge_cell_t *inp, size_t idx);
+/** As auth_challenge_cell_get_methods, but take and return a const
+ * pointer
+ */
+uint16_t auth_challenge_cell_getconst_methods(const auth_challenge_cell_t *inp, size_t idx);
+/** Change the element at position 'idx' of the dynamic array field
+ * methods of the auth_challenge_cell_t in 'inp', so that it will hold
+ * the value 'elt'.
+ */
+int auth_challenge_cell_set_methods(auth_challenge_cell_t *inp, size_t idx, uint16_t elt);
+/** Append a new element 'elt' to the dynamic array field methods of
+ * the auth_challenge_cell_t in 'inp'.
+ */
+int auth_challenge_cell_add_methods(auth_challenge_cell_t *inp, uint16_t elt);
+/** Return a pointer to the variable-length array field methods of
+ * 'inp'.
+ */
+uint16_t * auth_challenge_cell_getarray_methods(auth_challenge_cell_t *inp);
+/** As auth_challenge_cell_get_methods, but take and return a const
+ * pointer
+ */
+const uint16_t  * auth_challenge_cell_getconstarray_methods(const auth_challenge_cell_t *inp);
+/** Change the length of the variable-length array field methods of
+ * 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success;
+ * return -1 and set the error code on 'inp' on failure.
+ */
+int auth_challenge_cell_setlen_methods(auth_challenge_cell_t *inp, size_t newlen);
+/** Return a newly allocated certs_cell_cert with all elements set to
+ * zero.
+ */
+certs_cell_cert_t *certs_cell_cert_new(void);
+/** Release all storage held by the certs_cell_cert in 'victim'. (Do
+ * nothing if 'victim' is NULL.)
+ */
+void certs_cell_cert_free(certs_cell_cert_t *victim);
+/** Try to parse a certs_cell_cert from the buffer in 'input', using
+ * up to 'len_in' bytes from the input buffer. On success, return the
+ * number of bytes consumed and set *output to the newly allocated
+ * certs_cell_cert_t. On failure, return -2 if the input appears
+ * truncated, and -1 if the input is otherwise invalid.
+ */
+ssize_t certs_cell_cert_parse(certs_cell_cert_t **output, const uint8_t *input, const size_t len_in);
+/** Return the number of bytes we expect to need to encode the
+ * certs_cell_cert in 'obj'. On failure, return a negative value. Note
+ * that this value may be an overestimate, and can even be an
+ * underestimate for certain unencodeable objects.
+ */
+ssize_t certs_cell_cert_encoded_len(const certs_cell_cert_t *obj);
+/** Try to encode the certs_cell_cert from 'input' into the buffer at
+ * 'output', using up to 'avail' bytes of the output buffer. On
+ * success, return the number of bytes used. On failure, return -2 if
+ * the buffer was not long enough, and -1 if the input was invalid.
+ */
+ssize_t certs_cell_cert_encode(uint8_t *output, size_t avail, const certs_cell_cert_t *input);
+/** Check whether the internal state of the certs_cell_cert in 'obj'
+ * is consistent. Return NULL if it is, and a short message if it is
+ * not.
+ */
+const char *certs_cell_cert_check(const certs_cell_cert_t *obj);
+/** Clear any errors that were set on the object 'obj' by its setter
+ * functions. Return true iff errors were cleared.
+ */
+int certs_cell_cert_clear_errors(certs_cell_cert_t *obj);
+/** Return the value of the cert_type field of the certs_cell_cert_t
+ * in 'inp'
+ */
+uint8_t certs_cell_cert_get_cert_type(const certs_cell_cert_t *inp);
+/** Set the value of the cert_type field of the certs_cell_cert_t in
+ * 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int certs_cell_cert_set_cert_type(certs_cell_cert_t *inp, uint8_t val);
+/** Return the value of the cert_len field of the certs_cell_cert_t in
+ * 'inp'
+ */
+uint16_t certs_cell_cert_get_cert_len(const certs_cell_cert_t *inp);
+/** Set the value of the cert_len field of the certs_cell_cert_t in
+ * 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int certs_cell_cert_set_cert_len(certs_cell_cert_t *inp, uint16_t val);
+/** Return the length of the dynamic array holding the body field of
+ * the certs_cell_cert_t in 'inp'.
+ */
+size_t certs_cell_cert_getlen_body(const certs_cell_cert_t *inp);
+/** Return the element at position 'idx' of the dynamic array field
+ * body of the certs_cell_cert_t in 'inp'.
+ */
+uint8_t certs_cell_cert_get_body(certs_cell_cert_t *inp, size_t idx);
+/** As certs_cell_cert_get_body, but take and return a const pointer
+ */
+uint8_t certs_cell_cert_getconst_body(const certs_cell_cert_t *inp, size_t idx);
+/** Change the element at position 'idx' of the dynamic array field
+ * body of the certs_cell_cert_t in 'inp', so that it will hold the
+ * value 'elt'.
+ */
+int certs_cell_cert_set_body(certs_cell_cert_t *inp, size_t idx, uint8_t elt);
+/** Append a new element 'elt' to the dynamic array field body of the
+ * certs_cell_cert_t in 'inp'.
+ */
+int certs_cell_cert_add_body(certs_cell_cert_t *inp, uint8_t elt);
+/** Return a pointer to the variable-length array field body of 'inp'.
+ */
+uint8_t * certs_cell_cert_getarray_body(certs_cell_cert_t *inp);
+/** As certs_cell_cert_get_body, but take and return a const pointer
+ */
+const uint8_t  * certs_cell_cert_getconstarray_body(const certs_cell_cert_t *inp);
+/** Change the length of the variable-length array field body of 'inp'
+ * to 'newlen'.Fill extra elements with 0. Return 0 on success; return
+ * -1 and set the error code on 'inp' on failure.
+ */
+int certs_cell_cert_setlen_body(certs_cell_cert_t *inp, size_t newlen);
+/** Return a newly allocated rsa_ed_crosscert with all elements set to
+ * zero.
+ */
+rsa_ed_crosscert_t *rsa_ed_crosscert_new(void);
+/** Release all storage held by the rsa_ed_crosscert in 'victim'. (Do
+ * nothing if 'victim' is NULL.)
+ */
+void rsa_ed_crosscert_free(rsa_ed_crosscert_t *victim);
+/** Try to parse a rsa_ed_crosscert from the buffer in 'input', using
+ * up to 'len_in' bytes from the input buffer. On success, return the
+ * number of bytes consumed and set *output to the newly allocated
+ * rsa_ed_crosscert_t. On failure, return -2 if the input appears
+ * truncated, and -1 if the input is otherwise invalid.
+ */
+ssize_t rsa_ed_crosscert_parse(rsa_ed_crosscert_t **output, const uint8_t *input, const size_t len_in);
+/** Return the number of bytes we expect to need to encode the
+ * rsa_ed_crosscert in 'obj'. On failure, return a negative value.
+ * Note that this value may be an overestimate, and can even be an
+ * underestimate for certain unencodeable objects.
+ */
+ssize_t rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t *obj);
+/** Try to encode the rsa_ed_crosscert from 'input' into the buffer at
+ * 'output', using up to 'avail' bytes of the output buffer. On
+ * success, return the number of bytes used. On failure, return -2 if
+ * the buffer was not long enough, and -1 if the input was invalid.
+ */
+ssize_t rsa_ed_crosscert_encode(uint8_t *output, size_t avail, const rsa_ed_crosscert_t *input);
+/** Check whether the internal state of the rsa_ed_crosscert in 'obj'
+ * is consistent. Return NULL if it is, and a short message if it is
+ * not.
+ */
+const char *rsa_ed_crosscert_check(const rsa_ed_crosscert_t *obj);
+/** Clear any errors that were set on the object 'obj' by its setter
+ * functions. Return true iff errors were cleared.
+ */
+int rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t *obj);
+/** Return the (constant) length of the array holding the ed_key field
+ * of the rsa_ed_crosscert_t in 'inp'.
+ */
+size_t rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t *inp);
+/** Return the element at position 'idx' of the fixed array field
+ * ed_key of the rsa_ed_crosscert_t in 'inp'.
+ */
+uint8_t rsa_ed_crosscert_get_ed_key(rsa_ed_crosscert_t *inp, size_t idx);
+/** As rsa_ed_crosscert_get_ed_key, but take and return a const
+ * pointer
+ */
+uint8_t rsa_ed_crosscert_getconst_ed_key(const rsa_ed_crosscert_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field
+ * ed_key of the rsa_ed_crosscert_t in 'inp', so that it will hold the
+ * value 'elt'.
+ */
+int rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 32-element array field ed_key of 'inp'.
+ */
+uint8_t * rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t *inp);
+/** As rsa_ed_crosscert_get_ed_key, but take and return a const
+ * pointer
+ */
+const uint8_t  * rsa_ed_crosscert_getconstarray_ed_key(const rsa_ed_crosscert_t *inp);
+/** Return the value of the expiration field of the rsa_ed_crosscert_t
+ * in 'inp'
+ */
+uint32_t rsa_ed_crosscert_get_expiration(const rsa_ed_crosscert_t *inp);
+/** Set the value of the expiration field of the rsa_ed_crosscert_t in
+ * 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t *inp, uint32_t val);
+/** Return the position for end_of_signed when we parsed this object
+ */
+const uint8_t * rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t *inp);
+/** Return the value of the sig_len field of the rsa_ed_crosscert_t in
+ * 'inp'
+ */
+uint8_t rsa_ed_crosscert_get_sig_len(const rsa_ed_crosscert_t *inp);
+/** Set the value of the sig_len field of the rsa_ed_crosscert_t in
+ * 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t *inp, uint8_t val);
+/** Return the length of the dynamic array holding the sig field of
+ * the rsa_ed_crosscert_t in 'inp'.
+ */
+size_t rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t *inp);
+/** Return the element at position 'idx' of the dynamic array field
+ * sig of the rsa_ed_crosscert_t in 'inp'.
+ */
+uint8_t rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t *inp, size_t idx);
+/** As rsa_ed_crosscert_get_sig, but take and return a const pointer
+ */
+uint8_t rsa_ed_crosscert_getconst_sig(const rsa_ed_crosscert_t *inp, size_t idx);
+/** Change the element at position 'idx' of the dynamic array field
+ * sig of the rsa_ed_crosscert_t in 'inp', so that it will hold the
+ * value 'elt'.
+ */
+int rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt);
+/** Append a new element 'elt' to the dynamic array field sig of the
+ * rsa_ed_crosscert_t in 'inp'.
+ */
+int rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t *inp, uint8_t elt);
+/** Return a pointer to the variable-length array field sig of 'inp'.
+ */
+uint8_t * rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t *inp);
+/** As rsa_ed_crosscert_get_sig, but take and return a const pointer
+ */
+const uint8_t  * rsa_ed_crosscert_getconstarray_sig(const rsa_ed_crosscert_t *inp);
+/** Change the length of the variable-length array field sig of 'inp'
+ * to 'newlen'.Fill extra elements with 0. Return 0 on success; return
+ * -1 and set the error code on 'inp' on failure.
+ */
+int rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t *inp, size_t newlen);
 /** Return a newly allocated certs_cell with all elements set to zero.
  */
 certs_cell_t *certs_cell_new(void);
index b858e17c60754f34662c6402bf3395cb085d051f..2ecb221a9fc75a5ed35adc6b3d18cbf976537d59 100644 (file)
@@ -32,20 +32,12 @@ struct auth_challenge_cell {
   u16 methods[n_methods];
 }
 
-context auth_ctx {
-  u8 is_ed;
-}
-
-struct auth1 with context auth_ctx {
+struct auth1 {
   u8 type[8];
   u8 cid[32];
   u8 sid[32];
-  union u1[auth_ctx.is_ed] {
-    0 : ;
-    1 : u8 cid_ed[32];
-        u8 sid_ed[32];
-    default: fail;
-  };
+  u8 cid_ed[32];
+  u8 sid_ed[32];
   u8 slog[32];
   u8 clog[32];
   u8 scert[32];