diff options
Diffstat (limited to 'src/common/tortls.h')
-rw-r--r-- | src/common/tortls.h | 125 |
1 files changed, 120 insertions, 5 deletions
diff --git a/src/common/tortls.h b/src/common/tortls.h index 124b77160f..1a59c67df3 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2015, The Tor Project, Inc. */ + * Copyright (c) 2007-2016, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TORTLS_H @@ -12,6 +12,7 @@ **/ #include "crypto.h" +#include "compat_openssl.h" #include "compat.h" #include "testsupport.h" @@ -51,6 +52,120 @@ typedef struct tor_x509_cert_t tor_x509_cert_t; case TOR_TLS_ERROR_IO #define TOR_TLS_IS_ERROR(rv) ((rv) < TOR_TLS_CLOSE) + +#ifdef TORTLS_PRIVATE +#define TOR_TLS_MAGIC 0x71571571 + +typedef enum { + TOR_TLS_ST_HANDSHAKE, TOR_TLS_ST_OPEN, TOR_TLS_ST_GOTCLOSE, + TOR_TLS_ST_SENTCLOSE, TOR_TLS_ST_CLOSED, TOR_TLS_ST_RENEGOTIATE, + TOR_TLS_ST_BUFFEREVENT +} tor_tls_state_t; +#define tor_tls_state_bitfield_t ENUM_BF(tor_tls_state_t) + +/** Holds a SSL_CTX object and related state used to configure TLS + * connections. + */ +typedef struct tor_tls_context_t { + int refcnt; + SSL_CTX *ctx; + tor_x509_cert_t *my_link_cert; + tor_x509_cert_t *my_id_cert; + tor_x509_cert_t *my_auth_cert; + crypto_pk_t *link_key; + crypto_pk_t *auth_key; +} tor_tls_context_t; + +/** Structure that we use for a single certificate. */ +struct tor_x509_cert_t { + X509 *cert; + uint8_t *encoded; + size_t encoded_len; + unsigned pkey_digests_set : 1; + common_digests_t cert_digests; + common_digests_t pkey_digests; +}; + +/** Holds a SSL object and its associated data. Members are only + * accessed from within tortls.c. + */ +struct tor_tls_t { + uint32_t magic; + tor_tls_context_t *context; /** A link to the context object for this tls. */ + SSL *ssl; /**< An OpenSSL SSL object. */ + int socket; /**< The underlying file descriptor for this TLS connection. */ + char *address; /**< An address to log when describing this connection. */ + tor_tls_state_bitfield_t state : 3; /**< The current SSL state, + * depending on which operations + * have completed successfully. */ + unsigned int isServer:1; /**< True iff this is a server-side connection */ + unsigned int wasV2Handshake:1; /**< True iff the original handshake for + * this connection used the updated version + * of the connection protocol (client sends + * different cipher list, server sends only + * one certificate). */ + /** True iff we should call negotiated_callback when we're done reading. */ + unsigned int got_renegotiate:1; + /** Return value from tor_tls_classify_client_ciphers, or 0 if we haven't + * called that function yet. */ + int8_t client_cipher_list_type; + /** Incremented every time we start the server side of a handshake. */ + uint8_t server_handshake_count; + size_t wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last + * time. */ + /** Last values retrieved from BIO_number_read()/write(); see + * tor_tls_get_n_raw_bytes() for usage. + */ + unsigned long last_write_count; + unsigned long last_read_count; + /** If set, a callback to invoke whenever the client tries to renegotiate + * the handshake. */ + void (*negotiated_callback)(tor_tls_t *tls, void *arg); + /** Argument to pass to negotiated_callback. */ + void *callback_arg; +}; + +STATIC int tor_errno_to_tls_error(int e); +STATIC int tor_tls_get_error(tor_tls_t *tls, int r, int extra, + const char *doing, int severity, int domain); +STATIC tor_tls_t *tor_tls_get_by_ssl(const SSL *ssl); +STATIC void tor_tls_allocate_tor_tls_object_ex_data_index(void); +STATIC int always_accept_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx); +STATIC int tor_tls_classify_client_ciphers(const SSL *ssl, + STACK_OF(SSL_CIPHER) *peer_ciphers); +STATIC int tor_tls_client_is_using_v2_ciphers(const SSL *ssl); +MOCK_DECL(STATIC void, try_to_extract_certs_from_tls, + (int severity, tor_tls_t *tls, X509 **cert_out, X509 **id_cert_out)); +#ifndef HAVE_SSL_SESSION_GET_MASTER_KEY +STATIC size_t SSL_SESSION_get_master_key(SSL_SESSION *s, uint8_t *out, + size_t len); +#endif +STATIC void tor_tls_debug_state_callback(const SSL *ssl, int type, int val); +STATIC void tor_tls_server_info_callback(const SSL *ssl, int type, int val); +STATIC int tor_tls_session_secret_cb(SSL *ssl, void *secret, + int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + CONST_IF_OPENSSL_1_1_API SSL_CIPHER **cipher, + void *arg); +STATIC int find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, + uint16_t cipher); +MOCK_DECL(STATIC X509*, tor_tls_create_certificate,(crypto_pk_t *rsa, + crypto_pk_t *rsa_sign, + const char *cname, + const char *cname_sign, + unsigned int cert_lifetime)); +STATIC tor_tls_context_t *tor_tls_context_new(crypto_pk_t *identity, + unsigned int key_lifetime, unsigned flags, int is_client); +MOCK_DECL(STATIC tor_x509_cert_t *, tor_x509_cert_new,(X509 *x509_cert)); +STATIC int tor_tls_context_init_one(tor_tls_context_t **ppcontext, + crypto_pk_t *identity, + unsigned int key_lifetime, + unsigned int flags, + int is_client); +STATIC void tls_log_errors(tor_tls_t *tls, int severity, int domain, + const char *doing); +#endif + const char *tor_tls_err_to_string(int err); void tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz); @@ -81,7 +196,6 @@ MOCK_DECL(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); int tor_tls_handshake(tor_tls_t *tls); int tor_tls_finish_handshake(tor_tls_t *tls); -int tor_tls_renegotiate(tor_tls_t *tls); void tor_tls_unblock_renegotiation(tor_tls_t *tls); void tor_tls_block_renegotiation(tor_tls_t *tls); void tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls); @@ -99,7 +213,6 @@ int tor_tls_get_buffer_sizes(tor_tls_t *tls, MOCK_DECL(double, tls_get_write_overhead_ratio, (void)); int tor_tls_used_v1_handshake(tor_tls_t *tls); -int tor_tls_received_v3_certificate(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)); @@ -125,8 +238,10 @@ tor_x509_cert_t *tor_x509_cert_decode(const uint8_t *certificate, size_t certificate_len); void tor_x509_cert_get_der(const tor_x509_cert_t *cert, const uint8_t **encoded_out, size_t *size_out); -const digests_t *tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert); -const digests_t *tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert); +const common_digests_t *tor_x509_cert_get_id_digests( + const tor_x509_cert_t *cert); +const common_digests_t *tor_x509_cert_get_cert_digests( + const tor_x509_cert_t *cert); int tor_tls_get_my_certs(int server, const tor_x509_cert_t **link_cert_out, const tor_x509_cert_t **id_cert_out); |