+static void do_reneg_setup_step(PEER *peer)
+{
+ int ret;
+ char buf;
+
+ TEST_check(peer->status == PEER_RETRY);
+ /* We only support client initiated reneg at the moment */
+ /* TODO: server side */
+ if (!SSL_is_server(peer->ssl)) {
+ ret = SSL_renegotiate(peer->ssl);
+ if (!ret) {
+ peer->status = PEER_ERROR;
+ return;
+ }
+ do_handshake_step(peer);
+ /*
+ * If status is PEER_RETRY it means we're waiting on the server to
+ * continue the handshake. As far as setting up the renegotiation is
+ * concerned that is a success. The next step will continue the
+ * handshake to its conclusion.
+ */
+ if (peer->status == PEER_RETRY)
+ peer->status = PEER_SUCCESS;
+ return;
+ }
+
+ /*
+ * The SSL object is still expecting app data, even though it's going to
+ * get a handshake message. We try to read, and it should fail - after which
+ * we should be in a handshake
+ */
+ ret = SSL_read(peer->ssl, &buf, sizeof(buf));
+ if (ret >= 0) {
+ /* We're not actually expecting data - we're expect a reneg to start */
+ peer->status = PEER_ERROR;
+ return;
+ } else {
+ int error = SSL_get_error(peer->ssl, ret);
+ if (error != SSL_ERROR_WANT_READ || !SSL_in_init(peer->ssl)) {
+ peer->status = PEER_ERROR;
+ return;
+ }
+ }
+
+ peer->status = PEER_SUCCESS;
+}
+
+