mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
r14729@31-33-67: nickm | 2007-11-05 18:54:50 -0500
Send and Parse CERT cells correctly. Still need to understand the certs inside. svn:r12392
This commit is contained in:
@@ -29,18 +29,18 @@ Things we'd like to do in 0.2.0.x:
|
||||
o Revise versions and netinfo to use separate structure; make
|
||||
act-on-netinfo logic separate so it can get called _after_
|
||||
negotiation.
|
||||
- Variable-length cells
|
||||
o Variable-length cells
|
||||
o Add structure
|
||||
o Add parse logic
|
||||
- Make CERT variable.
|
||||
o Make CERT variable.
|
||||
o Make VERSIONS variable.
|
||||
- CERT cells
|
||||
- functions to parse x509 certs
|
||||
- functions to validate a single x509 cert against a TLS connection
|
||||
- functions to validate a chain of x509 certs, and extract a PK.
|
||||
o function to encode x509 certs
|
||||
- Parse CERT cells
|
||||
- Generate CERT cells
|
||||
o Parse CERT cells
|
||||
o Generate CERT cells
|
||||
o Keep copies of X509 certs around, not necessarily associated with
|
||||
connection.
|
||||
- LINK_AUTH cells
|
||||
|
||||
+46
-3
@@ -603,13 +603,51 @@ connection_or_act_on_netinfo(or_connection_t *conn)
|
||||
}
|
||||
}
|
||||
|
||||
/*DOCDOC*/
|
||||
static void
|
||||
command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
|
||||
{
|
||||
(void) cell;
|
||||
(void) conn;
|
||||
int n_certs = 0;
|
||||
uint16_t conn_cert_len, id_cert_len;
|
||||
const char *conn_cert = NULL, *id_cert = NULL;
|
||||
const char *cp, *end;
|
||||
|
||||
/*XXXX020 log messages*/
|
||||
if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING)
|
||||
goto err;
|
||||
tor_assert(conn->handshake_state);
|
||||
if (!conn->handshake_state->received_versions ||
|
||||
!conn->handshake_state->received_netinfo ||
|
||||
conn->handshake_state->received_certs)
|
||||
goto err;
|
||||
|
||||
cp = cell->payload;
|
||||
end = cell->payload + cell->payload_len;
|
||||
|
||||
while (cp < end) {
|
||||
uint16_t len;
|
||||
if (end-cp == 1)
|
||||
goto err;
|
||||
len = ntohs(get_uint16(cp));
|
||||
cp += 2;
|
||||
if (end-cp < len)
|
||||
goto err;
|
||||
if (n_certs == 0) {
|
||||
conn_cert = cp;
|
||||
conn_cert_len = len;
|
||||
} else if (n_certs == 1) {
|
||||
id_cert = cp;
|
||||
id_cert_len = len;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
cp += len;
|
||||
++n_certs;
|
||||
}
|
||||
|
||||
/* Now we have 0, 1, or 2 certs. */
|
||||
|
||||
|
||||
/* Parse certs. */
|
||||
/* Verify that identity cert has signed peer cert in SSL, or
|
||||
* peer cert in the cell. */
|
||||
/* Verify that identity cert is self-signed. */
|
||||
@@ -617,6 +655,11 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
|
||||
/* Learn cert digests. */
|
||||
/* Remember peer cert public key. */
|
||||
/* set received_certs. */
|
||||
|
||||
conn->handshake_state->received_certs = 1;
|
||||
return;
|
||||
err:
|
||||
;
|
||||
}
|
||||
|
||||
#define LINK_AUTH_STRING "Tor initiator certificate verification"
|
||||
|
||||
+37
-2
@@ -965,6 +965,7 @@ connection_or_send_versions(or_connection_t *conn)
|
||||
connection_or_write_var_cell_to_buf(cell, conn);
|
||||
conn->handshake_state->sent_versions_at = time(NULL);
|
||||
|
||||
var_cell_free(cell);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1037,8 +1038,42 @@ connection_or_compute_link_auth_hmac(or_connection_t *conn,
|
||||
int
|
||||
connection_or_send_cert(or_connection_t *conn)
|
||||
{
|
||||
(void)conn;
|
||||
/*XXX020 implement.*/
|
||||
size_t conn_cert_len = 0, id_cert_len = 0, total_len = 0;
|
||||
char *id_cert = NULL, *conn_cert = NULL;
|
||||
var_cell_t *cell;
|
||||
char *cp;
|
||||
|
||||
/* If we're a client, we can send no cert at all. XXXXX020 */
|
||||
/* DOCDOC length of cert before cert. */
|
||||
tor_assert(conn);
|
||||
tor_assert(conn->handshake_state);
|
||||
tor_assert(conn->handshake_state->received_versions == 1);
|
||||
if (conn->handshake_state->started_here)
|
||||
conn_cert = tor_tls_encode_my_certificate(conn->tls, &conn_cert_len, 1);
|
||||
id_cert = tor_tls_encode_my_certificate(conn->tls, &id_cert_len, 0);
|
||||
tor_assert(id_cert);
|
||||
total_len = id_cert_len + conn_cert_len + conn_cert ? 4 : 2;
|
||||
|
||||
cell = var_cell_new(total_len);
|
||||
cell->command = CELL_VERSIONS;
|
||||
cp = cell->payload;
|
||||
if (conn_cert) {
|
||||
set_uint16(cp, htons(conn_cert_len));
|
||||
cp += 2;
|
||||
memcpy(cp, conn_cert, conn_cert_len);
|
||||
cp += conn_cert_len;
|
||||
}
|
||||
set_uint16(cp, htons(id_cert_len));
|
||||
cp += 2;
|
||||
memcpy(cp, id_cert, id_cert_len);
|
||||
cp += id_cert_len;
|
||||
tor_assert(cp == cell->payload + total_len);
|
||||
|
||||
connection_or_write_var_cell_to_buf(cell, conn);
|
||||
|
||||
tor_free(conn_cert);
|
||||
tor_free(id_cert);
|
||||
var_cell_free(cell);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user