#include <openssl/srp.h>
#endif
+#ifndef OPENSSL_NO_SOCK
+# define USE_SOCKETS
+# include "e_os.h"
+#endif
+
#include "handshake_helper.h"
#include "testutil.h"
typedef enum {
PEER_SUCCESS,
PEER_RETRY,
- PEER_ERROR
+ PEER_ERROR,
+ PEER_WAITING
} peer_status_t;
/* An SSL object and associated read-write buffers. */
peer->status = PEER_SUCCESS;
} else if (ret < 0) { /* On 0, we retry. */
int error = SSL_get_error(peer->ssl, ret);
- /* Memory bios should never block with SSL_ERROR_WANT_WRITE. */
- if (error != SSL_ERROR_WANT_READ)
+
+ if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE)
peer->status = PEER_ERROR;
}
}
}
case PEER_RETRY:
- if (previous_status == PEER_RETRY) {
- /* Neither peer is done. */
- return HANDSHAKE_RETRY;
- } else {
- /*
- * Deadlock: second peer is waiting for more input while first
- * peer thinks they're done (no more input is coming).
- */
- return INTERNAL_ERROR;
- }
+ return HANDSHAKE_RETRY;
+
case PEER_ERROR:
switch (previous_status) {
+ case PEER_WAITING:
+ /* The client failed immediately before sending the ClientHello */
+ return client_spoke_last ? CLIENT_ERROR : INTERNAL_ERROR;
case PEER_SUCCESS:
/*
* First peer succeeded but second peer errored.
return NID_undef;
}
+#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
+static int set_sock_as_sctp(int sock)
+{
+ /*
+ * For SCTP we have to set various options on the socket prior to
+ * connecting. This is done automatically by BIO_new_dgram_sctp().
+ * We don't actually need the created BIO though so we free it again
+ * immediately.
+ */
+ BIO *tmpbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE);
+
+ if (tmpbio == NULL)
+ return 0;
+ BIO_free(tmpbio);
+
+ return 1;
+}
+
+static int create_sctp_socks(int *ssock, int *csock)
+{
+ BIO_ADDRINFO *res = NULL;
+ const BIO_ADDRINFO *ai = NULL;
+ int lsock = INVALID_SOCKET, asock = INVALID_SOCKET;
+ int consock = INVALID_SOCKET;
+ int ret = 0;
+ int family = 0;
+
+ if (!BIO_sock_init())
+ return 0;
+
+ /*
+ * Port is 4463. It could be anything. It will fail if it's already being
+ * used for some other SCTP service. It seems unlikely though so we don't
+ * worry about it here.
+ */
+ if (!BIO_lookup_ex(NULL, "4463", BIO_LOOKUP_SERVER, family, SOCK_STREAM,
+ IPPROTO_SCTP, &res))
+ return 0;
+
+ for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
+ family = BIO_ADDRINFO_family(ai);
+ lsock = BIO_socket(family, SOCK_STREAM, IPPROTO_SCTP, 0);
+ if (lsock == INVALID_SOCKET) {
+ /* Maybe the kernel doesn't support the socket family, even if
+ * BIO_lookup() added it in the returned result...
+ */
+ continue;
+ }
+
+ if (!set_sock_as_sctp(lsock)
+ || !BIO_listen(lsock, BIO_ADDRINFO_address(ai),
+ BIO_SOCK_REUSEADDR)) {
+ BIO_closesocket(lsock);
+ lsock = INVALID_SOCKET;
+ continue;
+ }
+
+ /* Success, don't try any more addresses */
+ break;
+ }
+
+ if (lsock == INVALID_SOCKET)
+ goto err;
+
+ BIO_ADDRINFO_free(res);
+ res = NULL;
+
+ if (!BIO_lookup_ex(NULL, "4463", BIO_LOOKUP_CLIENT, family, SOCK_STREAM,
+ IPPROTO_SCTP, &res))
+ goto err;
+
+ consock = BIO_socket(family, SOCK_STREAM, IPPROTO_SCTP, 0);
+ if (consock == INVALID_SOCKET)
+ goto err;
+
+ if (!set_sock_as_sctp(consock)
+ || !BIO_connect(consock, BIO_ADDRINFO_address(res), 0)
+ || !BIO_socket_nbio(consock, 1))
+ goto err;
+
+ asock = BIO_accept_ex(lsock, NULL, BIO_SOCK_NONBLOCK);
+ if (asock == INVALID_SOCKET)
+ goto err;
+
+ *csock = consock;
+ *ssock = asock;
+ consock = asock = INVALID_SOCKET;
+ ret = 1;
+
+ err:
+ BIO_ADDRINFO_free(res);
+ if (consock != INVALID_SOCKET)
+ BIO_closesocket(consock);
+ if (lsock != INVALID_SOCKET)
+ BIO_closesocket(lsock);
+ if (asock != INVALID_SOCKET)
+ BIO_closesocket(asock);
+ return ret;
+}
+#endif
+
/*
* Note that |extra| points to the correct client/server configuration
* within |test_ctx|. When configuring the handshake, general mode settings
SSL_SESSION *session_in, SSL_SESSION **session_out)
{
PEER server, client;
- BIO *client_to_server, *server_to_client;
+ BIO *client_to_server = NULL, *server_to_client = NULL;
HANDSHAKE_EX_DATA server_ex_data, client_ex_data;
CTX_DATA client_ctx_data, server_ctx_data, server2_ctx_data;
HANDSHAKE_RESULT *ret = HANDSHAKE_RESULT_new();
unsigned int proto_len = 0;
EVP_PKEY *tmp_key;
const STACK_OF(X509_NAME) *names;
+ time_t start;
memset(&server_ctx_data, 0, sizeof(server_ctx_data));
memset(&server2_ctx_data, 0, sizeof(server2_ctx_data));
ret->result = SSL_TEST_INTERNAL_ERROR;
- client_to_server = BIO_new(BIO_s_mem());
- server_to_client = BIO_new(BIO_s_mem());
+ if (test_ctx->use_sctp) {
+#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
+ int csock, ssock;
+
+ if (create_sctp_socks(&ssock, &csock)) {
+ client_to_server = BIO_new_dgram_sctp(csock, BIO_CLOSE);
+ server_to_client = BIO_new_dgram_sctp(ssock, BIO_CLOSE);
+ }
+#endif
+ } else {
+ client_to_server = BIO_new(BIO_s_mem());
+ server_to_client = BIO_new(BIO_s_mem());
+ }
TEST_check(client_to_server != NULL);
TEST_check(server_to_client != NULL);
SSL_set_accept_state(server.ssl);
/* The bios are now owned by the SSL object. */
- SSL_set_bio(client.ssl, server_to_client, client_to_server);
- TEST_check(BIO_up_ref(server_to_client) > 0);
- TEST_check(BIO_up_ref(client_to_server) > 0);
- SSL_set_bio(server.ssl, client_to_server, server_to_client);
+ if (test_ctx->use_sctp) {
+ SSL_set_bio(client.ssl, client_to_server, client_to_server);
+ SSL_set_bio(server.ssl, server_to_client, server_to_client);
+ } else {
+ SSL_set_bio(client.ssl, server_to_client, client_to_server);
+ TEST_check(BIO_up_ref(server_to_client) > 0);
+ TEST_check(BIO_up_ref(client_to_server) > 0);
+ SSL_set_bio(server.ssl, client_to_server, server_to_client);
+ }
ex_data_idx = SSL_get_ex_new_index(0, "ex data", NULL, NULL, NULL);
TEST_check(ex_data_idx >= 0);
SSL_set_info_callback(server.ssl, &info_cb);
SSL_set_info_callback(client.ssl, &info_cb);
- client.status = server.status = PEER_RETRY;
+ client.status = PEER_RETRY;
+ server.status = PEER_WAITING;
+
+ start = time(NULL);
/*
* Half-duplex handshake loop.
do_connect_step(test_ctx, &client, phase);
status = handshake_status(client.status, server.status,
1 /* client went last */);
+ if (server.status == PEER_WAITING)
+ server.status = PEER_RETRY;
} else {
do_connect_step(test_ctx, &server, phase);
status = handshake_status(server.status, client.status,
ret->result = SSL_TEST_INTERNAL_ERROR;
goto err;
case HANDSHAKE_RETRY:
- if (client_turn_count++ >= 2000) {
+ if (test_ctx->use_sctp) {
+ if (time(NULL) - start > 3) {
+ /*
+ * We've waited for too long. Give up.
+ */
+ ret->result = SSL_TEST_INTERNAL_ERROR;
+ goto err;
+ }
/*
- * At this point, there's been so many PEER_RETRY in a row
- * that it's likely both sides are stuck waiting for a read.
- * It's time to give up.
+ * With "real" sockets we only swap to processing the peer
+ * if they are expecting to retry. Otherwise we just retry the
+ * same endpoint again.
*/
- ret->result = SSL_TEST_INTERNAL_ERROR;
- goto err;
- }
+ if ((client_turn && server.status == PEER_RETRY)
+ || (!client_turn && client.status == PEER_RETRY))
+ client_turn ^= 1;
+ } else {
+ if (client_turn_count++ >= 2000) {
+ /*
+ * At this point, there's been so many PEER_RETRY in a row
+ * that it's likely both sides are stuck waiting for a read.
+ * It's time to give up.
+ */
+ ret->result = SSL_TEST_INTERNAL_ERROR;
+ goto err;
+ }
- /* Continue. */
- client_turn ^= 1;
+ /* Continue. */
+ client_turn ^= 1;
+ }
break;
}
}
VerifyMode = Peer
[test-0]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-1]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-2]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-3]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-4]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-5]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-6]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-7]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-8]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-9]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-10]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-11]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-12]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-13]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-14]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-15]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-16]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-17]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-18]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-19]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-20]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-21]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-22]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-23]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-24]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-25]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-156]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-157]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-158]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-159]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-160]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-161]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-162]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-163]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-164]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-165]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-166]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-167]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-168]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-169]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-170]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-171]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-172]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-173]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-174]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-175]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-176]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-177]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-178]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-179]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-180]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-181]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-624]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-625]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-626]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-627]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-628]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-629]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-630]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-631]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-632]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-633]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-634]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-635]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-636]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-637]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-638]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-639]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-640]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-641]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-642]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-643]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-644]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-645]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-646]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-647]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-648]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-649]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-650]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-651]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-652]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-653]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-654]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-655]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-656]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-657]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-658]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-659]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-660]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-661]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-662]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-663]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-664]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-665]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-666]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-667]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-668]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-669]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-670]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-671]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-672]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-673]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-674]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail
# ===========================================================
VerifyMode = Peer
[test-675]
-ExpectedResult = InternalError
+ExpectedResult = ClientFail