commit b004ff45d7f637675be976737eb7efea8da5b49c Author: Nick Mathewson nickm@torproject.org Date: Tue May 10 16:47:52 2016 -0400
New authentication types to use RFC5705.
See proposal 244. This feature lets us stop looking at the internals of SSL objects, *and* should let us port better to more SSL libraries, if they have RFC5705 support.
Preparatory for #19156 --- src/common/tortls.c | 22 ++++++++++++++++++++++ src/common/tortls.h | 5 +++++ src/or/connection_or.c | 39 ++++++++++++++++++++++++++++++++++----- src/or/or.h | 23 ++++++++++++++++++++++- 4 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/src/common/tortls.c b/src/common/tortls.c index 23889be..eaa5748 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -2448,6 +2448,28 @@ tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out)) 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 + * <b>secrets_out</b> that only the parties to this TLS session can + * compute. Return 0 on success and -1 on failure. + */ +MOCK_IMPL(int, +tor_tls_export_key_material,(tor_tls_t *tls, uint8_t *secrets_out, + const uint8_t *context, + size_t context_len, + const char *label)) +{ + tor_assert(tls); + tor_assert(tls->ssl); + + int r = SSL_export_keying_material(tls->ssl, + secrets_out, DIGEST256_LEN, + label, strlen(label), + context, context_len, 1); + return (r == 1) ? 0 : -1; +} + /** Examine the amount of memory used and available for buffers in <b>tls</b>. * Set *<b>rbuf_capacity</b> to the amount of storage allocated for the read * buffer and *<b>rbuf_bytes</b> to the amount actually used. diff --git a/src/common/tortls.h b/src/common/tortls.h index 7c035a2..fe5898e 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -226,6 +226,11 @@ int tor_tls_used_v1_handshake(tor_tls_t *tls); 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_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out)); +MOCK_DECL(int,tor_tls_export_key_material,( + tor_tls_t *tls, uint8_t *secrets_out, + const uint8_t *context, + size_t context_len, + const char *label));
/* Log and abort if there are unhandled TLS errors in OpenSSL's error stack. */ diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 09579f8..d06a246 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -2318,15 +2318,34 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, auth1_t *auth = NULL; auth_ctx_t *ctx = auth_ctx_new(); int result; + int old_tlssecrets_algorithm = 0; + const char *authtype_str = NULL;
- /* assert state is reasonable XXXX */ + int is_ed = 0; + const int authtype = 1; /* XXXX this should be an argument. */
- ctx->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"; + break; + case AUTHTYPE_ED25519_SHA256_RFC5705: + authtype_str = "AUTH0003"; + is_ed = 1; + break; + default: + tor_assert(0); + break; + }
auth = auth1_new();
/* Type: 8 bytes. */ - memcpy(auth1_getarray_type(auth), "AUTH0001", 8); + memcpy(auth1_getarray_type(auth), authtype_str, 8);
{ const tor_x509_cert_t *id_cert=NULL, *link_cert=NULL; @@ -2380,7 +2399,8 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, cert = freecert; } if (!cert) { - log_warn(LD_OR, "Unable to find cert when making AUTH1 data."); + log_warn(LD_OR, "Unable to find cert when making %s data.", + authtype_str); goto err; }
@@ -2392,7 +2412,16 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, }
/* HMAC of clientrandom and serverrandom using master key : 32 octets */ - tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets); + if (old_tlssecrets_algorithm) { + tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets); + } else { + char label[128]; + tor_snprintf(label, sizeof(label), + "EXPORTER FOR TOR TLS CLIENT BINDING %s", authtype_str); + tor_tls_export_key_material(conn->tls, auth->tlssecrets, + auth->cid, sizeof(auth->cid), + label); + }
/* 8 octets were reserved for the current time, but we're trying to get out * of the habit of sending time around willynilly. Fortunately, nothing diff --git a/src/or/or.h b/src/or/or.h index 5b9b007..402fbfd 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1348,13 +1348,34 @@ typedef struct listener_connection_t { #define OR_CERT_TYPE_RSA_ED_CROSSCERT 7 /**@}*/
-/** The one currently supported type of AUTHENTICATE cell. It contains +/** The first supported type of AUTHENTICATE cell. It contains * a bunch of structures signed with an RSA1024 key. The signed * structures include a HMAC using negotiated TLS secrets, and a digest * of all cells sent or received before the AUTHENTICATE cell (including * the random server-generated AUTH_CHALLENGE cell). */ #define AUTHTYPE_RSA_SHA256_TLSSECRET 1 +/** As AUTHTYPE_RSA_SHA256_TLSSECRET, but instead of using the + * negotiated TLS secrets, uses exported keying material from the TLS + * session as described in RFC 5705. + * + * Not used by today's tors, since everything that supports this + * also supports ED25519_SHA3_5705, which is better. + **/ +#define AUTHTYPE_RSA_SHA256_RFC5705 2 +/** As AUTHTYPE_RSA_SHA256_RFC5705, but uses an Ed25519 identity key to + * authenticate. */ +#define AUTHTYPE_ED25519_SHA256_RFC5705 3 +/* + * NOTE: authchallenge_type_is_better() relies on these AUTHTYPE codes + * being sorted in order of preference. If we someday add one with + * a higher numerical value that we don't like as much, we should revise + * authchallenge_type_is_better(). + */ + + + +
/** The length of the part of the AUTHENTICATE cell body that the client and * server can generate independently (when using RSA_SHA256_TLSSECRET). It
tor-commits@lists.torproject.org