+
+/* CipherSuite length. SSLv3 and all TLS versions. */
+#define TLS_CIPHER_LEN 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, int *recvd_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
+ * 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
+ * flags [ 13 ] EXPLICIT INTEGER -- optional flags
+ * }
+ * 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_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;
+ /* This is the cert and type for the other end. */
+ X509 *peer;
+ int peer_type;
+ /* Certificate chain of peer */
+ STACK_OF(X509) *peer_chain;
+ /*
+ * 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;
+ 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 */
+ unsigned long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
+# ifndef OPENSSL_NO_SRP
+ char *srp_username;
+# endif
+ uint32_t flags;
+};
+
+/* Extended master secret support */
+# define SSL_SESS_FLAG_EXTMS 0x1
+
+
+# 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
+
+typedef struct ssl_comp_st SSL_COMP;
+
+struct ssl_comp_st {
+ int id;
+ const char *name;
+ COMP_METHOD *method;
+};
+
+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.
+ */
+ uint32_t 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)
+ */
+
+ uint32_t options;
+ uint32_t 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;
+
+ uint32_t 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
+
+ /* 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;
+
+# 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
+
+# ifndef OPENSSL_NO_SRP
+ SRP_CTX srp_ctx; /* ctx for SRP authentication */
+# endif
+
+# 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;
+ /*
+ * 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;
+ 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 */
+
+ struct ssl3_state_st *s3; /* SSLv3 variables */
+ struct dtls1_state_st *d1; /* DTLSv1 variables */
+
+ /* 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
+ */
+ uint32_t mac_flags;
+ EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
+ EVP_MD_CTX *read_hash; /* used for mac generation */
+ COMP_CTX *compress; /* compression */
+ COMP_CTX *expand; /* uncompress */
+ EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+ EVP_MD_CTX *write_hash; /* used for mac generation */
+ /* 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
+ */
+ uint32_t 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_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 */
+ uint32_t options;
+ /* API behaviour */
+ uint32_t 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;
+
+ /* 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;
+
+ /*-
+ * 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);
+
+ RECORD_LAYER rlayer;
+};
+
+
+typedef struct ssl3_state_st {
+ long flags;
+ int read_mac_secret_size;
+ unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
+ 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;
+ /* 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_EC
+ 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;
+ /* Raw values of the cipher list from a client */
+ unsigned char *ciphers_raw;
+ size_t ciphers_rawlen;
+ /* Temporary storage for premaster secret */
+ unsigned char *pms;
+ size_t pmslen;
+#ifndef OPENSSL_NO_PSK
+ /* Temporary storage for PSK key */
+ unsigned char *psk;
+ size_t psklen;
+#endif
+ /*
+ * signature algorithms peer reports: e.g. supported signature
+ * algorithms extension for server or as part of a certificate
+ * request for client.
+ */
+ unsigned char *peer_sigalgs;
+ /* Size of above array */
+ size_t peer_sigalgslen;
+ /* Digest peer uses for signing */
+ const EVP_MD *peer_md;
+ /* Array of digests used for signing */
+ const EVP_MD *md[SSL_PKEY_NUM];
+ /*
+ * Set if corresponding CERT_PKEY can be used with current
+ * SSL session: e.g. appropriate curve, signature algorithms etc.
+ * If zero it can't be used at all.
+ */
+ uint32_t valid_flags[SSL_PKEY_NUM];
+ /*
+ * For servers the following masks are for the key and auth algorithms
+ * that are supported by the certs below. For clients they are masks of
+ * *disabled* algorithms based on the current session.
+ */
+ unsigned long mask_k;
+ unsigned long mask_a;
+ unsigned long export_mask_k;
+ unsigned long export_mask_a;
+ /* Client only */
+ unsigned long mask_ssl;
+ } 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
+
+ /*
+ * 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 */
+
+ /* For clients: peer temporary key */
+# ifndef OPENSSL_NO_RSA
+ RSA *peer_rsa_tmp;
+# endif
+# ifndef OPENSSL_NO_DH
+ DH *peer_dh_tmp;
+# endif
+# ifndef OPENSSL_NO_EC
+ EC_KEY *peer_ecdh_tmp;
+# endif
+
+} 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
+
+/*
+ * Flag used in message reuse to indicate the buffer contains the record
+ * header as well as the the handshake message header.
+ */
+# define DTLS1_SKIP_RECORD_HEADER 2
+
+struct dtls1_retransmit_state {
+ EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+ EVP_MD_CTX *write_hash; /* used for mac generation */
+ COMP_CTX *compress; /* compression */
+ 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 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 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;
+
+ /* handshake message numbers */
+ unsigned short handshake_write_seq;
+ unsigned short next_handshake_write_seq;
+ unsigned short handshake_read_seq;
+
+ /* Buffered handshake messages */
+ pqueue buffered_messages;
+ /* Buffered (sent) handshake records */
+ pqueue sent_messages;
+
+ 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;
+
+ unsigned int retransmitting;
+# ifndef OPENSSL_NO_SCTP
+ /* used when SSL_ST_XX_FLUSH is entered */
+ int next_state;
+ int shutdown_received;
+# endif
+} DTLS1_STATE;
+
+
+