#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <openssl/async.h>
#include <openssl/e_os2.h>
static char *keymatexportlabel = NULL;
static int keymatexportlen = 20;
+static int async = 0;
+
#ifndef OPENSSL_NO_ENGINE
static char *engine_id = NULL;
#endif
s_msg = 0;
s_quiet = 0;
s_brief = 0;
+ async = 0;
#ifndef OPENSSL_NO_ENGINE
engine_id = NULL;
#endif
goto done;
}
req = OCSP_REQUEST_new();
- if (!req)
+ if (req == NULL)
goto err;
id = OCSP_cert_to_id(NULL, x, obj.data.x509);
X509_free(obj.data.x509);
OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM,
OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT,
OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT,
- OPT_CAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE,
+ OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE,
OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
- OPT_BUILD_CHAIN, OPT_CAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE,
- OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, OPT_DEBUG,
- OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, OPT_STATUS_TIMEOUT,
- OPT_STATUS_URL, OPT_MSG, OPT_MSGFILE, OPT_TRACE, OPT_SECURITY_DEBUG,
- OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF, OPT_QUIET,
- OPT_BRIEF, OPT_NO_TMP_RSA, OPT_NO_DHE, OPT_NO_ECDHE,
+ OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE,
+ OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF,
+ OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE,
+ OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_MSG, OPT_MSGFILE, OPT_TRACE,
+ OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF,
+ OPT_QUIET, OPT_BRIEF, OPT_NO_TMP_RSA, OPT_NO_DHE, OPT_NO_ECDHE,
OPT_NO_RESUME_EPHEMERAL, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE,
- OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP,
+ OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC,
OPT_SSL3,
OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_CHAIN, OPT_LISTEN,
{"msg", OPT_MSG, '-', "Show protocol messages"},
{"msgfile", OPT_MSGFILE, '>'},
{"state", OPT_STATE, '-', "Print the SSL states"},
- {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
{"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
+ {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
+ {"no-CAfile", OPT_NOCAFILE, '-',
+ "Do not load the default certificates file"},
+ {"no-CApath", OPT_NOCAPATH, '-',
+ "Do not load certificates from the default certificates directory"},
{"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"},
{"quiet", OPT_QUIET, '-', "No server output"},
{"no_tmp_rsa", OPT_NO_TMP_RSA, '-', "Do not generate a tmp RSA key"},
{"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-'},
{"brief", OPT_BRIEF, '-'},
{"rev", OPT_REV, '-'},
+ {"async", OPT_ASYNC, '-', "Operate in asynchronous mode"},
OPT_S_OPTIONS,
OPT_V_OPTIONS,
OPT_X_OPTIONS,
int no_dhe = 0;
#endif
int no_tmp_rsa = 0, no_ecdhe = 0, nocert = 0, ret = 1;
+ int noCApath = 0, noCAfile = 0;
int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
int rev = 0, naccept = -1, sdebug = 0, socket_type = SOCK_STREAM;
case OPT_CAPATH:
CApath = opt_arg();
break;
+ case OPT_NOCAPATH:
+ noCApath = 1;
+ break;
case OPT_CHAINCAPATH:
chCApath = opt_arg();
break;
case OPT_CAFILE:
CAfile = opt_arg();
break;
+ case OPT_NOCAFILE:
+ noCAfile = 1;
+ break;
case OPT_CHAINCAFILE:
chCAfile = opt_arg();
break;
goto end;
}
break;
-#else
- case OPT_PSK_HINT:
- case OPT_PSK:
- break;
#endif
#ifndef OPENSSL_NO_SRP
case OPT_SRPVFILE:
case OPT_KEYMATEXPORTLEN:
keymatexportlen = atoi(opt_arg());
break;
+ case OPT_ASYNC:
+ async = 1;
+ break;
}
}
argc = opt_num_rest();
goto end;
}
- if (!app_load_modules(NULL))
- goto end;
-
if (s_key_file == NULL)
s_key_file = s_cert_file;
else
SSL_CTX_sess_set_cache_size(ctx, 128);
+ if (async) {
+ SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC);
+ ASYNC_init_pool(0, 0, 0);
+ }
+
#ifndef OPENSSL_NO_SRTP
if (srtp_profiles != NULL) {
/* Returns 0 on success! */
}
#endif
- if (!ctx_set_verify_locations(ctx, CAfile, CApath)) {
+ if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
ERR_print_errors(bio_err);
goto end;
}
else
SSL_CTX_sess_set_cache_size(ctx2, 128);
+ if (async)
+ SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC);
+
if ((!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) ||
(!SSL_CTX_set_default_verify_paths(ctx2))) {
ERR_print_errors(bio_err);
bio_s_out = NULL;
BIO_free(bio_s_msg);
bio_s_msg = NULL;
+ if (async) {
+ ASYNC_free_pool();
+ }
return (ret);
}
switch (SSL_get_error(con, k)) {
case SSL_ERROR_NONE:
break;
+ case SSL_ERROR_WANT_ASYNC:
+ BIO_printf(bio_s_out, "Write BLOCK (Async)\n");
+ break;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_X509_LOOKUP:
if (SSL_pending(con))
goto again;
break;
+ case SSL_ERROR_WANT_ASYNC:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
BIO_printf(bio_s_out, "Read BLOCK\n");
i = DTLSv1_listen(con, &client);
if (i > 0) {
BIO *wbio;
- int fd;
+ int fd = -1;
wbio = SSL_get_wbio(con);
if(wbio) {
}
} else
#endif
+
+ do {
i = SSL_accept(con);
#ifdef CERT_CB_TEST_RETRY
- {
- while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
- && SSL_state(con) == SSL3_ST_SR_CLNT_HELLO_C) {
- BIO_printf(bio_err,
+ {
+ while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
+ && SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) {
+ BIO_printf(bio_err,
"LOOKUP from certificate callback during accept\n");
- i = SSL_accept(con);
+ i = SSL_accept(con);
+ }
}
- }
#endif
+
#ifndef OPENSSL_NO_SRP
- while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
- BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
- srp_callback_parm.login);
- srp_callback_parm.user =
- SRP_VBASE_get_by_user(srp_callback_parm.vb,
- srp_callback_parm.login);
- if (srp_callback_parm.user)
- BIO_printf(bio_s_out, "LOOKUP done %s\n",
- srp_callback_parm.user->info);
- else
- BIO_printf(bio_s_out, "LOOKUP not successful\n");
- i = SSL_accept(con);
- }
+ while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
+ BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
+ srp_callback_parm.login);
+ srp_callback_parm.user =
+ SRP_VBASE_get_by_user(srp_callback_parm.vb,
+ srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out, "LOOKUP done %s\n",
+ srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out, "LOOKUP not successful\n");
+ i = SSL_accept(con);
+ }
#endif
+ } while (i < 0 && SSL_waiting_for_async(con));
if (i <= 0) {
if ((dtlslisten && i == 0)
#ifdef RENEG
int total_bytes = 0;
#endif
+ int width;
+ fd_set readfds;
+
+ /* Set width for a select call if needed */
+ width = s + 1;
buf = app_malloc(bufsize, "server www buffer");
io = BIO_new(BIO_f_buffer());
for (;;) {
i = BIO_gets(io, buf, bufsize - 1);
if (i < 0) { /* error */
- if (!BIO_should_retry(io)) {
+ if (!BIO_should_retry(io) && !SSL_waiting_for_async(con)) {
if (!s_quiet)
ERR_print_errors(bio_err);
goto err;
NULL);
i = SSL_renegotiate(con);
BIO_printf(bio_s_out, "SSL_renegotiate -> %d\n", i);
+ /* Send the HelloRequest */
i = SSL_do_handshake(con);
if (i <= 0) {
BIO_printf(bio_s_out, "SSL_do_handshake() Retval %d\n",
ERR_print_errors(bio_err);
goto err;
}
- /* EVIL HACK! */
- SSL_set_state(con, SSL_ST_ACCEPT);
- i = SSL_do_handshake(con);
- BIO_printf(bio_s_out, "SSL_do_handshake -> %d\n", i);
- if (i <= 0) {
- BIO_printf(bio_s_out, "SSL_do_handshake() Retval %d\n",
- SSL_get_error(con, i));
+ /* Wait for a ClientHello to come back */
+ FD_ZERO(&readfds);
+ openssl_fdset(s, &readfds);
+ i = select(width, (void *)&readfds, NULL, NULL, NULL);
+ if (i <= 0 || !FD_ISSET(s, &readfds)) {
+ BIO_printf(bio_s_out, "Error waiting for client response\n");
ERR_print_errors(bio_err);
goto err;
}
+ /*
+ * We're not acutally expecting any data here and we ignore
+ * any that is sent. This is just to force the handshake that
+ * we're expecting to come from the client. If they haven't
+ * sent one there's not much we can do.
+ */
+ BIO_gets(io, buf, bufsize - 1);
}
BIO_puts(io,
"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
BIO_puts(io, "<pre>\n");
-/* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
+/* BIO_puts(io,OpenSSL_version(OPENSSL_VERSION));*/
BIO_puts(io, "\n");
for (i = 0; i < local_argc; i++) {
const char *myp;
#endif
k = BIO_write(io, &(buf[j]), i - j);
if (k <= 0) {
- if (!BIO_should_retry(io))
+ if (!BIO_should_retry(io) && !SSL_waiting_for_async(con))
goto write_error;
else {
BIO_printf(bio_s_out, "rwrite W BLOCK\n");