[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r12382: Remember X509 certificates in the context. Store peer/self c (in tor/trunk: . doc src/common src/or)
Author: nickm
Date: 2007-11-05 13:15:50 -0500 (Mon, 05 Nov 2007)
New Revision: 12382
Modified:
tor/trunk/
tor/trunk/doc/TODO
tor/trunk/src/common/tortls.c
tor/trunk/src/common/tortls.h
tor/trunk/src/or/connection_or.c
tor/trunk/src/or/or.h
Log:
r16411@catbus: nickm | 2007-11-05 11:27:37 -0500
Remember X509 certificates in the context. Store peer/self certificate digests in handshake state.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r16411] on 8246c3cf-6607-4228-993b-4d95d33730f1
Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO 2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/doc/TODO 2007-11-05 18:15:50 UTC (rev 12382)
@@ -43,6 +43,7 @@
connection.
- LINK_AUTH cells
- Code to generate
+ o Remember certificate digests from TLS
- Code to parse and check
- Unit tests
- Revised handshake: TLS
@@ -57,6 +58,7 @@
- After we send NETINFO, send CERT and LINK_AUTH if needed.
- Once we get a good LINK_AUTH, the connection is OPEN.
- Ban most cell types on a non-OPEN connection.
+ - Make code work right wrt TLS context rotation.
- NETINFO fallout
- Don't extend a circuit over a noncanonical connection with
mismatched address.
Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c 2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/common/tortls.c 2007-11-05 18:15:50 UTC (rev 12382)
@@ -44,6 +44,8 @@
/** Structure holding the TLS state for a single connection. */
typedef struct tor_tls_context_t {
SSL_CTX *ctx;
+ X509 *my_cert;
+ X509 *my_id_cert;
} tor_tls_context_t;
/** Holds a SSL object and its associated data. Members are only
@@ -64,6 +66,7 @@
unsigned long last_read_count;
};
+static void tor_tls_context_free(tor_tls_context_t *ctx);
static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
crypto_pk_env_t *rsa_sign,
const char *cname,
@@ -211,8 +214,7 @@
tor_tls_free_all(void)
{
if (global_tls_context) {
- SSL_CTX_free(global_tls_context->ctx);
- tor_free(global_tls_context);
+ tor_tls_context_free(global_tls_context);
global_tls_context = NULL;
}
}
@@ -341,6 +343,16 @@
#error "Tor requires OpenSSL version 0.9.7 or later, for AES support."
#endif
+/** DOCDOC */
+static void
+tor_tls_context_free(tor_tls_context_t *ctx)
+{
+ SSL_CTX_free(ctx->ctx);
+ X509_free(ctx->my_cert);
+ X509_free(ctx->my_id_cert);
+ tor_free(ctx);
+}
+
/** Create a new TLS context for use with Tor TLS handshakes.
* <b>identity</b> should be set to the identity key used to sign the
* certificate, and <b>nickname</b> set to the nickname to use.
@@ -382,6 +394,9 @@
}
result = tor_malloc_zero(sizeof(tor_tls_context_t));
+ result->my_cert = X509_dup(cert);
+ result->my_id_cert = X509_dup(idcert);
+
#ifdef EVERYONE_HAS_AES
/* Tell OpenSSL to only use TLS1 */
if (!(result->ctx = SSL_CTX_new(TLSv1_method())))
@@ -431,8 +446,7 @@
if (global_tls_context) {
/* This is safe even if there are open connections: OpenSSL does
* reference counting with SSL and SSL_CTX objects. */
- SSL_CTX_free(global_tls_context->ctx);
- tor_free(global_tls_context);
+ tor_tls_context_free(global_tls_context);
}
global_tls_context = result;
if (rsa)
@@ -679,6 +693,29 @@
return 1;
}
+/** DOCDOC */
+int
+tor_tls_get_cert_digests(tor_tls_t *tls,
+ char *my_digest_out,
+ char *peer_digest_out)
+{
+ X509 *cert;
+ unsigned int len;
+ cert = SSL_get_certificate(tls->ssl);
+ if (cert) {
+ X509_digest(cert, EVP_sha1(), (unsigned char*)my_digest_out, &len);
+ if (len != DIGEST_LEN)
+ return -1;
+ }
+ cert = SSL_get_peer_certificate(tls->ssl);
+ if (cert) {
+ X509_digest(cert, EVP_sha1(), (unsigned char*)peer_digest_out, &len);
+ if (len != DIGEST_LEN)
+ return -1;
+ }
+ return 0;
+}
+
/** Warn that a certificate lifetime extends through a certain range. */
static void
log_cert_lifetime(X509 *cert, const char *problem)
@@ -736,7 +773,7 @@
* 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_env_t **identity_key)
+tor_tls_verify_v1(int severity, tor_tls_t *tls, crypto_pk_env_t **identity_key)
{
X509 *cert = NULL, *id_cert = NULL;
STACK_OF(X509) *chain = NULL;
@@ -932,4 +969,3 @@
return 0;
}
-
Modified: tor/trunk/src/common/tortls.h
===================================================================
--- tor/trunk/src/common/tortls.h 2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/common/tortls.h 2007-11-05 18:15:50 UTC (rev 12382)
@@ -53,9 +53,10 @@
int tor_tls_is_server(tor_tls_t *tls);
void tor_tls_free(tor_tls_t *tls);
int tor_tls_peer_has_cert(tor_tls_t *tls);
-int tor_tls_get_peer_cert_nickname(int severity, tor_tls_t *tls,
- char *buf, size_t buflen);
-int tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_env_t **identity);
+int tor_tls_get_cert_digests(tor_tls_t *tls, char *my_digest_out,
+ char *peer_digest_out);
+int tor_tls_verify_v1(int severity, tor_tls_t *tls,
+ crypto_pk_env_t **identity);
int tor_tls_check_lifetime(tor_tls_t *tls, int tolerance);
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);
Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c 2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/or/connection_or.c 2007-11-05 18:15:50 UTC (rev 12382)
@@ -17,6 +17,8 @@
static int connection_tls_finish_handshake(or_connection_t *conn);
static int connection_or_process_cells_from_inbuf(or_connection_t *conn);
static int connection_or_send_versions(or_connection_t *conn);
+static int connection_init_or_handshake_state(or_connection_t *conn,
+ int started_here);
/**************************************************************/
@@ -629,8 +631,8 @@
check_no_tls_errors();
if (has_cert) {
- int v = tor_tls_verify(started_here?severity:LOG_INFO,
- conn->tls, &identity_rcvd);
+ int v = tor_tls_verify_v1(started_here?severity:LOG_INFO,
+ conn->tls, &identity_rcvd);
if (started_here && v<0) {
log_fn(severity,LD_OR,"Tried connecting to router at %s:%d: It"
" has a cert but it's invalid. Closing.",
@@ -725,10 +727,11 @@
int started_here = connection_or_nonopen_was_started_here(conn);
log_debug(LD_OR,"tls handshake done. verifying.");
+ /* V1 only XXXX020 */
if (connection_or_check_valid_handshake(conn, started_here, digest_rcvd) < 0)
return -1;
- if (!started_here) { /* V1 only XXX020 */
+ if (!started_here) { /* V1 only XXXX020 */
connection_or_init_conn_from_address(conn,conn->_base.addr,
conn->_base.port, digest_rcvd, 0);
}
@@ -740,16 +743,36 @@
return connection_or_set_state_open(conn);
} else {
conn->_base.state = OR_CONN_STATE_OR_HANDSHAKING;
- conn->handshake_state = tor_malloc_zero(sizeof(or_handshake_state_t));
- conn->handshake_state->started_here = started_here ? 1 : 0;
- if (tor_tls_get_random_values(conn->tls,
- conn->handshake_state->client_random,
- conn->handshake_state->server_random) < 0)
+ if (connection_init_or_handshake_state(conn, started_here) < 0)
return -1;
return connection_or_send_versions(conn);
}
}
+/** DOCDOC */
+static int
+connection_init_or_handshake_state(or_connection_t *conn, int started_here)
+{
+ or_handshake_state_t *s;
+ s = conn->handshake_state = tor_malloc_zero(sizeof(or_handshake_state_t));
+ s->started_here = started_here ? 1 : 0;
+ if (tor_tls_get_random_values(conn->tls,
+ conn->handshake_state->client_random,
+ conn->handshake_state->server_random) < 0)
+ return -1;
+ if (started_here) {
+ if (tor_tls_get_cert_digests(conn->tls,
+ s->client_cert_digest,
+ s->server_cert_digest)<0)
+ return -1;
+ } else {
+ if (tor_tls_get_cert_digests(conn->tls,
+ s->server_cert_digest,
+ s->client_cert_digest)<0)
+ return -1;
+ }
+ return 0;
+}
/** DOCDOC */
void
Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h 2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/or/or.h 2007-11-05 18:15:50 UTC (rev 12382)
@@ -868,8 +868,10 @@
unsigned int authenticated : 1;
/* from tls */
- char client_random[32];
- char server_random[32];
+ char client_random[TOR_TLS_RANDOM_LEN];
+ char server_random[TOR_TLS_RANDOM_LEN];
+ char client_cert_digest[DIGEST_LEN]; /* may also be set by netinfo */
+ char server_cert_digest[DIGEST_LEN];
/* from netinfo */
long apparent_skew;