diff options
author | Adriaan de Jong <dejong@fox-it.com> | 2011-06-30 09:33:41 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2011-10-21 10:53:31 +0200 |
commit | 67d8a0d4e9bcca4299158c80f184c7dea57a9eab (patch) | |
tree | 3bc4ce8d9c75c0145b9faef339fc83859a31e456 | |
parent | 2e74a9d02da9ac071438e24de8561ccf9192e94a (diff) | |
download | openvpn-67d8a0d4e9bcca4299158c80f184c7dea57a9eab.tar.gz openvpn-67d8a0d4e9bcca4299158c80f184c7dea57a9eab.tar.xz openvpn-67d8a0d4e9bcca4299158c80f184c7dea57a9eab.zip |
Refactored tls_options, key_state, and key_source data structures
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | init.c | 2 | ||||
-rw-r--r-- | ssl.c | 50 | ||||
-rw-r--r-- | ssl.h | 211 | ||||
-rw-r--r-- | ssl_common.h | 201 | ||||
-rw-r--r-- | ssl_openssl.h | 7 |
5 files changed, 234 insertions, 237 deletions
@@ -2174,7 +2174,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) if (packet_id_long_form) to.crypto_flags_or = CO_PACKET_ID_LONG_FORM; - to.ssl_ctx = c->c1.ks.ssl_ctx.ctx; + to.ssl_ctx = c->c1.ks.ssl_ctx; to.key_type = c->c1.ks.key_type; to.server = options->tls_server; to.key_method = options->key_method; @@ -2042,7 +2042,7 @@ key_state_write_plaintext (struct tls_multi *multi, struct key_state *ks, struct { int ret; perf_push (PERF_BIO_WRITE_PLAINTEXT); - ret = bio_write (multi, ks->ssl_bio, BPTR(buf), BLEN(buf), "tls_write_plaintext"); + ret = bio_write (multi, ks->ks_ssl.ssl_bio, BPTR(buf), BLEN(buf), "tls_write_plaintext"); bio_write_post (ret, buf); perf_pop (); return ret; @@ -2069,7 +2069,7 @@ key_state_write_plaintext_const (struct tls_multi *multi, struct key_state *ks, { int ret; perf_push (PERF_BIO_WRITE_PLAINTEXT); - ret = bio_write (multi, ks->ssl_bio, data, len, "tls_write_plaintext_const"); + ret = bio_write (multi, ks->ks_ssl.ssl_bio, data, len, "tls_write_plaintext_const"); perf_pop (); return ret; } @@ -2099,7 +2099,7 @@ key_state_read_ciphertext (struct tls_multi *multi, struct key_state *ks, struct { int ret; perf_push (PERF_BIO_READ_CIPHERTEXT); - ret = bio_read (multi, ks->ct_out, buf, maxlen, "tls_read_ciphertext"); + ret = bio_read (multi, ks->ks_ssl.ct_out, buf, maxlen, "tls_read_ciphertext"); perf_pop (); return ret; } @@ -2133,7 +2133,7 @@ key_state_write_ciphertext (struct tls_multi *multi, struct key_state *ks, struc { int ret; perf_push (PERF_BIO_WRITE_CIPHERTEXT); - ret = bio_write (multi, ks->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext"); + ret = bio_write (multi, ks->ks_ssl.ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext"); bio_write_post (ret, buf); perf_pop (); return ret; @@ -2164,7 +2164,7 @@ key_state_read_plaintext (struct tls_multi *multi, struct key_state *ks, struct { int ret; perf_push (PERF_BIO_READ_PLAINTEXT); - ret = bio_read (multi, ks->ssl_bio, buf, maxlen, "tls_read_plaintext"); + ret = bio_read (multi, ks->ks_ssl.ssl_bio, buf, maxlen, "tls_read_plaintext"); perf_pop (); return ret; } @@ -2208,31 +2208,31 @@ key_state_init (struct tls_session *session, struct key_state *ks) */ CLEAR (*ks); - ks->ssl = SSL_new (session->opt->ssl_ctx); - if (!ks->ssl) + ks->ks_ssl.ssl = SSL_new (session->opt->ssl_ctx.ctx); + if (!ks->ks_ssl.ssl) msg (M_SSLERR, "SSL_new failed"); /* put session * in ssl object so we can access it from verify callback*/ - SSL_set_ex_data (ks->ssl, mydata_index, session); + SSL_set_ex_data (ks->ks_ssl.ssl, mydata_index, session); - ks->ssl_bio = getbio (BIO_f_ssl (), "ssl_bio"); - ks->ct_in = getbio (BIO_s_mem (), "ct_in"); - ks->ct_out = getbio (BIO_s_mem (), "ct_out"); + ks->ks_ssl.ssl_bio = getbio (BIO_f_ssl (), "ssl_bio"); + ks->ks_ssl.ct_in = getbio (BIO_s_mem (), "ct_in"); + ks->ks_ssl.ct_out = getbio (BIO_s_mem (), "ct_out"); #ifdef BIO_DEBUG - bio_debug_oc ("open ssl_bio", ks->ssl_bio); - bio_debug_oc ("open ct_in", ks->ct_in); - bio_debug_oc ("open ct_out", ks->ct_out); + bio_debug_oc ("open ssl_bio", ks->ks_ssl.ssl_bio); + bio_debug_oc ("open ct_in", ks->ks_ssl.ct_in); + bio_debug_oc ("open ct_out", ks->ks_ssl.ct_out); #endif if (session->opt->server) - SSL_set_accept_state (ks->ssl); + SSL_set_accept_state (ks->ks_ssl.ssl); else - SSL_set_connect_state (ks->ssl); + SSL_set_connect_state (ks->ks_ssl.ssl); - SSL_set_bio (ks->ssl, ks->ct_in, ks->ct_out); - BIO_set_ssl (ks->ssl_bio, ks->ssl, BIO_NOCLOSE); + SSL_set_bio (ks->ks_ssl.ssl, ks->ks_ssl.ct_in, ks->ks_ssl.ct_out); + BIO_set_ssl (ks->ks_ssl.ssl_bio, ks->ks_ssl.ssl, BIO_NOCLOSE); /* Set control-channel initiation mode */ ks->initial_opcode = session->initial_opcode; @@ -2300,14 +2300,14 @@ key_state_free (struct key_state *ks, bool clear) { ks->state = S_UNDEF; - if (ks->ssl) { + if (ks->ks_ssl.ssl) { #ifdef BIO_DEBUG - bio_debug_oc ("close ssl_bio", ks->ssl_bio); - bio_debug_oc ("close ct_in", ks->ct_in); - bio_debug_oc ("close ct_out", ks->ct_out); + bio_debug_oc ("close ssl_bio", ks->ks_ssl.ssl_bio); + bio_debug_oc ("close ct_in", ks->ks_ssl.ct_in); + bio_debug_oc ("close ct_out", ks->ks_ssl.ct_out); #endif - BIO_free_all(ks->ssl_bio); - SSL_free (ks->ssl); + BIO_free_all(ks->ks_ssl.ssl_bio); + SSL_free (ks->ks_ssl.ssl); } free_key_ctx_bi (&ks->key); @@ -4137,7 +4137,7 @@ tls_process (struct tls_multi *multi, ks->established = now; dmsg (D_TLS_DEBUG_MED, "STATE S_ACTIVE"); if (check_debug_level (D_HANDSHAKE)) - print_details (ks->ssl, "Control Channel:"); + print_details (ks->ks_ssl.ssl, "Control Channel:"); state_change = true; ks->state = S_ACTIVE; INCR_SUCCESS; @@ -239,108 +239,6 @@ void init_ssl_lib (void); */ void free_ssl_lib (void); -/** - * Container for one half of random material to be used in %key method 2 - * \ref key_generation "data channel key generation". - * @ingroup control_processor - */ -struct key_source { - uint8_t pre_master[48]; /**< Random used for master secret - * generation, provided only by client - * OpenVPN peer. */ - uint8_t random1[32]; /**< Seed used for master secret - * generation, provided by both client - * and server. */ - uint8_t random2[32]; /**< Seed used for key expansion, provided - * by both client and server. */ -}; - - -/** - * Container for both halves of random material to be used in %key method - * 2 \ref key_generation "data channel key generation". - * @ingroup control_processor - */ -struct key_source2 { - struct key_source client; /**< Random provided by client. */ - struct key_source server; /**< Random provided by server. */ -}; - -/** - * Security parameter state of one TLS and data channel %key session. - * @ingroup control_processor - * - * This structure represents one security parameter session between - * OpenVPN peers. It includes the control channel TLS state and the data - * channel crypto state. It also contains the reliability layer - * structures used for control channel messages. - * - * A new \c key_state structure is initialized for each hard or soft - * reset. - * - * @see - * - This structure should be initialized using the \c key_state_init() - * function. - * - This structure should be cleaned up using the \c key_state_free() - * function. - */ -struct key_state -{ - int state; - int key_id; /* inherited from struct tls_session below */ - - SSL *ssl; /* SSL object -- new obj created for each new key */ - BIO *ssl_bio; /* read/write plaintext from here */ - BIO *ct_in; /* write ciphertext to here */ - BIO *ct_out; /* read ciphertext from here */ - - time_t established; /* when our state went S_ACTIVE */ - time_t must_negotiate; /* key negotiation times out if not finished before this time */ - time_t must_die; /* this object is destroyed at this time */ - - int initial_opcode; /* our initial P_ opcode */ - struct session_id session_id_remote; /* peer's random session ID */ - struct link_socket_actual remote_addr; /* peer's IP addr */ - struct packet_id packet_id; /* for data channel, to prevent replay attacks */ - - struct key_ctx_bi key; /* data channel keys for encrypt/decrypt/hmac */ - - struct key_source2 *key_src; /* source entropy for key expansion */ - - struct buffer plaintext_read_buf; - struct buffer plaintext_write_buf; - struct buffer ack_write_buf; - - struct reliable *send_reliable; /* holds a copy of outgoing packets until ACK received */ - struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */ - struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */ - - struct buffer_list *paybuf; - - counter_type n_bytes; /* how many bytes sent/recvd since last key exchange */ - counter_type n_packets; /* how many packets sent/recvd since last key exchange */ - - /* - * If bad username/password, TLS connection will come up but 'authenticated' will be false. - */ - bool authenticated; - time_t auth_deferred_expire; - -#ifdef ENABLE_DEF_AUTH - /* If auth_deferred is true, authentication is being deferred */ - bool auth_deferred; -#ifdef MANAGEMENT_DEF_AUTH - unsigned int mda_key_id; - unsigned int mda_status; -#endif -#ifdef PLUGIN_DEF_AUTH - unsigned int auth_control_status; - time_t acf_last_mod; - char *auth_control_file; -#endif -#endif -}; - #ifdef ENABLE_X509_TRACK struct x509_track @@ -356,115 +254,6 @@ void x509_track_add (const struct x509_track **ll_head, const char *name, int ms #endif -/* - * Our const options, obtained directly or derived from - * command line options. - */ -struct tls_options -{ - /* our master SSL_CTX from which all SSL objects derived */ - SSL_CTX *ssl_ctx; - - /* data channel cipher, hmac, and key lengths */ - struct key_type key_type; - - /* true if we are a TLS server, client otherwise */ - bool server; - - /* if true, don't xmit until first packet from peer is received */ - bool xmit_hold; - -#ifdef ENABLE_OCC - /* local and remote options strings - that must match between client and server */ - const char *local_options; - const char *remote_options; -#endif - - /* from command line */ - int key_method; - bool replay; - bool single_session; -#ifdef ENABLE_OCC - bool disable_occ; -#endif -#ifdef ENABLE_PUSH_PEER_INFO - bool push_peer_info; -#endif - int transition_window; - int handshake_window; - interval_t packet_timeout; - int renegotiate_bytes; - int renegotiate_packets; - interval_t renegotiate_seconds; - - /* cert verification parms */ - const char *verify_command; - const char *verify_export_cert; - const char *verify_x509name; - const char *crl_file; - int ns_cert_type; - unsigned remote_cert_ku[MAX_PARMS]; - const char *remote_cert_eku; - uint8_t *verify_hash; - - /* allow openvpn config info to be - passed over control channel */ - bool pass_config_info; - - /* struct crypto_option flags */ - unsigned int crypto_flags_and; - unsigned int crypto_flags_or; - - int replay_window; /* --replay-window parm */ - int replay_time; /* --replay-window parm */ - bool tcp_mode; - - /* packet authentication for TLS handshake */ - struct crypto_options tls_auth; - struct key_ctx_bi tls_auth_key; - - /* frame parameters for TLS control channel */ - struct frame frame; - - /* used for username/password authentication */ - const char *auth_user_pass_verify_script; - bool auth_user_pass_verify_script_via_file; - const char *tmp_dir; - - /* use the client-config-dir as a positive authenticator */ - const char *client_config_dir_exclusive; - - /* instance-wide environment variable set */ - struct env_set *es; - const struct plugin_list *plugins; - - /* configuration file boolean options */ -# define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0) -# define SSLF_USERNAME_AS_COMMON_NAME (1<<1) -# define SSLF_AUTH_USER_PASS_OPTIONAL (1<<2) -# define SSLF_NO_NAME_REMAPPING (1<<3) -# define SSLF_OPT_VERIFY (1<<4) -# define SSLF_CRL_VERIFY_DIR (1<<5) - unsigned int ssl_flags; - -#ifdef MANAGEMENT_DEF_AUTH - struct man_def_auth_context *mda_context; -#endif - -#ifdef ENABLE_X509_TRACK - const struct x509_track *x509_track; -#endif - -#ifdef ENABLE_CLIENT_CR - const struct static_challenge_info *sci; -#endif - - /* --gremlin bits */ - int gremlin; -}; - - /** @addtogroup control_processor * @{ */ /** @name Index of key_state objects within a tls_session structure diff --git a/ssl_common.h b/ssl_common.h index 7a95274..02193bd 100644 --- a/ssl_common.h +++ b/ssl_common.h @@ -42,10 +42,211 @@ #define UP_TYPE_AUTH "Auth" #define UP_TYPE_PRIVATE_KEY "Private Key" +/** + * Container for one half of random material to be used in %key method 2 + * \ref key_generation "data channel key generation". + * @ingroup control_processor + */ +struct key_source { + uint8_t pre_master[48]; /**< Random used for master secret + * generation, provided only by client + * OpenVPN peer. */ + uint8_t random1[32]; /**< Seed used for master secret + * generation, provided by both client + * and server. */ + uint8_t random2[32]; /**< Seed used for key expansion, provided + * by both client and server. */ +}; + + +/** + * Container for both halves of random material to be used in %key method + * 2 \ref key_generation "data channel key generation". + * @ingroup control_processor + */ +struct key_source2 { + struct key_source client; /**< Random provided by client. */ + struct key_source server; /**< Random provided by server. */ +}; + +/** + * Security parameter state of one TLS and data channel %key session. + * @ingroup control_processor + * + * This structure represents one security parameter session between + * OpenVPN peers. It includes the control channel TLS state and the data + * channel crypto state. It also contains the reliability layer + * structures used for control channel messages. + * + * A new \c key_state structure is initialized for each hard or soft + * reset. + * + * @see + * - This structure should be initialized using the \c key_state_init() + * function. + * - This structure should be cleaned up using the \c key_state_free() + * function. + */ +struct key_state +{ + int state; + int key_id; /* inherited from struct tls_session below */ + + struct key_state_ssl ks_ssl; /* contains SSL object and BIOs for the control channel */ + + time_t established; /* when our state went S_ACTIVE */ + time_t must_negotiate; /* key negotiation times out if not finished before this time */ + time_t must_die; /* this object is destroyed at this time */ + + int initial_opcode; /* our initial P_ opcode */ + struct session_id session_id_remote; /* peer's random session ID */ + struct link_socket_actual remote_addr; /* peer's IP addr */ + struct packet_id packet_id; /* for data channel, to prevent replay attacks */ + + struct key_ctx_bi key; /* data channel keys for encrypt/decrypt/hmac */ + + struct key_source2 *key_src; /* source entropy for key expansion */ + + struct buffer plaintext_read_buf; + struct buffer plaintext_write_buf; + struct buffer ack_write_buf; + + struct reliable *send_reliable; /* holds a copy of outgoing packets until ACK received */ + struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */ + struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */ + + struct buffer_list *paybuf; + + counter_type n_bytes; /* how many bytes sent/recvd since last key exchange */ + counter_type n_packets; /* how many packets sent/recvd since last key exchange */ + + /* + * If bad username/password, TLS connection will come up but 'authenticated' will be false. + */ + bool authenticated; + time_t auth_deferred_expire; + +#ifdef ENABLE_DEF_AUTH + /* If auth_deferred is true, authentication is being deferred */ + bool auth_deferred; +#ifdef MANAGEMENT_DEF_AUTH + unsigned int mda_key_id; + unsigned int mda_status; +#endif +#ifdef PLUGIN_DEF_AUTH + unsigned int auth_control_status; + time_t acf_last_mod; + char *auth_control_file; +#endif +#endif +}; + +/* + * Our const options, obtained directly or derived from + * command line options. + */ +struct tls_options +{ + /* our master TLS context from which all SSL objects derived */ + struct tls_root_ctx ssl_ctx; + + /* data channel cipher, hmac, and key lengths */ + struct key_type key_type; + + /* true if we are a TLS server, client otherwise */ + bool server; + + /* if true, don't xmit until first packet from peer is received */ + bool xmit_hold; + +#ifdef ENABLE_OCC + /* local and remote options strings + that must match between client and server */ + const char *local_options; + const char *remote_options; +#endif + + /* from command line */ + int key_method; + bool replay; + bool single_session; +#ifdef ENABLE_OCC + bool disable_occ; +#endif +#ifdef ENABLE_PUSH_PEER_INFO + bool push_peer_info; +#endif + int transition_window; + int handshake_window; + interval_t packet_timeout; + int renegotiate_bytes; + int renegotiate_packets; + interval_t renegotiate_seconds; + + /* cert verification parms */ + const char *verify_command; + const char *verify_export_cert; + const char *verify_x509name; + const char *crl_file; + int ns_cert_type; + unsigned remote_cert_ku[MAX_PARMS]; + const char *remote_cert_eku; + uint8_t *verify_hash; + + /* allow openvpn config info to be + passed over control channel */ + bool pass_config_info; + + /* struct crypto_option flags */ + unsigned int crypto_flags_and; + unsigned int crypto_flags_or; + + int replay_window; /* --replay-window parm */ + int replay_time; /* --replay-window parm */ + bool tcp_mode; + + /* packet authentication for TLS handshake */ + struct crypto_options tls_auth; + struct key_ctx_bi tls_auth_key; + + /* frame parameters for TLS control channel */ + struct frame frame; + + /* used for username/password authentication */ + const char *auth_user_pass_verify_script; + bool auth_user_pass_verify_script_via_file; + const char *tmp_dir; + + /* use the client-config-dir as a positive authenticator */ + const char *client_config_dir_exclusive; + + /* instance-wide environment variable set */ + struct env_set *es; + const struct plugin_list *plugins; + /* configuration file boolean options */ # define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0) # define SSLF_USERNAME_AS_COMMON_NAME (1<<1) # define SSLF_AUTH_USER_PASS_OPTIONAL (1<<2) # define SSLF_NO_NAME_REMAPPING (1<<3) # define SSLF_OPT_VERIFY (1<<4) +# define SSLF_CRL_VERIFY_DIR (1<<5) + unsigned int ssl_flags; + +#ifdef MANAGEMENT_DEF_AUTH + struct man_def_auth_context *mda_context; +#endif + +#ifdef ENABLE_X509_TRACK + const struct x509_track *x509_track; +#endif + +#ifdef ENABLE_CLIENT_CR + const struct static_challenge_info *sci; +#endif + + /* --gremlin bits */ + int gremlin; +}; + #endif /* SSL_COMMON_H_ */ diff --git a/ssl_openssl.h b/ssl_openssl.h index a87861b..fc2052c 100644 --- a/ssl_openssl.h +++ b/ssl_openssl.h @@ -40,6 +40,13 @@ struct tls_root_ctx { SSL_CTX *ctx; }; +struct key_state_ssl { + SSL *ssl; /* SSL object -- new obj created for each new key */ + BIO *ssl_bio; /* read/write plaintext from here */ + BIO *ct_in; /* write ciphertext to here */ + BIO *ct_out; /* read ciphertext from here */ +}; + /** * Allocate space in SSL objects in which to store a struct tls_session * pointer back to parent. |