[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Basic function to write authenticate cells
commit 81024f43ec3a3ab32683764cb925606bfcb603d7
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Wed Sep 14 14:44:42 2011 -0400
Basic function to write authenticate cells
Also, tweak the cert cell code to send auth certs
---
src/or/connection_or.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++-
src/or/connection_or.h | 5 +
2 files changed, 197 insertions(+), 3 deletions(-)
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index dcb838b..c72d89d 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1776,13 +1776,14 @@ connection_or_send_cert_cell(or_connection_t *conn)
var_cell_t *cell;
size_t cell_len;
int pos;
+ int server_mode;
tor_assert(conn->_base.state == OR_CONN_STATE_OR_HANDSHAKING_V3);
if (! conn->handshake_state)
return -1;
- if (tor_tls_get_my_certs(! conn->handshake_state->started_here,
- &link_cert, &id_cert) < 0)
+ server_mode = ! conn->handshake_state->started_here;
+ if (tor_tls_get_my_certs(server_mode, &link_cert, &id_cert) < 0)
return -1;
tor_cert_get_der(link_cert, &link_encoded, &link_len);
tor_cert_get_der(id_cert, &id_encoded, &id_len);
@@ -1795,7 +1796,10 @@ connection_or_send_cert_cell(or_connection_t *conn)
cell->payload[0] = 2;
pos = 1;
- cell->payload[pos] = OR_CERT_TYPE_TLS_LINK; /* Link cert */
+ if (server_mode)
+ cell->payload[pos] = OR_CERT_TYPE_TLS_LINK; /* Link cert */
+ else
+ cell->payload[pos] = OR_CERT_TYPE_AUTH_1024; /* client authentication */
set_uint16(&cell->payload[pos+1], htons(link_len));
memcpy(&cell->payload[pos+3], link_encoded, link_len);
pos += 3 + link_len;
@@ -1842,3 +1846,188 @@ connection_or_send_auth_challenge_cell(or_connection_t *conn)
return 0;
}
+/** DOCDOC */
+#define V3_HS_AUTH_FIXED_PART_LEN (8+(32*6))
+#define V3_HS_AUTH_BODY_LEN (V3_HS_AUTH_FIXED_PART_LEN + 8 + 16)
+
+#define AUTHTYPE_RSA_SHA256_TLSSECRET 1
+
+/** Compute the main body of an AUTHENTICATE cell that a client can use
+ * to authenticate itself on a v3 handshake for <b>conn</b>. Write it to the
+ * <b>outlen</b>-byte buffer at <b>out</b>.
+ *
+ * If <b>server</b> is true, only calculate the first
+ * V3_HS_AUTH_FIXED_PART_LEN bytes -- the part of the authenticator that's
+ * 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
+ * first V3_HS_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>.
+ */
+int
+connection_or_compute_authenticate_cell_body(or_connection_t *conn,
+ uint8_t *out, size_t outlen,
+ crypto_pk_env_t *signing_key,
+ int server)
+{
+ uint8_t *ptr;
+
+ /* assert state is reasonable XXXX */
+
+ if (outlen < V3_HS_AUTH_FIXED_PART_LEN ||
+ (!server && outlen < V3_HS_AUTH_BODY_LEN))
+ return -1;
+
+ ptr = out;
+
+ /* Type: 8 bytes. */
+ memcpy(ptr, "AUTH0001", 8);
+ ptr += 8;
+
+ {
+ const tor_cert_t *id_cert=NULL, *link_cert=NULL;
+ const uint8_t *my_id, *their_id, *client_id, *server_id;
+ if (tor_tls_get_my_certs(0, &link_cert, &id_cert))
+ return -1;
+ my_id = (uint8_t*)tor_cert_get_id_digests(id_cert)->d[DIGEST_SHA256];
+ their_id = (uint8_t*)
+ tor_cert_get_id_digests(conn->handshake_state->id_cert)->d[DIGEST_SHA256];
+ client_id = server ? their_id : my_id;
+ server_id = server ? my_id : their_id;
+
+ /* Client ID digest: 32 octets. */
+ memcpy(ptr, client_id, 32);
+ ptr += 32;
+
+ /* Server ID digest: 32 octets. */
+ memcpy(ptr, server_id, 32);
+ ptr += 32;
+ }
+
+ {
+ crypto_digest_env_t *server_d, *client_d;
+ if (server) {
+ server_d = conn->handshake_state->digest_sent;
+ client_d = conn->handshake_state->digest_received;
+ } else {
+ client_d = conn->handshake_state->digest_sent;
+ server_d = conn->handshake_state->digest_received;
+ }
+
+ /* Server log digest : 32 octets */
+ crypto_digest_get_digest(server_d, (char*)ptr, 32);
+ ptr += 32;
+
+ /* Client log digest : 32 octets */
+ crypto_digest_get_digest(client_d, (char*)ptr, 32);
+ ptr += 32;
+ }
+
+ {
+ /* Digest of cert used on TLS link : 32 octets. */
+ const tor_cert_t *cert = NULL;
+ tor_cert_t *freecert = NULL;
+ if (server) {
+ tor_tls_get_my_certs(1, &cert, NULL);
+ } else {
+ freecert = tor_tls_get_peer_cert(conn->tls);
+ cert = freecert;
+ }
+ if (!cert)
+ return -1;
+ memcpy(ptr, tor_cert_get_cert_digests(cert)->d[DIGEST_SHA256], 32);
+
+ if (freecert)
+ tor_cert_free(freecert);
+ ptr += 32;
+ }
+
+ /* HMAC of clientrandom and serverrandom using master key : 32 octets */
+ tor_tls_get_tlssecrets(conn->tls, ptr);
+ ptr += 32;
+
+ tor_assert(ptr - out == V3_HS_AUTH_FIXED_PART_LEN);
+
+ if (server)
+ return ptr-out;
+
+ /* Time: 8 octets. */
+ {
+ uint64_t now = time(NULL);
+ if ((time_t)now < 0)
+ return -1;
+ set_uint32(ptr, htonl((uint32_t)(now>>32)));
+ set_uint32(ptr+4, htonl((uint32_t)now));
+ ptr += 8;
+ }
+
+ /* Nonce: 16 octets. */
+ crypto_rand((char*)ptr, 16);
+ ptr += 16;
+
+ tor_assert(ptr - out == V3_HS_AUTH_BODY_LEN);
+
+ if (!signing_key)
+ return ptr - out;
+
+ {
+ int siglen;
+ char d[32];
+ crypto_digest256(d, (char*)out, ptr-out, DIGEST_SHA256);
+ siglen = crypto_pk_private_sign(signing_key,
+ (char*)ptr, outlen - (ptr-out),
+ d, 32);
+ if (siglen < 0)
+ return -1;
+
+ ptr += siglen;
+ tor_assert(ptr <= out+outlen);
+ return ptr - out;
+ }
+}
+
+/** Send an AUTHENTICATE cell on the connection <b>conn</b>. Return 0 on
+ * success, -1 on failure */
+int
+connection_or_send_authenticate_cell(or_connection_t *conn)
+{
+ var_cell_t *cell;
+ crypto_pk_env_t *pk = tor_tls_get_my_client_auth_key();
+ int authlen;
+ int cell_maxlen;
+ /* XXXX make sure we're actually supposed to send this! */
+
+ if (!pk)
+ return -1;/*XXXX log*/
+ cell_maxlen = 4 + /* overhead */
+ V3_HS_AUTH_BODY_LEN + /* Authentication body */
+ crypto_pk_keysize(pk) + /* Max signature length */
+ 16 /* just in case XXXX */ ;
+
+ cell = var_cell_new(cell_maxlen);
+ set_uint16(cell->payload, htons(AUTHTYPE_RSA_SHA256_TLSSECRET));
+ /* skip over length ; we don't know that yet. */
+
+ authlen = connection_or_compute_authenticate_cell_body(conn,
+ cell->payload+4,
+ cell_maxlen-4,
+ pk,
+ 0 /* not server */);
+ if (authlen < 0) {
+ /* XXXX log */
+ var_cell_free(cell);
+ return -1;
+ }
+ tor_assert(authlen + 4 <= cell->payload_len);
+ set_uint16(cell->payload+2, htons(authlen));
+ cell->payload_len = authlen + 4;
+
+ connection_or_write_var_cell_to_buf(cell, conn);
+ var_cell_free(cell);
+
+ return 0;
+}
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index 6e50e29..ba441c4 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -52,6 +52,11 @@ int connection_or_send_destroy(circid_t circ_id, or_connection_t *conn,
int connection_or_send_netinfo(or_connection_t *conn);
int connection_or_send_cert_cell(or_connection_t *conn);
int connection_or_send_auth_challenge_cell(or_connection_t *conn);
+int connection_or_compute_authenticate_cell_body(or_connection_t *conn,
+ uint8_t *out, size_t outlen,
+ crypto_pk_env_t *signing_key,
+ int server);
+int connection_or_send_authenticate_cell(or_connection_t *conn);
int is_or_protocol_version_known(uint16_t version);
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits