From b6ba401497001c2f042feff693ed292b21c8369c Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 27 Jan 2015 20:11:24 +0000 Subject: [PATCH] Make libssl opaque. Move all structures that were previously protected by OPENSSL_NO_SSL_INTERN into internal header files. Reviewed-by: Richard Levitte --- ssl/bio_ssl.c | 2 +- ssl/dtls1.h | 143 ------- ssl/ssl.h | 702 -------------------------------- ssl/ssl3.h | 204 ---------- ssl/ssl_locl.h | 1036 ++++++++++++++++++++++++++++++++++++++++++++++++ ssl/ssltest.c | 2 + 6 files changed, 1039 insertions(+), 1050 deletions(-) diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c index a0c583e342..458e071872 100644 --- a/ssl/bio_ssl.c +++ b/ssl/bio_ssl.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include "ssl_locl.h" static int ssl_write(BIO *h, const char *buf, int num); static int ssl_read(BIO *h, char *buf, int size); diff --git a/ssl/dtls1.h b/ssl/dtls1.h index e2be78d346..ff406d8ba6 100644 --- a/ssl/dtls1.h +++ b/ssl/dtls1.h @@ -110,149 +110,6 @@ extern "C" { # define DTLS1_AL_HEADER_LENGTH 2 # endif -# ifndef OPENSSL_NO_SSL_INTERN - -# ifndef OPENSSL_NO_SCTP -# define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" -# endif - -/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */ -# define DTLS1_MAX_MTU_OVERHEAD 48 - -typedef struct dtls1_bitmap_st { - unsigned long map; /* track 32 packets on 32-bit systems and 64 - * - on 64-bit systems */ - unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit - * value in big-endian encoding */ -} DTLS1_BITMAP; - -struct dtls1_retransmit_state { - EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - EVP_MD_CTX *write_hash; /* used for mac generation */ -# ifndef OPENSSL_NO_COMP - COMP_CTX *compress; /* compression */ -# else - char *compress; -# endif - SSL_SESSION *session; - unsigned short epoch; -}; - -struct hm_header_st { - unsigned char type; - unsigned long msg_len; - unsigned short seq; - unsigned long frag_off; - unsigned long frag_len; - unsigned int is_ccs; - struct dtls1_retransmit_state saved_retransmit_state; -}; - -struct ccs_header_st { - unsigned char type; - unsigned short seq; -}; - -struct dtls1_timeout_st { - /* Number of read timeouts so far */ - unsigned int read_timeouts; - /* Number of write timeouts so far */ - unsigned int write_timeouts; - /* Number of alerts received so far */ - unsigned int num_alerts; -}; - -typedef struct record_pqueue_st { - unsigned short epoch; - pqueue q; -} record_pqueue; - -typedef struct hm_fragment_st { - struct hm_header_st msg_header; - unsigned char *fragment; - unsigned char *reassembly; -} hm_fragment; - -typedef struct dtls1_state_st { - unsigned int send_cookie; - unsigned char cookie[DTLS1_COOKIE_LENGTH]; - unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; - unsigned int cookie_len; - /* - * The current data and handshake epoch. This is initially - * undefined, and starts at zero once the initial handshake is - * completed - */ - unsigned short r_epoch; - unsigned short w_epoch; - /* records being received in the current epoch */ - DTLS1_BITMAP bitmap; - /* renegotiation starts a new set of sequence numbers */ - DTLS1_BITMAP next_bitmap; - /* handshake message numbers */ - unsigned short handshake_write_seq; - unsigned short next_handshake_write_seq; - unsigned short handshake_read_seq; - /* save last sequence number for retransmissions */ - unsigned char last_write_sequence[8]; - /* Received handshake records (processed and unprocessed) */ - record_pqueue unprocessed_rcds; - record_pqueue processed_rcds; - /* Buffered handshake messages */ - pqueue buffered_messages; - /* Buffered (sent) handshake records */ - pqueue sent_messages; - /* - * Buffered application records. Only for records between CCS and - * Finished to prevent either protocol violation or unnecessary message - * loss. - */ - record_pqueue buffered_app_data; - /* Is set when listening for new connections with dtls1_listen() */ - unsigned int listen; - unsigned int link_mtu; /* max on-the-wire DTLS packet size */ - unsigned int mtu; /* max DTLS packet size */ - struct hm_header_st w_msg_hdr; - struct hm_header_st r_msg_hdr; - struct dtls1_timeout_st timeout; - /* - * Indicates when the last handshake msg or heartbeat sent will timeout - */ - struct timeval next_timeout; - /* Timeout duration */ - unsigned short timeout_duration; - /* - * storage for Alert/Handshake protocol data received but not yet - * processed by ssl3_read_bytes: - */ - unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; - unsigned int alert_fragment_len; - unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; - unsigned int handshake_fragment_len; - unsigned int retransmitting; - /* - * Set when the handshake is ready to process peer's ChangeCipherSpec message. - * Cleared after the message has been processed. - */ - unsigned int change_cipher_spec_ok; -# ifndef OPENSSL_NO_SCTP - /* used when SSL_ST_XX_FLUSH is entered */ - int next_state; - int shutdown_received; -# endif -} DTLS1_STATE; - -typedef struct dtls1_record_data_st { - unsigned char *packet; - unsigned int packet_length; - SSL3_BUFFER rbuf; - SSL3_RECORD rrec; -# ifndef OPENSSL_NO_SCTP - struct bio_dgram_sctp_rcvinfo recordinfo; -# endif -} DTLS1_RECORD_DATA; - -# endif /* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ # define DTLS1_TMO_READ_COUNT 2 diff --git a/ssl/ssl.h b/ssl/ssl.h index 0a6f4dae39..df91c187fb 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -388,166 +388,6 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type, # endif -# ifndef OPENSSL_NO_SSL_INTERN - -/* used to hold info on the particular ciphers used */ -struct ssl_cipher_st { - int valid; - const char *name; /* text name */ - unsigned long id; /* id, 4 bytes, first is version */ - /* - * changed in 0.9.9: these four used to be portions of a single value - * 'algorithms' - */ - unsigned long algorithm_mkey; /* key exchange algorithm */ - unsigned long algorithm_auth; /* server authentication */ - unsigned long algorithm_enc; /* symmetric encryption */ - unsigned long algorithm_mac; /* symmetric authentication */ - unsigned long algorithm_ssl; /* (major) protocol version */ - unsigned long algo_strength; /* strength and export flags */ - unsigned long algorithm2; /* Extra flags */ - int strength_bits; /* Number of bits really used */ - int alg_bits; /* Number of bits for algorithm */ -}; - -/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ -struct ssl_method_st { - int version; - int (*ssl_new) (SSL *s); - void (*ssl_clear) (SSL *s); - void (*ssl_free) (SSL *s); - int (*ssl_accept) (SSL *s); - int (*ssl_connect) (SSL *s); - int (*ssl_read) (SSL *s, void *buf, int len); - int (*ssl_peek) (SSL *s, void *buf, int len); - int (*ssl_write) (SSL *s, const void *buf, int len); - int (*ssl_shutdown) (SSL *s); - int (*ssl_renegotiate) (SSL *s); - int (*ssl_renegotiate_check) (SSL *s); - long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long - max, int *ok); - int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len, - int peek); - int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len); - int (*ssl_dispatch_alert) (SSL *s); - long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); - long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg); - const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr); - int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr); - int (*ssl_pending) (const SSL *s); - int (*num_ciphers) (void); - const SSL_CIPHER *(*get_cipher) (unsigned ncipher); - const struct ssl_method_st *(*get_ssl_method) (int version); - long (*get_timeout) (void); - const struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ - int (*ssl_version) (void); - long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void)); - long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); -}; - -/*- - * Lets make this into an ASN.1 type structure as follows - * SSL_SESSION_ID ::= SEQUENCE { - * version INTEGER, -- structure version number - * SSLversion INTEGER, -- SSL version number - * Cipher OCTET STRING, -- the 3 byte cipher ID - * Session_ID OCTET STRING, -- the Session ID - * Master_key OCTET STRING, -- the master key - * KRB5_principal OCTET STRING -- optional Kerberos principal - * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument - * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time - * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds - * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate - * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context - * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' - * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension - * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint - * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity - * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket - * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) - * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method - * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username - * } - * Look in ssl/ssl_asn1.c for more details - * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). - */ -struct ssl_session_st { - int ssl_version; /* what ssl version session info is being - * kept in here? */ - int master_key_length; - unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; - /* session_id - valid? */ - unsigned int session_id_length; - unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; - /* - * this is used to determine whether the session is being reused in the - * appropriate context. It is up to the application to set this, via - * SSL_new - */ - unsigned int sid_ctx_length; - unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; -# ifndef OPENSSL_NO_KRB5 - unsigned int krb5_client_princ_len; - unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; -# endif /* OPENSSL_NO_KRB5 */ -# ifndef OPENSSL_NO_PSK - char *psk_identity_hint; - char *psk_identity; -# endif - /* - * Used to indicate that session resumption is not allowed. Applications - * can also set this bit for a new session via not_resumable_session_cb - * to disable session caching and tickets. - */ - int not_resumable; - /* The cert is the certificate used to establish this connection */ - struct sess_cert_st /* SESS_CERT */ *sess_cert; - /* - * This is the cert for the other end. On clients, it will be the same as - * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is - * not retained in the external representation of sessions, see - * ssl_asn1.c). - */ - X509 *peer; - /* - * when app_verify_callback accepts a session where the peer's - * certificate is not ok, we must remember the error for session reuse: - */ - long verify_result; /* only for servers */ - int references; - long timeout; - long time; - unsigned int compress_meth; /* Need to lookup the method */ - const SSL_CIPHER *cipher; - unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used - * to load the 'cipher' structure */ - STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ - CRYPTO_EX_DATA ex_data; /* application specific data */ - /* - * These are used to make removal of session-ids more efficient and to - * implement a maximum cache size. - */ - struct ssl_session_st *prev, *next; -# ifndef OPENSSL_NO_TLSEXT - char *tlsext_hostname; -# ifndef OPENSSL_NO_EC - size_t tlsext_ecpointformatlist_length; - unsigned char *tlsext_ecpointformatlist; /* peer's list */ - size_t tlsext_ellipticcurvelist_length; - unsigned char *tlsext_ellipticcurvelist; /* peer's list */ -# endif /* OPENSSL_NO_EC */ - /* RFC4507 info */ - unsigned char *tlsext_tick; /* Session ticket */ - size_t tlsext_ticklen; /* Session ticket length */ - long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ -# endif -# ifndef OPENSSL_NO_SRP - char *srp_username; -# endif -}; - -# endif - /* Allow initial connection to servers that don't support RI */ # define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L # define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L @@ -818,27 +658,6 @@ void SSL_set_msg_callback(SSL *ssl, # ifndef OPENSSL_NO_SRP -# ifndef OPENSSL_NO_SSL_INTERN - -typedef struct srp_ctx_st { - /* param for all the callbacks */ - void *SRP_cb_arg; - /* set client Hello login callback */ - int (*TLS_ext_srp_username_callback) (SSL *, int *, void *); - /* set SRP N/g param callback for verification */ - int (*SRP_verify_param_callback) (SSL *, void *); - /* set SRP client passwd callback */ - char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *); - char *login; - BIGNUM *N, *g, *s, *B, *A; - BIGNUM *a, *b, *v; - char *info; - int strength; - unsigned long srp_Mask; -} SRP_CTX; - -# endif - /* see tls_srp.c */ int SSL_SRP_CTX_init(SSL *s); int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); @@ -878,271 +697,6 @@ typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id, typedef struct ssl_comp_st SSL_COMP; -# ifndef OPENSSL_NO_SSL_INTERN - -struct ssl_comp_st { - int id; - const char *name; -# ifndef OPENSSL_NO_COMP - COMP_METHOD *method; -# else - char *method; -# endif -}; - -DECLARE_STACK_OF(SSL_COMP) -DECLARE_LHASH_OF(SSL_SESSION); - -struct ssl_ctx_st { - const SSL_METHOD *method; - STACK_OF(SSL_CIPHER) *cipher_list; - /* same as above but sorted for lookup */ - STACK_OF(SSL_CIPHER) *cipher_list_by_id; - struct x509_store_st /* X509_STORE */ *cert_store; - LHASH_OF(SSL_SESSION) *sessions; - /* - * Most session-ids that will be cached, default is - * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. - */ - unsigned long session_cache_size; - struct ssl_session_st *session_cache_head; - struct ssl_session_st *session_cache_tail; - /* - * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT, - * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which - * means only SSL_accept which cache SSL_SESSIONS. - */ - int session_cache_mode; - /* - * If timeout is not 0, it is the default timeout value set when - * SSL_new() is called. This has been put in to make life easier to set - * things up - */ - long session_timeout; - /* - * If this callback is not null, it will be called each time a session id - * is added to the cache. If this function returns 1, it means that the - * callback will do a SSL_SESSION_free() when it has finished using it. - * Otherwise, on 0, it means the callback has finished with it. If - * remove_session_cb is not null, it will be called when a session-id is - * removed from the cache. After the call, OpenSSL will - * SSL_SESSION_free() it. - */ - int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess); - void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess); - SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl, - unsigned char *data, int len, int *copy); - struct { - int sess_connect; /* SSL new conn - started */ - int sess_connect_renegotiate; /* SSL reneg - requested */ - int sess_connect_good; /* SSL new conne/reneg - finished */ - int sess_accept; /* SSL new accept - started */ - int sess_accept_renegotiate; /* SSL reneg - requested */ - int sess_accept_good; /* SSL accept/reneg - finished */ - int sess_miss; /* session lookup misses */ - int sess_timeout; /* reuse attempt on timeouted session */ - int sess_cache_full; /* session removed due to full cache */ - int sess_hit; /* session reuse actually done */ - int sess_cb_hit; /* session-id that was not in the cache was - * passed back via the callback. This - * indicates that the application is - * supplying session-id's from other - * processes - spooky :-) */ - } stats; - - int references; - - /* if defined, these override the X509_verify_cert() calls */ - int (*app_verify_callback) (X509_STORE_CTX *, void *); - void *app_verify_arg; - /* - * before OpenSSL 0.9.7, 'app_verify_arg' was ignored - * ('app_verify_callback' was called with just one argument) - */ - - /* Default password callback. */ - pem_password_cb *default_passwd_callback; - - /* Default password callback user data. */ - void *default_passwd_callback_userdata; - - /* get client cert callback */ - int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey); - - /* cookie generate callback */ - int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie, - unsigned int *cookie_len); - - /* verify cookie callback */ - int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie, - unsigned int cookie_len); - - CRYPTO_EX_DATA ex_data; - - const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ - const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ - - STACK_OF(X509) *extra_certs; - STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ - - /* Default values used when no per-SSL value is defined follow */ - - /* used if SSL's info_callback is NULL */ - void (*info_callback) (const SSL *ssl, int type, int val); - - /* what we put in client cert requests */ - STACK_OF(X509_NAME) *client_CA; - - /* - * Default values to use in SSL structures follow (these are copied by - * SSL_new) - */ - - unsigned long options; - unsigned long mode; - long max_cert_list; - - struct cert_st /* CERT */ *cert; - int read_ahead; - - /* callback that allows applications to peek at protocol messages */ - void (*msg_callback) (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); - void *msg_callback_arg; - - int verify_mode; - unsigned int sid_ctx_length; - unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; - /* called 'verify_callback' in the SSL */ - int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); - - /* Default generate session ID callback. */ - GEN_SESSION_CB generate_session_id; - - X509_VERIFY_PARAM *param; - - int quiet_shutdown; - - /* - * Maximum amount of data to send in one fragment. actual record size can - * be more than this due to padding and MAC overheads. - */ - unsigned int max_send_fragment; - -# ifndef OPENSSL_NO_ENGINE - /* - * Engine to pass requests for client certs to - */ - ENGINE *client_cert_engine; -# endif - -# ifndef OPENSSL_NO_TLSEXT - /* TLS extensions servername callback */ - int (*tlsext_servername_callback) (SSL *, int *, void *); - void *tlsext_servername_arg; - /* RFC 4507 session ticket keys */ - unsigned char tlsext_tick_key_name[16]; - unsigned char tlsext_tick_hmac_key[16]; - unsigned char tlsext_tick_aes_key[16]; - /* Callback to support customisation of ticket key setting */ - int (*tlsext_ticket_key_cb) (SSL *ssl, - unsigned char *name, unsigned char *iv, - EVP_CIPHER_CTX *ectx, - HMAC_CTX *hctx, int enc); - - /* certificate status request info */ - /* Callback for status request */ - int (*tlsext_status_cb) (SSL *ssl, void *arg); - void *tlsext_status_arg; -# endif - -# ifndef OPENSSL_NO_PSK - char *psk_identity_hint; - unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, - char *identity, - unsigned int max_identity_len, - unsigned char *psk, - unsigned int max_psk_len); - unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, - unsigned char *psk, - unsigned int max_psk_len); -# endif - -# ifndef OPENSSL_NO_SRP - SRP_CTX srp_ctx; /* ctx for SRP authentication */ -# endif - -# ifndef OPENSSL_NO_TLSEXT - -# ifndef OPENSSL_NO_NEXTPROTONEG - /* Next protocol negotiation information */ - /* (for experimental NPN extension). */ - - /* - * For a server, this contains a callback function by which the set of - * advertised protocols can be provided. - */ - int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf, - unsigned int *len, void *arg); - void *next_protos_advertised_cb_arg; - /* - * For a client, this contains a callback function that selects the next - * protocol from the list provided by the server. - */ - int (*next_proto_select_cb) (SSL *s, unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, void *arg); - void *next_proto_select_cb_arg; -# endif - - /* - * ALPN information (we are in the process of transitioning from NPN to - * ALPN.) - */ - - /*- - * For a server, this contains a callback function that allows the - * server to select the protocol for the connection. - * out: on successful return, this must point to the raw protocol - * name (without the length prefix). - * outlen: on successful return, this contains the length of |*out|. - * in: points to the client's list of supported protocols in - * wire-format. - * inlen: the length of |in|. - */ - int (*alpn_select_cb) (SSL *s, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, void *arg); - void *alpn_select_cb_arg; - - /* - * For a client, this contains the list of supported protocols in wire - * format. - */ - unsigned char *alpn_client_proto_list; - unsigned alpn_client_proto_list_len; - - /* SRTP profiles we are willing to do from RFC 5764 */ - STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; -# endif - /* - * Callback for disabling session caching and ticket support on a session - * basis, depending on the chosen cipher. - */ - int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure); -# ifndef OPENSSL_NO_EC - /* EC extension values inherited by SSL structure */ - size_t tlsext_ecpointformatlist_length; - unsigned char *tlsext_ecpointformatlist; - size_t tlsext_ellipticcurvelist_length; - unsigned char *tlsext_ellipticcurvelist; -# endif /* OPENSSL_NO_EC */ -}; - -# endif # define SSL_SESS_CACHE_OFF 0x0000 # define SSL_SESS_CACHE_CLIENT 0x0001 @@ -1376,262 +930,6 @@ int SSL_extension_supported(unsigned int ext_type); # define SSL_MAC_FLAG_READ_MAC_STREAM 1 # define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 -# ifndef OPENSSL_NO_SSL_INTERN - -struct ssl_st { - /* - * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, - * DTLS1_VERSION) - */ - int version; - /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ - int type; - /* SSLv3 */ - const SSL_METHOD *method; - /* - * There are 2 BIO's even though they are normally both the same. This - * is so data can be read and written to different handlers - */ - /* used by SSL_read */ - BIO *rbio; - /* used by SSL_write */ - BIO *wbio; - /* used during session-id reuse to concatenate messages */ - BIO *bbio; - /* - * This holds a variable that indicates what we were doing when a 0 or -1 - * is returned. This is needed for non-blocking IO so we know what - * request needs re-doing when in SSL_accept or SSL_connect - */ - int rwstate; - /* true when we are actually in SSL_accept() or SSL_connect() */ - int in_handshake; - int (*handshake_func) (SSL *); - /* - * Imagine that here's a boolean member "init" that is switched as soon - * as SSL_set_{accept/connect}_state is called for the first time, so - * that "state" and "handshake_func" are properly initialized. But as - * handshake_func is == 0 until then, we use this test instead of an - * "init" member. - */ - /* are we the server side? - mostly used by SSL_clear */ - int server; - /* - * Generate a new session or reuse an old one. - * NB: For servers, the 'new' session may actually be a previously - * cached session or even the previous session unless - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set - */ - int new_session; - /* don't send shutdown packets */ - int quiet_shutdown; - /* we have shut things down, 0x01 sent, 0x02 for received */ - int shutdown; - /* where we are */ - int state; - /* where we are when reading */ - int rstate; - BUF_MEM *init_buf; /* buffer used during init */ - void *init_msg; /* pointer to handshake message body, set by - * ssl3_get_message() */ - int init_num; /* amount read/written */ - int init_off; /* amount read/written */ - /* used internally to point at a raw packet */ - unsigned char *packet; - unsigned int packet_length; - struct ssl3_state_st *s3; /* SSLv3 variables */ - struct dtls1_state_st *d1; /* DTLSv1 variables */ - int read_ahead; /* Read as many input bytes as possible (for - * non-blocking reads) */ - /* callback that allows applications to peek at protocol messages */ - void (*msg_callback) (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); - void *msg_callback_arg; - int hit; /* reusing a previous session */ - X509_VERIFY_PARAM *param; - /* crypto */ - STACK_OF(SSL_CIPHER) *cipher_list; - STACK_OF(SSL_CIPHER) *cipher_list_by_id; - /* - * These are the ones being used, the ones in SSL_SESSION are the ones to - * be 'copied' into these ones - */ - int mac_flags; - EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ - EVP_MD_CTX *read_hash; /* used for mac generation */ -# ifndef OPENSSL_NO_COMP - COMP_CTX *expand; /* uncompress */ -# else - char *expand; -# endif - EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - EVP_MD_CTX *write_hash; /* used for mac generation */ -# ifndef OPENSSL_NO_COMP - COMP_CTX *compress; /* compression */ -# else - char *compress; -# endif - /* session info */ - /* client cert? */ - /* This is used to hold the server certificate used */ - struct cert_st /* CERT */ *cert; - /* - * the session_id_context is used to ensure sessions are only reused in - * the appropriate context - */ - unsigned int sid_ctx_length; - unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; - /* This can also be in the session once a session is established */ - SSL_SESSION *session; - /* Default generate session ID callback. */ - GEN_SESSION_CB generate_session_id; - /* Used in SSL3 */ - /* - * 0 don't care about verify failure. - * 1 fail if verify fails - */ - int verify_mode; - /* fail if callback returns 0 */ - int (*verify_callback) (int ok, X509_STORE_CTX *ctx); - /* optional informational callback */ - void (*info_callback) (const SSL *ssl, int type, int val); - /* error bytes to be written */ - int error; - /* actual code */ - int error_code; -# ifndef OPENSSL_NO_KRB5 - /* Kerberos 5 context */ - KSSL_CTX *kssl_ctx; -# endif /* OPENSSL_NO_KRB5 */ -# ifndef OPENSSL_NO_PSK - unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, - char *identity, - unsigned int max_identity_len, - unsigned char *psk, - unsigned int max_psk_len); - unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, - unsigned char *psk, - unsigned int max_psk_len); -# endif - SSL_CTX *ctx; - /* - * set this flag to 1 and a sleep(1) is put into all SSL_read() and - * SSL_write() calls, good for nbio debuging :-) - */ - int debug; - /* extra application data */ - long verify_result; - CRYPTO_EX_DATA ex_data; - /* for server side, keep the list of CA_dn we can use */ - STACK_OF(X509_NAME) *client_CA; - int references; - /* protocol behaviour */ - unsigned long options; - /* API behaviour */ - unsigned long mode; - long max_cert_list; - int first_packet; - /* what was passed, used for SSLv3/TLS rollback check */ - int client_version; - unsigned int max_send_fragment; -# ifndef OPENSSL_NO_TLSEXT - /* TLS extension debug callback */ - void (*tlsext_debug_cb) (SSL *s, int client_server, int type, - unsigned char *data, int len, void *arg); - void *tlsext_debug_arg; - char *tlsext_hostname; - /*- - * no further mod of servername - * 0 : call the servername extension callback. - * 1 : prepare 2, allow last ack just after in server callback. - * 2 : don't call servername callback, no ack in server hello - */ - int servername_done; - /* certificate status request info */ - /* Status type or -1 if no status type */ - int tlsext_status_type; - /* Expect OCSP CertificateStatus message */ - int tlsext_status_expected; - /* OCSP status request only */ - STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; - X509_EXTENSIONS *tlsext_ocsp_exts; - /* OCSP response received or to be sent */ - unsigned char *tlsext_ocsp_resp; - int tlsext_ocsp_resplen; - /* RFC4507 session ticket expected to be received or sent */ - int tlsext_ticket_expected; -# ifndef OPENSSL_NO_EC - size_t tlsext_ecpointformatlist_length; - /* our list */ - unsigned char *tlsext_ecpointformatlist; - size_t tlsext_ellipticcurvelist_length; - /* our list */ - unsigned char *tlsext_ellipticcurvelist; -# endif /* OPENSSL_NO_EC */ - /* TLS Session Ticket extension override */ - TLS_SESSION_TICKET_EXT *tlsext_session_ticket; - /* TLS Session Ticket extension callback */ - tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; - void *tls_session_ticket_ext_cb_arg; - /* TLS pre-shared secret session resumption */ - tls_session_secret_cb_fn tls_session_secret_cb; - void *tls_session_secret_cb_arg; - SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */ -# ifndef OPENSSL_NO_NEXTPROTONEG - /* - * Next protocol negotiation. For the client, this is the protocol that - * we sent in NextProtocol and is set when handling ServerHello - * extensions. For a server, this is the client's selected_protocol from - * NextProtocol and is set when handling the NextProtocol message, before - * the Finished message. - */ - unsigned char *next_proto_negotiated; - unsigned char next_proto_negotiated_len; -# endif -# define session_ctx initial_ctx - /* What we'll do */ - STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; - /* What's been chosen */ - SRTP_PROTECTION_PROFILE *srtp_profile; - /*- - * Is use of the Heartbeat extension negotiated? - * 0: disabled - * 1: enabled - * 2: enabled, but not allowed to send Requests - */ - unsigned int tlsext_heartbeat; - /* Indicates if a HeartbeatRequest is in flight */ - unsigned int tlsext_hb_pending; - /* HeartbeatRequest sequence number */ - unsigned int tlsext_hb_seq; - /* - * For a client, this contains the list of supported protocols in wire - * format. - */ - unsigned char *alpn_client_proto_list; - unsigned alpn_client_proto_list_len; -# else -# define session_ctx ctx -# endif /* OPENSSL_NO_TLSEXT */ - /*- - * 1 if we are renegotiating. - * 2 if we are a server and are inside a handshake - * (i.e. not just sending a HelloRequest) - */ - int renegotiate; -# ifndef OPENSSL_NO_SRP - /* ctx for SRP authentication */ - SRP_CTX srp_ctx; -# endif - /* - * Callback for disabling session caching and ticket support on a session - * basis, depending on the chosen cipher. - */ - int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure); -}; - -# endif - #ifdef __cplusplus } #endif diff --git a/ssl/ssl3.h b/ssl/ssl3.h index 23eb156c04..7d16d70de5 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -380,62 +380,6 @@ extern "C" { # define TLS1_HB_REQUEST 1 # define TLS1_HB_RESPONSE 2 -# ifndef OPENSSL_NO_SSL_INTERN - -typedef struct ssl3_record_st { - /* type of record */ - /* - * r - */ int type; - /* How many bytes available */ - /* - * rw - */ unsigned int length; - /* - * How many bytes were available before padding was removed? This is used - * to implement the MAC check in constant time for CBC records. - */ - /* - * rw - */ unsigned int orig_len; - /* read/write offset into 'buf' */ - /* - * r - */ unsigned int off; - /* pointer to the record data */ - /* - * rw - */ unsigned char *data; - /* where the decode bytes are */ - /* - * rw - */ unsigned char *input; - /* only used with decompression - malloc()ed */ - /* - * r - */ unsigned char *comp; - /* epoch number, needed by DTLS1 */ - /* - * r - */ unsigned long epoch; - /* sequence number, needed by DTLS1 */ - /* - * r - */ unsigned char seq_num[8]; -} SSL3_RECORD; - -typedef struct ssl3_buffer_st { - /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ - unsigned char *buf; - /* buffer size */ - size_t len; - /* where to 'copy from' */ - int offset; - /* how many bytes left */ - int left; -} SSL3_BUFFER; - -# endif # define SSL3_CT_RSA_SIGN 1 # define SSL3_CT_DSS_SIGN 2 @@ -465,154 +409,6 @@ typedef struct ssl3_buffer_st { /* Set if we encrypt then mac instead of usual mac then encrypt */ # define TLS1_FLAGS_ENCRYPT_THEN_MAC 0x0100 -# ifndef OPENSSL_NO_SSL_INTERN - -typedef struct ssl3_state_st { - long flags; - int delay_buf_pop_ret; - unsigned char read_sequence[8]; - int read_mac_secret_size; - unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; - unsigned char write_sequence[8]; - int write_mac_secret_size; - unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; - unsigned char server_random[SSL3_RANDOM_SIZE]; - unsigned char client_random[SSL3_RANDOM_SIZE]; - /* flags for countermeasure against known-IV weakness */ - int need_empty_fragments; - int empty_fragment_done; - /* The value of 'extra' when the buffers were initialized */ - int init_extra; - SSL3_BUFFER rbuf; /* read IO goes into here */ - SSL3_BUFFER wbuf; /* write IO goes into here */ - SSL3_RECORD rrec; /* each decoded record goes in here */ - SSL3_RECORD wrec; /* goes out from here */ - /* - * storage for Alert/Handshake protocol data received but not yet - * processed by ssl3_read_bytes: - */ - unsigned char alert_fragment[2]; - unsigned int alert_fragment_len; - unsigned char handshake_fragment[4]; - unsigned int handshake_fragment_len; - /* partial write - check the numbers match */ - unsigned int wnum; /* number of bytes sent so far */ - int wpend_tot; /* number bytes written */ - int wpend_type; - int wpend_ret; /* number of bytes submitted */ - const unsigned char *wpend_buf; - /* used during startup, digest all incoming/outgoing packets */ - BIO *handshake_buffer; - /* - * When set of handshake digests is determined, buffer is hashed and - * freed and MD_CTX-es for all required digests are stored in this array - */ - EVP_MD_CTX **handshake_dgst; - /* - * Set whenever an expected ChangeCipherSpec message is processed. - * Unset when the peer's Finished message is received. - * Unexpected ChangeCipherSpec messages trigger a fatal alert. - */ - int change_cipher_spec; - int warn_alert; - int fatal_alert; - /* - * we allow one fatal and one warning alert to be outstanding, send close - * alert via the warning alert - */ - int alert_dispatch; - unsigned char send_alert[2]; - /* - * This flag is set when we should renegotiate ASAP, basically when there - * is no more data in the read or write buffers - */ - int renegotiate; - int total_renegotiations; - int num_renegotiations; - int in_read_app_data; - struct { - /* actually only needs to be 16+20 */ - unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2]; - /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ - unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; - int finish_md_len; - unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; - int peer_finish_md_len; - unsigned long message_size; - int message_type; - /* used to hold the new cipher we are going to use */ - const SSL_CIPHER *new_cipher; -# ifndef OPENSSL_NO_DH - DH *dh; -# endif -# ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh; /* holds short lived ECDH key */ -# endif - /* used when SSL_ST_FLUSH_DATA is entered */ - int next_state; - int reuse_message; - /* used for certificate requests */ - int cert_req; - int ctype_num; - char ctype[SSL3_CT_NUMBER]; - STACK_OF(X509_NAME) *ca_names; - int use_rsa_tmp; - int key_block_length; - unsigned char *key_block; - const EVP_CIPHER *new_sym_enc; - const EVP_MD *new_hash; - int new_mac_pkey_type; - int new_mac_secret_size; -# ifndef OPENSSL_NO_COMP - const SSL_COMP *new_compression; -# else - char *new_compression; -# endif - int cert_request; - } tmp; - - /* Connection binding to prevent renegotiation attacks */ - unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; - unsigned char previous_client_finished_len; - unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; - unsigned char previous_server_finished_len; - int send_connection_binding; /* TODOEKR */ - -# ifndef OPENSSL_NO_NEXTPROTONEG - /* - * Set if we saw the Next Protocol Negotiation extension from our peer. - */ - int next_proto_neg_seen; -# endif - -# ifndef OPENSSL_NO_TLSEXT - - /* - * ALPN information (we are in the process of transitioning from NPN to - * ALPN.) - */ - - /* - * In a server these point to the selected ALPN protocol after the - * ClientHello has been processed. In a client these contain the protocol - * that the server selected once the ServerHello has been processed. - */ - unsigned char *alpn_selected; - unsigned alpn_selected_len; - -# ifndef OPENSSL_NO_EC - /* - * This is set to true if we believe that this is a version of Safari - * running on OS X 10.6 or newer. We wish to know this because Safari on - * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. - */ - char is_probably_safari; -# endif /* !OPENSSL_NO_EC */ - -# endif /* !OPENSSL_NO_TLSEXT */ -} SSL3_STATE; - -# endif /* SSLv3 */ /* diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index f3ce460665..56d6108ea3 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -520,6 +520,1042 @@ #define CERT_PRIVATE_KEY 2 */ +/* used to hold info on the particular ciphers used */ +struct ssl_cipher_st { + int valid; + const char *name; /* text name */ + unsigned long id; /* id, 4 bytes, first is version */ + /* + * changed in 0.9.9: these four used to be portions of a single value + * 'algorithms' + */ + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + unsigned long algo_strength; /* strength and export flags */ + unsigned long algorithm2; /* Extra flags */ + int strength_bits; /* Number of bits really used */ + int alg_bits; /* Number of bits for algorithm */ +}; + +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ +struct ssl_method_st { + int version; + int (*ssl_new) (SSL *s); + void (*ssl_clear) (SSL *s); + void (*ssl_free) (SSL *s); + int (*ssl_accept) (SSL *s); + int (*ssl_connect) (SSL *s); + int (*ssl_read) (SSL *s, void *buf, int len); + int (*ssl_peek) (SSL *s, void *buf, int len); + int (*ssl_write) (SSL *s, const void *buf, int len); + int (*ssl_shutdown) (SSL *s); + int (*ssl_renegotiate) (SSL *s); + int (*ssl_renegotiate_check) (SSL *s); + long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long + max, int *ok); + int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len, + int peek); + int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len); + int (*ssl_dispatch_alert) (SSL *s); + long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); + long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg); + const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr); + int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr); + int (*ssl_pending) (const SSL *s); + int (*num_ciphers) (void); + const SSL_CIPHER *(*get_cipher) (unsigned ncipher); + const struct ssl_method_st *(*get_ssl_method) (int version); + long (*get_timeout) (void); + const struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ + int (*ssl_version) (void); + long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void)); + long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); +}; + +/*- + * Lets make this into an ASN.1 type structure as follows + * SSL_SESSION_ID ::= SEQUENCE { + * version INTEGER, -- structure version number + * SSLversion INTEGER, -- SSL version number + * Cipher OCTET STRING, -- the 3 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument + * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time + * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds + * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity + * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket + * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) + * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method + * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username + * } + * Look in ssl/ssl_asn1.c for more details + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). + */ +struct ssl_session_st { + int ssl_version; /* what ssl version session info is being + * kept in here? */ + int master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + /* session_id - valid? */ + unsigned int session_id_length; + unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + /* + * this is used to determine whether the session is being reused in the + * appropriate context. It is up to the application to set this, via + * SSL_new + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; +# ifndef OPENSSL_NO_KRB5 + unsigned int krb5_client_princ_len; + unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + char *psk_identity; +# endif + /* + * Used to indicate that session resumption is not allowed. Applications + * can also set this bit for a new session via not_resumable_session_cb + * to disable session caching and tickets. + */ + int not_resumable; + /* The cert is the certificate used to establish this connection */ + struct sess_cert_st /* SESS_CERT */ *sess_cert; + /* + * This is the cert for the other end. On clients, it will be the same as + * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is + * not retained in the external representation of sessions, see + * ssl_asn1.c). + */ + X509 *peer; + /* + * when app_verify_callback accepts a session where the peer's + * certificate is not ok, we must remember the error for session reuse: + */ + long verify_result; /* only for servers */ + int references; + long timeout; + long time; + unsigned int compress_meth; /* Need to lookup the method */ + const SSL_CIPHER *cipher; + unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used + * to load the 'cipher' structure */ + STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ + CRYPTO_EX_DATA ex_data; /* application specific data */ + /* + * These are used to make removal of session-ids more efficient and to + * implement a maximum cache size. + */ + struct ssl_session_st *prev, *next; +# ifndef OPENSSL_NO_TLSEXT + char *tlsext_hostname; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* peer's list */ +# endif /* OPENSSL_NO_EC */ + /* RFC4507 info */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ +# endif +# ifndef OPENSSL_NO_SRP + char *srp_username; +# endif +}; + + +# ifndef OPENSSL_NO_SRP + +typedef struct srp_ctx_st { + /* param for all the callbacks */ + void *SRP_cb_arg; + /* set client Hello login callback */ + int (*TLS_ext_srp_username_callback) (SSL *, int *, void *); + /* set SRP N/g param callback for verification */ + int (*SRP_verify_param_callback) (SSL *, void *); + /* set SRP client passwd callback */ + char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *); + char *login; + BIGNUM *N, *g, *s, *B, *A; + BIGNUM *a, *b, *v; + char *info; + int strength; + unsigned long srp_Mask; +} SRP_CTX; + +# endif + + +struct ssl_comp_st { + int id; + const char *name; +# ifndef OPENSSL_NO_COMP + COMP_METHOD *method; +# else + char *method; +# endif +}; + +DECLARE_STACK_OF(SSL_COMP) +DECLARE_LHASH_OF(SSL_SESSION); + +struct ssl_ctx_st { + const SSL_METHOD *method; + STACK_OF(SSL_CIPHER) *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + struct x509_store_st /* X509_STORE */ *cert_store; + LHASH_OF(SSL_SESSION) *sessions; + /* + * Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. + */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; + /* + * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT, + * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which + * means only SSL_accept which cache SSL_SESSIONS. + */ + int session_cache_mode; + /* + * If timeout is not 0, it is the default timeout value set when + * SSL_new() is called. This has been put in to make life easier to set + * things up + */ + long session_timeout; + /* + * If this callback is not null, it will be called each time a session id + * is added to the cache. If this function returns 1, it means that the + * callback will do a SSL_SESSION_free() when it has finished using it. + * Otherwise, on 0, it means the callback has finished with it. If + * remove_session_cb is not null, it will be called when a session-id is + * removed from the cache. After the call, OpenSSL will + * SSL_SESSION_free() it. + */ + int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess); + void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl, + unsigned char *data, int len, int *copy); + struct { + int sess_connect; /* SSL new conn - started */ + int sess_connect_renegotiate; /* SSL reneg - requested */ + int sess_connect_good; /* SSL new conne/reneg - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate; /* SSL reneg - requested */ + int sess_accept_good; /* SSL accept/reneg - finished */ + int sess_miss; /* session lookup misses */ + int sess_timeout; /* reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ + int sess_hit; /* session reuse actually done */ + int sess_cb_hit; /* session-id that was not in the cache was + * passed back via the callback. This + * indicates that the application is + * supplying session-id's from other + * processes - spooky :-) */ + } stats; + + int references; + + /* if defined, these override the X509_verify_cert() calls */ + int (*app_verify_callback) (X509_STORE_CTX *, void *); + void *app_verify_arg; + /* + * before OpenSSL 0.9.7, 'app_verify_arg' was ignored + * ('app_verify_callback' was called with just one argument) + */ + + /* Default password callback. */ + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + void *default_passwd_callback_userdata; + + /* get client cert callback */ + int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey); + + /* cookie generate callback */ + int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); + + /* verify cookie callback */ + int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int cookie_len); + + CRYPTO_EX_DATA ex_data; + + const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ + const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ + + STACK_OF(X509) *extra_certs; + STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ + + /* Default values used when no per-SSL value is defined follow */ + + /* used if SSL's info_callback is NULL */ + void (*info_callback) (const SSL *ssl, int type, int val); + + /* what we put in client cert requests */ + STACK_OF(X509_NAME) *client_CA; + + /* + * Default values to use in SSL structures follow (these are copied by + * SSL_new) + */ + + unsigned long options; + unsigned long mode; + long max_cert_list; + + struct cert_st /* CERT */ *cert; + int read_ahead; + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int verify_mode; + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* called 'verify_callback' in the SSL */ + int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + X509_VERIFY_PARAM *param; + + int quiet_shutdown; + + /* + * Maximum amount of data to send in one fragment. actual record size can + * be more than this due to padding and MAC overheads. + */ + unsigned int max_send_fragment; + +# ifndef OPENSSL_NO_ENGINE + /* + * Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +# endif + +# ifndef OPENSSL_NO_TLSEXT + /* TLS extensions servername callback */ + int (*tlsext_servername_callback) (SSL *, int *, void *); + void *tlsext_servername_arg; + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; + /* Callback to support customisation of ticket key setting */ + int (*tlsext_ticket_key_cb) (SSL *ssl, + unsigned char *name, unsigned char *iv, + EVP_CIPHER_CTX *ectx, + HMAC_CTX *hctx, int enc); + + /* certificate status request info */ + /* Callback for status request */ + int (*tlsext_status_cb) (SSL *ssl, void *arg); + void *tlsext_status_arg; +# endif + +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + +# ifndef OPENSSL_NO_SRP + SRP_CTX srp_ctx; /* ctx for SRP authentication */ +# endif + +# ifndef OPENSSL_NO_TLSEXT + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* Next protocol negotiation information */ + /* (for experimental NPN extension). */ + + /* + * For a server, this contains a callback function by which the set of + * advertised protocols can be provided. + */ + int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf, + unsigned int *len, void *arg); + void *next_protos_advertised_cb_arg; + /* + * For a client, this contains a callback function that selects the next + * protocol from the list provided by the server. + */ + int (*next_proto_select_cb) (SSL *s, unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, void *arg); + void *next_proto_select_cb_arg; +# endif + + /* + * ALPN information (we are in the process of transitioning from NPN to + * ALPN.) + */ + + /*- + * For a server, this contains a callback function that allows the + * server to select the protocol for the connection. + * out: on successful return, this must point to the raw protocol + * name (without the length prefix). + * outlen: on successful return, this contains the length of |*out|. + * in: points to the client's list of supported protocols in + * wire-format. + * inlen: the length of |in|. + */ + int (*alpn_select_cb) (SSL *s, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, void *arg); + void *alpn_select_cb_arg; + + /* + * For a client, this contains the list of supported protocols in wire + * format. + */ + unsigned char *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; + + /* SRTP profiles we are willing to do from RFC 5764 */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; +# endif + /* + * Callback for disabling session caching and ticket support on a session + * basis, depending on the chosen cipher. + */ + int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure); +# ifndef OPENSSL_NO_EC + /* EC extension values inherited by SSL structure */ + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; +# endif /* OPENSSL_NO_EC */ +}; + + +struct ssl_st { + /* + * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, + * DTLS1_VERSION) + */ + int version; + /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ + int type; + /* SSLv3 */ + const SSL_METHOD *method; + /* + * There are 2 BIO's even though they are normally both the same. This + * is so data can be read and written to different handlers + */ + /* used by SSL_read */ + BIO *rbio; + /* used by SSL_write */ + BIO *wbio; + /* used during session-id reuse to concatenate messages */ + BIO *bbio; + /* + * This holds a variable that indicates what we were doing when a 0 or -1 + * is returned. This is needed for non-blocking IO so we know what + * request needs re-doing when in SSL_accept or SSL_connect + */ + int rwstate; + /* true when we are actually in SSL_accept() or SSL_connect() */ + int in_handshake; + int (*handshake_func) (SSL *); + /* + * Imagine that here's a boolean member "init" that is switched as soon + * as SSL_set_{accept/connect}_state is called for the first time, so + * that "state" and "handshake_func" are properly initialized. But as + * handshake_func is == 0 until then, we use this test instead of an + * "init" member. + */ + /* are we the server side? - mostly used by SSL_clear */ + int server; + /* + * Generate a new session or reuse an old one. + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set + */ + int new_session; + /* don't send shutdown packets */ + int quiet_shutdown; + /* we have shut things down, 0x01 sent, 0x02 for received */ + int shutdown; + /* where we are */ + int state; + /* where we are when reading */ + int rstate; + BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by + * ssl3_get_message() */ + int init_num; /* amount read/written */ + int init_off; /* amount read/written */ + /* used internally to point at a raw packet */ + unsigned char *packet; + unsigned int packet_length; + struct ssl3_state_st *s3; /* SSLv3 variables */ + struct dtls1_state_st *d1; /* DTLSv1 variables */ + int read_ahead; /* Read as many input bytes as possible (for + * non-blocking reads) */ + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + int hit; /* reusing a previous session */ + X509_VERIFY_PARAM *param; + /* crypto */ + STACK_OF(SSL_CIPHER) *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* + * These are the ones being used, the ones in SSL_SESSION are the ones to + * be 'copied' into these ones + */ + int mac_flags; + EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ + EVP_MD_CTX *read_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *expand; /* uncompress */ +# else + char *expand; +# endif + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + /* session info */ + /* client cert? */ + /* This is used to hold the server certificate used */ + struct cert_st /* CERT */ *cert; + /* + * the session_id_context is used to ensure sessions are only reused in + * the appropriate context + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* This can also be in the session once a session is established */ + SSL_SESSION *session; + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + /* Used in SSL3 */ + /* + * 0 don't care about verify failure. + * 1 fail if verify fails + */ + int verify_mode; + /* fail if callback returns 0 */ + int (*verify_callback) (int ok, X509_STORE_CTX *ctx); + /* optional informational callback */ + void (*info_callback) (const SSL *ssl, int type, int val); + /* error bytes to be written */ + int error; + /* actual code */ + int error_code; +# ifndef OPENSSL_NO_KRB5 + /* Kerberos 5 context */ + KSSL_CTX *kssl_ctx; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + SSL_CTX *ctx; + /* + * set this flag to 1 and a sleep(1) is put into all SSL_read() and + * SSL_write() calls, good for nbio debuging :-) + */ + int debug; + /* extra application data */ + long verify_result; + CRYPTO_EX_DATA ex_data; + /* for server side, keep the list of CA_dn we can use */ + STACK_OF(X509_NAME) *client_CA; + int references; + /* protocol behaviour */ + unsigned long options; + /* API behaviour */ + unsigned long mode; + long max_cert_list; + int first_packet; + /* what was passed, used for SSLv3/TLS rollback check */ + int client_version; + unsigned int max_send_fragment; +# ifndef OPENSSL_NO_TLSEXT + /* TLS extension debug callback */ + void (*tlsext_debug_cb) (SSL *s, int client_server, int type, + unsigned char *data, int len, void *arg); + void *tlsext_debug_arg; + char *tlsext_hostname; + /*- + * no further mod of servername + * 0 : call the servername extension callback. + * 1 : prepare 2, allow last ack just after in server callback. + * 2 : don't call servername callback, no ack in server hello + */ + int servername_done; + /* certificate status request info */ + /* Status type or -1 if no status type */ + int tlsext_status_type; + /* Expect OCSP CertificateStatus message */ + int tlsext_status_expected; + /* OCSP status request only */ + STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; + X509_EXTENSIONS *tlsext_ocsp_exts; + /* OCSP response received or to be sent */ + unsigned char *tlsext_ocsp_resp; + int tlsext_ocsp_resplen; + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + /* our list */ + unsigned char *tlsext_ecpointformatlist; + size_t tlsext_ellipticcurvelist_length; + /* our list */ + unsigned char *tlsext_ellipticcurvelist; +# endif /* OPENSSL_NO_EC */ + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */ +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Next protocol negotiation. For the client, this is the protocol that + * we sent in NextProtocol and is set when handling ServerHello + * extensions. For a server, this is the client's selected_protocol from + * NextProtocol and is set when handling the NextProtocol message, before + * the Finished message. + */ + unsigned char *next_proto_negotiated; + unsigned char next_proto_negotiated_len; +# endif +# define session_ctx initial_ctx + /* What we'll do */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + /* What's been chosen */ + SRTP_PROTECTION_PROFILE *srtp_profile; + /*- + * Is use of the Heartbeat extension negotiated? + * 0: disabled + * 1: enabled + * 2: enabled, but not allowed to send Requests + */ + unsigned int tlsext_heartbeat; + /* Indicates if a HeartbeatRequest is in flight */ + unsigned int tlsext_hb_pending; + /* HeartbeatRequest sequence number */ + unsigned int tlsext_hb_seq; + /* + * For a client, this contains the list of supported protocols in wire + * format. + */ + unsigned char *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; +# else +# define session_ctx ctx +# endif /* OPENSSL_NO_TLSEXT */ + /*- + * 1 if we are renegotiating. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) + */ + int renegotiate; +# ifndef OPENSSL_NO_SRP + /* ctx for SRP authentication */ + SRP_CTX srp_ctx; +# endif + /* + * Callback for disabling session caching and ticket support on a session + * basis, depending on the chosen cipher. + */ + int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure); +}; + +typedef struct ssl3_record_st { + /* type of record */ + /* + * r + */ int type; + /* How many bytes available */ + /* + * rw + */ unsigned int length; + /* + * How many bytes were available before padding was removed? This is used + * to implement the MAC check in constant time for CBC records. + */ + /* + * rw + */ unsigned int orig_len; + /* read/write offset into 'buf' */ + /* + * r + */ unsigned int off; + /* pointer to the record data */ + /* + * rw + */ unsigned char *data; + /* where the decode bytes are */ + /* + * rw + */ unsigned char *input; + /* only used with decompression - malloc()ed */ + /* + * r + */ unsigned char *comp; + /* epoch number, needed by DTLS1 */ + /* + * r + */ unsigned long epoch; + /* sequence number, needed by DTLS1 */ + /* + * r + */ unsigned char seq_num[8]; +} SSL3_RECORD; + +typedef struct ssl3_buffer_st { + /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ + unsigned char *buf; + /* buffer size */ + size_t len; + /* where to 'copy from' */ + int offset; + /* how many bytes left */ + int left; +} SSL3_BUFFER; + +typedef struct ssl3_state_st { + long flags; + int delay_buf_pop_ret; + unsigned char read_sequence[8]; + int read_mac_secret_size; + unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char write_sequence[8]; + int write_mac_secret_size; + unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + /* The value of 'extra' when the buffers were initialized */ + int init_extra; + SSL3_BUFFER rbuf; /* read IO goes into here */ + SSL3_BUFFER wbuf; /* write IO goes into here */ + SSL3_RECORD rrec; /* each decoded record goes in here */ + SSL3_RECORD wrec; /* goes out from here */ + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[2]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[4]; + unsigned int handshake_fragment_len; + /* partial write - check the numbers match */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; /* number bytes written */ + int wpend_type; + int wpend_ret; /* number of bytes submitted */ + const unsigned char *wpend_buf; + /* used during startup, digest all incoming/outgoing packets */ + BIO *handshake_buffer; + /* + * When set of handshake digests is determined, buffer is hashed and + * freed and MD_CTX-es for all required digests are stored in this array + */ + EVP_MD_CTX **handshake_dgst; + /* + * Set whenever an expected ChangeCipherSpec message is processed. + * Unset when the peer's Finished message is received. + * Unexpected ChangeCipherSpec messages trigger a fatal alert. + */ + int change_cipher_spec; + int warn_alert; + int fatal_alert; + /* + * we allow one fatal and one warning alert to be outstanding, send close + * alert via the warning alert + */ + int alert_dispatch; + unsigned char send_alert[2]; + /* + * This flag is set when we should renegotiate ASAP, basically when there + * is no more data in the read or write buffers + */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + int in_read_app_data; + struct { + /* actually only needs to be 16+20 */ + unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2]; + /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; + int finish_md_len; + unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; + int peer_finish_md_len; + unsigned long message_size; + int message_type; + /* used to hold the new cipher we are going to use */ + const SSL_CIPHER *new_cipher; +# ifndef OPENSSL_NO_DH + DH *dh; +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh; /* holds short lived ECDH key */ +# endif + /* used when SSL_ST_FLUSH_DATA is entered */ + int next_state; + int reuse_message; + /* used for certificate requests */ + int cert_req; + int ctype_num; + char ctype[SSL3_CT_NUMBER]; + STACK_OF(X509_NAME) *ca_names; + int use_rsa_tmp; + int key_block_length; + unsigned char *key_block; + const EVP_CIPHER *new_sym_enc; + const EVP_MD *new_hash; + int new_mac_pkey_type; + int new_mac_secret_size; +# ifndef OPENSSL_NO_COMP + const SSL_COMP *new_compression; +# else + char *new_compression; +# endif + int cert_request; + } tmp; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_server_finished_len; + int send_connection_binding; /* TODOEKR */ + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Set if we saw the Next Protocol Negotiation extension from our peer. + */ + int next_proto_neg_seen; +# endif + +# ifndef OPENSSL_NO_TLSEXT + + /* + * ALPN information (we are in the process of transitioning from NPN to + * ALPN.) + */ + + /* + * In a server these point to the selected ALPN protocol after the + * ClientHello has been processed. In a client these contain the protocol + * that the server selected once the ServerHello has been processed. + */ + unsigned char *alpn_selected; + unsigned alpn_selected_len; + +# ifndef OPENSSL_NO_EC + /* + * This is set to true if we believe that this is a version of Safari + * running on OS X 10.6 or newer. We wish to know this because Safari on + * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. + */ + char is_probably_safari; +# endif /* !OPENSSL_NO_EC */ + +# endif /* !OPENSSL_NO_TLSEXT */ +} SSL3_STATE; + + +/* DTLS structures */ + +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" +# endif + +/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */ +# define DTLS1_MAX_MTU_OVERHEAD 48 + +typedef struct dtls1_bitmap_st { + unsigned long map; /* track 32 packets on 32-bit systems and 64 + * - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit + * value in big-endian encoding */ +} DTLS1_BITMAP; + +struct dtls1_retransmit_state { + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + SSL_SESSION *session; + unsigned short epoch; +}; + +struct hm_header_st { + unsigned char type; + unsigned long msg_len; + unsigned short seq; + unsigned long frag_off; + unsigned long frag_len; + unsigned int is_ccs; + struct dtls1_retransmit_state saved_retransmit_state; +}; + +struct ccs_header_st { + unsigned char type; + unsigned short seq; +}; + +struct dtls1_timeout_st { + /* Number of read timeouts so far */ + unsigned int read_timeouts; + /* Number of write timeouts so far */ + unsigned int write_timeouts; + /* Number of alerts received so far */ + unsigned int num_alerts; +}; + +typedef struct record_pqueue_st { + unsigned short epoch; + pqueue q; +} record_pqueue; + +typedef struct hm_fragment_st { + struct hm_header_st msg_header; + unsigned char *fragment; + unsigned char *reassembly; +} hm_fragment; + +typedef struct dtls1_state_st { + unsigned int send_cookie; + unsigned char cookie[DTLS1_COOKIE_LENGTH]; + unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; + unsigned int cookie_len; + /* + * The current data and handshake epoch. This is initially + * undefined, and starts at zero once the initial handshake is + * completed + */ + unsigned short r_epoch; + unsigned short w_epoch; + /* records being received in the current epoch */ + DTLS1_BITMAP bitmap; + /* renegotiation starts a new set of sequence numbers */ + DTLS1_BITMAP next_bitmap; + /* handshake message numbers */ + unsigned short handshake_write_seq; + unsigned short next_handshake_write_seq; + unsigned short handshake_read_seq; + /* save last sequence number for retransmissions */ + unsigned char last_write_sequence[8]; + /* Received handshake records (processed and unprocessed) */ + record_pqueue unprocessed_rcds; + record_pqueue processed_rcds; + /* Buffered handshake messages */ + pqueue buffered_messages; + /* Buffered (sent) handshake records */ + pqueue sent_messages; + /* + * Buffered application records. Only for records between CCS and + * Finished to prevent either protocol violation or unnecessary message + * loss. + */ + record_pqueue buffered_app_data; + /* Is set when listening for new connections with dtls1_listen() */ + unsigned int listen; + unsigned int link_mtu; /* max on-the-wire DTLS packet size */ + unsigned int mtu; /* max DTLS packet size */ + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; + struct dtls1_timeout_st timeout; + /* + * Indicates when the last handshake msg or heartbeat sent will timeout + */ + struct timeval next_timeout; + /* Timeout duration */ + unsigned short timeout_duration; + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; + unsigned int handshake_fragment_len; + unsigned int retransmitting; + /* + * Set when the handshake is ready to process peer's ChangeCipherSpec message. + * Cleared after the message has been processed. + */ + unsigned int change_cipher_spec_ok; +# ifndef OPENSSL_NO_SCTP + /* used when SSL_ST_XX_FLUSH is entered */ + int next_state; + int shutdown_received; +# endif +} DTLS1_STATE; + +typedef struct dtls1_record_data_st { + unsigned char *packet; + unsigned int packet_length; + SSL3_BUFFER rbuf; + SSL3_RECORD rrec; +# ifndef OPENSSL_NO_SCTP + struct bio_dgram_sctp_rcvinfo recordinfo; +# endif +} DTLS1_RECORD_DATA; + + # ifndef OPENSSL_NO_EC /* * From ECC-TLS draft, used in encoding the curve type in ECParameters diff --git a/ssl/ssltest.c b/ssl/ssltest.c index fb78aeaf9c..7bf7e5577d 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -188,6 +188,8 @@ #endif #include +#include "../ssl/ssl_locl.h" + /* * Or gethostname won't be declared properly * on Compaq platforms (at least with DEC C). -- 2.34.1