Extract tortls structures into a new header; clean up a little

This commit is contained in:
Nick Mathewson 2018-08-11 19:38:07 -04:00
parent 9a4f05b05c
commit 598bc78bfa
7 changed files with 99 additions and 70 deletions

View file

@ -28,6 +28,7 @@
#include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_dh.h" #include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_util.h" #include "lib/crypt_ops/crypto_util.h"
#include "lib/crypt_ops/compat_openssl.h"
#include "lib/tls/x509.h" #include "lib/tls/x509.h"
/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in /* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
@ -51,8 +52,8 @@ DISABLE_GCC_WARNING(redundant-decls)
ENABLE_GCC_WARNING(redundant-decls) ENABLE_GCC_WARNING(redundant-decls)
#define TORTLS_PRIVATE
#include "lib/tls/tortls.h" #include "lib/tls/tortls.h"
#include "lib/tls/tortls_st.h"
#include "lib/log/log.h" #include "lib/log/log.h"
#include "lib/log/util_bug.h" #include "lib/log/util_bug.h"
#include "lib/container/smartlist.h" #include "lib/container/smartlist.h"
@ -599,7 +600,7 @@ tor_tls_cert_matches_key,(const tor_tls_t *tls, const tor_x509_cert_t *cert))
if (!peercert) if (!peercert)
return 0; return 0;
link_key = X509_get_pubkey(peercert); link_key = X509_get_pubkey(peercert);
cert_key = X509_get_pubkey(cert->cert); cert_key = X509_get_pubkey((X509 *)tor_x509_cert_get_impl(cert));
result = link_key && cert_key && EVP_PKEY_cmp(cert_key, link_key) == 1; result = link_key && cert_key && EVP_PKEY_cmp(cert_key, link_key) == 1;

View file

@ -12,7 +12,6 @@
**/ **/
#include "lib/crypt_ops/crypto_rsa.h" #include "lib/crypt_ops/crypto_rsa.h"
#include "lib/crypt_ops/compat_openssl.h"
#include "lib/testsupport/testsupport.h" #include "lib/testsupport/testsupport.h"
/* Opaque structure to hold a TLS connection. */ /* Opaque structure to hold a TLS connection. */
@ -52,14 +51,6 @@ struct tor_x509_cert_t;
#define TOR_TLS_IS_ERROR(rv) ((rv) < TOR_TLS_CLOSE) #define TOR_TLS_IS_ERROR(rv) ((rv) < TOR_TLS_CLOSE)
#ifdef TORTLS_PRIVATE #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)
#ifdef ENABLE_OPENSSL #ifdef ENABLE_OPENSSL
struct ssl_st; struct ssl_st;
@ -70,54 +61,7 @@ struct ssl_session_st;
/** Holds a SSL_CTX object and related state used to configure TLS /** Holds a SSL_CTX object and related state used to configure TLS
* connections. * connections.
*/ */
typedef struct tor_tls_context_t { typedef struct tor_tls_context_t tor_tls_context_t;
int refcnt;
struct ssl_ctx_st *ctx;
struct tor_x509_cert_t *my_link_cert;
struct tor_x509_cert_t *my_id_cert;
struct tor_x509_cert_t *my_auth_cert;
crypto_pk_t *link_key;
crypto_pk_t *auth_key;
} tor_tls_context_t;
/** 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. */
struct ssl_st *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_errno_to_tls_error(int e);
STATIC int tor_tls_get_error(tor_tls_t *tls, int r, int extra, STATIC int tor_tls_get_error(tor_tls_t *tls, int r, int extra,

67
src/lib/tls/tortls_st.h Normal file
View file

@ -0,0 +1,67 @@
/* Copyright (c) 2003, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_TORTLS_ST_H
#define TOR_TORTLS_ST_H
#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)
struct tor_tls_context_t {
int refcnt;
struct ssl_ctx_st *ctx;
struct tor_x509_cert_t *my_link_cert;
struct tor_x509_cert_t *my_id_cert;
struct tor_x509_cert_t *my_auth_cert;
crypto_pk_t *link_key;
crypto_pk_t *auth_key;
};
/** 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. */
struct ssl_st *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;
};
#endif

View file

@ -9,11 +9,12 @@
* X.509 functions from OpenSSL. * X.509 functions from OpenSSL.
**/ **/
#define TOR_X509_PRIVATE
#include "lib/tls/x509.h" #include "lib/tls/x509.h"
#include "lib/tls/tortls.h" #include "lib/tls/tortls.h"
//#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h" #include "lib/crypt_ops/crypto_util.h"
#include "lib/crypt_ops/compat_openssl.h"
/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in /* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
* srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */ * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
@ -332,6 +333,14 @@ tor_x509_cert_get_der(const tor_x509_cert_t *cert,
*size_out = cert->encoded_len; *size_out = cert->encoded_len;
} }
/** Return the underlying implementation for <b>cert</b> */
const tor_x509_cert_impl_t *
tor_x509_cert_get_impl(const tor_x509_cert_t *cert)
{
tor_assert(cert);
return cert->cert;
}
/** Return a set of digests for the public key in <b>cert</b>, or NULL if this /** Return a set of digests for the public key in <b>cert</b>, or NULL if this
* cert's public key is not one we know how to take the digest of. */ * cert's public key is not one we know how to take the digest of. */
const common_digests_t * const common_digests_t *

View file

