tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit 742dbae978d53ffc8ec039dedd0748cbf676d39c
parent dab02adbe475a130b0af45e7f10e49ac3f68724a
Author: Nick Mathewson <nickm@torproject.org>
Date:   Wed, 19 Mar 2025 16:36:49 +0000

Merge branch 'too_many_tlssecrets' into 'main'

Remove RSA-SHA256-TLSSecrets link authentication

Closes #41020 and #41021

See merge request tpo/core/tor!862
Diffstat:
Achanges/bug41021 | 4++++
Achanges/too_many_tlssecrets | 6++++++
Mconfigure.ac | 3---
Msrc/core/or/channeltls.c | 58++++++++--------------------------------------------------
Msrc/core/or/connection_or.c | 2+-
Msrc/core/or/connection_or.h | 4----
Msrc/core/or/protover.c | 4----
Msrc/feature/relay/relay_handshake.c | 96++++++++++++++++++-------------------------------------------------------------
Msrc/feature/relay/relay_handshake.h | 2--
Msrc/lib/tls/tortls.c | 18+++---------------
Msrc/lib/tls/tortls.h | 9++-------
Msrc/lib/tls/tortls_internal.h | 6------
Msrc/lib/tls/tortls_nss.c | 11-----------
Msrc/lib/tls/tortls_openssl.c | 131-------------------------------------------------------------------------------
Msrc/test/test_link_handshake.c | 111+++++++++++++++++--------------------------------------------------------------
Msrc/test/test_tortls.c | 131+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/test/test_tortls.h | 1+
Msrc/test/test_tortls_openssl.c | 46++++++++++------------------------------------
Msrc/trunnel/link_handshake.c | 1864+++++++++++++++++++++++++++++++++++++------------------------------------------
Msrc/trunnel/link_handshake.h | 884+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/trunnel/link_handshake.trunnel | 14+++-----------
21 files changed, 1472 insertions(+), 1933 deletions(-)

