mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-23 22:47:12 +01:00
and now the exciting part: there is now no such thing as doing
a client-only tls, that is, one with no certs. svn:r6558
This commit is contained in:
parent
0bfef523df
commit
8cf45df230
3 changed files with 38 additions and 60 deletions
|
@ -40,7 +40,6 @@ const char tortls_c_id[] =
|
|||
/* DOCDOC */
|
||||
typedef struct tor_tls_context_t {
|
||||
SSL_CTX *ctx;
|
||||
SSL_CTX *client_only_ctx;
|
||||
} tor_tls_context_t;
|
||||
|
||||
/** Holds a SSL object and its associated data. Members are only
|
||||
|
@ -170,7 +169,6 @@ tor_tls_free_all(void)
|
|||
{
|
||||
if (global_tls_context) {
|
||||
SSL_CTX_free(global_tls_context->ctx);
|
||||
SSL_CTX_free(global_tls_context->client_only_ctx);
|
||||
tor_free(global_tls_context);
|
||||
global_tls_context = NULL;
|
||||
}
|
||||
|
@ -305,10 +303,6 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa,
|
|||
* <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.
|
||||
*
|
||||
* XXX to be removed next:
|
||||
* If we're only going to be a client, identity should be NULL, and nickname
|
||||
* should be NULL. Return -1 if failure, else 0.
|
||||
*
|
||||
* You can call this function multiple times. Each time you call it,
|
||||
* it generates new certificates; all new connections will use
|
||||
* the new SSL context.
|
||||
|
@ -323,8 +317,6 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname,
|
|||
tor_tls_context_t *result = NULL;
|
||||
X509 *cert = NULL, *idcert = NULL;
|
||||
char nn2[128];
|
||||
int client_only;
|
||||
SSL_CTX **ctx;
|
||||
if (!nickname)
|
||||
nickname = "null";
|
||||
tor_snprintf(nn2, sizeof(nn2), "%s <identity>", nickname);
|
||||
|
@ -348,57 +340,48 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname,
|
|||
}
|
||||
|
||||
result = tor_malloc(sizeof(tor_tls_context_t));
|
||||
result->ctx = result->client_only_ctx = NULL;
|
||||
for (client_only=0; client_only <= 1; ++client_only) {
|
||||
ctx = client_only ? &result->client_only_ctx : &result->ctx;
|
||||
#ifdef EVERYONE_HAS_AES
|
||||
/* Tell OpenSSL to only use TLS1 */
|
||||
if (!(*ctx = SSL_CTX_new(TLSv1_method())))
|
||||
goto error;
|
||||
/* Tell OpenSSL to only use TLS1 */
|
||||
if (!(result->ctx = SSL_CTX_new(TLSv1_method())))
|
||||
goto error;
|
||||
#else
|
||||
/* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */
|
||||
if (!(*ctx = SSL_CTX_new(SSLv23_method())))
|
||||
goto error;
|
||||
SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2);
|
||||
/* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */
|
||||
if (!(result->ctx = SSL_CTX_new(SSLv23_method())))
|
||||
goto error;
|
||||
SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2);
|
||||
#endif
|
||||
SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_DH_USE);
|
||||
if (!SSL_CTX_set_cipher_list(*ctx, CIPHER_LIST))
|
||||
goto error;
|
||||
if (!client_only) {
|
||||
if (cert && !SSL_CTX_use_certificate(*ctx,cert))
|
||||
goto error;
|
||||
X509_free(cert); /* We just added a reference to cert. */
|
||||
cert=NULL;
|
||||
if (idcert && !SSL_CTX_add_extra_chain_cert(*ctx,idcert))
|
||||
goto error;
|
||||
idcert=NULL; /* The context now owns the reference to idcert */
|
||||
}
|
||||
SSL_CTX_set_session_cache_mode(*ctx, SSL_SESS_CACHE_OFF);
|
||||
if (!client_only) {
|
||||
tor_assert(rsa);
|
||||
if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
|
||||
goto error;
|
||||
if (!SSL_CTX_use_PrivateKey(*ctx, pkey))
|
||||
goto error;
|
||||
EVP_PKEY_free(pkey);
|
||||
pkey = NULL;
|
||||
if (!SSL_CTX_check_private_key(*ctx))
|
||||
goto error;
|
||||
}
|
||||
dh = crypto_dh_new();
|
||||
SSL_CTX_set_tmp_dh(*ctx, _crypto_dh_env_get_dh(dh));
|
||||
crypto_dh_free(dh);
|
||||
SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER,
|
||||
always_accept_verify_cb);
|
||||
/* let us realloc bufs that we're writing from */
|
||||
SSL_CTX_set_mode(*ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
}
|
||||
SSL_CTX_set_options(result->ctx, SSL_OP_SINGLE_DH_USE);
|
||||
if (!SSL_CTX_set_cipher_list(result->ctx, CIPHER_LIST))
|
||||
goto error;
|
||||
if (cert && !SSL_CTX_use_certificate(result->ctx,cert))
|
||||
goto error;
|
||||
X509_free(cert); /* We just added a reference to cert. */
|
||||
cert=NULL;
|
||||
if (idcert && !SSL_CTX_add_extra_chain_cert(result->ctx,idcert))
|
||||
goto error;
|
||||
idcert=NULL; /* The context now owns the reference to idcert */
|
||||
SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
|
||||
tor_assert(rsa);
|
||||
if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
|
||||
goto error;
|
||||
if (!SSL_CTX_use_PrivateKey(result->ctx, pkey))
|
||||
goto error;
|
||||
EVP_PKEY_free(pkey);
|
||||
pkey = NULL;
|
||||
if (!SSL_CTX_check_private_key(result->ctx))
|
||||
goto error;
|
||||
dh = crypto_dh_new();
|
||||
SSL_CTX_set_tmp_dh(result->ctx, _crypto_dh_env_get_dh(dh));
|
||||
crypto_dh_free(dh);
|
||||
SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER,
|
||||
always_accept_verify_cb);
|
||||
/* let us realloc bufs that we're writing from */
|
||||
SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
/* Free the old context if one exists. */
|
||||
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);
|
||||
SSL_CTX_free(global_tls_context->client_only_ctx);
|
||||
tor_free(global_tls_context);
|
||||
}
|
||||
global_tls_context = result;
|
||||
|
@ -416,8 +399,6 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname,
|
|||
crypto_dh_free(dh);
|
||||
if (result && result->ctx)
|
||||
SSL_CTX_free(result->ctx);
|
||||
if (result && result->client_only_ctx)
|
||||
SSL_CTX_free(result->client_only_ctx);
|
||||
if (result)
|
||||
tor_free(result);
|
||||
if (cert)
|
||||
|
@ -431,14 +412,11 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname,
|
|||
* determine whether it is functioning as a server.
|
||||
*/
|
||||
tor_tls_t *
|
||||
tor_tls_new(int sock, int isServer, int use_no_cert)
|
||||
tor_tls_new(int sock, int isServer)
|
||||
{
|
||||
tor_tls_t *result = tor_malloc(sizeof(tor_tls_t));
|
||||
SSL_CTX *ctx;
|
||||
tor_assert(global_tls_context); /* make sure somebody made it first */
|
||||
ctx = use_no_cert ? global_tls_context->client_only_ctx
|
||||
: global_tls_context->ctx;
|
||||
if (!(result->ssl = SSL_new(ctx))) {
|
||||
if (!(result->ssl = SSL_new(global_tls_context->ctx))) {
|
||||
tls_log_errors(LOG_WARN, "generating TLS context");
|
||||
tor_free(result);
|
||||
return NULL;
|
||||
|
|
|
@ -28,7 +28,7 @@ typedef struct tor_tls_t tor_tls_t;
|
|||
void tor_tls_free_all(void);
|
||||
int tor_tls_context_new(crypto_pk_env_t *rsa,
|
||||
const char *nickname, unsigned int key_lifetime);
|
||||
tor_tls_t *tor_tls_new(int sock, int is_server, int use_no_cert);
|
||||
tor_tls_t *tor_tls_new(int sock, int is_server);
|
||||
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);
|
||||
|
|
|
@ -492,7 +492,7 @@ int
|
|||
connection_tls_start_handshake(connection_t *conn, int receiving)
|
||||
{
|
||||
conn->state = OR_CONN_STATE_HANDSHAKING;
|
||||
conn->tls = tor_tls_new(conn->s, receiving, 0);
|
||||
conn->tls = tor_tls_new(conn->s, receiving);
|
||||
if (!conn->tls) {
|
||||
log_warn(LD_BUG,"tor_tls_new failed. Closing.");
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Reference in a new issue