Implement SSL_clear with ssl_new and ssl_free.

State on s3 gets freed in both ssl3_clear and ssl3_free. Considate to just
ssl3_free. This replaces the (SSL,ssl,ssl3)_clear calls in (SSL,ssl,ssl3)_new
with the state that was initialized. This results in a little code duplication
between SSL_new and SSL_clear because state is on the wrong object. I've just
left TODOs for now; some of it will need disentangling.

We're far from it, but going forward, separate state between s and s->s3 as:

- s contains configuration state, DTLS or TLS. It is initialized from SSL_CTX,
  configurable directly afterwards, and preserved across SSL_clear calls.
  (Including when it's implicitly set as part of a handshake callback.)

- Connection state hangs off s->s3 (TLS) and s->d1 (DTLS). It is reset across
  SSL_clear. This should happen naturally out of a ssl_free/ssl_new pair.

The goal is to avoid needing separate initialize and reset code for anything;
the point any particular state is reset is the point its owning context is
destroyed and recreated.

Change-Id: I5d779010778109f8c339c07433a0777feaf94d1f
Reviewed-on: https://boringssl-review.googlesource.com/2822
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index e783c8f..ef4e024 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -640,15 +640,20 @@
   memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num));
 
   s->s3 = s3;
-  s->method->ssl_clear(s);
 
+  /* Set the version to the highest supported version for TLS. This controls the
+   * initial state of |s->enc_method| and what the API reports as the version
+   * prior to negotiation.
+   *
+   * TODO(davidben): This is fragile and confusing. */
+  s->version = TLS1_2_VERSION;
   return 1;
 err:
   return 0;
 }
 
 void ssl3_free(SSL *s) {
-  if (s == NULL) {
+  if (s == NULL || s->s3 == NULL) {
     return;
   }
 
@@ -699,92 +704,6 @@
   s->s3 = NULL;
 }
 
-void ssl3_clear(SSL *s) {
-  uint8_t *rp, *wp;
-  size_t rlen, wlen;
-  int init_extra;
-
-  /* TODO(davidben): Can this just call ssl3_free + ssl3_new. rbuf, wbuf, and
-   * init_extra are preserved, but this may not serve anything more than saving
-   * a malloc. */
-
-  if (s->s3->sniff_buffer != NULL) {
-    BUF_MEM_free(s->s3->sniff_buffer);
-  }
-  s->s3->sniff_buffer = NULL;
-
-  ssl3_cleanup_key_block(s);
-  if (s->s3->tmp.ca_names != NULL) {
-    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
-  }
-  s->s3->tmp.ca_names = NULL;
-  if (s->s3->tmp.certificate_types != NULL) {
-    OPENSSL_free(s->s3->tmp.certificate_types);
-  }
-  s->s3->tmp.certificate_types = NULL;
-  if (s->s3->tmp.peer_ecpointformatlist) {
-    OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
-  }
-  s->s3->tmp.peer_ecpointformatlist = NULL;
-  if (s->s3->tmp.peer_ellipticcurvelist) {
-    OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
-  }
-  s->s3->tmp.peer_ellipticcurvelist = NULL;
-  if (s->s3->tmp.peer_psk_identity_hint) {
-    OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
-  }
-  s->s3->tmp.peer_psk_identity_hint = NULL;
-
-  if (s->s3->tmp.dh != NULL) {
-    DH_free(s->s3->tmp.dh);
-    s->s3->tmp.dh = NULL;
-  }
-  if (s->s3->tmp.ecdh != NULL) {
-    EC_KEY_free(s->s3->tmp.ecdh);
-    s->s3->tmp.ecdh = NULL;
-  }
-  rp = s->s3->rbuf.buf;
-  wp = s->s3->wbuf.buf;
-  rlen = s->s3->rbuf.len;
-  wlen = s->s3->wbuf.len;
-  init_extra = s->s3->init_extra;
-  if (s->s3->handshake_buffer) {
-    BIO_free(s->s3->handshake_buffer);
-    s->s3->handshake_buffer = NULL;
-  }
-  if (s->s3->handshake_dgst) {
-    ssl3_free_digest_list(s);
-  }
-
-  if (s->s3->alpn_selected) {
-    OPENSSL_free(s->s3->alpn_selected);
-    s->s3->alpn_selected = NULL;
-  }
-  memset(s->s3, 0, sizeof *s->s3);
-  s->s3->rbuf.buf = rp;
-  s->s3->wbuf.buf = wp;
-  s->s3->rbuf.len = rlen;
-  s->s3->wbuf.len = wlen;
-  s->s3->init_extra = init_extra;
-
-  ssl_free_wbio_buffer(s);
-
-  s->packet_length = 0;
-  s->s3->renegotiate = 0;
-  s->s3->total_renegotiations = 0;
-  s->s3->num_renegotiations = 0;
-  s->s3->in_read_app_data = 0;
-  s->version = TLS1_2_VERSION;
-
-  if (s->next_proto_negotiated) {
-    OPENSSL_free(s->next_proto_negotiated);
-    s->next_proto_negotiated = NULL;
-    s->next_proto_negotiated_len = 0;
-  }
-
-  s->s3->tlsext_channel_id_valid = 0;
-}
-
 static int ssl3_set_req_cert_type(CERT *c, const uint8_t *p, size_t len);
 
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) {