diff --git a/changes/bug41021 b/changes/bug41021 @@ -0,0 +1,4 @@ + o Minor bugfixes (tests): + - Fix a test failure with OpenSSL builds running at security level 1 or + greater, which does not permit SHA-1 certificates. + (Fixes bug 41021; bugfix on 0.2.8.1-alpha.) diff --git a/changes/too_many_tlssecrets b/changes/too_many_tlssecrets @@ -0,0 +1,6 @@ + o Removed features: + - Relays no longer support the obsolete "RSA-SHA256-TLSSecret" + authentication method, which used a dangerously short RSA key, + and which required access TLS session internals. The current method + ("Ed25519-SHA256-RFC5705") has been supported since 0.3.0.1-alpha. + Closes ticket 41020. diff --git a/configure.ac b/configure.ac @@ -1122,10 +1122,7 @@ AC_CHECK_FUNCS([ \ SSL_CIPHER_find \ SSL_CTX_set1_groups_list \ SSL_CTX_set_security_level \ - SSL_SESSION_get_master_key \ SSL_get_client_ciphers \ - SSL_get_client_random \ - SSL_get_server_random \ TLS_method \ ]) diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c @@ -2465,22 +2465,20 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan) ERR("Authenticator was too short"); expected_cell = connection_or_compute_authenticate_cell_body( - chan->conn, authtype, NULL, NULL, 1); + chan->conn, authtype, NULL, 1); if (! expected_cell) ERR("Couldn't compute expected AUTHENTICATE cell body"); - int sig_is_rsa; - if (authtype == AUTHTYPE_RSA_SHA256_TLSSECRET || - authtype == AUTHTYPE_RSA_SHA256_RFC5705) { - bodylen = V3_AUTH_BODY_LEN; - sig_is_rsa = 1; + if (BUG(authtype != AUTHTYPE_ED25519_SHA256_RFC5705)) { + /* We should have detected that we don't support this + * authentication type earlier, when we called + * authchallenge_type_is_supported(). */ + ERR("Unsupported authentication type"); } else { - tor_assert(authtype == AUTHTYPE_ED25519_SHA256_RFC5705); /* Our earlier check had better have made sure we had room * for an ed25519 sig (inadvertently) */ tor_assert(V3_AUTH_BODY_LEN > ED25519_SIG_LEN); bodylen = authlen - ED25519_SIG_LEN; - sig_is_rsa = 0; } if (expected_cell->payload_len != bodylen+4) { ERR("Expected AUTHENTICATE cell body len not as expected."); @@ -2496,47 +2494,7 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan) if (tor_memneq(expected_cell->payload+4, auth, bodylen-24)) ERR("Some field in the AUTHENTICATE cell body was not as expected"); - if (sig_is_rsa) { - if (chan->conn->handshake_state->certs->ed_id_sign != NULL) - ERR("RSA-signed AUTHENTICATE response provided with an ED25519 cert"); - - if (chan->conn->handshake_state->certs->auth_cert == NULL) - ERR("We never got an RSA authentication certificate"); - - crypto_pk_t *pk = tor_tls_cert_get_key( - chan->conn->handshake_state->certs->auth_cert); - char d[DIGEST256_LEN]; - char *signed_data; - size_t keysize; - int signed_len; - - if (! pk) { - ERR("Couldn't get RSA key from AUTH cert."); - } - crypto_digest256(d, (char*)auth, V3_AUTH_BODY_LEN, DIGEST_SHA256); - - keysize = crypto_pk_keysize(pk); - signed_data = tor_malloc(keysize); - signed_len = crypto_pk_public_checksig(pk, signed_data, keysize, - (char*)auth + V3_AUTH_BODY_LEN, - authlen - V3_AUTH_BODY_LEN); - crypto_pk_free(pk); - if (signed_len < 0) { - tor_free(signed_data); - ERR("RSA signature wasn't valid"); - } - if (signed_len < DIGEST256_LEN) { - tor_free(signed_data); - ERR("Not enough data was signed"); - } - /* Note that we deliberately allow *more* than DIGEST256_LEN bytes here, - * in case they're later used to hold a SHA3 digest or something. */ - if (tor_memneq(signed_data, d, DIGEST256_LEN)) { - tor_free(signed_data); - ERR("Signature did not match data to be signed."); - } - tor_free(signed_data); - } else { + { if (chan->conn->handshake_state->certs->ed_id_sign == NULL) ERR("We never got an Ed25519 identity certificate."); if (chan->conn->handshake_state->certs->ed_sign_auth == NULL) @@ -2563,7 +2521,7 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan) const common_digests_t *id_digests = tor_x509_cert_get_id_digests(id_cert); const ed25519_public_key_t *ed_identity_received = NULL; - if (! sig_is_rsa) { + { chan->conn->handshake_state->authenticated_ed25519 = 1; ed_identity_received = &chan->conn->handshake_state->certs->ed_id_sign->signing_key; diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c @@ -1843,7 +1843,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn, if (has_cert) { int v = tor_tls_verify(started_here?severity:LOG_INFO, - conn->tls, &identity_rcvd); + conn->tls, time(NULL), &identity_rcvd); if (started_here && v<0) { log_fn(severity,LD_HANDSHAKE,"Tried connecting to router at %s: It" " has a cert but it's invalid. Closing.", diff --git a/src/core/or/connection_or.h b/src/core/or/connection_or.h @@ -129,8 +129,4 @@ STATIC void note_or_connect_failed(const or_connection_t *or_conn); MOCK_DECL(void, connection_or_change_state, (or_connection_t *conn, uint8_t state)); -#ifdef TOR_UNIT_TESTS -extern int testing__connection_or_pretend_TLSSECRET_is_supported; -#endif - #endif /* !defined(TOR_CONNECTION_OR_H) */ diff --git a/src/core/or/protover.c b/src/core/or/protover.c @@ -396,11 +396,7 @@ protocol_list_supports_protocol_or_later(const char *list, #define PR_HSINTRO_V "4-5" #define PR_HSREND_V "1-2" #define PR_LINK_V "1-5" -#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS -#define PR_LINKAUTH_V "1,3" -#else #define PR_LINKAUTH_V "3" -#endif #define PR_MICRODESC_V "1-3" #define PR_PADDING_V "2" #define PR_RELAY_V "2-4" diff --git a/src/feature/relay/relay_handshake.c b/src/feature/relay/relay_handshake.c @@ -183,27 +183,17 @@ connection_or_send_certs_cell(or_connection_t *conn) return 0; } -#ifdef TOR_UNIT_TESTS -int testing__connection_or_pretend_TLSSECRET_is_supported = 0; -#else -#define testing__connection_or_pretend_TLSSECRET_is_supported 0 -#endif - /** Return true iff <b>challenge_type</b> is an AUTHCHALLENGE type that * we can send and receive. */ int authchallenge_type_is_supported(uint16_t challenge_type) { switch (challenge_type) { - case AUTHTYPE_RSA_SHA256_TLSSECRET: -#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS - return 1; -#else - return testing__connection_or_pretend_TLSSECRET_is_supported; -#endif case AUTHTYPE_ED25519_SHA256_RFC5705: return 1; - case AUTHTYPE_RSA_SHA256_RFC5705: + + case AUTHTYPE_RSA_SHA256_TLSSECRET: // obsolete. + case AUTHTYPE_RSA_SHA256_RFC5705: // never implemented. default: return 0; } @@ -243,11 +233,6 @@ connection_or_send_auth_challenge_cell(or_connection_t *conn) tor_assert(sizeof(ac->challenge) == 32); crypto_rand((char*)ac->challenge, sizeof(ac->challenge)); - if (authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET)) - auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET); - /* Disabled, because everything that supports this method also supports - * the much-superior ED25519_SHA256_RFC5705 */ - /* auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_RFC5705); */ if (authchallenge_type_is_supported(AUTHTYPE_ED25519_SHA256_RFC5705)) auth_challenge_cell_add_methods(ac, AUTHTYPE_ED25519_SHA256_RFC5705); auth_challenge_cell_set_n_methods(ac, @@ -283,42 +268,36 @@ connection_or_send_auth_challenge_cell(or_connection_t *conn) * determined by the rest of the handshake, and which match the provided value * exactly. * - * If <b>server</b> is false and <b>signing_key</b> is NULL, calculate the + * If <b>server</b> is false and <b>ed_signing_key</b> is NULL, calculate the * first V3_AUTH_BODY_LEN bytes of the authenticator (that is, everything * that should be signed), but don't actually sign it. * - * If <b>server</b> is false and <b>signing_key</b> is provided, calculate the - * entire authenticator, signed with <b>signing_key</b>. + * If <b>server</b> is false and <b>ed_signing_key</b> is provided, + * calculate the + * entire authenticator, signed with <b>ed_signing_key</b>. * * Return the length of the cell body on success, and -1 on failure. */ var_cell_t * connection_or_compute_authenticate_cell_body(or_connection_t *conn, const int authtype, - crypto_pk_t *signing_key, const ed25519_keypair_t *ed_signing_key, int server) { auth1_t *auth = NULL; - auth_ctx_t *ctx = auth_ctx_new(); var_cell_t *result = NULL; - int old_tlssecrets_algorithm = 0; const char *authtype_str = NULL; - int is_ed = 0; - /* assert state is reasonable XXXX */ switch (authtype) { case AUTHTYPE_RSA_SHA256_TLSSECRET: - authtype_str = "AUTH0001"; - old_tlssecrets_algorithm = 1; - break; case AUTHTYPE_RSA_SHA256_RFC5705: - authtype_str = "AUTH0002"; + /* These are unsupported; we should never reach this point. */ + tor_assert_nonfatal_unreached_once(); + return NULL; break; case AUTHTYPE_ED25519_SHA256_RFC5705: authtype_str = "AUTH0003"; - is_ed = 1; break; default: tor_assert(0); @@ -326,7 +305,6 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, } auth = auth1_new(); - ctx->is_ed = is_ed; /* Type: 8 bytes. */ memcpy(auth1_getarray_type(auth), authtype_str, 8); @@ -355,7 +333,7 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, memcpy(auth->sid, server_id, 32); } - if (is_ed) { + { const ed25519_public_key_t *my_ed_id, *their_ed_id; if (!conn->handshake_state->certs->ed_id_sign) { log_warn(LD_OR, "Ed authenticate without Ed ID cert from peer."); @@ -367,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); } { @@ -408,15 +386,8 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, tor_x509_cert_free(cert); } - /* HMAC of clientrandom and serverrandom using master key : 32 octets */ - if (old_tlssecrets_algorithm) { - if (tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets) < 0) { - log_fn(LOG_PROTOCOL_WARN, LD_OR, "Somebody asked us for an older TLS " - "authentication method (AUTHTYPE_RSA_SHA256_TLSSECRET) " - "which we don't support."); - goto err; - } - } else { + /* RFC5709 key exporter material : 32 octets */ + { char label[128]; tor_snprintf(label, sizeof(label), "EXPORTER FOR TOR TLS CLIENT BINDING %s", authtype_str); @@ -436,11 +407,9 @@ 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); - if (ed_signing_key && is_ed) { + ssize_t maxlen = auth1_encoded_len(auth); + if (ed_signing_key) { maxlen += ED25519_SIG_LEN; - } else if (signing_key && !is_ed) { - maxlen += crypto_pk_keysize(signing_key); } const int AUTH_CELL_HEADER_LEN = 4; /* 2 bytes of type, 2 bytes of length */ @@ -452,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; @@ -461,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 " @@ -481,7 +450,7 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, goto done; } - if (ed_signing_key && is_ed) { + if (ed_signing_key) { ed25519_signature_t sig; if (ed25519_sign(&sig, out, len, ed_signing_key) < 0) { /* LCOV_EXCL_START */ @@ -491,25 +460,9 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, } auth1_setlen_sig(auth, ED25519_SIG_LEN); memcpy(auth1_getarray_sig(auth), sig.sig, ED25519_SIG_LEN); - - } else if (signing_key && !is_ed) { - auth1_setlen_sig(auth, crypto_pk_keysize(signing_key)); - - char d[32]; - crypto_digest256(d, (char*)out, len, DIGEST_SHA256); - int siglen = crypto_pk_private_sign(signing_key, - (char*)auth1_getarray_sig(auth), - auth1_getlen_sig(auth), - d, 32); - if (siglen < 0) { - log_warn(LD_OR, "Unable to sign AUTH1 data."); - goto err; - } - - auth1_setlen_sig(auth, siglen); } - 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."); @@ -527,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; } @@ -537,13 +489,8 @@ MOCK_IMPL(int, connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype)) { var_cell_t *cell; - crypto_pk_t *pk = tor_tls_get_my_client_auth_key(); /* XXXX make sure we're actually supposed to send this! */ - if (!pk) { - log_warn(LD_BUG, "Can't compute authenticate cell: no client auth key"); - return -1; - } if (! authchallenge_type_is_supported(authtype)) { log_warn(LD_BUG, "Tried to send authenticate cell with unknown " "authentication type %d", authtype); @@ -552,7 +499,6 @@ connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype)) cell = connection_or_compute_authenticate_cell_body(conn, authtype, - pk, get_current_auth_keypair(), 0 /* not server */); if (! cell) { diff --git a/src/feature/relay/relay_handshake.h b/src/feature/relay/relay_handshake.h @@ -21,7 +21,6 @@ int connection_or_send_auth_challenge_cell(or_connection_t *conn); var_cell_t *connection_or_compute_authenticate_cell_body( or_connection_t *conn, const int authtype, - crypto_pk_t *signing_key, const struct ed25519_keypair_t *ed_signing_key, int server); @@ -56,7 +55,6 @@ static inline var_cell_t * connection_or_compute_authenticate_cell_body( or_connection_t *conn, const int authtype, - crypto_pk_t *signing_key, const struct ed25519_keypair_t *ed_signing_key, int server) { diff --git a/src/lib/tls/tortls.c b/src/lib/tls/tortls.c @@ -93,19 +93,6 @@ tor_tls_get_my_certs(int server, return rv; } -/** - * Return the authentication key that we use to authenticate ourselves as a - * client in the V3 in-protocol handshake. - */ -crypto_pk_t * -tor_tls_get_my_client_auth_key(void) -{ - tor_tls_context_t *context = tor_tls_context_get(0); - if (! context) - return NULL; - return context->auth_key; -} - /** Increase the reference count of <b>ctx</b>. */ void tor_tls_context_incref(tor_tls_context_t *ctx) @@ -413,7 +400,8 @@ tor_tls_free_(tor_tls_t *tls) * 0. Else, return -1 and log complaints with log-level <b>severity</b>. */ int -tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity) +tor_tls_verify(int severity, tor_tls_t *tls, time_t now, + crypto_pk_t **identity) { tor_x509_cert_impl_t *cert = NULL, *id_cert = NULL; tor_x509_cert_t *peer_x509 = NULL, *id_x509 = NULL; @@ -432,7 +420,7 @@ tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity) id_x509 = tor_x509_cert_new(id_cert); cert = id_cert = NULL; /* Prevent double-free */ - if (! tor_tls_cert_is_valid(severity, peer_x509, id_x509, time(NULL), 0)) { + if (! tor_tls_cert_is_valid(severity, peer_x509, id_x509, now, 0)) { goto done; } diff --git a/src/lib/tls/tortls.h b/src/lib/tls/tortls.h @@ -101,7 +101,8 @@ void tor_tls_free_(tor_tls_t *tls); int tor_tls_peer_has_cert(tor_tls_t *tls); MOCK_DECL(struct tor_x509_cert_t *,tor_tls_get_peer_cert,(tor_tls_t *tls)); MOCK_DECL(struct tor_x509_cert_t *,tor_tls_get_own_cert,(tor_tls_t *tls)); -int tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity); +int tor_tls_verify(int severity, tor_tls_t *tls, time_t now, + crypto_pk_t **identity); MOCK_DECL(int, tor_tls_read, (tor_tls_t *tls, char *cp, size_t len)); int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n); int tor_tls_handshake(tor_tls_t *tls); @@ -125,11 +126,6 @@ int tor_tls_get_num_server_handshakes(tor_tls_t *tls); int tor_tls_server_got_renegotiate(tor_tls_t *tls); MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls, const struct tor_x509_cert_t *cert)); -MOCK_DECL(int,tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out)); -#ifdef ENABLE_OPENSSL -/* OpenSSL lets us see these master secrets; NSS sensibly does not. */ -#define HAVE_WORKING_TOR_TLS_GET_TLSSECRETS -#endif MOCK_DECL(int,tor_tls_export_key_material,( tor_tls_t *tls, uint8_t *secrets_out, const uint8_t *context, @@ -151,7 +147,6 @@ void tor_tls_log_one_error(tor_tls_t *tls, unsigned long err, int tor_tls_get_my_certs(int server, const struct tor_x509_cert_t **link_cert_out, const struct tor_x509_cert_t **id_cert_out); -crypto_pk_t *tor_tls_get_my_client_auth_key(void); const char *tor_tls_get_ciphersuite_name(tor_tls_t *tls); diff --git a/src/lib/tls/tortls_internal.h b/src/lib/tls/tortls_internal.h @@ -51,12 +51,6 @@ void tor_tls_server_info_callback(const struct ssl_st *ssl, int type, int val); void tor_tls_allocate_tor_tls_object_ex_data_index(void); -#if !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) -size_t SSL_SESSION_get_master_key(struct ssl_session_st *s, - uint8_t *out, - size_t len); -#endif - #ifdef TORTLS_OPENSSL_PRIVATE int always_accept_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx); int tor_tls_classify_client_ciphers(const struct ssl_st *ssl, diff --git a/src/lib/tls/tortls_nss.c b/src/lib/tls/tortls_nss.c @@ -789,17 +789,6 @@ tor_tls_cert_matches_key,(const tor_tls_t *tls, } MOCK_IMPL(int, -tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out)) -{ - tor_assert(tls); - tor_assert(secrets_out); - - /* There's no way to get this information out of NSS. */ - - return -1; -} - -MOCK_IMPL(int, tor_tls_export_key_material,(tor_tls_t *tls, uint8_t *secrets_out, const uint8_t *context, size_t context_len, diff --git a/src/lib/tls/tortls_openssl.c b/src/lib/tls/tortls_openssl.c @@ -1589,137 +1589,6 @@ tor_tls_server_got_renegotiate(tor_tls_t *tls) return tls->got_renegotiate; } -#ifndef HAVE_SSL_GET_CLIENT_RANDOM -static size_t -SSL_get_client_random(SSL *s, uint8_t *out, size_t len) -{ - if (len == 0) - return SSL3_RANDOM_SIZE; - tor_assert(len == SSL3_RANDOM_SIZE); - tor_assert(s->s3); - memcpy(out, s->s3->client_random, len); - return len; -} -#endif /* !defined(HAVE_SSL_GET_CLIENT_RANDOM) */ - -#ifndef HAVE_SSL_GET_SERVER_RANDOM -static size_t -SSL_get_server_random(SSL *s, uint8_t *out, size_t len) -{ - if (len == 0) - return SSL3_RANDOM_SIZE; - tor_assert(len == SSL3_RANDOM_SIZE); - tor_assert(s->s3); - memcpy(out, s->s3->server_random, len); - return len; -} -#endif /* !defined(HAVE_SSL_GET_SERVER_RANDOM) */ - -#ifndef HAVE_SSL_SESSION_GET_MASTER_KEY -size_t -SSL_SESSION_get_master_key(SSL_SESSION *s, uint8_t *out, size_t len) -{ - tor_assert(s); - if (len == 0) - return s->master_key_length; - tor_assert(len == (size_t)s->master_key_length); - tor_assert(out); - memcpy(out, s->master_key, len); - return len; -} -#endif /* !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) */ - -/** Set the DIGEST256_LEN buffer at <b>secrets_out</b> to the value used in - * the v3 handshake to prove that the client knows the TLS secrets for the - * connection <b>tls</b>. Return 0 on success, -1 on failure. - */ -MOCK_IMPL(int, -tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out)) -{ -#define TLSSECRET_MAGIC "Tor V3 handshake TLS cross-certification" - uint8_t buf[128]; - size_t len; - tor_assert(tls); - - SSL *const ssl = tls->ssl; - SSL_SESSION *const session = SSL_get_session(ssl); - - tor_assert(ssl); - tor_assert(session); - - const size_t server_random_len = SSL_get_server_random(ssl, NULL, 0); - const size_t client_random_len = SSL_get_client_random(ssl, NULL, 0); - const size_t master_key_len = SSL_SESSION_get_master_key(session, NULL, 0); - - if (BUG(! server_random_len)) { - log_warn(LD_NET, "Missing server randomness after handshake " - "using %s (cipher: %s, server: %s) from %s", - SSL_get_version(ssl), - SSL_get_cipher_name(ssl), - tls->isServer ? "true" : "false", - ADDR(tls)); - return -1; - } - - if (BUG(! client_random_len)) { - log_warn(LD_NET, "Missing client randomness after handshake " - "using %s (cipher: %s, server: %s) from %s", - SSL_get_version(ssl), - SSL_get_cipher_name(ssl), - tls->isServer ? "true" : "false", - ADDR(tls)); - return -1; - } - - if (BUG(! master_key_len)) { - log_warn(LD_NET, "Missing master key after handshake " - "using %s (cipher: %s, server: %s) from %s", - SSL_get_version(ssl), - SSL_get_cipher_name(ssl), - tls->isServer ? "true" : "false", - ADDR(tls)); - return -1; - } - - len = client_random_len + server_random_len + strlen(TLSSECRET_MAGIC) + 1; - tor_assert(len <= sizeof(buf)); - - { - size_t r = SSL_get_client_random(ssl, buf, client_random_len); - tor_assert(r == client_random_len); - } - - { - size_t r = SSL_get_server_random(ssl, - buf+client_random_len, - server_random_len); - tor_assert(r == server_random_len); - } - - uint8_t *master_key = tor_malloc_zero(master_key_len); - { - size_t r = SSL_SESSION_get_master_key(session, master_key, master_key_len); - tor_assert(r == master_key_len); - } - - uint8_t *nextbuf = buf + client_random_len + server_random_len; - memcpy(nextbuf, TLSSECRET_MAGIC, strlen(TLSSECRET_MAGIC) + 1); - - /* - The value is an HMAC, using the TLS master key as the HMAC key, of - client_random | server_random | TLSSECRET_MAGIC - */ - crypto_hmac_sha256((char*)secrets_out, - (char*)master_key, - master_key_len, - (char*)buf, len); - memwipe(buf, 0, sizeof(buf)); - memwipe(master_key, 0, master_key_len); - tor_free(master_key); - - return 0; -} - /** Using the RFC5705 key material exporting construction, and the * provided <b>context</b> (<b>context_len</b> bytes long) and * <b>label</b> (a NUL-terminated string), compute a 32-byte secret in diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c @@ -943,25 +943,15 @@ test_link_handshake_send_authchallenge(void *arg) cell1 = mock_got_var_cell; tt_int_op(0, OP_EQ, connection_or_send_auth_challenge_cell(c1)); cell2 = mock_got_var_cell; -#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS - tt_int_op(38, OP_EQ, cell1->payload_len); - tt_int_op(38, OP_EQ, cell2->payload_len); -#else tt_int_op(36, OP_EQ, cell1->payload_len); tt_int_op(36, OP_EQ, cell2->payload_len); -#endif /* defined(HAVE_WORKING_TOR_TLS_GET_TLSSECRETS) */ tt_int_op(0, OP_EQ, cell1->circ_id); tt_int_op(0, OP_EQ, cell2->circ_id); tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell1->command); tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell2->command); -#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS - tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 6); - tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 6); -#else tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 4); tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 4); -#endif /* defined(HAVE_WORKING_TOR_TLS_GET_TLSSECRETS) */ tt_mem_op(cell1->payload, OP_NE, cell2->payload, 32); done: @@ -1004,7 +994,6 @@ recv_authchallenge_setup(const struct testcase_t *test) { (void)test; - testing__connection_or_pretend_TLSSECRET_is_supported = 1; authchallenge_data_t *d = tor_malloc_zero(sizeof(*d)); d->c = or_connection_new(CONN_TYPE_OR, AF_INET); d->chan = tor_malloc_zero(sizeof(*d->chan)); @@ -1019,7 +1008,7 @@ recv_authchallenge_setup(const struct testcase_t *test) d->cell->payload_len = 38; d->cell->payload[33] = 2; /* 2 methods */ d->cell->payload[35] = 7; /* This one isn't real */ - d->cell->payload[37] = 1; /* This is the old RSA one. */ + d->cell->payload[37] = 3; /* This is the currently supported Ed25519 one. */ d->cell->command = CELL_AUTH_CHALLENGE; get_options_mutable()->ORPort_set = 1; @@ -1043,18 +1032,19 @@ static struct testcase_setup_t setup_recv_authchallenge = { }; static void -test_link_handshake_recv_authchallenge_ok(void *arg) +test_link_handshake_recv_authchallenge_no_ed25519(void *arg) { authchallenge_data_t *d = arg; + d->cell->payload[33] = 1; /* only 1 type supported. */ + d->cell->payload_len -= 2; + + setup_capture_of_logs(LOG_INFO); channel_tls_process_auth_challenge_cell(d->cell, d->chan); - tt_int_op(0, OP_EQ, mock_close_called); - tt_int_op(1, OP_EQ, d->c->handshake_state->received_auth_challenge); - tt_int_op(1, OP_EQ, mock_send_authenticate_called); - tt_int_op(1, OP_EQ, mock_send_netinfo_called); - tt_int_op(1, OP_EQ, mock_send_authenticate_called_with_type); /* RSA */ + expect_log_msg_containing("we don't know any of its authentication types"); + done: - ; + teardown_capture_of_logs(); } static void @@ -1154,14 +1144,6 @@ AUTHCHALLENGE_FAIL(nonzero_circid, require_failure_message = "It had a nonzero circuit ID"; d->cell->circ_id = 1337) -static int -mock_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out) -{ - (void)tls; - memcpy(secrets_out, "int getRandomNumber(){return 4;}", 32); - return 0; -} - static void mock_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd, @@ -1173,7 +1155,6 @@ mock_set_circid_type(channel_t *chan, } typedef struct authenticate_data_t { - int is_ed; or_connection_t *c1, *c2; channel_tls_t *chan2; var_cell_t *cell; @@ -1187,7 +1168,6 @@ authenticate_data_cleanup(const struct testcase_t *test, void *arg) UNMOCK(connection_or_write_var_cell_to_buf); UNMOCK(tor_tls_get_peer_cert); UNMOCK(tor_tls_get_own_cert); - UNMOCK(tor_tls_get_tlssecrets); UNMOCK(connection_or_close_for_error); UNMOCK(channel_set_circid_type); UNMOCK(tor_tls_export_key_material); @@ -1216,16 +1196,12 @@ static void * authenticate_data_setup(const struct testcase_t *test) { authenticate_data_t *d = tor_malloc_zero(sizeof(*d)); - int is_ed = d->is_ed = (test->setup_data == (void*)3); - - testing__connection_or_pretend_TLSSECRET_is_supported = 1; scheduler_init(); MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell); MOCK(tor_tls_get_peer_cert, mock_get_peer_cert); MOCK(tor_tls_get_own_cert, mock_get_own_cert); - MOCK(tor_tls_get_tlssecrets, mock_get_tlssecrets); MOCK(connection_or_close_for_error, mock_close_for_err); MOCK(channel_set_circid_type, mock_set_circid_type); MOCK(tor_tls_export_key_material, mock_export_key_material); @@ -1265,7 +1241,7 @@ authenticate_data_setup(const struct testcase_t *test) d->c2->tls = tor_tls_new(-1, 1); d->c2->handshake_state->received_certs_cell = 1; - const tor_x509_cert_t *id_cert=NULL, *link_cert=NULL, *auth_cert=NULL; + const tor_x509_cert_t *id_cert=NULL, *link_cert=NULL; tt_assert(! tor_tls_get_my_certs(1, &link_cert, &id_cert)); const uint8_t *der; @@ -1274,17 +1250,13 @@ authenticate_data_setup(const struct testcase_t *test) d->c1->handshake_state->certs->id_cert = tor_x509_cert_decode(der, sz); d->c2->handshake_state->certs->id_cert = tor_x509_cert_decode(der, sz); - if (is_ed) { + { d->c1->handshake_state->certs->ed_id_sign = tor_cert_dup(get_master_signing_key_cert()); d->c2->handshake_state->certs->ed_id_sign = tor_cert_dup(get_master_signing_key_cert()); d->c2->handshake_state->certs->ed_sign_auth = tor_cert_dup(get_current_auth_key_cert()); - } else { - tt_assert(! tor_tls_get_my_certs(0, &auth_cert, &id_cert)); - tor_x509_cert_get_der(auth_cert, &der, &sz); - d->c2->handshake_state->certs->auth_cert = tor_x509_cert_decode(der, sz); } tor_x509_cert_get_der(link_cert, &der, &sz); @@ -1295,11 +1267,8 @@ authenticate_data_setup(const struct testcase_t *test) tt_assert(mock_own_cert); /* Make an authenticate cell ... */ - int authtype; - if (is_ed) - authtype = AUTHTYPE_ED25519_SHA256_RFC5705; - else - authtype = AUTHTYPE_RSA_SHA256_TLSSECRET; + int authtype = AUTHTYPE_ED25519_SHA256_RFC5705; + tt_int_op(0, OP_EQ, connection_or_send_authenticate_cell(d->c1, authtype)); tt_assert(mock_got_var_cell); @@ -1327,50 +1296,27 @@ test_link_handshake_auth_cell(void *arg) /* Is the cell well-formed on the outer layer? */ tt_int_op(d->cell->command, OP_EQ, CELL_AUTHENTICATE); tt_int_op(d->cell->payload[0], OP_EQ, 0); - if (d->is_ed) - tt_int_op(d->cell->payload[1], OP_EQ, 3); - else - tt_int_op(d->cell->payload[1], OP_EQ, 1); + tt_int_op(d->cell->payload[1], OP_EQ, 3); tt_int_op(ntohs(get_uint16(d->cell->payload + 2)), OP_EQ, d->cell->payload_len - 4); /* Check it out for plausibility... */ - auth_ctx_t ctx; - ctx.is_ed = d->is_ed; 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); - if (d->is_ed) { - tt_mem_op(auth1->type, OP_EQ, "AUTH0003", 8); - } else { - tt_mem_op(auth1->type, OP_EQ, "AUTH0001", 8); - } + tt_mem_op(auth1->type, OP_EQ, "AUTH0003", 8); tt_mem_op(auth1->tlssecrets, OP_EQ, "int getRandomNumber(){return 4;}", 32); /* Is the signature okay? */ const uint8_t *start = d->cell->payload+4, *end = auth1->end_of_signed; - if (d->is_ed) { + { ed25519_signature_t sig; tt_int_op(auth1_getlen_sig(auth1), OP_EQ, ED25519_SIG_LEN); memcpy(&sig.sig, auth1_getarray_sig(auth1), ED25519_SIG_LEN); tt_assert(!ed25519_checksig(&sig, start, end-start, &get_current_auth_keypair()->pubkey)); - } else { - uint8_t sig[128]; - uint8_t digest[32]; - tt_int_op(auth1_getlen_sig(auth1), OP_GT, 120); - auth_pubkey = tor_tls_cert_get_key( - d->c2->handshake_state->certs->auth_cert); - int n = crypto_pk_public_checksig( - auth_pubkey, - (char*)sig, sizeof(sig), (char*)auth1_getarray_sig(auth1), - auth1_getlen_sig(auth1)); - tt_int_op(n, OP_EQ, 32); - crypto_digest256((char*)digest, - (const char*)start, end-start, DIGEST_SHA256); - tt_mem_op(sig, OP_EQ, digest, 32); } /* Then feed it to c2. */ @@ -1378,12 +1324,9 @@ test_link_handshake_auth_cell(void *arg) channel_tls_process_authenticate_cell(d->cell, d->chan2); tt_int_op(mock_close_called, OP_EQ, 0); tt_int_op(d->c2->handshake_state->authenticated, OP_EQ, 1); - if (d->is_ed) { + { tt_int_op(d->c2->handshake_state->authenticated_ed25519, OP_EQ, 1); tt_int_op(d->c2->handshake_state->authenticated_rsa, OP_EQ, 1); - } else { - tt_int_op(d->c2->handshake_state->authenticated_ed25519, OP_EQ, 0); - tt_int_op(d->c2->handshake_state->authenticated_rsa, OP_EQ, 1); } done: @@ -1445,11 +1388,6 @@ AUTHENTICATE_FAIL(noidcert, "certificate"; tor_x509_cert_free(d->c2->handshake_state->certs->id_cert); d->c2->handshake_state->certs->id_cert = NULL) -AUTHENTICATE_FAIL(noauthcert, - require_failure_message = "We never got an RSA " - "authentication certificate"; - tor_x509_cert_free(d->c2->handshake_state->certs->auth_cert); - d->c2->handshake_state->certs->auth_cert = NULL) AUTHENTICATE_FAIL(tooshort, require_failure_message = "Cell was way too short"; d->cell->payload_len = 3) @@ -1473,10 +1411,7 @@ AUTHENTICATE_FAIL(badcontent, "cell body was not as expected"; d->cell->payload[10] ^= 0xff) AUTHENTICATE_FAIL(badsig_1, - if (d->is_ed) - require_failure_message = "Ed25519 signature wasn't valid"; - else - require_failure_message = "RSA signature wasn't valid"; + require_failure_message = "Ed25519 signature wasn't valid"; d->cell->payload[d->cell->payload_len - 5] ^= 0xff) AUTHENTICATE_FAIL(missing_ed_id, { @@ -1522,10 +1457,13 @@ AUTHENTICATE_FAIL(missing_ed_auth, test_link_handshake_recv_certs_ ## name, TT_FORK, \ &setup_recv_certs, (void*)type } +/* These two used to have different behavior, but since we've + disabled RSA-SHAS256-TLSSecret authentication, we no longer + have any need to distinguish. +*/ #define TEST_AUTHENTICATE(name) \ { "authenticate/" #name , test_link_handshake_auth_ ## name, TT_FORK, \ &setup_authenticate, NULL } - #define TEST_AUTHENTICATE_ED(name) \ { "authenticate/" #name "_ed25519" , test_link_handshake_auth_ ## name, \ TT_FORK, &setup_authenticate, (void*)3 } @@ -1581,7 +1519,7 @@ struct testcase_t link_handshake_tests[] = { TEST_RCV_CERTS(server_wrong_labels_1), TEST_RSA(send_authchallenge, TT_FORK), - TEST_RCV_AUTHCHALLENGE(ok), + TEST_RCV_AUTHCHALLENGE(no_ed25519), TEST_RCV_AUTHCHALLENGE(ok_ed25519), TEST_RCV_AUTHCHALLENGE(ok_noserver), TEST_RCV_AUTHCHALLENGE(ok_unrecognized), @@ -1603,7 +1541,6 @@ struct testcase_t link_handshake_tests[] = { TEST_AUTHENTICATE(already_authenticated), TEST_AUTHENTICATE(nocerts), TEST_AUTHENTICATE(noidcert), - TEST_AUTHENTICATE(noauthcert), TEST_AUTHENTICATE(tooshort), TEST_AUTHENTICATE(badtype), TEST_AUTHENTICATE(truncated_1), diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c @@ -49,62 +49,80 @@ const char* notCompletelyValidCertString = "evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n" "-----END CERTIFICATE-----\n"; -const char* validCertString = "-----BEGIN CERTIFICATE-----\n" - "MIIDpTCCAY0CAg3+MA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMREwDwYD\n" - "VQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIGA1UECgwLVG9yIFRl\n" - "c3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkwNjEzMzk1OVoXDTQz\n" - "MDEyMjEzMzk1OVowVjELMAkGA1UEBhMCVVMxEDAOBgNVBAcMB0NoaWNhZ28xFDAS\n" - "BgNVBAoMC1RvciBUZXN0aW5nMR8wHQYDVQQDDBZ0ZXN0aW5nLnRvcnByb2plY3Qu\n" - "b3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoT6uyVVhWyOF3wkHjjYbd\n" - "nKaykyRv4JVtKQdZ4OpEErmX1zw4MmyzpQNV6iR4bQnWiyLfzyVJMZDIC/WILBfX\n" - "w2Pza/yuLgUvDc3twMuhOACzOQVO8PrEF/aVv2+hbCCy2udXvKhnYn+CCXl3ozc8\n" - "XcKYvujTXDyvGWY3xwAjlQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQCUvnhzQWuQ\n" - "MrN+pERkE+zcTI/9dGS90rUMMLgu8VDNqTa0TUQh8uO0EQ6uDvI8Js6e8tgwS0BR\n" - "UBahqb7ZHv+rejGCBr5OudqD+x4STiiuPNJVs86JTLN8SpM9CHjIBH5WCCN2KOy3\n" - "mevNoRcRRyYJzSFULCunIK6FGulszigMYGscrO4oiTkZiHPh9KvWT40IMiHfL+Lw\n" - "EtEWiLex6064LcA2YQ1AMuSZyCexks63lcfaFmQbkYOKqXa1oLkIRuDsOaSVjTfe\n" - "vec+X6jvf12cFTKS5WIeqkKF2Irt+dJoiHEGTe5RscUMN/f+gqHPzfFz5dR23sxo\n" - "g+HC6MZHlFkLAOx3wW6epPS8A/m1mw3zMPoTnb2U2YYt8T0dJMMlUn/7Y1sEAa+a\n" - "dSTMaeUf6VnJ//11m454EZl1to9Z7oJOgqmFffSrdD4BGIWe8f7hhW6L1Enmqe/J\n" - "BKL3wbzZh80O1W0bndAwhnEEhlzneFY84cbBo9pmVxpODHkUcStpr5Z7pBDrcL21\n" - "Ss/aB/1YrsVXhdvJdOGxl3Mnl9dUY57CympLGlT8f0pPS6GAKOelECOhFMHmJd8L\n" - "dj3XQSmKtYHevZ6IvuMXSlB/fJvSjSlkCuLo5+kJoaqPuRu+i/S1qxeRy3CBwmnE\n" - "LdSNdcX4N79GQJ996PA8+mUCQG7YRtK+WA==\n" +// Tor www.torproject.org certificate. +// Fetched March 6 2025, ~1320 UTC. +const char* validCertString = + "-----BEGIN CERTIFICATE-----\n" + "MIIF8zCCBNugAwIBAgISBMmLkAm3fEUb8UQC5EdseU8ZMA0GCSqGSIb3DQEBCwUA\n" + "MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD\n" + "EwNSMTAwHhcNMjUwMTMwMDA1MTU0WhcNMjUwNDMwMDA1MTUzWjAdMRswGQYDVQQD\n" + "ExJ3d3cudG9ycHJvamVjdC5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\n" + "AoICAQDGG3XaG3ZB5QbJisjUbyBW+dgoZy2E3dJ0qMaWyO3/dB8yz4gKKMFCr1Gj\n" + "xjcfWYiayN1mcL8/QWOiD8x1s25FHeWBoDpyHX70TlRK6ZL1u2imsgoIiNaOh7f6\n" + "zfY7EQHu5UTuwSF9xBVf6FGuJ1b+ZGfXE5dBg3JJ78E8unT+xz6TUzEBUHRF7mgR\n" + "nGSgy2vqTT2EpoGq2ZioV8v8JrjkLFUx40XimUPphBs0vdY+gzVCp2wKHRgxglAD\n" + "ut3UzLLs7dW/JV9OSSj5L46CQwuaC5xjGEBcarS202oyBdC7DZpolHVKmwJd6IOj\n" + "DcachL3VFDGPXQe3/TVcale8y6mfhYbGYn8v9SpeHOdsWv5kCNCpHaHYmdSCiCFG\n" + "lmFxnuisu74WghiLrHeHB3oydjACQOyJ4d3u1P9oFKqxPX4ui3ACVWcvksNVQSmR\n" + "LlLE2SrK9wIwn2oNs5jJuR68yMV57i20TGvqBSsCZ3m99glpXwG50tzgqfBwFFDX\n" + "QElJWI8GQvKQIh43TYBvpZXYIG9srvGdl9eUCNXTFhGosc0+sfKoPpUf7f0R58pj\n" + "fjdyDyXb+M6Z60mflOeUM+UR9Q5VeTJ69IfpLypC2JaHy2HCuNekvkbB7TuPuvC9\n" + "vANjovgo5zI3MAcp2v9Y6EDgeScKMbZBQM6nuljvw9npaqkHXQIDAQABo4ICFTCC\n" + "AhEwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD\n" + "AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRWG7Q4+uqENJPVGkL74DH+LCrhjzAf\n" + "BgNVHSMEGDAWgBS7vMNHpeS8qcbDpHIMEI2iNeHI6DBXBggrBgEFBQcBAQRLMEkw\n" + "IgYIKwYBBQUHMAGGFmh0dHA6Ly9yMTAuby5sZW5jci5vcmcwIwYIKwYBBQUHMAKG\n" + "F2h0dHA6Ly9yMTAuaS5sZW5jci5vcmcvMB0GA1UdEQQWMBSCEnd3dy50b3Jwcm9q\n" + "ZWN0Lm9yZzATBgNVHSAEDDAKMAgGBmeBDAECATCCAQMGCisGAQQB1nkCBAIEgfQE\n" + "gfEA7wB1AMz7D2qFcQll/pWbU87psnwi6YVcDZeNtql+VMD+TA2wAAABlLTm/wYA\n" + "AAQDAEYwRAIgHWbnkMLOUDDJg7vog3J66Aa2wuRYg4DFS21uUtPVUQgCIFZhio8Z\n" + "CQcZsdFpeGzAUjXcyboVrvdMg3/3jwWgdQ82AHYA5tIxY0B3jMEQQQbXcbnOwdJA\n" + "9paEhvu6hzId/R43jlAAAAGUtOb/DQAABAMARzBFAiBHNO8CjQdQcMENnXyH5oBL\n" + "kfdZghUHzMEfFKlg5p+QDAIhAP0dEqz+Q2A2XCvN09vZJ1gsG8IzQELHpBM8QDyM\n" + "KSavMA0GCSqGSIb3DQEBCwUAA4IBAQDNh8KjUWJKio63zn2JrFlpIsnrVchPP+ee\n" + "1XUrHQt/BA1pUdlTFPQrHOCf6KOGpiyjXxKkBdtJvc/5ZJZYJ26E6Ytd0nGOCirE\n" + "v0W45Vh22rH1w0Q1fH1xOqZx1qeh4QYr1/QJ3gWWMTOH5uV5dTzK9RWfp0C1pjQ6\n" + "Rct/0ZqyZHYqMD9VoAiVap7lwnWNWOj+UEioH2cMqjCkD5g8QGNHEfereB3DtoV3\n" + "Qw1Z3KoUEr2zEDfq+Uv6RLKCw3HjzDYKbHWSYkrUO7YyIQ3nlZAT861478k5WSKv\n" + "hpy8XisMLpQLAhSByV965gINlmHXbe61anJUh3JJpnOu/JyMfaf/\n" "-----END CERTIFICATE-----\n"; -const char* caCertString = "-----BEGIN CERTIFICATE-----\n" - "MIIFjzCCA3egAwIBAgIJAKd5WgyfPMYRMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV\n" - "BAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIG\n" - "A1UECgwLVG9yIFRlc3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkw\n" - "NjEzMzc0MVoXDTQzMDEyMjEzMzc0MVowXjELMAkGA1UEBhMCVVMxETAPBgNVBAgM\n" - "CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRQwEgYDVQQKDAtUb3IgVGVzdGlu\n" - "ZzEUMBIGA1UEAwwLVG9yIFRlc3RpbmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n" - "ggIKAoICAQCpLMUEiLW5leUgBZoEJms2V7lZRhIAjnJBhVMHD0e3UubNknmaQoxf\n" - "ARz3rvqOaRd0JlV+qM9qE0DjiYcCVP1cAfqAo9d83uS1vwY3YMVJzADlaIiHfyVW\n" - "uEgBy0vvkeUBqaua24dYlcwsemOiXYLu41yM1wkcGHW1AhBNHppY6cznb8TyLgNM\n" - "2x3SGUdzc5XMyAFx51faKGBA3wjs+Hg1PLY7d30nmCgEOBavpm5I1disM/0k+Mcy\n" - "YmAKEo/iHJX/rQzO4b9znP69juLlR8PDBUJEVIG/CYb6+uw8MjjUyiWXYoqfVmN2\n" - "hm/lH8b6rXw1a2Aa3VTeD0DxaWeacMYHY/i01fd5n7hCoDTRNdSw5KJ0L3Z0SKTu\n" - "0lzffKzDaIfyZGlpW5qdouACkWYzsaitQOePVE01PIdO30vUfzNTFDfy42ccx3Di\n" - "59UCu+IXB+eMtrBfsok0Qc63vtF1linJgjHW1z/8ujk8F7/qkOfODhk4l7wngc2A\n" - "EmwWFIFoGaiTEZHB9qteXr4unbXZ0AHpM02uGGwZEGohjFyebEb73M+J57WKKAFb\n" - "PqbLcGUksL1SHNBNAJcVLttX55sO4nbidOS/kA3m+F1R04MBTyQF9qA6YDDHqdI3\n" - "h/3pw0Z4fxVouTYT4/NfRnX4JTP4u+7Mpcoof28VME0qWqD1LnRhFQIDAQABo1Aw\n" - "TjAdBgNVHQ4EFgQUMoAgIXH7pZ3QMRwTjT+DM9Yo/v0wHwYDVR0jBBgwFoAUMoAg\n" - "IXH7pZ3QMRwTjT+DM9Yo/v0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n" - "AgEAUJxacjXR9sT+Xs6ISFiUsyd0T6WVKMnV46xrYJHirGfx+krWHrjxMY+ZtxYD\n" - "DBDGlo11Qc4v6QrclNf5QUBfIiGQsP9Cm6hHcQ+Tpg9HHCgSqG1YNPwCPReCR4br\n" - "BLvLfrfkcBL2IWM0PdQdCze+59DBfipsULD2mEn9fjYRXQEwb2QWtQ9qRc20Yb/x\n" - "Q4b/+CvUodLkaq7B8MHz0BV8HHcBoph6DYaRmO/N+hPauIuSp6XyaGYcEefGKVKj\n" - "G2+fcsdyXsoijNdL8vNKwm4j2gVwCBnw16J00yfFoV46YcbfqEdJB2je0XSvwXqt\n" - "14AOTngxso2h9k9HLtrfpO1ZG/B5AcCMs1lzbZ2fp5DPHtjvvmvA2RJqgo3yjw4W\n" - "4DHAuTglYFlC3mDHNfNtcGP20JvepcQNzNP2UzwcpOc94hfKikOFw+gf9Vf1qd0y\n" - "h/Sk6OZHn2+JVUPiWHIQV98Vtoh4RmUZDJD+b55ia3fQGTGzt4z1XFzQYSva5sfs\n" - "wocS/papthqWldQU7x+3wofNd5CNU1x6WKXG/yw30IT/4F8ADJD6GeygNT8QJYvt\n" - "u/8lAkbOy6B9xGmSvr0Kk1oq9P2NshA6kalxp1Oz/DTNDdL4AeBXV3JmM6WWCjGn\n" - "Yy1RT69d0rwYc5u/vnqODz1IjvT90smsrkBumGt791FAFeg=\n" +// Let's encrypt certificate, used to sign validCertString. +// Also fetched March 6 2025, ~1320 UTC. +const char* caCertString = + "-----BEGIN CERTIFICATE-----\n" + "MIIFBTCCAu2gAwIBAgIQS6hSk/eaL6JzBkuoBI110DANBgkqhkiG9w0BAQsFADBP\n" + "MQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFy\n" + "Y2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMTAeFw0yNDAzMTMwMDAwMDBa\n" + "Fw0yNzAzMTIyMzU5NTlaMDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBF\n" + "bmNyeXB0MQwwCgYDVQQDEwNSMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" + "AoIBAQDPV+XmxFQS7bRH/sknWHZGUCiMHT6I3wWd1bUYKb3dtVq/+vbOo76vACFL\n" + "YlpaPAEvxVgD9on/jhFD68G14BQHlo9vH9fnuoE5CXVlt8KvGFs3Jijno/QHK20a\n" + "/6tYvJWuQP/py1fEtVt/eA0YYbwX51TGu0mRzW4Y0YCF7qZlNrx06rxQTOr8IfM4\n" + "FpOUurDTazgGzRYSespSdcitdrLCnF2YRVxvYXvGLe48E1KGAdlX5jgc3421H5KR\n" + "mudKHMxFqHJV8LDmowfs/acbZp4/SItxhHFYyTr6717yW0QrPHTnj7JHwQdqzZq3\n" + "DZb3EoEmUVQK7GH29/Xi8orIlQ2NAgMBAAGjgfgwgfUwDgYDVR0PAQH/BAQDAgGG\n" + "MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATASBgNVHRMBAf8ECDAGAQH/\n" + "AgEAMB0GA1UdDgQWBBS7vMNHpeS8qcbDpHIMEI2iNeHI6DAfBgNVHSMEGDAWgBR5\n" + "tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAKG\n" + "Fmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0gBAwwCjAIBgZngQwBAgEwJwYD\n" + "VR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVuY3Iub3JnLzANBgkqhkiG9w0B\n" + "AQsFAAOCAgEAkrHnQTfreZ2B5s3iJeE6IOmQRJWjgVzPw139vaBw1bGWKCIL0vIo\n" + "zwzn1OZDjCQiHcFCktEJr59L9MhwTyAWsVrdAfYf+B9haxQnsHKNY67u4s5Lzzfd\n" + "u6PUzeetUK29v+PsPmI2cJkxp+iN3epi4hKu9ZzUPSwMqtCceb7qPVxEbpYxY1p9\n" + "1n5PJKBLBX9eb9LU6l8zSxPWV7bK3lG4XaMJgnT9x3ies7msFtpKK5bDtotij/l0\n" + "GaKeA97pb5uwD9KgWvaFXMIEt8jVTjLEvwRdvCn294GPDF08U8lAkIv7tghluaQh\n" + "1QnlE4SEN4LOECj8dsIGJXpGUk3aU3KkJz9icKy+aUgA+2cP21uh6NcDIS3XyfaZ\n" + "QjmDQ993ChII8SXWupQZVBiIpcWO4RqZk3lr7Bz5MUCwzDIA359e57SSq5CCkY0N\n" + "4B6Vulk7LktfwrdGNVI5BsC9qqxSwSKgRJeZ9wygIaehbHFHFhcBaMDKpiZlBHyz\n" + "rsnnlFXCb5s8HKn5LsUgGvB24L7sGNZP2CX7dhHov+YhD+jozLW2p9W4959Bz2Ei\n" + "RmqDtmiXLnzqTpXbI+suyCsohKRg6Un0RC47+cpiVwHiXZAW+cn8eiNIjqbVgXLx\n" + "KPpdzvvtTnOPlC7SQZSYmdunr3Bf9b77AiC/ZidstK36dRILKz7OA54=\n" "-----END CERTIFICATE-----\n"; +// A time at which the certs above are valid. +const time_t cert_strings_valid_at = 1741267580; + static tor_x509_cert_t *fixed_x509_cert = NULL; static tor_x509_cert_t * get_peer_cert_mock_return_fixed(tor_tls_t *tls) @@ -482,6 +500,7 @@ test_tortls_verify(void *ignored) crypto_pk_t *k = NULL; tor_x509_cert_impl_t *cert1 = NULL, *cert2 = NULL, *invalidCert = NULL, *validCert = NULL, *caCert = NULL; + time_t now = cert_strings_valid_at; validCert = read_cert_from(validCertString); caCert = read_cert_from(caCertString); @@ -492,23 +511,23 @@ test_tortls_verify(void *ignored) MOCK(try_to_extract_certs_from_tls, fixed_try_to_extract_certs_from_tls); fixed_try_to_extract_certs_from_tls_cert_out_result = cert1; - ret = tor_tls_verify(LOG_WARN, tls, &k); + ret = tor_tls_verify(LOG_WARN, tls, now, &k); tt_int_op(ret, OP_EQ, -1); fixed_try_to_extract_certs_from_tls_id_cert_out_result = cert2; - ret = tor_tls_verify(LOG_WARN, tls, &k); + ret = tor_tls_verify(LOG_WARN, tls, now, &k); tt_int_op(ret, OP_EQ, -1); fixed_try_to_extract_certs_from_tls_cert_out_result = invalidCert; fixed_try_to_extract_certs_from_tls_id_cert_out_result = invalidCert; - ret = tor_tls_verify(LOG_WARN, tls, &k); + ret = tor_tls_verify(LOG_WARN, tls, now, &k); tt_int_op(ret, OP_EQ, -1); fixed_try_to_extract_certs_from_tls_cert_out_result = validCert; fixed_try_to_extract_certs_from_tls_id_cert_out_result = caCert; - ret = tor_tls_verify(LOG_WARN, tls, &k); + ret = tor_tls_verify(LOG_WARN, tls, now, &k); tt_int_op(ret, OP_EQ, 0); tt_assert(k); diff --git a/src/test/test_tortls.h b/src/test/test_tortls.h @@ -9,5 +9,6 @@ tor_x509_cert_impl_t *read_cert_from(const char *str); extern const char *notCompletelyValidCertString; extern const char *validCertString; extern const char *caCertString; +extern const time_t cert_strings_valid_at; #endif /* !defined(TEST_TORTLS_H) */ diff --git a/src/test/test_tortls_openssl.c b/src/test/test_tortls_openssl.c @@ -505,32 +505,6 @@ test_tortls_cert_get_key(void *ignored) } #endif /* !defined(OPENSSL_OPAQUE) */ -static void -test_tortls_get_my_client_auth_key(void *ignored) -{ - (void)ignored; - crypto_pk_t *ret; - crypto_pk_t *expected; - tor_tls_context_t *ctx; - RSA *k = RSA_new(); - - ctx = tor_malloc_zero(sizeof(tor_tls_context_t)); - expected = crypto_new_pk_from_openssl_rsa_(k); - ctx->auth_key = expected; - - client_tls_context = NULL; - ret = tor_tls_get_my_client_auth_key(); - tt_assert(!ret); - - client_tls_context = ctx; - ret = tor_tls_get_my_client_auth_key(); - tt_assert(ret == expected); - - done: - crypto_pk_free(expected); - tor_free(ctx); -} - #ifndef HAVE_SSL_GET_CLIENT_CIPHERS static SSL_CIPHER * get_cipher_by_name(const char *name) @@ -2068,20 +2042,21 @@ test_tortls_cert_is_valid(void *ignored) (void)ignored; int ret; tor_x509_cert_t *cert = NULL, *scert = NULL; + time_t now = cert_strings_valid_at; scert = tor_malloc_zero(sizeof(tor_x509_cert_t)); - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 0); tt_int_op(ret, OP_EQ, 0); cert = tor_malloc_zero(sizeof(tor_x509_cert_t)); - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 0); tt_int_op(ret, OP_EQ, 0); tor_free(scert); tor_free(cert); cert = tor_x509_cert_new(read_cert_from(validCertString)); scert = tor_x509_cert_new(read_cert_from(caCertString)); - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 0); tt_int_op(ret, OP_EQ, 1); #ifndef OPENSSL_OPAQUE @@ -2092,7 +2067,7 @@ test_tortls_cert_is_valid(void *ignored) ASN1_TIME_free(cert->cert->cert_info->validity->notAfter); cert->cert->cert_info->validity->notAfter = ASN1_TIME_set(NULL, time(NULL)-1000000); - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 0); tt_int_op(ret, OP_EQ, 0); tor_x509_cert_free(cert); @@ -2101,7 +2076,7 @@ test_tortls_cert_is_valid(void *ignored) scert = tor_x509_cert_new(read_cert_from(caCertString)); X509_PUBKEY_free(cert->cert->cert_info->key); cert->cert->cert_info->key = NULL; - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 1); tt_int_op(ret, OP_EQ, 0); #endif /* !defined(OPENSSL_OPAQUE) */ @@ -2112,7 +2087,7 @@ test_tortls_cert_is_valid(void *ignored) scert = tor_x509_cert_new(read_cert_from(caCertString)); /* This doesn't actually change the key in the cert. XXXXXX */ BN_one(EVP_PKEY_get1_RSA(X509_get_pubkey(cert->cert))->n); - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 1); tt_int_op(ret, OP_EQ, 0); tor_x509_cert_free(cert); @@ -2121,7 +2096,7 @@ test_tortls_cert_is_valid(void *ignored) scert = tor_x509_cert_new(read_cert_from(caCertString)); /* This doesn't actually change the key in the cert. XXXXXX */ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC; - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 1); tt_int_op(ret, OP_EQ, 0); tor_x509_cert_free(cert); @@ -2130,7 +2105,7 @@ test_tortls_cert_is_valid(void *ignored) scert = tor_x509_cert_new(read_cert_from(caCertString)); /* This doesn't actually change the key in the cert. XXXXXX */ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC; - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 0); tt_int_op(ret, OP_EQ, 1); tor_x509_cert_free(cert); @@ -2140,7 +2115,7 @@ test_tortls_cert_is_valid(void *ignored) /* This doesn't actually change the key in the cert. XXXXXX */ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC; X509_get_pubkey(cert->cert)->ameth = NULL; - ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, now, 0); tt_int_op(ret, OP_EQ, 0); #endif /* 0 */ @@ -2187,7 +2162,6 @@ struct testcase_t tortls_openssl_tests[] = { LOCAL_TEST_CASE(always_accept_verify_cb, 0), INTRUSIVE_TEST_CASE(x509_cert_free, 0), INTRUSIVE_TEST_CASE(cert_get_key, 0), - LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK), INTRUSIVE_TEST_CASE(get_ciphersuite_name, 0), INTRUSIVE_TEST_CASE(classify_client_ciphers, 0), LOCAL_TEST_CASE(client_is_using_v2_ciphers, 0), diff --git a/src/trunnel/link_handshake.c b/src/trunnel/link_handshake.c @@ -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; diff --git a/src/trunnel/link_handshake.h b/src/trunnel/link_handshake.h @@ -15,6 +15,25 @@ #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); diff --git a/src/trunnel/link_handshake.trunnel b/src/trunnel/link_handshake.trunnel @@ -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];