#define FR_TLS_H
#ifdef WITH_TLS
-/*
+/**
* $Id$
*
* @file tls.h
typedef struct fr_tls_server_conf_t fr_tls_server_conf_t;
typedef enum {
- FR_TLS_INVALID = 0, /* invalid, don't reply */
- FR_TLS_REQUEST, /* request, ok to send, invalid to receive */
- FR_TLS_RESPONSE, /* response, ok to receive, invalid to send */
- FR_TLS_SUCCESS, /* success, send success */
- FR_TLS_FAIL, /* fail, send fail */
- FR_TLS_NOOP, /* noop, continue */
-
- FR_TLS_START, /* start, ok to send, invalid to receive */
- FR_TLS_OK, /* ok, continue */
- FR_TLS_ACK, /* acknowledge, continue */
- FR_TLS_FIRST_FRAGMENT, /* first fragment */
- FR_TLS_MORE_FRAGMENTS, /* more fragments, to send/receive */
- FR_TLS_LENGTH_INCLUDED, /* length included */
- FR_TLS_MORE_FRAGMENTS_WITH_LENGTH, /* more fragments with length */
- FR_TLS_HANDLED /* tls code has handled it */
+ FR_TLS_INVALID = 0, //!< Invalid, don't reply.
+ FR_TLS_REQUEST, //!< Request, ok to send, invalid to receive.
+ FR_TLS_RESPONSE, //!< Response, ok to receive, invalid to send.
+ FR_TLS_SUCCESS, //!< Success, send success.
+ FR_TLS_FAIL, //!< Fail, send fail.
+ FR_TLS_NOOP, //!< Noop, continue.
+
+ FR_TLS_START, //!< Start, ok to send, invalid to receive.
+ FR_TLS_OK, //!< Ok, continue.
+ FR_TLS_ACK, //!< Acknowledge, continue.
+ FR_TLS_FIRST_FRAGMENT, //!< First fragment.
+ FR_TLS_MORE_FRAGMENTS, //!< More fragments, to send/receive.
+ FR_TLS_LENGTH_INCLUDED, //!< Length included.
+ FR_TLS_MORE_FRAGMENTS_WITH_LENGTH, //!< More fragments with length.
+ FR_TLS_HANDLED //!< TLS code has handled it.
} fr_tls_status_t;
+extern FR_NAME_NUMBER const fr_tls_status_table[];
#define MAX_RECORD_SIZE 16384
* or configure TLS not to exceed MAX_RECORD_SIZE.
*/
typedef struct _record_t {
- unsigned char data[MAX_RECORD_SIZE];
- unsigned int used;
+ uint8_t data[MAX_RECORD_SIZE];
+ size_t used;
} record_t;
typedef struct _tls_info_t {
- unsigned char origin;
- unsigned char content_type;
- unsigned char handshake_type;
- unsigned char alert_level;
- unsigned char alert_description;
+ int origin;
+ int content_type;
+ uint8_t handshake_type;
+ uint8_t alert_level;
+ uint8_t alert_description;
+ bool initialized;
+
char info_description[256];
size_t record_len;
int version;
- char initialized;
} tls_info_t;
-/*
- * tls_session_t Structure gets stored as opaque in eap_handler_t
- * This contains EAP-REQUEST specific data
- * (ie FR_TLS_DATA(fragment), EAPTLS-ALERT, EAPTLS-REQUEST ...)
+#if OPENSSL_VERSION_NUMBER < 0x10001000L
+#define ssl_session ssl->session
+#else
+#define ssl_session session
+#endif
+
+/** Contains EAP-REQUEST specific data (ie FR_TLS_DATA(fragment), EAPTLS-ALERT, EAPTLS-REQUEST ...)
*
- * clean_in - data that needs to be sent but only after it is soiled.
- * dirty_in - data EAP server receives.
- * clean_out - data that is cleaned after receiving.
- * dirty_out - data EAP server sends.
- * offset - current fragment size transmitted
- * fragment - Flag, In fragment mode or not.
- * tls_msg_len - Actual/Total TLS message length.
- * length_flag - A flag to include length in every TLS Data/Alert packet
- * if set to no then only the first fragment contains length
+ * The tls_session_t Structure gets stored as opaque in eap_handler_t
*/
typedef struct _tls_session_t {
SSL_CTX *ctx;
SSL *ssl;
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L
+ SSL_SESSION *session;
+#endif
tls_info_t info;
BIO *into_ssl;
BIO *from_ssl;
- record_t clean_in;
- record_t clean_out;
- record_t dirty_in;
- record_t dirty_out;
+ record_t clean_in; //!< Data that needs to be sent but only after it is soiled.
+ record_t clean_out; //!< Data that is cleaned after receiving.
+ record_t dirty_in; //!< Data EAP server receives.
+ record_t dirty_out; //!< Data EAP server sends.
void (*record_init)(record_t *buf);
void (*record_close)(record_t *buf);
- unsigned int (*record_plus)(record_t *buf, void const *ptr,
- unsigned int size);
- unsigned int (*record_minus)(record_t *buf, void *ptr,
- unsigned int size);
+ unsigned int (*record_plus)(record_t *buf, void const *ptr, unsigned int size);
+ unsigned int (*record_minus)(record_t *buf, void *ptr, unsigned int size);
- bool invalid_hb_used;
+ bool invalid_hb_used; //!< Whether heartbleed attack was detected.
+ bool connected; //!< whether the outgoing socket is connected
/*
- * Framed-MTU attribute in RADIUS,
- * if present, can also be used to set this
+ * Framed-MTU attribute in RADIUS, if present, can also be used to set this
*/
- unsigned int offset;
- unsigned int tls_msg_len;
- int fragment;
- int length_flag;
+ size_t mtu; //!< Current fragment size transmitted.
+ size_t tls_msg_len; //!< Actual/Total TLS message length.
+ bool fragment; //!< Flag, In fragment mode or not.
+ bool length_flag; //!< A flag to include length in every TLS Data/Alert packet.
+ //!< If set to no then only the first fragment contains length.
int peap_flag;
+ size_t tls_record_in_total_len; //!< How long the peer indicated the complete tls record
+ //!< would be.
+ size_t tls_record_in_recvd_len; //!< How much of the record we've received so far.
+
/*
- * Used by TTLS & PEAP to keep track of other per-session
- * data.
+ * Used by TTLS & PEAP to keep track of other per-session data.
*/
void *opaque;
void (*free_opaque)(void *opaque);
char const *prf_label;
- int allow_session_resumption;
+ bool allow_session_resumption; //!< Whether session resumption is allowed.
} tls_session_t;
-
/*
* RFC 2716, Section 4.2:
*
server_hello_done = 14,
certificate_verify = 15,
client_key_exchange = 16,
- finished = 20
+ handshake_finished = 20
};
int cbtls_verify(int ok, X509_STORE_CTX *ctx);
/* TLS */
-int tls_global_init(char const *acknowledged);
-tls_session_t *tls_new_session(fr_tls_server_conf_t *conf, REQUEST *request,
- int client_cert);
-tls_session_t *tls_new_client_session(fr_tls_server_conf_t *conf, int fd);
+void tls_global_init(void);
+#ifdef ENABLE_OPENSSL_VERSION_CHECK
+int tls_global_version_check(char const *acknowledged);
+#endif
+
+int tls_error_log(REQUEST *request, char const *msg, ...) CC_HINT(format (printf, 2, 3));
+int tls_error_io_log(REQUEST *request, tls_session_t *session, int ret, char const *msg, ...)
+ CC_HINT(format (printf, 4, 5));
+
+void tls_global_cleanup(void);
+tls_session_t *tls_new_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *conf, REQUEST *request, bool client_cert);
+tls_session_t *tls_new_client_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *conf, int fd);
fr_tls_server_conf_t *tls_server_conf_parse(CONF_SECTION *cs);
fr_tls_server_conf_t *tls_client_conf_parse(CONF_SECTION *cs);
+fr_tls_server_conf_t *tls_server_conf_alloc(TALLOC_CTX *ctx);
+SSL_CTX *tls_init_ctx(fr_tls_server_conf_t *conf, int client);
int tls_handshake_recv(REQUEST *, tls_session_t *ssn);
int tls_handshake_send(REQUEST *, tls_session_t *ssn);
void tls_session_information(tls_session_t *ssn);
+void tls_session_id(SSL_SESSION *ssn, char *buffer, size_t bufsize);
/*
* Low-level TLS stuff
fr_tls_status_t tls_ack_handler(tls_session_t *tls_session, REQUEST *request);
fr_tls_status_t tls_application_data(tls_session_t *ssn, REQUEST *request);
-/* Session */
-void session_free(void *ssn);
-void session_close(tls_session_t *ssn);
-void session_init(tls_session_t *ssn);
-
#define FR_TLS_EX_INDEX_HANDLER (10)
#define FR_TLS_EX_INDEX_CONF (11)
#define FR_TLS_EX_INDEX_REQUEST (12)
#define FR_TLS_EX_INDEX_SSN (15)
#define FR_TLS_EX_INDEX_TALLOC (16)
-extern int FR_TLS_EX_INDEX_CERTS;
+extern int fr_tls_ex_index_certs;
+extern int fr_tls_ex_index_vps;
/* configured values goes right here */
struct fr_tls_server_conf_t {
SSL_CTX *ctx;
CONF_SECTION *cs;
- char *private_key_password;
- char *private_key_file;
- char *certificate_file;
- char *random_file;
- char *ca_path;
- char *ca_file;
- char *dh_file;
- char *rsa_file;
- bool rsa_key;
- bool dh_key;
- int rsa_key_length;
- int dh_key_length;
- int verify_depth;
+ char const *private_key_password;
+ char const *private_key_file;
+ char const *certificate_file;
+ char const *random_file;
+ char const *ca_path;
+ char const *ca_file;
+ char const *dh_file;
+ char const *rsa_file;
+ uint32_t verify_depth;
bool file_type;
bool include_length;
+ bool auto_chain;
+ bool disable_single_dh_use;
+ bool disable_tlsv1;
+ bool disable_tlsv1_1;
+ bool disable_tlsv1_2;
/*
- * Always < 4096 (due to radius limit), 0 by default = 2048
+ * Always < 4096 (due to radius limit), 0 by default = 1024
*/
- int fragment_size;
+ uint32_t fragment_size;
bool check_crl;
+ bool check_all_crl;
bool allow_expired_crl;
- char *check_cert_cn;
- char *cipher_list;
- char *check_cert_issuer;
+ char const *check_cert_cn;
+ char const *cipher_list;
+ bool cipher_server_preference;
+ char const *check_cert_issuer;
bool session_cache_enable;
- int session_timeout;
- int session_cache_size;
- char *session_id_name;
- char *session_cache_path;
+ uint32_t session_timeout;
+ uint32_t session_cache_size;
+ char const *session_id_name;
+ char const *session_cache_path;
char session_context_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
time_t session_last_flushed;
- char *verify_tmp_dir;
- char *verify_client_cert_cmd;
+ bool verify_skip_if_ocsp_ok;
+ char const *verify_tmp_dir;
+ char const *verify_client_cert_cmd;
bool require_client_cert;
#ifdef HAVE_OPENSSL_OCSP_H
*/
bool ocsp_enable;
bool ocsp_override_url;
- char *ocsp_url;
+ char const *ocsp_url;
bool ocsp_use_nonce;
X509_STORE *ocsp_store;
- int ocsp_timeout;
+ uint32_t ocsp_timeout;
bool ocsp_softfail;
#endif
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
- char *ecdh_curve;
+ char const *ecdh_curve;
#endif
#endif
#ifdef PSK_MAX_IDENTITY_LEN
- char *psk_identity;
- char *psk_password;
+ char const *psk_identity;
+ char const *psk_password;
+ char const *psk_query;
#endif
};