+ SSL_CTX *cctx, *sctx;
+
+ T(sctx = SSL_CTX_new(TLS_server_method()));
+ T(SSL_CTX_use_certificate(sctx, ck.cert));
+ T(SSL_CTX_use_PrivateKey(sctx, ck.pkey));
+ T(SSL_CTX_check_private_key(sctx));
+
+ T(cctx = SSL_CTX_new(TLS_client_method()));
+
+ /* create_ssl_objects */
+ SSL *serverssl, *clientssl;
+ T(serverssl = SSL_new(sctx));
+ T(clientssl = SSL_new(cctx));
+ BIO *s_to_c_bio, *c_to_s_bio;
+ T(s_to_c_bio = BIO_new(BIO_s_mem()));
+ T(c_to_s_bio = BIO_new(BIO_s_mem()));
+ /* Non-blocking IO. */
+ BIO_set_mem_eof_return(s_to_c_bio, -1);
+ BIO_set_mem_eof_return(c_to_s_bio, -1);
+ /* Transfer BIOs to SSL objects. */
+ SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
+ BIO_up_ref(s_to_c_bio);
+ BIO_up_ref(c_to_s_bio);
+ SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
+ c_to_s_bio = NULL;
+ c_to_s_bio = NULL;
+
+ /* create_ssl_connection */
+ int retc = -1, rets = -1, err;
+ do {
+ err = SSL_ERROR_WANT_WRITE;
+ while (retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
+ retc = SSL_connect(clientssl);
+ if (retc <= 0)
+ err = SSL_get_error(clientssl, retc);
+ if (verbose)
+ printf("SSL_connect: %d %d\n", retc, err);
+ }
+ if (retc <= 0 && err != SSL_ERROR_WANT_READ) {
+ ERR_print_errors_fp(stderr);
+ OpenSSLDie(__FILE__, __LINE__, "SSL_connect");
+ }
+ err = SSL_ERROR_WANT_WRITE;
+ while (rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
+ rets = SSL_accept(serverssl);
+ if (rets <= 0)
+ err = SSL_get_error(serverssl, rets);
+ if (verbose)
+ printf("SSL_accept: %d %d\n", rets, err);
+ }
+ if (rets <= 0 && err != SSL_ERROR_WANT_READ &&
+ err != SSL_ERROR_WANT_X509_LOOKUP) {
+ ERR_print_errors_fp(stderr);
+ OpenSSLDie(__FILE__, __LINE__, "SSL_accept");
+ }
+ } while (retc <=0 || rets <= 0);
+
+ /* Two SSL_read_ex should fail. */
+ unsigned char buf;
+ size_t readbytes;
+ T(!SSL_read_ex(clientssl, &buf, sizeof(buf), &readbytes));
+ T(!SSL_read_ex(clientssl, &buf, sizeof(buf), &readbytes));
+
+ /* Connect client to the server. */
+ T(SSL_do_handshake(clientssl) == 1);
+ printf("Protocol: %s\n", SSL_get_version(clientssl));
+ printf("Cipher: %s\n", SSL_get_cipher_name(clientssl));
+ if (verbose) {
+ SSL_SESSION *sess = SSL_get0_session(clientssl);
+ SSL_SESSION_print_fp(stdout, sess);
+ }
+
+ /* Transfer some data. */
+ int i;
+ for (i = 0; i < 16; i++) {
+ char pbuf[512], lbuf[512];
+
+ memset(pbuf, 'c' + i, sizeof(pbuf));
+ T(SSL_write(serverssl, pbuf, sizeof(pbuf)) == sizeof(pbuf));
+ T(SSL_read(clientssl, lbuf, sizeof(lbuf)) == sizeof(lbuf));
+ T(memcmp(pbuf, lbuf, sizeof(pbuf)) == 0);
+
+ memset(lbuf, 's' + i, sizeof(lbuf));
+ T(SSL_write(clientssl, lbuf, sizeof(lbuf)) == sizeof(lbuf));
+ T(SSL_read(serverssl, pbuf, sizeof(pbuf)) == sizeof(pbuf));
+ T(memcmp(pbuf, lbuf, sizeof(pbuf)) == 0);