If SSL_clear is called before SSL_set_{connect,accept}_state (as SSL_new does internally), s->state will get set prematurely. Likewise, s->server is set based on the method's ssl_accept hook, but client SSL's may be initialized from a generic SSL_METHOD too. Since we can't easily get rid of the generic SSL_METHODs, defer s->state and s->server initialization until the side is known. Change-Id: I0972e17083df22a3c09f6f087011b54c699a22e7 Reviewed-on: https://boringssl-review.googlesource.com/2439 Reviewed-by: Adam Langley <agl@google.com>kris/onging/CECPQ3_patch15
@@ -1188,7 +1188,11 @@ struct ssl_st | |||||
* test instead of an "init" member. | * test instead of an "init" member. | ||||
*/ | */ | ||||
int server; /* are we the server side? - mostly used by SSL_clear*/ | |||||
/* server is true iff the this SSL* is the server half. Note: | |||||
* before the SSL* is initialized by either | |||||
* SSL_set_accept_state or SSL_set_connect_state, the side is | |||||
* not determined. In this state, server is always false. */ | |||||
int server; | |||||
int new_session;/* Generate a new session or reuse an old one. | int new_session;/* Generate a new session or reuse an old one. | ||||
* NB: For servers, the 'new' session may actually be a previously | * NB: For servers, the 'new' session may actually be a previously | ||||
@@ -210,7 +210,20 @@ int SSL_clear(SSL *s) | |||||
} | } | ||||
#endif | #endif | ||||
s->state=SSL_ST_BEFORE|((s->server)?SSL_ST_ACCEPT:SSL_ST_CONNECT); | |||||
/* SSL_clear may be called before or after the |s| is initialized in | |||||
* either accept or connect state. In the latter case, SSL_clear should | |||||
* preserve the half and reset |s->state| accordingly. */ | |||||
if (s->handshake_func != NULL) | |||||
{ | |||||
if (s->server) | |||||
SSL_set_accept_state(s); | |||||
else | |||||
SSL_set_connect_state(s); | |||||
} | |||||
else | |||||
{ | |||||
assert(s->state == 0); | |||||
} | |||||
s->version=s->method->version; | s->version=s->method->version; | ||||
s->client_version=s->version; | s->client_version=s->version; | ||||
@@ -369,7 +382,6 @@ SSL *SSL_new(SSL_CTX *ctx) | |||||
goto err; | goto err; | ||||
s->references=1; | s->references=1; | ||||
s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1; | |||||
SSL_clear(s); | SSL_clear(s); | ||||