@ -12,36 +12,35 @@
**/ **/
#include "lib/crypt_ops/crypto_rsa.h" #include "lib/crypt_ops/crypto_rsa.h"
#include "lib/crypt_ops/compat_openssl.h"
#include "lib/testsupport/testsupport.h" #include "lib/testsupport/testsupport.h"
/* Opaque structure to hold an X509 certificate. */ /* Opaque structure to hold an X509 certificate. */
typedef struct tor_x509_cert_t tor_x509_cert_t; typedef struct tor_x509_cert_t tor_x509_cert_t;
#ifdef ENABLE_OPENSSL #ifdef ENABLE_OPENSSL
struct x509_st; typedef struct x509_st tor_x509_cert_impl_t;
#endif #endif
#ifdef TOR_X509_PRIVATE
/** Structure that we use for a single certificate. */ /** Structure that we use for a single certificate. */
struct tor_x509_cert_t { struct tor_x509_cert_t {
#ifdef ENABLE_OPENSSL tor_x509_cert_impl_t *cert;
struct x509_st *cert;
#endif
uint8_t *encoded; uint8_t *encoded;
size_t encoded_len; size_t encoded_len;
unsigned pkey_digests_set : 1; unsigned pkey_digests_set : 1;
common_digests_t cert_digests; common_digests_t cert_digests;
common_digests_t pkey_digests; common_digests_t pkey_digests;
}; };
#endif
MOCK_DECL(struct x509_st *, tor_tls_create_certificate, MOCK_DECL(tor_x509_cert_impl_t *, tor_tls_create_certificate,
(crypto_pk_t *rsa, (crypto_pk_t *rsa,
crypto_pk_t *rsa_sign, crypto_pk_t *rsa_sign,
const char *cname, const char *cname,
const char *cname_sign, const char *cname_sign,
unsigned int cert_lifetime)); unsigned int cert_lifetime));
MOCK_DECL(tor_x509_cert_t *, tor_x509_cert_new, MOCK_DECL(tor_x509_cert_t *, tor_x509_cert_new,
(struct x509_st *x509_cert)); (tor_x509_cert_impl_t *x509_cert));
#ifdef TOR_UNIT_TESTS #ifdef TOR_UNIT_TESTS
tor_x509_cert_t *tor_x509_cert_replace_expiration( tor_x509_cert_t *tor_x509_cert_replace_expiration(
@ -57,21 +56,26 @@ void tor_x509_cert_free_(tor_x509_cert_t *cert);
FREE_AND_NULL(tor_x509_cert_t, tor_x509_cert_free_, (c)) FREE_AND_NULL(tor_x509_cert_t, tor_x509_cert_free_, (c))
tor_x509_cert_t *tor_x509_cert_decode(const uint8_t *certificate, tor_x509_cert_t *tor_x509_cert_decode(const uint8_t *certificate,
size_t certificate_len); size_t certificate_len);
const tor_x509_cert_impl_t *tor_x509_cert_get_impl(
const tor_x509_cert_t *cert);
void tor_x509_cert_get_der(const tor_x509_cert_t *cert, void tor_x509_cert_get_der(const tor_x509_cert_t *cert,
const uint8_t **encoded_out, size_t *size_out); const uint8_t **encoded_out, size_t *size_out);
const common_digests_t *tor_x509_cert_get_id_digests( const common_digests_t *tor_x509_cert_get_id_digests(
const tor_x509_cert_t *cert); const tor_x509_cert_t *cert);
const common_digests_t *tor_x509_cert_get_cert_digests( const common_digests_t *tor_x509_cert_get_cert_digests(
const tor_x509_cert_t *cert); const tor_x509_cert_t *cert);
crypto_pk_t *tor_tls_cert_get_key(tor_x509_cert_t *cert); crypto_pk_t *tor_tls_cert_get_key(tor_x509_cert_t *cert);
int tor_tls_cert_is_valid(int severity, int tor_tls_cert_is_valid(int severity,
const tor_x509_cert_t *cert, const tor_x509_cert_t *cert,
const tor_x509_cert_t *signing_cert, const tor_x509_cert_t *signing_cert,
time_t now, time_t now,
int check_rsa_1024); int check_rsa_1024);
int check_cert_lifetime_internal(int severity, const X509 *cert, int check_cert_lifetime_internal(int severity,
const tor_x509_cert_impl_t *cert,
time_t now, time_t now,
int past_tolerance, int future_tolerance); int past_tolerance, int future_tolerance);

View file

@ -24,6 +24,7 @@
#include "core/or/or_handshake_state_st.h" #include "core/or/or_handshake_state_st.h"
#include "core/or/var_cell_st.h" #include "core/or/var_cell_st.h"
#define TOR_X509_PRIVATE
#include "lib/tls/tortls.h" #include "lib/tls/tortls.h"
#include "lib/tls/x509.h" #include "lib/tls/x509.h"

View file

@ -3,6 +3,7 @@
#define TORTLS_PRIVATE #define TORTLS_PRIVATE
#define TORTLS_OPENSSL_PRIVATE #define TORTLS_OPENSSL_PRIVATE
#define TOR_X509_PRIVATE
#define LOG_PRIVATE #define LOG_PRIVATE
#include "orconfig.h" #include "orconfig.h"
@ -33,7 +34,9 @@ ENABLE_GCC_WARNING(redundant-decls)
#include "core/or/or.h" #include "core/or/or.h"
#include "lib/log/log.h" #include "lib/log/log.h"
#include "app/config/config.h" #include "app/config/config.h"
#include "lib/crypt_ops/compat_openssl.h"
#include "lib/tls/tortls.h" #include "lib/tls/tortls.h"
#include "lib/tls/tortls_st.h"
#include "lib/tls/x509.h" #include "lib/tls/x509.h"
#include "app/config/or_state_st.h" #include "app/config/or_state_st.h"