static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server) { GIOSSLChannel *chan; GIOChannel *gchan; int fd; SSL *ssl; SSL_CTX *ctx = NULL; const char *mycert = server->connrec->tls_cert; const char *mypkey = server->connrec->tls_pkey; const char *mypass = server->connrec->tls_pass; const char *cafile = server->connrec->tls_cafile; const char *capath = server->connrec->tls_capath; const char *ciphers = server->connrec->tls_ciphers; gboolean verify = server->connrec->tls_verify; g_return_val_if_fail(handle != NULL, NULL); if(!ssl_inited && !irssi_ssl_init()) return NULL; if(!(fd = g_io_channel_unix_get_fd(handle))) return NULL; ERR_clear_error(); ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { g_error("Could not allocate memory for SSL context"); return NULL; } SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback); SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass); if (ciphers != NULL && ciphers[0] != '\0') { if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1) g_warning("No valid SSL cipher suite could be selected"); } if (mycert && *mycert) { char *scert = NULL, *spkey = NULL; FILE *fp; scert = convert_home(mycert); if (mypkey && *mypkey) spkey = convert_home(mypkey); if ((fp = fopen(scert, "r"))) { X509 *cert; /* Let's parse the certificate by hand instead of using * SSL_CTX_use_certificate_file so that we can validate * some parts of it. */ cert = PEM_read_X509(fp, NULL, get_pem_password_callback, (void *)mypass); if (cert != NULL) { /* Only the expiration date is checked right now */ if (X509_cmp_current_time(X509_get_notAfter(cert)) <= 0 || X509_cmp_current_time(X509_get_notBefore(cert)) >= 0) g_warning("The client certificate is expired"); ERR_clear_error(); if (! SSL_CTX_use_certificate(ctx, cert)) g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error())); else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM)) g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error())); else if (! SSL_CTX_check_private_key(ctx)) g_warning("Private key does not match the certificate"); X509_free(cert); } else g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error())); fclose(fp); } else g_warning("Could not find client certificate '%s'", scert); g_free(scert); g_free(spkey); } if ((cafile && *cafile) || (capath && *capath)) { char *scafile = NULL; char *scapath = NULL; if (cafile && *cafile) scafile = convert_home(cafile); if (capath && *capath) scapath = convert_home(capath); if (! SSL_CTX_load_verify_locations(ctx, scafile, scapath)) { g_warning("Could not load CA list for verifying TLS server certificate"); g_free(scafile); g_free(scapath); SSL_CTX_free(ctx); return NULL; } g_free(scafile); g_free(scapath); verify = TRUE; } else if (store != NULL) { /* Make sure to increment the refcount every time the store is * used, that's essential not to get it free'd by OpenSSL when * the SSL_CTX is destroyed. */ X509_STORE_up_ref(store); SSL_CTX_set_cert_store(ctx, store); } if(!(ssl = SSL_new(ctx))) { g_warning("Failed to allocate SSL structure"); SSL_CTX_free(ctx); return NULL; } if(!SSL_set_fd(ssl, fd)) { g_warning("Failed to associate socket to SSL stream"); SSL_free(ssl); SSL_CTX_free(ctx); return NULL; } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME SSL_set_tlsext_host_name(ssl, server->connrec->address); #endif SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); chan = g_new0(GIOSSLChannel, 1); chan->fd = fd; chan->giochan = handle; chan->ssl = ssl; chan->ctx = ctx; chan->server = server; chan->port = port; chan->verify = verify; gchan = (GIOChannel *)chan; gchan->funcs = &irssi_ssl_channel_funcs; g_io_channel_init(gchan); gchan->is_readable = gchan->is_writeable = TRUE; gchan->use_buffer = FALSE; return gchan; }
/* * Fetches the resource denoted by |uri|. */ static void fetch_uri(const struct URI *uri) { nghttp2_session_callbacks callbacks; int fd; SSL_CTX *ssl_ctx; SSL *ssl; struct Request req; struct Connection connection; int rv; nfds_t npollfds = 1; struct pollfd pollfds[1]; request_init(&req, uri); setup_nghttp2_callbacks(&callbacks); /* Establish connection and setup SSL */ fd = connect_to(req.host, req.port); if(fd == -1) { die("Could not open file descriptor"); } ssl_ctx = SSL_CTX_new(SSLv23_client_method()); if(ssl_ctx == NULL) { dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL)); } init_ssl_ctx(ssl_ctx); ssl = SSL_new(ssl_ctx); if(ssl == NULL) { dief("SSL_new", ERR_error_string(ERR_get_error(), NULL)); } /* To simplify the program, we perform SSL/TLS handshake in blocking I/O. */ ssl_handshake(ssl, fd); connection.ssl = ssl; connection.want_io = IO_NONE; /* Send connection header in blocking I/O mode */ SSL_write(ssl, NGHTTP2_CLIENT_CONNECTION_PREFACE, NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN); /* Here make file descriptor non-block */ make_non_block(fd); set_tcp_nodelay(fd); printf("[INFO] SSL/TLS handshake completed\n"); rv = nghttp2_session_client_new(&connection.session, &callbacks, &connection); if(rv != 0) { diec("nghttp2_session_client_new", rv); } /* Submit the HTTP request to the outbound queue. */ submit_request(&connection, &req); pollfds[0].fd = fd; ctl_poll(pollfds, &connection); /* Event loop */ while(nghttp2_session_want_read(connection.session) || nghttp2_session_want_write(connection.session)) { int nfds = poll(pollfds, npollfds, -1); if(nfds == -1) { dief("poll", strerror(errno)); } if(pollfds[0].revents & (POLLIN | POLLOUT)) { exec_io(&connection); } if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) { die("Connection error"); } ctl_poll(pollfds, &connection); } /* Resource cleanup */ nghttp2_session_del(connection.session); SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ssl_ctx); shutdown(fd, SHUT_WR); close(fd); request_free(&req); }
void child_cycle(int channel) { int message = 0; int result = 0; int local_socket = 0; int remote_socket = 0; struct sockaddr_in my_addr, peer_addr; socklen_t peer_addr_size = 0; memset(&my_addr, 0, sizeof(struct sockaddr_in)); memset(&peer_addr, 0, sizeof(struct sockaddr_in)); /* * Do the TLS initialization dance. */ result = ssl_server_init(); if (result < 0) { message = -1; result = write(channel, &message, sizeof(int)); exit(0); } /* * Create a unix socket */ local_socket = socket(AF_INET, SOCK_STREAM, 0); my_addr.sin_family = AF_INET; my_addr.sin_addr.s_addr = INADDR_ANY; my_addr.sin_port = htons(8035); /* Avoid spurious failures when rerunning the test due to socket not yet * being released. */ int opt = 1; setsockopt(local_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); /* * Bind it */ result = bind(local_socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in)); if (result < 0) { message = -1; result = write(channel, &message, sizeof(int)); exit(0); } /* * Start listening for connections */ result = listen(local_socket, 5); if (result < 0) { message = -1; result = write(channel, &message, sizeof(int)); exit(0); } /* * Signal the parent that we are ok. */ result = write(channel, &message, sizeof(int)); /* * If this did not work, then we abort. */ if (result < 0) { exit(0); } /* * Send the name of the public key file. */ result = write(channel, server_name_template_public, strlen(server_name_template_public)); if (result < 0) { exit(0); } /* * Send the name of the certificate file. */ result = write(channel, server_certificate_template_public, strlen(server_certificate_template_public)); if (result < 0) { exit(0); } /* * Now wait until somebody calls. */ peer_addr_size = sizeof(struct sockaddr_in); while (true) { remote_socket = accept(local_socket, (struct sockaddr *)&peer_addr, &peer_addr_size); if (remote_socket < 0) { Log (LOG_LEVEL_CRIT, "Could not accept connection"); continue; } /* * We are not testing the server, we are testing the functions to send and receive data * over TLS. We do not need a full fletched server for that, we just need to send and * receive data and try the error conditions. */ SSL *ssl = SSL_new(SSLSERVERCONTEXT); if (!ssl) { Log(LOG_LEVEL_CRIT, "Could not create SSL structure on the server side"); SSL_free(ssl); close (remote_socket); remote_socket = -1; continue; } SSL_set_fd(ssl, remote_socket); result = SSL_accept(ssl); if (result < 0) { Log(LOG_LEVEL_CRIT, "Could not accept a TLS connection"); close (remote_socket); remote_socket = -1; continue; } /* * Our mission is pretty simple, receive data and send it back. */ int received = 0; int sent = 0; char buffer[4096]; do { received = SSL_read(ssl, buffer, 4096); if (received < 0) { Log(LOG_LEVEL_CRIT, "Failure while receiving data over TLS"); break; } sent = SSL_write(ssl, buffer, received); if (sent < 0) { Log(LOG_LEVEL_CRIT, "Failure while sending data over TLS"); break; } } while (received > 0); /* * Mission completed, start again. */ SSL_shutdown(ssl); SSL_free(ssl); remote_socket = -1; } exit(0); }
static void proceed_handshake(h2o_socket_t *sock, const char *err) { h2o_iovec_t first_input = {}; int ret; sock->_cb.write = NULL; if (err != NULL) { goto Complete; } if (sock->ssl->handshake.server.async_resumption.state == ASYNC_RESUMPTION_STATE_RECORD) { if (sock->ssl->input.encrypted->size <= 1024) { /* retain a copy of input if performing async resumption */ first_input = h2o_iovec_init(alloca(sock->ssl->input.encrypted->size), sock->ssl->input.encrypted->size); memcpy(first_input.base, sock->ssl->input.encrypted->bytes, first_input.len); } else { sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE; } } Redo: if (sock->ssl->ssl->server) { ret = SSL_accept(sock->ssl->ssl); } else { ret = SSL_connect(sock->ssl->ssl); } switch (sock->ssl->handshake.server.async_resumption.state) { case ASYNC_RESUMPTION_STATE_RECORD: /* async resumption has not been triggered; proceed the state to complete */ sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE; break; case ASYNC_RESUMPTION_STATE_REQUEST_SENT: { /* sent async request, reset the ssl state, and wait for async response */ assert(ret < 0); SSL_CTX *ssl_ctx = SSL_get_SSL_CTX(sock->ssl->ssl); SSL_free(sock->ssl->ssl); create_ssl(sock, ssl_ctx); clear_output_buffer(sock->ssl); h2o_buffer_consume(&sock->ssl->input.encrypted, sock->ssl->input.encrypted->size); h2o_buffer_reserve(&sock->ssl->input.encrypted, first_input.len); memcpy(sock->ssl->input.encrypted->bytes, first_input.base, first_input.len); sock->ssl->input.encrypted->size = first_input.len; h2o_socket_read_stop(sock); return; } default: break; } if (ret == 0 || (ret < 0 && SSL_get_error(sock->ssl->ssl, ret) != SSL_ERROR_WANT_READ)) { /* failed */ long verify_result = SSL_get_verify_result(sock->ssl->ssl); if (verify_result != X509_V_OK) { err = X509_verify_cert_error_string(verify_result); } else { err = "ssl handshake failure"; } goto Complete; } if (sock->ssl->output.bufs.size != 0) { h2o_socket_read_stop(sock); flush_pending_ssl(sock, ret == 1 ? on_handshake_complete : proceed_handshake); } else { if (ret == 1) { if (!sock->ssl->ssl->server) { X509 *cert = SSL_get_peer_certificate(sock->ssl->ssl); if (cert != NULL) { switch (validate_hostname(sock->ssl->handshake.client.server_name, cert)) { case MatchFound: /* ok */ break; case MatchNotFound: err = h2o_socket_error_ssl_cert_name_mismatch; break; default: err = h2o_socket_error_ssl_cert_invalid; break; } X509_free(cert); } else { err = h2o_socket_error_ssl_no_cert; } } goto Complete; } if (sock->ssl->input.encrypted->size != 0) goto Redo; h2o_socket_read_start(sock, proceed_handshake); } return; Complete: h2o_socket_read_stop(sock); on_handshake_complete(sock, err); }
LWS_VISIBLE int lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd) { struct lws_context *context = wsi->context; struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; int n, m; #if !defined(USE_WOLFSSL) && !defined(LWS_USE_POLARSSL) && !defined(LWS_USE_MBEDTLS) BIO *bio; #endif if (!LWS_SSL_ENABLED(wsi->vhost)) return 0; switch (wsi->mode) { case LWSCM_SSL_INIT: if (wsi->ssl) lwsl_err("%s: leaking ssl\n", __func__); if (accept_fd == LWS_SOCK_INVALID) assert(0); #if defined(LWS_USE_POLARSSL) { ssl_session *ssn; int rc; wsi->ssl = lws_zalloc(sizeof(ssl_context)); ssn = lws_zalloc(sizeof(ssl_session)); rc = ssl_init(wsi->ssl); if (rc) { lwsl_err("ssl_init failed\n"); goto fail; } ssl_set_endpoint(wsi->ssl, SSL_IS_SERVER); ssl_set_authmode(wsi->ssl, SSL_VERIFY_OPTIONAL); ssl_set_rng(wsi->ssl, urandom_bytes, NULL); ssl_set_dbg(wsi->ssl, pssl_debug, NULL); ssl_set_bio(wsi->ssl, net_recv, &wsi->sock, net_send, &wsi->sock); ssl_set_ciphersuites(wsi->ssl, ciphers); ssl_set_session(wsi->ssl, ssn); ssl_set_ca_chain(wsi->ssl, &wsi->vhost->ssl_ctx->ca, NULL, NULL); ssl_set_own_cert_rsa(wsi->ssl, &wsi->vhost->ssl_ctx->certificate, &wsi->vhost->ssl_ctx->key); // ssl_set_dh_param(wsi->ssl, my_dhm_P, my_dhm_G); lwsl_err("%s: polarssl init done\n", __func__); } #else #if defined(LWS_USE_MBEDTLS) #else wsi->ssl = SSL_new(wsi->vhost->ssl_ctx); if (wsi->ssl == NULL) { lwsl_err("SSL_new failed: %s\n", ERR_error_string(lws_ssl_get_error(wsi, 0), NULL)); lws_decode_ssl_error(); if (accept_fd != LWS_SOCK_INVALID) compatible_close(accept_fd); goto fail; } SSL_set_ex_data(wsi->ssl, openssl_websocket_private_data_index, wsi->vhost); SSL_set_fd(wsi->ssl, accept_fd); #endif #endif #ifdef USE_WOLFSSL #ifdef USE_OLD_CYASSL CyaSSL_set_using_nonblock(wsi->ssl, 1); #else wolfSSL_set_using_nonblock(wsi->ssl, 1); #endif #else #if defined(LWS_USE_POLARSSL) #else #if defined(LWS_USE_MBEDTLS) #else SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); bio = SSL_get_rbio(wsi->ssl); if (bio) BIO_set_nbio(bio, 1); /* nonblocking */ else lwsl_notice("NULL rbio\n"); bio = SSL_get_wbio(wsi->ssl); if (bio) BIO_set_nbio(bio, 1); /* nonblocking */ else lwsl_notice("NULL rbio\n"); #endif #endif #endif /* * we are not accepted yet, but we need to enter ourselves * as a live connection. That way we can retry when more * pieces come if we're not sorted yet */ wsi->mode = LWSCM_SSL_ACK_PENDING; if (insert_wsi_socket_into_fds(context, wsi)) { lwsl_err("%s: failed to insert into fds\n", __func__); goto fail; } lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT, context->timeout_secs); lwsl_info("inserted SSL accept into fds, trying SSL_accept\n"); /* fallthru */ case LWSCM_SSL_ACK_PENDING: if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { lwsl_err("%s: lws_change_pollfd failed\n", __func__); goto fail; } lws_latency_pre(context, wsi); n = recv(wsi->sock, (char *)pt->serv_buf, context->pt_serv_buf_size, MSG_PEEK); /* * optionally allow non-SSL connect on SSL listening socket * This is disabled by default, if enabled it goes around any * SSL-level access control (eg, client-side certs) so leave * it disabled unless you know it's not a problem for you */ if (wsi->vhost->allow_non_ssl_on_ssl_port) { if (n >= 1 && pt->serv_buf[0] >= ' ') { /* * TLS content-type for Handshake is 0x16, and * for ChangeCipherSpec Record, it's 0x14 * * A non-ssl session will start with the HTTP * method in ASCII. If we see it's not a legit * SSL handshake kill the SSL for this * connection and try to handle as a HTTP * connection upgrade directly. */ wsi->use_ssl = 0; #if defined(LWS_USE_POLARSSL) ssl_close_notify(wsi->ssl); ssl_free(wsi->ssl); #else #if defined(LWS_USE_MBEDTLS) #else SSL_shutdown(wsi->ssl); SSL_free(wsi->ssl); #endif #endif wsi->ssl = NULL; if (lws_check_opt(context->options, LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS)) wsi->redirect_to_https = 1; goto accepted; } if (!n) /* * connection is gone, or nothing to read * if it's gone, we will timeout on * PENDING_TIMEOUT_SSL_ACCEPT */ break; if (n < 0 && (LWS_ERRNO == LWS_EAGAIN || LWS_ERRNO == LWS_EWOULDBLOCK)) { /* * well, we get no way to know ssl or not * so go around again waiting for something * to come and give us a hint, or timeout the * connection. */ m = SSL_ERROR_WANT_READ; goto go_again; } } /* normal SSL connection processing path */ #if defined(LWS_USE_POLARSSL) n = ssl_handshake(wsi->ssl); #else #if defined(LWS_USE_MBEDTLS) #else n = SSL_accept(wsi->ssl); #endif #endif lws_latency(context, wsi, "SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1); if (n == 1) goto accepted; m = lws_ssl_get_error(wsi, n); lwsl_debug("SSL_accept failed %d / %s\n", m, ERR_error_string(m, NULL)); go_again: if (m == SSL_ERROR_WANT_READ) { if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) { lwsl_err("%s: WANT_READ change_pollfd failed\n", __func__); goto fail; } lwsl_info("SSL_ERROR_WANT_READ\n"); break; } if (m == SSL_ERROR_WANT_WRITE) { if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) { lwsl_err("%s: WANT_WRITE change_pollfd failed\n", __func__); goto fail; } break; } lwsl_err("SSL_accept failed skt %u: %s\n", wsi->sock, ERR_error_string(m, NULL)); lws_ssl_elaborate_error(); goto fail; accepted: /* OK, we are accepted... give him some time to negotiate */ lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, context->timeout_secs); wsi->mode = LWSCM_HTTP_SERVING; lws_http2_configure_if_upgraded(wsi); lwsl_debug("accepted new SSL conn\n"); break; } return 0; fail: return 1; }
int main(int argc, char *argv[]) { int client_sock = -1; int client_name_len = sizeof (client_name); int request=0; struct nunetwork_headerstruct *header_buf; header_buf = (struct nunetwork_headerstruct*)malloc( sizeof(*header_buf) ); /******************** * Don't forget to make pointer to variable cast (*pointer) * When using sizeof(). Otherwise it may cost you a week of * debug time. *******************/ if (geteuid()) { printf("Netustad must be run as root.\n"); exit(1); } conffile = (char *)strdup(default_conf_file); /*setlocale (LC_ALL, "");*/ bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR); textdomain ( PACKAGE ); /*******************/ /* Check Arguments */ /*******************/ if (argc==2) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { printf( gettext("\nnetUstad: Network Ustadi (Network Master)\n")); printf( gettext("Copyright (C) 2004 by Ozkan KIRIK\n")); printf( gettext("Usage: netustad [options]\n")); printf( gettext("\n")); printf( "%s:\n", gettext("Options")); printf( gettext("\t-h\tShow this help screen\n")); printf( gettext("\t-v\tShow version\n")); printf (gettext("\t-c\tUse following parameter as configuration file")); printf("\n"); exit(0); } else if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) { printf(gettext("\nnetUstad: Network Ustadi (Network Master)\n")); printf(gettext("Copyright (C) 2004 by Ozkan KIRIK\n\n")); printf(gettext("Version: %s\n\n"), NUVERSION); exit(0); } } else if (argc == 3 && strcmp(argv[1], "-c") == 0) { conffile = strdup(argv[2]); } else if (argc!=1) { if (strcmp(argv[1], "-c") == 0) { printf (gettext("\nnetUstad: Invalid Number Of Arguments\n\n")); } else { printf(gettext("\nnetUstad: Invalid Argument\n\n")); } exit(1); } /**********************/ /* Start Main Program */ /**********************/ readconfig(conffile); if (setlocale (LC_ALL, (const char*) lc_all) == NULL) { log_msg(mainlogfile, gettext("setlocale failed\n"), 1); printf(gettext("setlocale failed\n")); } bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR); textdomain ( PACKAGE ); nameoftty = ttyname(0); daemonize(); #ifndef WITHOUT_SSL ssl = nunetwork_init_ssl( nunetwork_init_ctx( cert_file, key_file) ); #endif server_sock = startup(&port); /* Open Socket & Listen */ log_msg(mainlogfile, "<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n", 0); snprintf(log_msg_text, sizeof(log_msg_text)-1, "netUstad-%s\n", NUVERSION); log_msg(mainlogfile, log_msg_text, 0); snprintf(log_msg_text, sizeof (log_msg_text)-1, "%s", gettext("netUstad is started\n")); log_msg(mainlogfile, log_msg_text, 1); snprintf(log_msg_text, sizeof (log_msg_text)-1, gettext("\nListening port %d\n"), port); log_msg(mainlogfile, log_msg_text, 0); log_msg(mainlogfile, gettext("Ready for requests...\n\n"), 0); snprintf(log_msg_text, sizeof(log_msg_text)-1, "netUstad-%s\n", NUVERSION); log_msg(nameoftty, log_msg_text, 0); snprintf(log_msg_text, sizeof (log_msg_text)-1, gettext("\nnetUstad is started\nListening port %d\n"), port); log_msg(nameoftty, log_msg_text, 0); while (1) { client_sock = accept(server_sock, (struct sockaddr *) &client_name, (socklen_t *)&client_name_len); if (client_sock == -1) continue; #ifndef WITHOUT_SSL SSL_set_fd(ssl, client_sock); sslerror = SSL_accept(ssl); if ( sslerror <= 0 ) { sslerror= SSL_get_error(ssl, sslerror); ERR_error_string(sslerror, log_msg_text); log_msg(mainlogfile, log_msg_text, 1); log_msg(mainlogfile, "\n",0); SSL_shutdown(ssl); SSL_free(ssl); close(client_sock); ssl = nunetwork_init_ssl(ctx); continue; } request = nunetwork_getheaders(ssl, header_buf, nu_acceptedheaders); if (request > 0) accept_request(ssl, header_buf); else if (request==-2 || request==0) bad_request(ssl); nunetwork_close(ssl); #else request = nunetwork_getheaders(client_sock, header_buf, nu_acceptedheaders); if (request > 0) accept_request(client_sock, header_buf); else if (request==-2 || request==0 ) bad_request(ssl); nunetwork_close(client_sock); #endif } #ifndef WITHOUT_SSL SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); #else close(server_sock); #endif return (0); }
void DataPlaneServer::readyRead(int) { memset(&client_addr, 0, sizeof(struct sockaddr_storage)); /* Create BIO */ bio = BIO_new_dgram(fd, BIO_NOCLOSE); /* Set and activate timeouts */ timeout.tv_sec = 5; timeout.tv_usec = 0; BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); ssl = SSL_new(ctx); SSL_set_bio(ssl, bio, bio); SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); int dtlsRet; errno = 0; while ((dtlsRet = DTLSv1_listen(ssl, &client_addr)) <= 0) { if (errno != EAGAIN) { qWarning() << "DTLSv1_listen error"; qWarning() << SSL_get_error(ssl, dtlsRet); qWarning() << "Errno is" << errno; if (errno == EINVAL) { qWarning() << "!!!!!!!!!!! Your openssl library does not support DTLSv1_listen !!!!!!!!!!!"; qWarning() << "Cannot accept new connection"; SSL_shutdown(ssl); close(fd); SSL_free(ssl); ERR_remove_state(0); return; } } } QThread* workerThread = new QThread(); threads.append(workerThread); addrUnion infServer_addr; addrUnion infClient_addr; memcpy(&infServer_addr, &server_addr, sizeof(struct sockaddr_storage)); memcpy(&infClient_addr, &client_addr, sizeof(struct sockaddr_storage)); // get UID from friend using his IP to create worker thread // if IP is not in DB we close the connection char friendIp[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &infClient_addr.s6.sin6_addr, friendIp, INET6_ADDRSTRLEN); ConnectionInitiator* init = ConnectionInitiator::getInstance(); QString friendUid = qSql->getUidFromIP(QHostAddress(QString(friendIp))); ControlPlaneConnection* cp = init->getConnection(friendUid); if (friendUid.isEmpty() || cp->getMode() == Closed) { qDebug() << "friendUId NOT in DB or no control plane connection!"; SSL_shutdown(ssl); close(fd); //free(info); SSL_free(ssl); ERR_remove_state(0); qDebug("done, connection closed."); fflush(stdout); return; } // associate with dataplaneconnection DataPlaneConnection* dpc = init->getDpConnection(friendUid); ServerWorker* worker = new ServerWorker(infServer_addr, infClient_addr, ssl, dpc); worker->moveToThread(workerThread); connect(workerThread, SIGNAL(started()), worker, SLOT(connection_handle())); connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); //connect(worker, SIGNAL(bufferReady(const char*, int)), dpc, SLOT(readBuffer(const char*, int))); UnixSignalHandler* u = UnixSignalHandler::getInstance(); connect(u, SIGNAL(exiting()), workerThread, SLOT(quit())); workerThread->start(); }
/* The program expects at most four arguments: host in IP format, port * number to connect to, proxy in IP format and proxy port number. * If last two are specified, host can be in any format proxy will * understand (since this is an example for SSL programming, host name * resolving code is left out). * * Default values are "127.0.0.1", 443. If any proxy parameter is * omitted, the program will connect directly to the host. */ int main(int argc, char *argv[]) { char buffer[4096]; /* This should be dynamically allocated */ const char *request = "GET / HTTP/1.0\r\n\r\n"; BOOL is_ok = FALSE; X509 *server_cert; SSL_CTX *ctx; BIO *bio_err; SSL *ssl; if (Init()) { /* Basic intialization. Next few steps (up to SSL_new()) need * to be done only once per AmiSSL opener. */ SSLeay_add_ssl_algorithms(); SSL_load_error_strings(); /* Note: BIO writing routines are prepared for NULL BIO handle */ if((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp_amiga(bio_err, GetStdErr(), BIO_NOCLOSE | BIO_FP_TEXT); /* Get a new SSL context */ if((ctx = SSL_CTX_new(SSLv23_client_method())) != NULL) { /* Basic certificate handling. OpenSSL documentation has more * information on this. */ SSL_CTX_set_default_verify_paths(ctx); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); /* The following needs to be done once per socket */ if((ssl = SSL_new(ctx)) != NULL) { int sock; /* Connect to the HTTPS server, directly or through a proxy */ if (argc > 4) sock = ConnectToServer(argv[1], atol(argv[2]), argv[3], atol(argv[4])); else sock = ConnectToServer(argv[1] ? argv[1] : (char *)"127.0.0.1", argc > 2 ? atol(argv[2]) : 443, NULL, 0); /* Check if connection was established */ if (sock >= 0) { int ssl_err = 0; /* Associate the socket with the ssl structure */ SSL_set_fd(ssl, sock); /* Perform SSL handshake */ if((ssl_err = SSL_connect(ssl)) >= 0) { Printf("SSL connection using %s\n", SSL_get_cipher(ssl)); /* Certificate checking. This example is *very* basic */ if((server_cert = SSL_get_peer_certificate(ssl))) { char *str; Printf("Server certificate:\n"); if((str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0))) { Printf("\tSubject: %s\n", str); OPENSSL_free(str); } else FPrintf(GetStdErr(), "Warning: couldn't read subject name in certificate!\n"); if((str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0)) != NULL) { Printf("\tIssuer: %s\n", str); OPENSSL_free(str); } else FPrintf(GetStdErr(), "Warning: couldn't read issuer name in certificate!\n"); X509_free(server_cert); /* Send a HTTP request. Again, this is just * a very basic example. */ if ((ssl_err = SSL_write(ssl, request, strlen(request))) > 0) { /* Dump everything to output */ while ((ssl_err = SSL_read(ssl, buffer, sizeof(buffer) - 1)) > 0) FWrite(Output(), buffer, ssl_err, 1); FFlush(Output()); /* This is not entirely true, check * the SSL_read documentation */ is_ok = ssl_err == 0; } else FPrintf(GetStdErr(), "Couldn't write request!\n"); } else FPrintf(GetStdErr(), "Couldn't get server certificate!\n"); } else FPrintf(GetStdErr(), "Couldn't establish SSL connection!\n"); /* If there were errors, print them */ if (ssl_err < 0) ERR_print_errors(bio_err); /* Send SSL close notification and close the socket */ SSL_shutdown(ssl); CloseSocket(sock); } else FPrintf(GetStdErr(), "Couldn't connect to host!\n"); FPrintf(GetStdErr(), "before SSL_free()\n"); SSL_free(ssl); } else FPrintf(GetStdErr(), "Couldn't create new SSL handle!\n"); FPrintf(GetStdErr(), "before SSL_CTX_free()\n"); SSL_CTX_free(ctx); } else FPrintf(GetStdErr(), "Couldn't create new context!\n"); FPrintf(GetStdErr(), "before Cleanup()\n"); Cleanup(); } FPrintf(GetStdErr(), "before end of main()\n"); return(is_ok ? RETURN_OK : RETURN_ERROR); }
LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) { if (!connection || connection->ssl_data) return IDEVICE_E_INVALID_ARG; idevice_error_t ret = IDEVICE_E_SSL_ERROR; uint32_t return_me = 0; plist_t pair_record = NULL; userpref_read_pair_record(connection->udid, &pair_record); if (!pair_record) { debug_info("ERROR: Failed enabling SSL. Unable to read pair record for udid %s.", connection->udid); return ret; } #ifdef HAVE_OPENSSL key_data_t root_cert = { NULL, 0 }; key_data_t root_privkey = { NULL, 0 }; pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_privkey); if (pair_record) plist_free(pair_record); BIO *ssl_bio = BIO_new(BIO_s_socket()); if (!ssl_bio) { debug_info("ERROR: Could not create SSL bio."); return ret; } BIO_set_fd(ssl_bio, (int)(long)connection->data, BIO_NOCLOSE); SSL_CTX *ssl_ctx = SSL_CTX_new(TLSv1_method()); if (ssl_ctx == NULL) { debug_info("ERROR: Could not create SSL context."); BIO_free(ssl_bio); return ret; } BIO* membp; X509* rootCert = NULL; membp = BIO_new_mem_buf(root_cert.data, root_cert.size); PEM_read_bio_X509(membp, &rootCert, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_certificate(ssl_ctx, rootCert) != 1) { debug_info("WARNING: Could not load RootCertificate"); } X509_free(rootCert); free(root_cert.data); RSA* rootPrivKey = NULL; membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size); PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, rootPrivKey) != 1) { debug_info("WARNING: Could not load RootPrivateKey"); } RSA_free(rootPrivKey); free(root_privkey.data); SSL *ssl = SSL_new(ssl_ctx); if (!ssl) { debug_info("ERROR: Could not create SSL object"); BIO_free(ssl_bio); SSL_CTX_free(ssl_ctx); return ret; } SSL_set_connect_state(ssl); SSL_set_verify(ssl, 0, ssl_verify_callback); SSL_set_bio(ssl, ssl_bio, ssl_bio); return_me = SSL_do_handshake(ssl); if (return_me != 1) { debug_info("ERROR in SSL_do_handshake: %s", ssl_error_to_string(SSL_get_error(ssl, return_me))); SSL_free(ssl); SSL_CTX_free(ssl_ctx); } else { ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); ssl_data_loc->session = ssl; ssl_data_loc->ctx = ssl_ctx; connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled, cipher: %s", SSL_get_cipher(ssl)); } /* required for proper multi-thread clean up to prevent leaks */ #ifdef HAVE_ERR_REMOVE_THREAD_STATE ERR_remove_thread_state(NULL); #else ERR_remove_state(0); #endif #else ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); /* Set up GnuTLS... */ debug_info("enabling SSL mode"); errno = 0; gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); #if GNUTLS_VERSION_NUMBER >= 0x020b07 gnutls_certificate_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); #else gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); #endif gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); gnutls_priority_set_direct(ssl_data_loc->session, "NONE:+VERS-TLS1.0:+ANON-DH:+RSA:+AES-128-CBC:+AES-256-CBC:+SHA1:+MD5:+COMP-NULL", NULL); gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc); gnutls_x509_crt_init(&ssl_data_loc->root_cert); gnutls_x509_crt_init(&ssl_data_loc->host_cert); gnutls_x509_privkey_init(&ssl_data_loc->root_privkey); gnutls_x509_privkey_init(&ssl_data_loc->host_privkey); pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, ssl_data_loc->root_cert); pair_record_import_crt_with_name(pair_record, USERPREF_HOST_CERTIFICATE_KEY, ssl_data_loc->host_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, ssl_data_loc->root_privkey); pair_record_import_key_with_name(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, ssl_data_loc->host_privkey); if (pair_record) plist_free(pair_record); debug_info("GnuTLS step 1..."); gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); debug_info("GnuTLS step 2..."); gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write); debug_info("GnuTLS step 3..."); gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read); debug_info("GnuTLS step 4 -- now handshaking..."); if (errno) { debug_info("WARNING: errno says %s before handshake!", strerror(errno)); } return_me = gnutls_handshake(ssl_data_loc->session); debug_info("GnuTLS handshake done..."); if (return_me != GNUTLS_E_SUCCESS) { internal_ssl_cleanup(ssl_data_loc); free(ssl_data_loc); debug_info("GnuTLS reported something wrong."); gnutls_perror(return_me); debug_info("oh.. errno says %s", strerror(errno)); } else { connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled"); } #endif return ret; }
THREAD_RETURN CYASSL_THREAD server_test(void* args) { SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID; wolfSSL_method_func method = NULL; SSL_CTX* ctx = 0; SSL* ssl = 0; #ifndef WOLFSSL_ALT_TEST_STRINGS const char msg[] = "I hear you fa shizzle!"; #else const char msg[] = "I hear you fa shizzle!\n"; #endif char input[80]; int ch; int version = SERVER_DEFAULT_VERSION; int doCliCertCheck = 1; int useAnyAddr = 0; word16 port = wolfSSLPort; int usePsk = 0; int usePskPlus = 0; int useAnon = 0; int doDTLS = 0; int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; int trackMemory = 0; int fewerPackets = 0; int pkCallbacks = 0; int wc_shutdown = 0; int resume = 0; int resumeCount = 0; int loopIndefinitely = 0; int echoData = 0; int throughput = 0; int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS; short minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS; short minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS; int doListen = 1; int crlFlags = 0; int ret; int err = 0; char* serverReadyFile = NULL; char* alpnList = NULL; unsigned char alpn_opt = 0; char* cipherList = NULL; const char* verifyCert = cliCert; const char* ourCert = svrCert; const char* ourKey = svrKey; const char* ourDhParam = dhParam; tcp_ready* readySignal = NULL; int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; #ifdef WOLFSSL_TRUST_PEER_CERT const char* trustCert = NULL; #endif #ifndef NO_PSK int sendPskIdentityHint = 1; #endif #ifdef HAVE_SNI char* sniHostName = NULL; #endif #ifdef HAVE_OCSP int useOcsp = 0; char* ocspUrl = NULL; #endif #ifdef HAVE_WNR const char* wnrConfigFile = wnrConfig; #endif #ifdef WOLFSSL_STATIC_MEMORY #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ || defined(SESSION_CERTS) /* big enough to handle most cases including session certs */ byte memory[204000]; #else byte memory[80000]; #endif byte memoryIO[34500]; /* max of 17k for IO buffer (TLS packet can be 16k) */ WOLFSSL_MEM_CONN_STATS ssl_stats; #endif ((func_args*)args)->return_code = -1; /* error state */ #ifdef NO_RSA verifyCert = (char*)cliEccCert; ourCert = (char*)eccCert; ourKey = (char*)eccKey; #endif (void)pkCallbacks; (void)needDH; (void)ourKey; (void)ourCert; (void)ourDhParam; (void)verifyCert; (void)useNtruKey; (void)doCliCertCheck; (void)minDhKeyBits; (void)minRsaKeyBits; (void)minEccKeyBits; (void)alpnList; (void)alpn_opt; (void)crlFlags; (void)readySignal; #ifdef CYASSL_TIRTOS fdOpenSession(Task_self()); #endif #ifdef WOLFSSL_VXWORKS useAnyAddr = 1; #else while ((ch = mygetopt(argc, argv, "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) { switch (ch) { case '?' : Usage(); exit(EXIT_SUCCESS); case 'd' : doCliCertCheck = 0; break; case 'b' : useAnyAddr = 1; break; case 's' : usePsk = 1; break; case 'j' : usePskPlus = 1; break; case 't' : #ifdef USE_WOLFSSL_MEMORY trackMemory = 1; #endif break; case 'n' : useNtruKey = 1; break; case 'u' : doDTLS = 1; break; case 'f' : fewerPackets = 1; break; case 'R' : serverReadyFile = myoptarg; break; case 'r' : #ifndef NO_SESSION_CACHE resume = 1; #endif break; case 'P' : #ifdef HAVE_PK_CALLBACKS pkCallbacks = 1; #endif break; case 'p' : port = (word16)atoi(myoptarg); break; case 'w' : wc_shutdown = 1; break; case 'v' : version = atoi(myoptarg); if (version < 0 || version > 3) { Usage(); exit(MY_EX_USAGE); } break; case 'l' : cipherList = myoptarg; break; case 'A' : verifyCert = myoptarg; break; case 'c' : ourCert = myoptarg; break; case 'k' : ourKey = myoptarg; break; case 'D' : #ifndef NO_DH ourDhParam = myoptarg; #endif break; case 'Z' : #ifndef NO_DH minDhKeyBits = atoi(myoptarg); if (minDhKeyBits <= 0 || minDhKeyBits > 16000) { Usage(); exit(MY_EX_USAGE); } #endif break; case 'N': nonBlocking = 1; break; case 'S' : #ifdef HAVE_SNI sniHostName = myoptarg; #endif break; case 'o' : #ifdef HAVE_OCSP useOcsp = 1; #endif break; case 'O' : #ifdef HAVE_OCSP useOcsp = 1; ocspUrl = myoptarg; #endif break; case 'a' : #ifdef HAVE_ANON useAnon = 1; #endif break; case 'I': #ifndef NO_PSK sendPskIdentityHint = 0; #endif break; case 'L' : #ifdef HAVE_ALPN alpnList = myoptarg; if (alpnList[0] == 'C' && alpnList[1] == ':') alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH; else if (alpnList[0] == 'F' && alpnList[1] == ':') alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH; else { Usage(); exit(MY_EX_USAGE); } alpnList += 2; #endif break; case 'i' : loopIndefinitely = 1; break; case 'e' : echoData = 1; break; case 'B': throughput = atoi(myoptarg); if (throughput <= 0) { Usage(); exit(MY_EX_USAGE); } break; #ifdef WOLFSSL_TRUST_PEER_CERT case 'E' : trustCert = myoptarg; break; #endif case 'q' : #ifdef HAVE_WNR wnrConfigFile = myoptarg; #endif break; default: Usage(); exit(MY_EX_USAGE); } } myoptind = 0; /* reset for test cases */ #endif /* !WOLFSSL_VXWORKS */ /* sort out DTLS versus TLS versions */ if (version == CLIENT_INVALID_VERSION) { if (doDTLS) version = CLIENT_DTLS_DEFAULT_VERSION; else version = CLIENT_DEFAULT_VERSION; } else { if (doDTLS) { if (version == 3) version = -2; else version = -1; } } #if defined(USE_CYASSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) if (trackMemory) InitMemoryTracker(); #endif #ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0) err_sys("can't load whitewood net random config file"); #endif switch (version) { #ifndef NO_OLD_TLS #ifdef WOLFSSL_ALLOW_SSLV3 case 0: method = wolfSSLv3_server_method_ex; break; #endif #ifndef NO_TLS case 1: method = wolfTLSv1_server_method_ex; break; case 2: method = wolfTLSv1_1_server_method_ex; break; #endif #endif #ifndef NO_TLS case 3: method = wolfTLSv1_2_server_method_ex; break; #endif #ifdef CYASSL_DTLS #ifndef NO_OLD_TLS case -1: method = wolfDTLSv1_server_method_ex; break; #endif case -2: method = wolfDTLSv1_2_server_method_ex; break; #endif default: err_sys("Bad SSL version"); } if (method == NULL) err_sys("unable to get method"); #ifdef WOLFSSL_STATIC_MEMORY #ifdef DEBUG_WOLFSSL /* print off helper buffer sizes for use with static memory * printing to stderr incase of debug mode turned on */ fprintf(stderr, "static memory management size = %d\n", wolfSSL_MemoryPaddingSz()); fprintf(stderr, "calculated optimum general buffer size = %d\n", wolfSSL_StaticBufferSz(memory, sizeof(memory), 0)); fprintf(stderr, "calculated optimum IO buffer size = %d\n", wolfSSL_StaticBufferSz(memoryIO, sizeof(memoryIO), WOLFMEM_IO_POOL_FIXED)); #endif /* DEBUG_WOLFSSL */ if (wolfSSL_CTX_load_static_memory(&ctx, method, memory, sizeof(memory),0,1) != SSL_SUCCESS) err_sys("unable to load static memory and create ctx"); /* load in a buffer for IO */ if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO), WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1) != SSL_SUCCESS) err_sys("unable to load static memory and create ctx"); #else ctx = SSL_CTX_new(method(NULL)); #endif if (ctx == NULL) err_sys("unable to get ctx"); #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ defined(HAVE_POLY1305) if (TicketInit() != 0) err_sys("unable to setup Session Ticket Key context"); wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb); #endif if (cipherList) if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 1"); #ifdef CYASSL_LEANPSK if (!usePsk) { usePsk = 1; } #endif #if defined(NO_RSA) && !defined(HAVE_ECC) if (!usePsk) { usePsk = 1; } #endif if (fewerPackets) CyaSSL_CTX_set_group_messages(ctx); #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if ((!usePsk || usePskPlus) && !useAnon) { if (SSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " wolfSSL home dir"); } #endif #ifndef NO_DH if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits) != SSL_SUCCESS) { err_sys("Error setting minimum DH key size"); } #endif #ifndef NO_RSA if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != SSL_SUCCESS){ err_sys("Error setting minimum RSA key size"); } #endif #ifdef HAVE_ECC if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){ err_sys("Error setting minimum ECC key size"); } #endif #ifdef HAVE_NTRU if (useNtruKey) { if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey) != SSL_SUCCESS) err_sys("can't load ntru key file, " "Please run from wolfSSL home dir"); } #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon) { if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server private key file, check file and run " "from wolfSSL home dir"); } #endif if (usePsk || usePskPlus) { #ifndef NO_PSK SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); if (sendPskIdentityHint == 1) SSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); if (cipherList == NULL && !usePskPlus) { const char *defaultCipherList; #if defined(HAVE_AESGCM) && !defined(NO_DH) defaultCipherList = "DHE-PSK-AES128-GCM-SHA256"; needDH = 1; #elif defined(HAVE_NULL_CIPHER) defaultCipherList = "PSK-NULL-SHA256"; #else defaultCipherList = "PSK-AES128-CBC-SHA256"; #endif if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 2"); } #endif } if (useAnon) { #ifdef HAVE_ANON CyaSSL_CTX_allow_anon_cipher(ctx); if (cipherList == NULL) { if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS) err_sys("server can't set cipher list 4"); } #endif } #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) /* if not using PSK, verify peer with certs if using PSK Plus then verify peer certs except PSK suites */ if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | ((usePskPlus)? SSL_VERIFY_FAIL_EXCEPT_PSK : SSL_VERIFY_FAIL_IF_NO_PEER_CERT),0); if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); #ifdef WOLFSSL_TRUST_PEER_CERT if (trustCert) { if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert, SSL_FILETYPE_PEM)) != SSL_SUCCESS) { err_sys("can't load trusted peer cert file"); } } #endif /* WOLFSSL_TRUST_PEER_CERT */ } #endif #if defined(CYASSL_SNIFFER) /* don't use EDH, can't sniff tmp keys */ if (cipherList == NULL) { if (SSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS) err_sys("server can't set cipher list 3"); } #endif #ifdef HAVE_SNI if (sniHostName) if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName, XSTRLEN(sniHostName)) != SSL_SUCCESS) err_sys("UseSNI failed"); #endif #ifdef USE_WINDOWS_API if (port == 0) { /* Generate random port for testing */ port = GetRandomPort(); } #endif /* USE_WINDOWS_API */ while (1) { /* allow resume option */ if(resumeCount > 1) { if (doDTLS == 0) { SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); clientfd = accept(sockfd, (struct sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); } else { tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); clientfd = sockfd; } if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) { err_sys("tcp accept failed"); } } #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) { WOLFSSL_MEM_STATS mem_stats; fprintf(stderr, "Before creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) err_sys("ctx not using static memory"); if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ err_sys("error printing out memory stats"); } #endif ssl = SSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL"); #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) { WOLFSSL_MEM_STATS mem_stats; fprintf(stderr, "After creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) err_sys("ctx not using static memory"); if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ err_sys("error printing out memory stats"); } #endif #ifndef NO_HANDSHAKE_DONE_CB wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL); #endif #ifdef HAVE_CRL #ifdef HAVE_CRL_MONITOR crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON; #endif if (CyaSSL_EnableCRL(ssl, 0) != SSL_SUCCESS) err_sys("unable to enable CRL"); if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, crlFlags) != SSL_SUCCESS) err_sys("unable to load CRL"); if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS) err_sys("unable to set CRL callback url"); #endif #ifdef HAVE_OCSP if (useOcsp) { if (ocspUrl != NULL) { CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl); CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE | CYASSL_OCSP_URL_OVERRIDE); } else CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE); } #endif #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS) err_sys("can't enable OCSP Stapling Certificate Manager"); if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate1-ca-cert.pem", 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate2-ca-cert.pem", 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate3-ca-cert.pem", 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); #endif #ifdef HAVE_PK_CALLBACKS if (pkCallbacks) SetupPkCallbacks(ctx, ssl); #endif /* do accept */ readySignal = ((func_args*)args)->signal; if (readySignal) { readySignal->srfName = serverReadyFile; } tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS, serverReadyFile ? 1 : 0, doListen); doListen = 0; /* Don't listen next time */ if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } #ifdef HAVE_ALPN if (alpnList != NULL) { printf("ALPN accepted protocols list : %s\n", alpnList); wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt); } #endif #ifdef WOLFSSL_DTLS if (doDTLS) { SOCKADDR_IN_T cliaddr; byte b[1500]; int n; socklen_t len = sizeof(cliaddr); /* For DTLS, peek at the next datagram so we can get the client's * address and set it into the ssl object later to generate the * cookie. */ n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK, (struct sockaddr*)&cliaddr, &len); if (n <= 0) err_sys("recvfrom failed"); wolfSSL_dtls_set_peer(ssl, &cliaddr, len); } #endif if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL || needDH == 1) { #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN) CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM); #elif !defined(NO_DH) SetDH(ssl); /* repick suites with DHE, higher priority than PSK */ #endif } #ifndef CYASSL_CALLBACKS if (nonBlocking) { CyaSSL_set_using_nonblock(ssl, 1); tcp_set_nonblocking(&clientfd); } #endif do { #ifdef WOLFSSL_ASYNC_CRYPT if (err == WC_PENDING_E) { ret = AsyncCryptPoll(ssl); if (ret < 0) { break; } else if (ret == 0) { continue; } } #endif err = 0; /* Reset error */ #ifndef CYASSL_CALLBACKS if (nonBlocking) { ret = NonBlockingSSL_Accept(ssl); } else { ret = SSL_accept(ssl); } #else ret = NonBlockingSSL_Accept(ssl); #endif if (ret != SSL_SUCCESS) { err = SSL_get_error(ssl, 0); } } while (ret != SSL_SUCCESS && err == WC_PENDING_E); if (ret != SSL_SUCCESS) { char buffer[CYASSL_MAX_ERROR_SZ]; err = SSL_get_error(ssl, 0); printf("error = %d, %s\n", err, ERR_error_string(err, buffer)); err_sys("SSL_accept failed"); } showPeer(ssl); #ifdef HAVE_ALPN if (alpnList != NULL) { char *protocol_name = NULL, *list = NULL; word16 protocol_nameSz = 0, listSz = 0; err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz); if (err == SSL_SUCCESS) printf("Sent ALPN protocol : %s (%d)\n", protocol_name, protocol_nameSz); else if (err == SSL_ALPN_NOT_FOUND) printf("No ALPN response sent (no match)\n"); else printf("Getting ALPN protocol name failed\n"); err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz); if (err == SSL_SUCCESS) printf("List of protocol names sent by Client: %s (%d)\n", list, listSz); else printf("Get list of client's protocol name failed\n"); free(list); } #endif if(echoData == 0 && throughput == 0) { ret = SSL_read(ssl, input, sizeof(input)-1); if (ret > 0) { input[ret] = 0; printf("Client message: %s\n", input); } else if (ret < 0) { int readErr = SSL_get_error(ssl, 0); if (readErr != SSL_ERROR_WANT_READ) err_sys("SSL_read failed"); } if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) err_sys("SSL_write failed"); } else { ServerEchoData(ssl, clientfd, echoData, throughput); } #if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX) os_dly_wait(500) ; #elif defined (CYASSL_TIRTOS) Task_yield(); #endif if (doDTLS == 0) { ret = SSL_shutdown(ssl); if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) SSL_shutdown(ssl); /* bidirectional shutdown */ } /* display collected statistics */ #ifdef WOLFSSL_STATIC_MEMORY if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1) err_sys("static memory was not used with ssl"); fprintf(stderr, "\nprint off SSL memory stats\n"); fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n"); fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem); fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem); fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc); fprintf(stderr, "current connection allocs = %d\n",ssl_stats.curAlloc); fprintf(stderr, "total connection allocs = %d\n",ssl_stats.totalAlloc); fprintf(stderr, "total connection frees = %d\n\n", ssl_stats.totalFr); #endif SSL_free(ssl); CloseSocket(clientfd); if (resume == 1 && resumeCount == 0) { resumeCount++; /* only do one resume for testing */ continue; } resumeCount = 0; if(!loopIndefinitely) { break; /* out of while loop, done with normal and resume option */ } } /* while(1) */ CloseSocket(sockfd); SSL_CTX_free(ctx); ((func_args*)args)->return_code = 0; #if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \ && defined(HAVE_THREAD_LS) ecc_fp_free(); /* free per thread cache */ #endif #if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) if (trackMemory) ShowMemoryTracker(); #endif #ifdef CYASSL_TIRTOS fdCloseSession(Task_self()); #endif #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ defined(HAVE_POLY1305) TicketCleanup(); #endif /* There are use cases when these assignments are not read. To avoid * potential confusion those warnings have been handled here. */ (void) ourKey; (void) verifyCert; (void) doCliCertCheck; (void) useNtruKey; (void) ourDhParam; (void) ourCert; (void) trackMemory; #ifndef CYASSL_TIRTOS return 0; #endif }
PEGASUS_NAMESPACE_BEGIN // // Basic SSL socket // SSLSocket::SSLSocket( SocketHandle socket, SSLContext * sslcontext, ReadWriteSem * sslContextObjectLock, const String& ipAddress) : _SSLConnection(0), _socket(socket), _SSLContext(sslcontext), _sslContextObjectLock(sslContextObjectLock), _ipAddress(ipAddress), _certificateVerified(false) { PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::SSLSocket()"); SSL* sslConnection; SharedPtr<X509_STORE, FreeX509STOREPtr> tmpCrlStore; _sslReadErrno = 0; // // create the SSLConnection area // if (!(sslConnection = SSL_new(_SSLContext->_rep->getContext()))) { PEG_METHOD_EXIT(); MessageLoaderParms parms( "Common.TLS.COULD_NOT_GET_SSL_CONNECTION_AREA", "Could not get SSL Connection Area."); throw SSLException(parms); } // This try/catch block is necessary so that we can free the SSL Connection // Area if any exceptions are thrown. try { // // set the verification callback data // // we are only storing one set of data, so we can just use index 0, // this is defined in SSLContext.h //int index = SSL_get_ex_new_index( // 0, (void*)"pegasus", NULL, NULL, NULL); // // Create a new callback info for each new connection // #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION tmpCrlStore = _SSLContext->_rep->getCRLStore(); #endif _SSLCallbackInfo.reset(new SSLCallbackInfo( _SSLContext->getSSLCertificateVerifyFunction(), tmpCrlStore.get(), _ipAddress )); if (SSL_set_ex_data( sslConnection, SSLCallbackInfo::SSL_CALLBACK_INDEX, _SSLCallbackInfo.get())) { PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "--->SSL: Set callback info"); } else { PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1, "--->SSL: Error setting callback info"); } // // and connect the active socket with the ssl operation // if (!(SSL_set_fd(sslConnection, _socket) )) { PEG_METHOD_EXIT(); MessageLoaderParms parms( "Common.TLS.COULD_NOT_LINK_SOCKET", "Could not link socket to SSL Connection."); throw SSLException(parms); } } catch (...) { SSL_free(sslConnection); throw; } _SSLConnection = sslConnection; _crlStore = new SharedPtr<X509_STORE, FreeX509STOREPtr>(tmpCrlStore); PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: Created SSL socket"); PEG_METHOD_EXIT(); }
int MAIN(int argc, char **argv) { int ret = 1, i; int verbose = 0, Verbose = 0; const char **pp; const char *p; int badops = 0; SSL_CTX *ctx = NULL; SSL *ssl = NULL; char *ciphers = NULL; const SSL_METHOD *meth = NULL; STACK_OF(SSL_CIPHER) *sk; char buf[512]; BIO *STDout = NULL; meth = SSLv23_server_method(); apps_startup(); if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); STDout = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); STDout = BIO_push(tmpbio, STDout); } #endif if (!load_config(bio_err, NULL)) goto end; argc--; argv++; while (argc >= 1) { if (strcmp(*argv, "-v") == 0) verbose = 1; else if (strcmp(*argv, "-V") == 0) verbose = Verbose = 1; #ifndef OPENSSL_NO_SSL2 else if (strcmp(*argv, "-ssl2") == 0) meth = SSLv2_client_method(); #endif #ifndef OPENSSL_NO_SSL3 else if (strcmp(*argv, "-ssl3") == 0) meth = SSLv3_client_method(); #endif #ifndef OPENSSL_NO_TLS1 else if (strcmp(*argv, "-tls1") == 0) meth = TLSv1_client_method(); #endif else if ((strncmp(*argv, "-h", 2) == 0) || (strcmp(*argv, "-?") == 0)) { badops = 1; break; } else { ciphers = *argv; } argc--; argv++; } if (badops) { for (pp = ciphers_usage; (*pp != NULL); pp++) BIO_printf(bio_err, "%s", *pp); goto end; } OpenSSL_add_ssl_algorithms(); ctx = SSL_CTX_new(meth); if (ctx == NULL) goto err; if (ciphers != NULL) { if (!SSL_CTX_set_cipher_list(ctx, ciphers)) { BIO_printf(bio_err, "Error in cipher list\n"); goto err; } } ssl = SSL_new(ctx); if (ssl == NULL) goto err; if (!verbose) { for (i = 0;; i++) { p = SSL_get_cipher_list(ssl, i); if (p == NULL) break; if (i != 0) BIO_printf(STDout, ":"); BIO_printf(STDout, "%s", p); } BIO_printf(STDout, "\n"); } else { /* verbose */ sk = SSL_get_ciphers(ssl); for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { SSL_CIPHER *c; c = sk_SSL_CIPHER_value(sk, i); if (Verbose) { unsigned long id = SSL_CIPHER_get_id(c); int id0 = (int)(id >> 24); int id1 = (int)((id >> 16) & 0xffL); int id2 = (int)((id >> 8) & 0xffL); int id3 = (int)(id & 0xffL); if ((id & 0xff000000L) == 0x02000000L) { /* SSL2 cipher */ BIO_printf(STDout, " 0x%02X,0x%02X,0x%02X - ", id1, id2, id3); } else if ((id & 0xff000000L) == 0x03000000L) { /* SSL3 cipher */ BIO_printf(STDout, " 0x%02X,0x%02X - ", id2, id3); } else { /* whatever */ BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); } } BIO_puts(STDout, SSL_CIPHER_description(c, buf, sizeof buf)); } } ret = 0; if (0) { err: SSL_load_error_strings(); ERR_print_errors(bio_err); } end: if (ctx != NULL) SSL_CTX_free(ctx); if (ssl != NULL) SSL_free(ssl); if (STDout != NULL) BIO_free_all(STDout); apps_shutdown(); OPENSSL_EXIT(ret); }
/* {{{ ftp_login */ int ftp_login(ftpbuf_t *ftp, const char *user, const char *pass) { #ifdef HAVE_FTP_SSL SSL_CTX *ctx = NULL; long ssl_ctx_options = SSL_OP_ALL; int err, res; zend_bool retry; #endif if (ftp == NULL) { return 0; } #ifdef HAVE_FTP_SSL if (ftp->use_ssl && !ftp->ssl_active) { if (!ftp_putcmd(ftp, "AUTH", "TLS")) { return 0; } if (!ftp_getresp(ftp)) { return 0; } if (ftp->resp != 234) { if (!ftp_putcmd(ftp, "AUTH", "SSL")) { return 0; } if (!ftp_getresp(ftp)) { return 0; } if (ftp->resp != 334) { return 0; } else { ftp->old_ssl = 1; ftp->use_ssl_for_data = 1; } } ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { php_error_docref(NULL, E_WARNING, "failed to create the SSL context"); return 0; } #if OPENSSL_VERSION_NUMBER >= 0x0090605fL ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif SSL_CTX_set_options(ctx, ssl_ctx_options); ftp->ssl_handle = SSL_new(ctx); if (ftp->ssl_handle == NULL) { php_error_docref(NULL, E_WARNING, "failed to create the SSL handle"); SSL_CTX_free(ctx); return 0; } SSL_set_fd(ftp->ssl_handle, ftp->fd); do { res = SSL_connect(ftp->ssl_handle); err = SSL_get_error(ftp->ssl_handle, res); /* TODO check if handling other error codes would make sense */ switch (err) { case SSL_ERROR_NONE: retry = 0; break; case SSL_ERROR_ZERO_RETURN: retry = 0; SSL_shutdown(ftp->ssl_handle); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: { php_pollfd p; int i; p.fd = ftp->fd; p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT; p.revents = 0; i = php_poll2(&p, 1, 300); retry = i > 0; } break; default: php_error_docref(NULL, E_WARNING, "SSL/TLS handshake failed"); SSL_shutdown(ftp->ssl_handle); SSL_free(ftp->ssl_handle); return 0; } } while (retry); ftp->ssl_active = 1; if (!ftp->old_ssl) { /* set protection buffersize to zero */ if (!ftp_putcmd(ftp, "PBSZ", "0")) { return 0; } if (!ftp_getresp(ftp)) { return 0; } /* enable data conn encryption */ if (!ftp_putcmd(ftp, "PROT", "P")) { return 0; } if (!ftp_getresp(ftp)) { return 0; } ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299); } } #endif if (!ftp_putcmd(ftp, "USER", user)) { return 0; } if (!ftp_getresp(ftp)) { return 0; } if (ftp->resp == 230) { return 1; } if (ftp->resp != 331) { return 0; } if (!ftp_putcmd(ftp, "PASS", pass)) { return 0; } if (!ftp_getresp(ftp)) { return 0; } return (ftp->resp == 230); }
/* {{{ data_accept */ databuf_t* data_accept(databuf_t *data, ftpbuf_t *ftp) { php_sockaddr_storage addr; socklen_t size; #ifdef HAVE_FTP_SSL SSL_CTX *ctx; zend_long ssl_ctx_options = SSL_OP_ALL; int err, res; zend_bool retry; #endif if (data->fd != -1) { goto data_accepted; } size = sizeof(addr); data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size); closesocket(data->listener); data->listener = -1; if (data->fd == -1) { efree(data); return NULL; } data_accepted: #ifdef HAVE_FTP_SSL /* now enable ssl if we need to */ if (ftp->use_ssl && ftp->use_ssl_for_data) { ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL context"); return 0; } #if OPENSSL_VERSION_NUMBER >= 0x0090605fL ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif SSL_CTX_set_options(ctx, ssl_ctx_options); data->ssl_handle = SSL_new(ctx); if (data->ssl_handle == NULL) { php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle"); SSL_CTX_free(ctx); return 0; } SSL_set_fd(data->ssl_handle, data->fd); if (ftp->old_ssl) { SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle); } do { res = SSL_connect(data->ssl_handle); err = SSL_get_error(data->ssl_handle, res); switch (err) { case SSL_ERROR_NONE: retry = 0; break; case SSL_ERROR_ZERO_RETURN: retry = 0; SSL_shutdown(data->ssl_handle); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: { php_pollfd p; int i; p.fd = ftp->fd; p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT; p.revents = 0; i = php_poll2(&p, 1, 300); retry = i > 0; } break; default: php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed"); SSL_shutdown(data->ssl_handle); SSL_free(data->ssl_handle); return 0; } } while (retry); data->ssl_active = 1; } #endif return data; }
int main(int argc, char *argv[]) { /* deletes existeng ecents */ remove("ecents.txt"); SSL_CTX *ctx; int type, server, localport, proxyport, bankport; int i = 0; SSL *ssl; char buf[1024]; char buf2[33000]; int bytes; char *proxyhost; char *bankhost; if ( argc <6 ) { printf("usage: type localport proxyhost proxyport bankhost bankport \n"); exit(0); } /* initialises SSL library and copies line arguments */ SSL_library_init(); type = atoi(argv[1]); localport=atoi(argv[2]); proxyhost=argv[3]; proxyport = atoi(argv[4]); bankhost = argv[5]; bankport = atoi(argv[6]); registrationrequest(type, localport, proxyhost, proxyport); int requestedecents = 1000; while(1){ char msg[1024]; bzero(msg,1024); ctx = InitCTX(); if(i == 0){ printf("\nrequested number of eCents: \n"); wait(3); printf("\t%i\n", requestedecents); wait(3); sprintf(msg,"%c%i",'0',requestedecents); server = OpenConnection(bankhost, localport, bankport); } else{ printf("\ninput:\n"); strcpy(msg, geteCent()); if(strlen(msg) != 32){ printf("no eCents\n"); } else { strcat(msg, getData()); server = OpenConnection(proxyhost, localport, proxyport); } } /* creates ssl context and sets socket to it*/ ssl = SSL_new(ctx); SSL_set_fd(ssl, server); if ( SSL_connect(ssl) == -1 ){ ERR_print_errors_fp(stderr); printf("connection error\n"); } else { printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); printf("sending: %s\n", msg); ShowCerts(ssl); /* Write to Bank to verify ecent */ SSL_write(ssl, msg, sizeof(msg)); if(i == 0){ bzero(buf2, 33000); /* Read from Bank, confirm verification*/ bytes = SSL_read(ssl, buf2, sizeof(buf2)); if(bytes < 1) { printf("Exit read error from Bank\n"); exit(1); } buf2[bytes] = '\0'; printf("eCents received: %s\n", buf2); puteCents(buf2); } else{ /* Reads from Collector*/ bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ buf[bytes] = '\0'; if(bytes < 1) { printf("Exit: read error from Analyst\n"); exit(1); } if(strcmp(buf, "invalid eCent") == 0) printf("\n%s\n", buf); else printf("\naverage: %s\n", buf); } SSL_free(ssl); } sleep(1); close(server); SSL_CTX_free(ctx); i++; } return 0; }
static void sl_destroy_ssl (SLtype type, VOID_STAR f){ SLssl_Type *ssl; ssl=(SLssl_Type *)f; SSL_free((SSL *)(ssl->ssl)); }
Result<SslFd> SslFd::init(SocketFd fd, CSlice host, CSlice cert_file, VerifyPeer verify_peer) { #if TD_WINDOWS return Status::Error("TODO"); #else static bool init_openssl = [] { #if OPENSSL_VERSION_NUMBER >= 0x10100000L return OPENSSL_init_ssl(0, nullptr) != 0; #else OpenSSL_add_all_algorithms(); SSL_load_error_strings(); return OpenSSL_add_ssl_algorithms() != 0; #endif }(); CHECK(init_openssl); openssl_clear_errors("Before SslFd::init"); CHECK(!fd.empty()); auto ssl_method = #if OPENSSL_VERSION_NUMBER >= 0x10100000L TLS_client_method(); #else SSLv23_client_method(); #endif if (ssl_method == nullptr) { return create_openssl_error(-6, "Failed to create an SSL client method"); } auto ssl_ctx = SSL_CTX_new(ssl_method); if (ssl_ctx == nullptr) { return create_openssl_error(-7, "Failed to create an SSL context"); } auto ssl_ctx_guard = ScopeExit() + [&]() { SSL_CTX_free(ssl_ctx); }; long options = 0; #ifdef SSL_OP_NO_SSLv2 options |= SSL_OP_NO_SSLv2; #endif #ifdef SSL_OP_NO_SSLv3 options |= SSL_OP_NO_SSLv3; #endif SSL_CTX_set_options(ssl_ctx, options); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE); if (cert_file.empty()) { SSL_CTX_set_default_verify_paths(ssl_ctx); } else { if (SSL_CTX_load_verify_locations(ssl_ctx, cert_file.c_str(), nullptr) == 0) { return create_openssl_error(-8, "Failed to set custom cert file"); } } if (VERIFY_PEER && verify_peer == VerifyPeer::On) { SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_callback); if (VERIFY_DEPTH != -1) { SSL_CTX_set_verify_depth(ssl_ctx, VERIFY_DEPTH); } } else { SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, nullptr); } // TODO(now): cipher list string cipher_list; if (SSL_CTX_set_cipher_list(ssl_ctx, cipher_list.empty() ? "DEFAULT" : cipher_list.c_str()) == 0) { return create_openssl_error(-9, PSLICE("Failed to set cipher list \"%s\"", cipher_list.c_str())); } auto ssl_handle = SSL_new(ssl_ctx); if (ssl_handle == nullptr) { return create_openssl_error(-13, "Failed to create an SSL handle"); } auto ssl_handle_guard = ScopeExit() + [&]() { do_ssl_shutdown(ssl_handle); SSL_free(ssl_handle); }; #if OPENSSL_VERSION_NUMBER >= 0x10002000L X509_VERIFY_PARAM *param = SSL_get0_param(ssl_handle); /* Enable automatic hostname checks */ // TODO: X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS X509_VERIFY_PARAM_set_hostflags(param, 0); X509_VERIFY_PARAM_set1_host(param, host.c_str(), 0); #else #warning DANGEROUS! HTTPS HOST WILL NOT BE CHECKED. INSTALL OPENSSL >= 1.0.2 OR IMPLEMENT HTTPS HOST CHECK MANUALLY #endif if (!SSL_set_fd(ssl_handle, fd.get_fd().get_native_fd())) { return create_openssl_error(-14, "Failed to set fd"); } #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) auto host_str = host.str(); SSL_set_tlsext_host_name(ssl_handle, MutableCSlice(host_str).begin()); #endif SSL_set_connect_state(ssl_handle); ssl_ctx_guard.dismiss(); ssl_handle_guard.dismiss(); return SslFd(std::move(fd), ssl_handle, ssl_ctx); #endif }
/*@C PetscHTTPSRequest - Send a request to an HTTPS server Input Parameters: + type - either "POST" or "GET" . url - URL of request host/path . header - additional header information, may be NULL . ctype - data type of body, for example application/json . body - data to send to server . ssl - obtained with PetscHTTPSConnect() - buffsize - size of buffer Output Parameter: . buff - everything returned from server Level: advanced .seealso: PetscHTTPRequest(), PetscHTTPSConnect(), PetscSSLInitializeContext(), PetscSSLDestroyContext(), PetscPullJSONValue() @*/ PetscErrorCode PetscHTTPSRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],SSL *ssl,char buff[],size_t buffsize) { char *request; int r; size_t request_len,len; PetscErrorCode ierr; PetscBool foundbody = PETSC_FALSE; PetscFunctionBegin; ierr = PetscHTTPBuildRequest(type,url,header,ctype,body,&request);CHKERRQ(ierr); ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr); r = SSL_write(ssl,request,(int)request_len); switch (SSL_get_error(ssl,r)){ case SSL_ERROR_NONE: if (request_len != (size_t)r) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Incomplete write to SSL socket"); break; default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL socket write problem"); } /* Now read the server's response, globus sends it in two chunks hence must read a second time if needed */ ierr = PetscMemzero(buff,buffsize);CHKERRQ(ierr); len = 0; foundbody = PETSC_FALSE; do { char *clen; int cl; size_t nlen; r = SSL_read(ssl,buff+len,(int)buffsize); len += r; switch (SSL_get_error(ssl,r)){ case SSL_ERROR_NONE: break; case SSL_ERROR_ZERO_RETURN: foundbody = PETSC_TRUE; SSL_shutdown(ssl); break; case SSL_ERROR_SYSCALL: foundbody = PETSC_TRUE; break; default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL read problem"); } ierr = PetscStrstr(buff,"Content-Length: ",&clen);CHKERRQ(ierr); if (clen) { clen += 15; sscanf(clen,"%d",&cl); if (!cl) foundbody = PETSC_TRUE; else { ierr = PetscStrstr(buff,"\r\n\r\n",&clen);CHKERRQ(ierr); if (clen) { ierr = PetscStrlen(clen,&nlen);CHKERRQ(ierr); if (nlen-4 == (size_t) cl) foundbody = PETSC_TRUE; } } } else { /* if no content length than must leave because you don't know if you can read again */ foundbody = PETSC_TRUE; } } while (!foundbody); ierr = PetscInfo1(NULL,"HTTPS result follows: \n%s\n",buff);CHKERRQ(ierr); SSL_free(ssl); ierr = PetscFree(request);CHKERRQ(ierr); PetscFunctionReturn(0); }
void signal_handler(int sig) { switch (sig) { case SIGXFSZ: log_msg(mainlogfile, gettext("File size limit exceeded"), 1); log_msg(mainlogfile, gettext("\nProgram Terminated.\n"), 1); log_msg(mainlogfile, "<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n\n", 0); if (client_sock != -1) close(client_sock); #ifndef WITHOUT_SSL SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); #else close(server_sock); #endif exit(1); break; case SIGPIPE: #ifndef WITHOUT_SSL nunetwork_close(ssl); #else nunetwork_close(client_sock); #endif break; case SIGHUP: log_msg(mainlogfile, gettext("Hangup signal catched"), 1); log_msg(mainlogfile, gettext("\nReloading configuration...\n\n"), 1); readconfig(conffile); setlocale (LC_ALL, (const char*)lc_all); bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR); textdomain ( PACKAGE ); log_msg(mainlogfile, gettext("Configuration reloaded successfully.\n\n"), 1); break; case SIGTERM: log_msg(mainlogfile, gettext("Terminate signal catched"), 1); log_msg(mainlogfile, gettext("\nClosing active sessions...\n"), 1); if (client_sock != -1) close(client_sock); #ifndef WITHOUT_SSL SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); #else close(server_sock); #endif log_msg(mainlogfile, gettext("Bye bye\n"), 1); log_msg(mainlogfile, "<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n\n", 0); log_msg(logfile, "<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n\n", 0); exit(0); break; } }
void main() { int err; int verify_client = OFF; /* To verify a client certificate, set ON */ int listen_sock; int sock; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; size_t client_len; char *str; char buf[4096]; SSL_CTX *ctx; SSL *ssl; SSL_METHOD *meth; X509 *client_cert = NULL; short int s_port = 5555; /*----------------------------------------------------------------*/ /* Load encryption & hashing algorithms for the SSL program */ SSL_library_init(); /* Load the error strings for SSL & CRYPTO APIs */ SSL_load_error_strings(); /* Create a SSL_METHOD structure (choose a SSL/TLS protocol version) */ meth = SSLv3_method(); /* Create a SSL_CTX structure */ ctx = SSL_CTX_new(meth); if (!ctx) { ERR_print_errors_fp(stderr); exit(1); } /* Load the server certificate into the SSL_CTX structure */ if (SSL_CTX_use_certificate_file(ctx, RSA_SERVER_CERT, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(1); } /* Load the private-key corresponding to the server certificate */ if (SSL_CTX_use_PrivateKey_file(ctx, RSA_SERVER_KEY, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(1); } /* Check if the server certificate and private-key matches */ if (!SSL_CTX_check_private_key(ctx)) { fprintf(stderr,"Private key does not match the certificate public key\n"); exit(1); } if(verify_client == ON) { /* Load the RSA CA certificate into the SSL_CTX structure */ if (!SSL_CTX_load_verify_locations(ctx, RSA_SERVER_CA_CERT, NULL)) { ERR_print_errors_fp(stderr); exit(1); } /* Set to require peer (client) certificate verification */ SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); /* Set the verification depth to 1 */ SSL_CTX_set_verify_depth(ctx,1); } /* ----------------------------------------------- */ /* Set up a TCP socket */ listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); RETURN_ERR(listen_sock, "socket"); memset (&sa_serv, '\0', sizeof(sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; sa_serv.sin_port = htons (s_port); /* Server Port number */ err = bind(listen_sock, (struct sockaddr*)&sa_serv,sizeof(sa_serv)); RETURN_ERR(err, "bind"); /* Wait for an incoming TCP connection. */ err = listen(listen_sock, 5); RETURN_ERR(err, "listen"); client_len = sizeof(sa_cli); /* Socket for a TCP/IP connection is created */ sock = accept(listen_sock, (struct sockaddr*)&sa_cli, &client_len); RETURN_ERR(sock, "accept"); close (listen_sock); printf ("Connection from %lx, port %x\n", sa_cli.sin_addr.s_addr, sa_cli.sin_port); /* ----------------------------------------------- */ /* TCP connection is ready. */ /* A SSL structure is created */ ssl = SSL_new(ctx); RETURN_NULL(ssl); /* Assign the socket into the SSL structure (SSL and socket without BIO) */ SSL_set_fd(ssl, sock); /* Perform SSL Handshake on the SSL server */ err = SSL_accept(ssl); RETURN_SSL(err); /* Informational output (optional) */ printf("SSL connection using %s\n", SSL_get_cipher (ssl)); if (verify_client == ON) { /* Get the client's certificate (optional) */ client_cert = SSL_get_peer_certificate(ssl); if (client_cert != NULL) { printf ("Client certificate:\n"); str = X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0); RETURN_NULL(str); printf ("\t subject: %s\n", str); free (str); str = X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0); RETURN_NULL(str); printf ("\t issuer: %s\n", str); free (str); X509_free(client_cert); } else printf("The SSL client does not have certificate.\n"); } /*------- DATA EXCHANGE - Receive message and send reply. -------*/ /* Receive data from the SSL client */ err = SSL_read(ssl, buf, sizeof(buf) - 1); RETURN_SSL(err); buf[err] = '\0'; printf ("Received %d chars:'%s'\n", err, buf); /* Send data to the SSL client */ err = SSL_write(ssl, "This message is from the SSL server", strlen("This message is from the SSL server")); RETURN_SSL(err); /*--------------- SSL closure ---------------*/ /* Shutdown this side (server) of the connection. */ err = SSL_shutdown(ssl); RETURN_SSL(err); /* Terminate communication on a socket */ err = close(sock); RETURN_ERR(err, "close"); /* Free the SSL structure */ SSL_free(ssl); /* Free the SSL_CTX structure */ SSL_CTX_free(ctx); }
int main_tls_client() { SSL_CTX *ctx; SSL *ssl; int server = 0; int ret; if ( (ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) printf("Unable to create a new SSL context structure.\n"); SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); // Force gcm(aes) mode SSL_CTX_set_cipher_list(ctx, "ECDH-ECDSA-AES128-GCM-SHA256"); ssl = SSL_new(ctx); server = create_socket(); SSL_set_fd(ssl, server); if ( SSL_connect(ssl) != 1 ) { printf("Error: Could not build a SSL session\n"); exit(-1); } // Start tests clock_t start, end; double cpu_time_used; int filefd; int bytes; int totalbytes = 0; bytes_recv = 0; char buf[16384]; int res = 0; int total_recv = 0; start = clock(); filefd = open(test_data, O_RDONLY); totalbytes = 0; do { bytes = read(filefd, buf, sizeof(buf)); totalbytes += bytes; if (bytes > 0) SSL_write(ssl, buf, bytes); } while(bytes > 0); close(filefd); end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; printf("OpenSSL receive time: %.02f\n", cpu_time_used); res = 0; total_recv = 0; res = SSL_read(ssl, buf, 1); total_recv += res; if (res < 0) { printf("SSL Read error: %i\n", res); } printf("Received openssl test data: %i %i\n", res, total_recv); /* Kernel TLS tests */ int tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0); if (tfmfd == -1) { perror("socket error:"); exit(-1); } struct sockaddr_alg sa = { .salg_family = AF_ALG, .salg_type = "tls", /* this selects the hash logic in the kernel */ .salg_name = "rfc5288(gcm(aes))" /* this is the cipher name */ }; if (bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { perror("AF_ALG: bind failed"); close(tfmfd); exit(-1); } int opfd = accept(tfmfd, NULL, 0); if (opfd == -1) { perror("accept:"); close(tfmfd); exit(-1); } if (setsockopt(tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 16)) { perror("AF_ALG: set authsize failed\n"); exit(-1); } EVP_CIPHER_CTX * writeCtx = ssl->enc_write_ctx; EVP_CIPHER_CTX * readCtx = ssl->enc_read_ctx; EVP_AES_GCM_CTX* gcmWrite = (EVP_AES_GCM_CTX*)(writeCtx->cipher_data); EVP_AES_GCM_CTX* gcmRead = (EVP_AES_GCM_CTX*)(readCtx->cipher_data); unsigned char* writeKey = (unsigned char*)(gcmWrite->gcm.key); unsigned char* readKey = (unsigned char*)(gcmRead->gcm.key); unsigned char* writeIV = gcmWrite->iv; unsigned char* readIV = gcmRead->iv; char keyiv[20]; memcpy(keyiv, writeKey, 16); memcpy(keyiv + 16, writeIV, 4); if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, keyiv, 20)) { perror("AF_ALG: set write key failed\n"); exit(-1); } memcpy(keyiv, readKey, 16); memcpy(keyiv + 16, readIV, 4); if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, keyiv, 20)) { perror("AF_ALG: set read key failed\n"); exit(-1); } // Load up the cmsg data struct cmsghdr *header = NULL; uint32_t *type = NULL; struct msghdr msg; /* IV data */ struct af_alg_iv *alg_iv = NULL; int ivsize = 12; uint32_t iv_msg_size = CMSG_SPACE(sizeof(*alg_iv) + ivsize); /* AEAD data */ uint32_t *assoclen = NULL; uint32_t assoc_msg_size = CMSG_SPACE(sizeof(*assoclen)); uint32_t bufferlen = CMSG_SPACE(sizeof(*type)) + /* Encryption / Decryption */ iv_msg_size +/* IV */ assoc_msg_size;/* AEAD associated data size */ memset(&msg, 0, sizeof(msg)); char* buffer = calloc(1, bufferlen); if (!buffer) return -ENOMEM; msg.msg_control = buffer; msg.msg_controllen = bufferlen; msg.msg_iov = NULL; msg.msg_iovlen = 0; /* encrypt/decrypt operation */ header = CMSG_FIRSTHDR(&msg); header->cmsg_level = SOL_ALG; header->cmsg_type = ALG_SET_OP; header->cmsg_len = CMSG_LEN(sizeof(*type)); type = (void*)CMSG_DATA(header); *type = server; /* set IV */ header = CMSG_NXTHDR(&msg, header); header->cmsg_level = SOL_ALG; header->cmsg_type = ALG_SET_IV; header->cmsg_len = iv_msg_size; alg_iv = (void*)CMSG_DATA(header); alg_iv->ivlen = 8; uint64_t writeSeq; unsigned char* writeSeqNum = ssl->s3->write_sequence; memcpy(&writeSeq, writeSeqNum, sizeof(writeSeq)); memcpy(alg_iv->iv, &writeSeq, 8); /* set AEAD information */ /* Set associated data length */ header = CMSG_NXTHDR(&msg, header); header->cmsg_level = SOL_ALG; header->cmsg_type = ALG_SET_AEAD_ASSOCLEN; header->cmsg_len = CMSG_LEN(sizeof(*assoclen)); assoclen = (void*)CMSG_DATA(header); *assoclen = 13 + 8; ret = sendmsg(opfd, &msg, MSG_MORE); if (ret < 0) { perror("sendmsg"); exit(-1); } header = CMSG_FIRSTHDR(&msg); header = CMSG_NXTHDR(&msg, header); alg_iv = (void*)CMSG_DATA(header); uint64_t readSeq; unsigned char* readSeqNum = ssl->s3->read_sequence; memcpy(&readSeq, readSeqNum, sizeof(readSeq)); memcpy(alg_iv->iv, &readSeq, 8); ret = sendmsg(opfd, &msg, MSG_MORE); if (ret < 0) { perror("sendmsg recv"); exit(-1); } // Try some simple writes send(opfd, buf, 10, 0); send(opfd, buf, 100, 0); send(opfd, buf, 16000, 0); printf("Successful send\n"); res = 0; total_recv = 0; res = recv(opfd, &buf, 1, 0); total_recv += res; if (res < 0) { printf("Ktls recv error: %i\n", res); } printf("Recvd ktls test data: %i %i\n", res, total_recv); start = clock(); off_t offset = 0; filefd = open(test_data, O_RDONLY); res = sendfile(opfd, filefd, &offset, totalbytes); close(filefd); end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; printf("ktls receive time: %.02f\n", cpu_time_used); SSL_free(ssl); close(server); SSL_CTX_free(ctx); return(0); } int OpenListener(int port) { int sd; struct sockaddr_in6 addr; sd = socket(PF_INET6, SOCK_STREAM, 0); bzero(&addr, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_port = htons(port); memcpy(addr.sin6_addr.s6_addr, &in6addr_any, sizeof(in6addr_any)); if ( bind(sd, (const struct sockaddr*)&addr, sizeof(addr)) != 0 ) { perror("can't bind port"); abort(); } if ( listen(sd, 10) != 0 ) { perror("Can't configure listening port"); abort(); } return sd; }
int MAIN(int argc, char **argv) { int off=0; SSL *con=NULL,*con2=NULL; X509_STORE *store = NULL; int s,k,width,state=0; char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL; int cbuf_len,cbuf_off; int sbuf_len,sbuf_off; fd_set readfds,writefds; short port=PORT; int full_log=1; char *host=SSL_HOST_NAME; char *cert_file=NULL,*key_file=NULL; int cert_format = FORMAT_PEM, key_format = FORMAT_PEM; char *passarg = NULL, *pass = NULL; X509 *cert = NULL; EVP_PKEY *key = NULL; char *CApath=NULL,*CAfile=NULL,*cipher=NULL; int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0; int crlf=0; int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending; SSL_CTX *ctx=NULL; int ret=1,in_init=1,i,nbio_test=0; int starttls_proto = 0; int prexit = 0, vflags = 0; SSL_METHOD *meth=NULL; #ifdef sock_type #undef sock_type #endif int sock_type=SOCK_STREAM; BIO *sbio; char *inrand=NULL; #ifndef OPENSSL_NO_ENGINE char *engine_id=NULL; ENGINE *e=NULL; #endif #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) struct timeval tv; #endif struct sockaddr peer; int peerlen = sizeof(peer); int enable_timeouts = 0 ; long mtu = 0; #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_client_method(); #elif !defined(OPENSSL_NO_SSL3) meth=SSLv3_client_method(); #elif !defined(OPENSSL_NO_SSL2) meth=SSLv2_client_method(); #endif apps_startup(); c_Pause=0; c_quiet=0; c_ign_eof=0; c_debug=0; c_msg=0; c_showcerts=0; if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; if ( ((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) || ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) || ((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL)) { BIO_printf(bio_err,"out of memory\n"); goto end; } verify_depth=0; verify_error=X509_V_OK; #ifdef FIONBIO c_nbio=0; #endif argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-host") == 0) { if (--argc < 1) goto bad; host= *(++argv); } else if (strcmp(*argv,"-port") == 0) { if (--argc < 1) goto bad; port=atoi(*(++argv)); if (port == 0) goto bad; } else if (strcmp(*argv,"-connect") == 0) { if (--argc < 1) goto bad; if (!extract_host_port(*(++argv),&host,NULL,&port)) goto bad; } else if (strcmp(*argv,"-verify") == 0) { verify=SSL_VERIFY_PEER; if (--argc < 1) goto bad; verify_depth=atoi(*(++argv)); BIO_printf(bio_err,"verify depth is %d\n",verify_depth); } else if (strcmp(*argv,"-cert") == 0) { if (--argc < 1) goto bad; cert_file= *(++argv); } else if (strcmp(*argv,"-certform") == 0) { if (--argc < 1) goto bad; cert_format = str2fmt(*(++argv)); } else if (strcmp(*argv,"-crl_check") == 0) vflags |= X509_V_FLAG_CRL_CHECK; else if (strcmp(*argv,"-crl_check_all") == 0) vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; else if (strcmp(*argv,"-prexit") == 0) prexit=1; else if (strcmp(*argv,"-crlf") == 0) crlf=1; else if (strcmp(*argv,"-quiet") == 0) { c_quiet=1; c_ign_eof=1; } else if (strcmp(*argv,"-ign_eof") == 0) c_ign_eof=1; else if (strcmp(*argv,"-pause") == 0) c_Pause=1; else if (strcmp(*argv,"-debug") == 0) c_debug=1; #ifdef WATT32 else if (strcmp(*argv,"-wdebug") == 0) dbug_init(); #endif else if (strcmp(*argv,"-msg") == 0) c_msg=1; else if (strcmp(*argv,"-showcerts") == 0) c_showcerts=1; else if (strcmp(*argv,"-nbio_test") == 0) nbio_test=1; else if (strcmp(*argv,"-state") == 0) state=1; #ifndef OPENSSL_NO_SSL2 else if (strcmp(*argv,"-ssl2") == 0) meth=SSLv2_client_method(); #endif #ifndef OPENSSL_NO_SSL3 else if (strcmp(*argv,"-ssl3") == 0) meth=SSLv3_client_method(); #endif #ifndef OPENSSL_NO_TLS1 else if (strcmp(*argv,"-tls1") == 0) meth=TLSv1_client_method(); #endif #ifndef OPENSSL_NO_DTLS1 else if (strcmp(*argv,"-dtls1") == 0) { meth=DTLSv1_client_method(); sock_type=SOCK_DGRAM; } else if (strcmp(*argv,"-timeout") == 0) enable_timeouts=1; else if (strcmp(*argv,"-mtu") == 0) { if (--argc < 1) goto bad; mtu = atol(*(++argv)); } #endif else if (strcmp(*argv,"-bugs") == 0) bugs=1; else if (strcmp(*argv,"-keyform") == 0) { if (--argc < 1) goto bad; key_format = str2fmt(*(++argv)); } else if (strcmp(*argv,"-pass") == 0) { if (--argc < 1) goto bad; passarg = *(++argv); } else if (strcmp(*argv,"-key") == 0) { if (--argc < 1) goto bad; key_file= *(++argv); } else if (strcmp(*argv,"-reconnect") == 0) { reconnect=5; } else if (strcmp(*argv,"-CApath") == 0) { if (--argc < 1) goto bad; CApath= *(++argv); } else if (strcmp(*argv,"-CAfile") == 0) { if (--argc < 1) goto bad; CAfile= *(++argv); } else if (strcmp(*argv,"-no_tls1") == 0) off|=SSL_OP_NO_TLSv1; else if (strcmp(*argv,"-no_ssl3") == 0) off|=SSL_OP_NO_SSLv3; else if (strcmp(*argv,"-no_ssl2") == 0) off|=SSL_OP_NO_SSLv2; else if (strcmp(*argv,"-serverpref") == 0) off|=SSL_OP_CIPHER_SERVER_PREFERENCE; else if (strcmp(*argv,"-cipher") == 0) { if (--argc < 1) goto bad; cipher= *(++argv); } #ifdef FIONBIO else if (strcmp(*argv,"-nbio") == 0) { c_nbio=1; } #endif else if (strcmp(*argv,"-starttls") == 0) { if (--argc < 1) goto bad; ++argv; if (strcmp(*argv,"smtp") == 0) starttls_proto = 1; else if (strcmp(*argv,"pop3") == 0) starttls_proto = 2; else goto bad; } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine_id = *(++argv); } #endif else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) goto bad; inrand= *(++argv); } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badop=1; break; } argc--; argv++; } if (badop) { bad: sc_usage(); goto end; } OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine_id, 1); #endif if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (key_file == NULL) key_file = cert_file; if (key_file) { key = load_key(bio_err, key_file, key_format, 0, pass, e, "client certificate private key file"); if (!key) { ERR_print_errors(bio_err); goto end; } } if (cert_file) { cert = load_cert(bio_err,cert_file,cert_format, NULL, e, "client certificate file"); if (!cert) { ERR_print_errors(bio_err); goto end; } } if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); if (bio_c_out == NULL) { if (c_quiet && !c_debug && !c_msg) { bio_c_out=BIO_new(BIO_s_null()); } else { if (bio_c_out == NULL) bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE); } } ctx=SSL_CTX_new(meth); if (ctx == NULL) { ERR_print_errors(bio_err); goto end; } if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL|off); else SSL_CTX_set_options(ctx,off); /* DTLS: partial reads end up discarding unread UDP bytes :-( * Setting read ahead solves this problem. */ if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); if (cipher != NULL) if(!SSL_CTX_set_cipher_list(ctx,cipher)) { BIO_printf(bio_err,"error setting cipher list\n"); ERR_print_errors(bio_err); goto end; } #if 0 else SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER")); #endif SSL_CTX_set_verify(ctx,verify,verify_callback); if (!set_cert_key_stuff(ctx,cert,key)) goto end; if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || (!SSL_CTX_set_default_verify_paths(ctx))) { /* BIO_printf(bio_err,"error setting default verify locations\n"); */ ERR_print_errors(bio_err); /* goto end; */ } store = SSL_CTX_get_cert_store(ctx); X509_STORE_set_flags(store, vflags); con=SSL_new(ctx); #ifndef OPENSSL_NO_KRB5 if (con && (con->kssl_ctx = kssl_ctx_new()) != NULL) { kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host); } #endif /* OPENSSL_NO_KRB5 */ /* SSL_set_cipher_list(con,"RC4-MD5"); */ re_start: if (init_client(&s,host,port,sock_type) == 0) { BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); SHUTDOWN(s); goto end; } BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s); #ifdef FIONBIO if (c_nbio) { unsigned long l=1; BIO_printf(bio_c_out,"turning on non blocking io\n"); if (BIO_socket_ioctl(s,FIONBIO,&l) < 0) { ERR_print_errors(bio_err); goto end; } } #endif if (c_Pause & 0x01) con->debug=1; if ( SSL_version(con) == DTLS1_VERSION) { struct timeval timeout; sbio=BIO_new_dgram(s,BIO_NOCLOSE); if (getsockname(s, &peer, (void *)&peerlen) < 0) { BIO_printf(bio_err, "getsockname:errno=%d\n", get_last_socket_error()); SHUTDOWN(s); goto end; } BIO_ctrl_set_connected(sbio, 1, &peer); if ( enable_timeouts) { timeout.tv_sec = 0; timeout.tv_usec = DGRAM_RCV_TIMEOUT; BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); timeout.tv_sec = 0; timeout.tv_usec = DGRAM_SND_TIMEOUT; BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); } if ( mtu > 0) { SSL_set_options(con, SSL_OP_NO_QUERY_MTU); SSL_set_mtu(con, mtu); } else /* want to do MTU discovery */ BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); } else sbio=BIO_new_socket(s,BIO_NOCLOSE); if (nbio_test) { BIO *test; test=BIO_new(BIO_f_nbio_test()); sbio=BIO_push(test,sbio); } if (c_debug) { con->debug=1; BIO_set_callback(sbio,bio_dump_callback); BIO_set_callback_arg(sbio,bio_c_out); } if (c_msg) { SSL_set_msg_callback(con, msg_cb); SSL_set_msg_callback_arg(con, bio_c_out); } SSL_set_bio(con,sbio,sbio); SSL_set_connect_state(con); /* ok, lets connect */ width=SSL_get_fd(con)+1; read_tty=1; write_tty=0; tty_on=0; read_ssl=1; write_ssl=1; cbuf_len=0; cbuf_off=0; sbuf_len=0; sbuf_off=0; /* This is an ugly hack that does a lot of assumptions */ if (starttls_proto == 1) { BIO_read(sbio,mbuf,BUFSIZZ); BIO_printf(sbio,"STARTTLS\r\n"); BIO_read(sbio,sbuf,BUFSIZZ); } if (starttls_proto == 2) { BIO_read(sbio,mbuf,BUFSIZZ); BIO_printf(sbio,"STLS\r\n"); BIO_read(sbio,sbuf,BUFSIZZ); } for (;;) { FD_ZERO(&readfds); FD_ZERO(&writefds); if (SSL_in_init(con) && !SSL_total_renegotiations(con)) { in_init=1; tty_on=0; } else { tty_on=1; if (in_init) { in_init=0; print_stuff(bio_c_out,con,full_log); if (full_log > 0) full_log--; if (starttls_proto) { BIO_printf(bio_err,"%s",mbuf); /* We don't need to know any more */ starttls_proto = 0; } if (reconnect) { reconnect--; BIO_printf(bio_c_out,"drop connection and then reconnect\n"); SSL_shutdown(con); SSL_set_connect_state(con); SHUTDOWN(SSL_get_fd(con)); goto re_start; } } } ssl_pending = read_ssl && SSL_pending(con); if (!ssl_pending) { #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) if (tty_on) { if (read_tty) FD_SET(fileno(stdin),&readfds); if (write_tty) FD_SET(fileno(stdout),&writefds); } if (read_ssl) FD_SET(SSL_get_fd(con),&readfds); if (write_ssl) FD_SET(SSL_get_fd(con),&writefds); #else if(!tty_on || !write_tty) { if (read_ssl) FD_SET(SSL_get_fd(con),&readfds); if (write_ssl) FD_SET(SSL_get_fd(con),&writefds); } #endif /* printf("mode tty(%d %d%d) ssl(%d%d)\n", tty_on,read_tty,write_tty,read_ssl,write_ssl);*/ /* Note: under VMS with SOCKETSHR the second parameter * is currently of type (int *) whereas under other * systems it is (void *) if you don't have a cast it * will choke the compiler: if you do have a cast then * you can either go for (int *) or (void *). */ #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) /* Under Windows/DOS we make the assumption that we can * always write to the tty: therefore if we need to * write to the tty we just fall through. Otherwise * we timeout the select every second and see if there * are any keypresses. Note: this is a hack, in a proper * Windows application we wouldn't do this. */ i=0; if(!write_tty) { if(read_tty) { tv.tv_sec = 1; tv.tv_usec = 0; i=select(width,(void *)&readfds,(void *)&writefds, NULL,&tv); #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) if(!i && (!_kbhit() || !read_tty) ) continue; #else if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue; #endif } else i=select(width,(void *)&readfds,(void *)&writefds, NULL,NULL); } #elif defined(OPENSSL_SYS_NETWARE) if(!write_tty) { if(read_tty) { tv.tv_sec = 1; tv.tv_usec = 0; i=select(width,(void *)&readfds,(void *)&writefds, NULL,&tv); } else i=select(width,(void *)&readfds,(void *)&writefds, NULL,NULL); } #else i=select(width,(void *)&readfds,(void *)&writefds, NULL,NULL); #endif if ( i < 0) { BIO_printf(bio_err,"bad select %d\n", get_last_socket_error()); goto shut; /* goto end; */ } } if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds)) { k=SSL_write(con,&(cbuf[cbuf_off]), (unsigned int)cbuf_len); switch (SSL_get_error(con,k)) { case SSL_ERROR_NONE: cbuf_off+=k; cbuf_len-=k; if (k <= 0) goto end; /* we have done a write(con,NULL,0); */ if (cbuf_len <= 0) { read_tty=1; write_ssl=0; } else /* if (cbuf_len > 0) */ { read_tty=0; write_ssl=1; } break; case SSL_ERROR_WANT_WRITE: BIO_printf(bio_c_out,"write W BLOCK\n"); write_ssl=1; read_tty=0; break; case SSL_ERROR_WANT_READ: BIO_printf(bio_c_out,"write R BLOCK\n"); write_tty=0; read_ssl=1; write_ssl=0; break; case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_c_out,"write X BLOCK\n"); break; case SSL_ERROR_ZERO_RETURN: if (cbuf_len != 0) { BIO_printf(bio_c_out,"shutdown\n"); goto shut; } else { read_tty=1; write_ssl=0; break; } case SSL_ERROR_SYSCALL: if ((k != 0) || (cbuf_len != 0)) { BIO_printf(bio_err,"write:errno=%d\n", get_last_socket_error()); goto shut; } else { read_tty=1; write_ssl=0; } break; case SSL_ERROR_SSL: ERR_print_errors(bio_err); goto shut; } } #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) /* Assume Windows/DOS can always write */ else if (!ssl_pending && write_tty) #else else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds)) #endif { #ifdef CHARSET_EBCDIC ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len); #endif i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len); if (i <= 0) { BIO_printf(bio_c_out,"DONE\n"); goto shut; /* goto end; */ } sbuf_len-=i;; sbuf_off+=i; if (sbuf_len <= 0) { read_ssl=1; write_tty=0; } } else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds)) { #ifdef RENEG { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } } #endif #if 1 k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ ); #else /* Demo for pending and peek :-) */ k=SSL_read(con,sbuf,16); { char zbuf[10240]; printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240)); } #endif switch (SSL_get_error(con,k)) { case SSL_ERROR_NONE: if (k <= 0) goto end; sbuf_off=0; sbuf_len=k; read_ssl=0; write_tty=1; break; case SSL_ERROR_WANT_WRITE: BIO_printf(bio_c_out,"read W BLOCK\n"); write_ssl=1; read_tty=0; break; case SSL_ERROR_WANT_READ: BIO_printf(bio_c_out,"read R BLOCK\n"); write_tty=0; read_ssl=1; if ((read_tty == 0) && (write_ssl == 0)) write_ssl=1; break; case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_c_out,"read X BLOCK\n"); break; case SSL_ERROR_SYSCALL: BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error()); goto shut; case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_c_out,"closed\n"); goto shut; case SSL_ERROR_SSL: ERR_print_errors(bio_err); goto shut; /* break; */ } } #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) else if (_kbhit()) #else else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) #endif #elif defined (OPENSSL_SYS_NETWARE) else if (_kbhit()) #else else if (FD_ISSET(fileno(stdin),&readfds)) #endif { if (crlf) { int j, lf_num; i=read(fileno(stdin),cbuf,BUFSIZZ/2); lf_num = 0; /* both loops are skipped when i <= 0 */ for (j = 0; j < i; j++) if (cbuf[j] == '\n') lf_num++; for (j = i-1; j >= 0; j--) { cbuf[j+lf_num] = cbuf[j]; if (cbuf[j] == '\n') { lf_num--; i++; cbuf[j+lf_num] = '\r'; } } assert(lf_num == 0); } else i=read(fileno(stdin),cbuf,BUFSIZZ); if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) { BIO_printf(bio_err,"DONE\n"); goto shut; } if ((!c_ign_eof) && (cbuf[0] == 'R')) { BIO_printf(bio_err,"RENEGOTIATING\n"); SSL_renegotiate(con); cbuf_len=0; } else { cbuf_len=i; cbuf_off=0; #ifdef CHARSET_EBCDIC ebcdic2ascii(cbuf, cbuf, i); #endif } write_ssl=1; read_tty=0; } } shut: SSL_shutdown(con); SHUTDOWN(SSL_get_fd(con)); ret=0; end: if(prexit) print_stuff(bio_c_out,con,1); if (con != NULL) SSL_free(con); if (con2 != NULL) SSL_free(con2); if (ctx != NULL) SSL_CTX_free(ctx); if (cert) X509_free(cert); if (key) EVP_PKEY_free(key); if (pass) OPENSSL_free(pass); if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); } if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); } if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); } if (bio_c_out != NULL) { BIO_free(bio_c_out); bio_c_out=NULL; } apps_shutdown(); OPENSSL_EXIT(ret); }
THREAD_RETURN CYASSL_THREAD server_test(void* args) { SOCKET_T sockfd = 0; SOCKET_T clientfd = 0; SSL_METHOD* method = 0; SSL_CTX* ctx = 0; SSL* ssl = 0; char msg[] = "I hear you fa shizzle!"; char input[80]; int idx; int ch; int version = SERVER_DEFAULT_VERSION; int doCliCertCheck = 1; int useAnyAddr = 0; int port = yasslPort; int usePsk = 0; int doDTLS = 0; int useNtruKey = 0; int nonBlocking = 0; int trackMemory = 0; int fewerPackets = 0; char* cipherList = NULL; char* verifyCert = (char*)cliCert; char* ourCert = (char*)svrCert; char* ourKey = (char*)svrKey; int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; #ifdef HAVE_SNI char* sniHostName = NULL; #endif ((func_args*)args)->return_code = -1; /* error state */ #ifdef NO_RSA verifyCert = (char*)cliEccCert; ourCert = (char*)eccCert; ourKey = (char*)eccKey; #endif (void)trackMemory; while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:S:")) != -1) { switch (ch) { case '?' : Usage(); exit(EXIT_SUCCESS); case 'd' : doCliCertCheck = 0; break; case 'b' : useAnyAddr = 1; break; case 's' : usePsk = 1; break; case 't' : #ifdef USE_CYASSL_MEMORY trackMemory = 1; #endif break; case 'n' : useNtruKey = 1; break; case 'u' : doDTLS = 1; break; case 'f' : fewerPackets = 1; break; case 'p' : port = atoi(myoptarg); #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API) if (port == 0) err_sys("port number cannot be 0"); #endif break; case 'v' : version = atoi(myoptarg); if (version < 0 || version > 3) { Usage(); exit(MY_EX_USAGE); } break; case 'l' : cipherList = myoptarg; break; case 'A' : verifyCert = myoptarg; break; case 'c' : ourCert = myoptarg; break; case 'k' : ourKey = myoptarg; break; case 'N': nonBlocking = 1; break; case 'S' : #ifdef HAVE_SNI sniHostName = myoptarg; #endif break; default: Usage(); exit(MY_EX_USAGE); } } myoptind = 0; /* reset for test cases */ /* sort out DTLS versus TLS versions */ if (version == CLIENT_INVALID_VERSION) { if (doDTLS) version = CLIENT_DTLS_DEFAULT_VERSION; else version = CLIENT_DEFAULT_VERSION; } else { if (doDTLS) { if (version == 3) version = -2; else version = -1; } } #ifdef USE_CYASSL_MEMORY if (trackMemory) InitMemoryTracker(); #endif switch (version) { #ifndef NO_OLD_TLS case 0: method = SSLv3_server_method(); break; #ifndef NO_TLS case 1: method = TLSv1_server_method(); break; case 2: method = TLSv1_1_server_method(); break; #endif #endif #ifndef NO_TLS case 3: method = TLSv1_2_server_method(); break; #endif #ifdef CYASSL_DTLS case -1: method = DTLSv1_server_method(); break; case -2: method = DTLSv1_2_server_method(); break; #endif default: err_sys("Bad SSL version"); } if (method == NULL) err_sys("unable to get method"); ctx = SSL_CTX_new(method); if (ctx == NULL) err_sys("unable to get ctx"); if (cipherList) if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 1"); #ifdef CYASSL_LEANPSK usePsk = 1; #endif #if defined(NO_RSA) && !defined(HAVE_ECC) usePsk = 1; #endif if (fewerPackets) CyaSSL_CTX_set_group_messages(ctx); #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if (!usePsk) { if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " CyaSSL home dir"); } #endif #ifdef HAVE_NTRU if (useNtruKey) { if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey) != SSL_SUCCESS) err_sys("can't load ntru key file, " "Please run from CyaSSL home dir"); } #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) if (!useNtruKey && !usePsk) { if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " CyaSSL home dir"); } #endif if (usePsk) { #ifndef NO_PSK SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); SSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); if (cipherList == NULL) { const char *defaultCipherList; #ifdef HAVE_NULL_CIPHER defaultCipherList = "PSK-NULL-SHA256"; #else defaultCipherList = "PSK-AES128-CBC-SHA256"; #endif if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS) err_sys("server can't set cipher list 2"); } #endif } #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) /* if not using PSK, verify peer with certs */ if (doCliCertCheck && usePsk == 0) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0); if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from CyaSSL home dir"); } #endif #ifdef OPENSSL_EXTRA SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC) /* don't use EDH, can't sniff tmp keys */ if (cipherList == NULL) { if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS) err_sys("server can't set cipher list 3"); } #endif #ifdef HAVE_SNI if (sniHostName) { if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName, XSTRLEN(sniHostName))) err_sys("UseSNI failed"); else CyaSSL_CTX_SNI_SetOptions(ctx, CYASSL_SNI_HOST_NAME, CYASSL_SNI_ABORT_ON_MISMATCH); } #endif ssl = SSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL"); CyaSSL_set_quiet_shutdown(ssl, 1) ; #ifdef HAVE_CRL CyaSSL_EnableCRL(ssl, 0); CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON); CyaSSL_SetCRL_Cb(ssl, CRL_CallBack); #endif osDelay(5000) ; tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS); if (!doDTLS) CloseSocket(sockfd); SSL_set_fd(ssl, clientfd); if (usePsk == 0) { #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); #elif !defined(NO_CERTS) SetDH(ssl); /* repick suites with DHE, higher priority than PSK */ #endif } osDelay(5000) ; #ifndef CYASSL_CALLBACKS if (nonBlocking) { CyaSSL_set_using_nonblock(ssl, 1); tcp_set_nonblocking(&clientfd); NonBlockingSSL_Accept(ssl); } else if (SSL_accept(ssl) != SSL_SUCCESS) { int err = SSL_get_error(ssl, 0); char buffer[80]; printf("error = %d, %s\n", err, ERR_error_string(err, buffer)); err_sys("SSL_accept failed"); } #else NonBlockingSSL_Accept(ssl); #endif showPeer(ssl); osDelay(5000) ; idx = SSL_read(ssl, input, sizeof(input)-1); if (idx > 0) { input[idx] = 0; printf("Client message: %s\n", input); } else if (idx < 0) { int readErr = SSL_get_error(ssl, 0); if (readErr != SSL_ERROR_WANT_READ) err_sys("SSL_read failed"); } if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) err_sys("SSL_write failed"); SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); CloseSocket(clientfd); ((func_args*)args)->return_code = 0; #ifdef USE_CYASSL_MEMORY if (trackMemory) ShowMemoryTracker(); #endif /* USE_CYASSL_MEMORY */ return 0; }
/* sock stream/TCP handler */ void ev_handler(int fd, short ev_flags, void *arg) { int n = 0; if(ev_flags & E_READ) { if(is_use_ssl) { #ifdef USE_SSL n = SSL_read(conns[fd].ssl, conns[fd].response, EV_BUF_SIZE - 1); #else n = read(fd, conns[fd].response, EV_BUF_SIZE - 1); #endif } else { n = read(fd, conns[fd].response, EV_BUF_SIZE - 1); } if(n > 0 ) { SHOW_LOG("Read %d bytes from %d", n, fd); conns[fd].response[n] = 0; SHOW_LOG("Updating event[%p] on %d ", &conns[fd].event, fd); event_add(&conns[fd].event, E_WRITE); } else { if(n < 0 ) FATAL_LOG("Reading from %d failed, %s", fd, strerror(errno)); goto err; } } if(ev_flags & E_WRITE) { if(is_use_ssl) { #ifdef USE_SSL n = SSL_write(conns[fd].ssl, conns[fd].request, strlen(conns[fd].request)); #else n = write(fd, conns[fd].request, strlen(conns[fd].request)); #endif } else { n = write(fd, conns[fd].request, strlen(conns[fd].request)); } if(n > 0 ) { SHOW_LOG("Wrote %d bytes via %d", n, fd); } else { if(n < 0) FATAL_LOG("Wrote data via %d failed, %s", fd, strerror(errno)); goto err; } event_del(&conns[fd].event, E_WRITE); } return ; err: { event_destroy(&conns[fd].event); shutdown(fd, SHUT_RDWR); close(fd); #ifdef USE_SSL if(conns[fd].ssl) { SSL_shutdown(conns[fd].ssl); SSL_free(conns[fd].ssl); conns[fd].ssl = NULL; } #endif SHOW_LOG("Connection %d closed", fd); } }
void echoclient_test(void* args) { SOCKET_T sockfd = 0; FILE* fin = stdin ; FILE* fout = stdout; int inCreated = 0; int outCreated = 0; char msg[1024]; char reply[1024+1]; SSL_METHOD* method = 0; SSL_CTX* ctx = 0; SSL* ssl = 0; int doDTLS = 0; int doPSK = 0; int sendSz; int argc = 0; char** argv = 0; int port = yasslPort; ((func_args*)args)->return_code = -1; /* error state */ #ifndef CYASSL_MDK_SHELL argc = ((func_args*)args)->argc; argv = ((func_args*)args)->argv; #endif if (argc >= 2) { fin = fopen(argv[1], "r"); inCreated = 1; } if (argc >= 3) { fout = fopen(argv[2], "w"); outCreated = 1; } if (!fin) err_sys("can't open input file"); if (!fout) err_sys("can't open output file"); #ifdef CYASSL_DTLS doDTLS = 1; #endif #ifdef CYASSL_LEANPSK doPSK = 1; #endif #if defined(NO_RSA) && !defined(HAVE_ECC) doPSK = 1; #endif #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_SHELL) port = ((func_args*)args)->signal->port; #endif #if defined(CYASSL_DTLS) method = DTLSv1_client_method(); #elif !defined(NO_TLS) method = CyaSSLv23_client_method(); #else method = SSLv3_client_method(); #endif ctx = SSL_CTX_new(method); #ifndef NO_FILESYSTEM #ifndef NO_RSA if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from CyaSSL home dir"); #endif #ifdef HAVE_ECC if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from CyaSSL home dir"); #endif #elif !defined(NO_CERTS) if (!doPSK) load_buffer(ctx, caCert, CYASSL_CA); #endif #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC) /* don't use EDH, can't sniff tmp keys */ SSL_CTX_set_cipher_list(ctx, "AES256-SHA"); #endif if (doPSK) { #ifndef NO_PSK const char *defaultCipherList; CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb); #ifdef HAVE_NULL_CIPHER defaultCipherList = "PSK-NULL-SHA256"; #else defaultCipherList = "PSK-AES128-CBC-SHA256"; #endif if (CyaSSL_CTX_set_cipher_list(ctx,defaultCipherList) !=SSL_SUCCESS) err_sys("client can't set cipher list 2"); #endif } #ifdef OPENSSL_EXTRA SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif #if defined(CYASSL_MDK_ARM) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); #endif ssl = SSL_new(ctx); if (doDTLS) { SOCKADDR_IN_T addr; build_addr(&addr, yasslIP, port, 1); CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); tcp_socket(&sockfd, 1); } else { tcp_connect(&sockfd, yasslIP, port, 0); } SSL_set_fd(ssl, sockfd); #if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER) /* let echoserver bind first, TODO: add Windows signal like pthreads does */ Sleep(100); #endif if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed"); while (fgets(msg, sizeof(msg), fin) != 0) { sendSz = (int)strlen(msg); if (SSL_write(ssl, msg, sendSz) != sendSz) err_sys("SSL_write failed"); if (strncmp(msg, "quit", 4) == 0) { fputs("sending server shutdown command: quit!\n", fout); break; } if (strncmp(msg, "break", 5) == 0) { fputs("sending server session close: break!\n", fout); break; } #ifndef CYASSL_MDK_SHELL while (sendSz) { int got; if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) { reply[got] = 0; fputs(reply, fout); fflush(fout) ; sendSz -= got; } else break; } #else { int got; if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) { reply[got] = 0; fputs(reply, fout); fflush(fout) ; sendSz -= got; } } #endif } #ifdef CYASSL_DTLS strncpy(msg, "break", 6); sendSz = (int)strlen(msg); /* try to tell server done */ SSL_write(ssl, msg, sendSz); #else SSL_shutdown(ssl); #endif SSL_free(ssl); SSL_CTX_free(ctx); fflush(fout); if (inCreated) fclose(fin); if (outCreated) fclose(fout); CloseSocket(sockfd); ((func_args*)args)->return_code = 0; }
int main(int argc, char **argv) { char *ip = NULL; int port = 0; int fd = 0; struct sockaddr_in sa, lsa; socklen_t sa_len, lsa_len = -1; int i = 0; int conn_num = 0; int sock_type = 0; int flag = 0; if(argc < 5) { fprintf(stderr, "Usage:%s sock_type(0/TCP|1/UDP) ip port connection_number\n", argv[0]); _exit(-1); } ev_sock_type = atoi(argv[1]); if(ev_sock_type < 0 || ev_sock_type > ev_sock_count) { fprintf(stderr, "sock_type must be 0/TCP OR 1/UDP\n"); _exit(-1); } sock_type = ev_sock_list[ev_sock_type]; ip = argv[2]; port = atoi(argv[3]); conn_num = atoi(argv[4]); /* Set resource limit */ setrlimiter("RLIMIT_NOFILE", RLIMIT_NOFILE, CONN_MAX); /* Initialize global vars */ if((conns = (CONN *)calloc(CONN_MAX, sizeof(CONN)))) { //memset(events, 0, sizeof(EVENT *) * CONN_MAX); /* Initialize inet */ memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr(ip); sa.sin_port = htons(port); sa_len = sizeof(struct sockaddr); /* set evbase */ if((evbase = evbase_init(0))) { LOGGER_INIT(evbase->logger, "/tmp/ev_client.log"); #ifdef USE_SSL SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); if((ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { ERR_print_errors_fp(stdout); _exit(-1); } #endif //evbase->set_evops(evbase, EOP_POLL); while((fd = socket(AF_INET, sock_type, 0)) > 0 && i < conn_num) { conns[fd].fd = fd; /* Connect */ if(connect(fd, (struct sockaddr *)&sa, sa_len) != 0) { FATAL_LOG("Connect to %s:%d failed, %s", ip, port, strerror(errno)); break; } if(is_use_ssl && sock_type == SOCK_STREAM) { #ifdef USE_SSL conns[fd].ssl = SSL_new(ctx); if(conns[fd].ssl == NULL ) { FATAL_LOG("new SSL with created CTX failed:%s\n", ERR_reason_error_string(ERR_get_error())); break; } if((ret = SSL_set_fd(conns[fd].ssl, fd)) == 0) { FATAL_LOG("add SSL to tcp socket failed:%s\n", ERR_reason_error_string(ERR_get_error())); break; } /* SSL Connect */ if(SSL_connect(conns[fd].ssl) < 0) { FATAL_LOG("SSL connection failed:%s\n", ERR_reason_error_string(ERR_get_error())); break; } #endif } /* set FD NON-BLOCK */ flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); if(sock_type == SOCK_STREAM) { event_set(&conns[fd].event, fd, E_READ|E_WRITE|E_PERSIST, (void *)&conns[fd].event, &ev_handler); } else { event_set(&conns[fd].event, fd, E_READ|E_WRITE|E_PERSIST, (void *)&conns[fd].event, &ev_udp_handler); } evbase->add(evbase, &conns[fd].event); sprintf(conns[fd].request, "GET / HTTP/1.0\r\n\r\n"); lsa_len = sizeof(struct sockaddr); memset(&lsa, 0, lsa_len); getsockname(fd, (struct sockaddr *)&lsa, &lsa_len); SHOW_LOG("%d:Connected to %s:%d via %d port:%d", i, ip, port, fd, ntohs(lsa.sin_port)); i++; } while(1) { evbase->loop(evbase, 0, NULL); usleep(1000); } for(i = 0; i < CONN_MAX; i++) { shutdown(conns[i].fd, SHUT_RDWR); close(conns[i].fd); event_destroy(&conns[i].event); #ifdef USE_SSL if(conns[i].ssl) { SSL_shutdown(conns[i].ssl); SSL_free(conns[i].ssl); } #endif } #ifdef USE_SSL ERR_free_strings(); SSL_CTX_free(ctx); #endif } free(conns); } return -1; }
/* * This test checks for the three basic operations: * - TLSSend * - TLSRecv * - TLSRecvLine * It is difficult to test each one separatedly, so we test all at once. * The test consists on establishing a connection to our child process and then * sending and receiving data. We switch between the original functions and the * mock functions. * We do not test SSL_new, SSL_accept and such because those will be covered by either * the client or server tests. */ static void test_TLSBasicIO(void) { ASSERT_IF_NOT_INITIALIZED; RESET_STATUS; SSL *ssl = NULL; char output_buffer[] = "this is a buffer"; int output_buffer_length = strlen(output_buffer); char input_buffer[4096]; int result = 0; /* * Open a socket and establish a tcp connection. */ struct sockaddr_in server_addr; int server = 0; memset(&server_addr, 0, sizeof(struct sockaddr_in)); server = socket(AF_INET, SOCK_STREAM, 0); assert_int_not_equal(-1, server); server_addr.sin_family = AF_INET; /* We should not use inet_addr, but it is easier for this particular case. */ server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(8035); /* * Connect */ result = connect(server, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)); assert_int_not_equal(-1, result); /* * Create a SSL instance */ ssl = SSL_new(SSLCLIENTCONTEXT); assert_true(ssl != NULL); SSL_set_fd(ssl, server); /* * Establish the TLS connection over the socket. */ result = SSL_connect(ssl); assert_int_not_equal(-1, result); /* * Start testing. The first obvious thing to test is to send data. */ result = TLSSend(ssl, output_buffer, output_buffer_length); assert_int_equal(result, output_buffer_length); /* * Good we sent data and the data was sent. Let's check what we get back * by using TLSRecv. */ result = TLSRecv(ssl, input_buffer, output_buffer_length); assert_int_equal(output_buffer_length, result); input_buffer[output_buffer_length] = '\0'; assert_string_equal(output_buffer, input_buffer); /* * Brilliant! We transmitted and received data using simple communication. * Let's try the line sending. */ char output_line_buffer[] = "hello\ngoodbye\n"; int output_line_buffer_length = strlen(output_line_buffer); char output_just_hello[] = "hello"; int output_just_hello_length = strlen(output_just_hello); result = TLSSend(ssl, output_line_buffer, output_line_buffer_length); assert_int_equal(result, output_line_buffer_length); result = TLSRecvLine(ssl, input_buffer, output_line_buffer_length); /* The reply should be up to the first hello */ assert_int_equal(result, output_just_hello_length); assert_string_equal(input_buffer, output_just_hello); /* * Basic check */ USE_MOCK(SSL_write); USE_MOCK(SSL_read); assert_int_equal(0, TLSSend(ssl, output_buffer, 0)); assert_int_equal(-1, TLSSend(ssl, output_buffer, output_buffer_length)); assert_int_equal(-1, TLSRecv(ssl, input_buffer, output_buffer_length)); RESET_STATUS; /* * Start replacing the functions inside to check that the logic works * We start by testing TLSSend, then TLSRead and at last TLSRecvLine. */ USE_MOCK(SSL_write); SSL_WRITE_RETURN(0); assert_int_equal(0, TLSSend(ssl, output_buffer, output_buffer_length)); USE_MOCK(SSL_get_shutdown); SSL_GET_SHUTDOWN_RETURN(1); assert_int_equal(0, TLSSend(ssl, output_buffer, output_buffer_length)); SSL_WRITE_RETURN(-1); assert_int_equal(-1, TLSSend(ssl, output_buffer, output_buffer_length)); USE_MOCK(SSL_read); SSL_READ_RETURN(0); SSL_GET_SHUTDOWN_RETURN(0); assert_int_equal(0, TLSRecv(ssl, input_buffer, output_buffer_length)); SSL_GET_SHUTDOWN_RETURN(1); assert_int_equal(0, TLSRecv(ssl, input_buffer, output_buffer_length)); SSL_READ_RETURN(-1); assert_int_equal(-1, TLSRecv(ssl, input_buffer, output_buffer_length)); USE_ORIGINAL(SSL_write); SSL_READ_RETURN(0); assert_int_equal(-1, TLSRecvLine(ssl, input_buffer, output_buffer_length)); SSL_READ_RETURN(-1); assert_int_equal(-1, TLSRecvLine(ssl, input_buffer, output_buffer_length)); SSL_READ_RETURN(5); assert_int_equal(-1, TLSRecvLine(ssl, input_buffer, 10)); SSL_READ_USE_BUFFER(output_line_buffer); assert_int_equal(5, TLSRecvLine(ssl, input_buffer, output_line_buffer_length)); assert_string_equal(output_just_hello, input_buffer); result = SSL_shutdown(ssl); if (ssl) { SSL_free(ssl); } RESET_STATUS; }
//static void fetch_uri(const struct URI *uri) static void * fetch_uri(void * arg) { spdylay_session_callbacks callbacks; int fd; SSL_CTX *ssl_ctx; SSL *ssl; struct Request req; struct Connection connection; int rv; nfds_t npollfds = 1; struct pollfd pollfds[1]; uint16_t spdy_proto_version; struct URI *uri = (struct URI *)arg; // typecast void * back to proper type request_init(&req, uri); setup_spdylay_callbacks(&callbacks); /* Establish connection and setup SSL */ fd = connect_to(req.host, req.port); ssl_ctx = SSL_CTX_new(SSLv23_client_method()); if(ssl_ctx == NULL) { dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL)); } init_ssl_ctx(ssl_ctx, &spdy_proto_version); ssl = SSL_new(ssl_ctx); if(ssl == NULL) { dief("SSL_new", ERR_error_string(ERR_get_error(), NULL)); } /* To simplify the program, we perform SSL/TLS handshake in blocking I/O. */ ssl_handshake(ssl, fd); connection.ssl = ssl; connection.want_io = IO_NONE; /* Here make file descriptor non-block */ make_non_block(fd); set_tcp_nodelay(fd); printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version); rv = spdylay_session_client_new(&connection.session, spdy_proto_version, &callbacks, &connection); if(rv != 0) { diec("spdylay_session_client_new", rv); } /* Submit the HTTP request to the outbound queue. */ submit_request(&connection, &req); pollfds[0].fd = fd; ctl_poll(pollfds, &connection); /* Event loop */ while(spdylay_session_want_read(connection.session) || spdylay_session_want_write(connection.session)) { int nfds = poll(pollfds, npollfds, -1); if(nfds == -1) { dief("poll", strerror(errno)); } if(pollfds[0].revents & (POLLIN | POLLOUT)) { exec_io(&connection); } if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) { die("Connection error"); } ctl_poll(pollfds, &connection); } /* Resource cleanup */ spdylay_session_del(connection.session); SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ssl_ctx); shutdown(fd, SHUT_WR); close(fd); request_free(&req); }
int main(int argc, char *argv[]) { if(argc != 2) { printf("usage : %s <ipaddress>\n", argv[0]); return -1; } strcpy(server_address, argv[1]); sleep_us(500000); /* * configure the client. */ if(client_configure(master_port, transmit_port, ssl_certificate, ssl_key) < 0) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "client configured"); return -1; } printf("%-60s[\033[;32mOK\033[0m]\n", "client configured"); sleep_us(500000); /* * initialize the SSL */ ctx_server = ssl_server_init(ssl_certificate, ssl_key); if(ctx_server == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL server initialize"); return -1; } ctx_client = ssl_client_init(); if(ctx_client == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL client initialize"); return -1; } printf("%-60s[\033[;32mOK\033[0m]\n", "SSL initialize"); sleep_us(500000); /* * connect to the master server. */ char temp[MAXLINE]; snprintf(temp, MAXLINE, "connect to master server: %s", argv[1]); int masterfd = client_connect(argv[1], master_port); if(masterfd == -1) { printf("%-60s[\033[;31mFAILED\033[0m]\n", temp); return -1; } sockaddr_in clientaddr; socklen_t len = sizeof(clientaddr); memset(&clientaddr, 0, len); getsockname(masterfd, (sockaddr*)&clientaddr, &len); inet_ntop(AF_INET, (void *)&clientaddr.sin_addr, ip_address, MAXLINE); printf("%-60s[\033[;32mOK\033[0m]\n", temp); sleep_us(500000); SSL *ssl = ssl_client(ctx_client, masterfd); if(ssl == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "ssl_client\n"); return -1; } /* * verify the executable client to judge if it's a fake one. */ char *ver_buf = file_verify(argv[0]); if(ver_buf == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client"); return -1; } int k = SSL_write(ssl, ver_buf, strlen(ver_buf)); if( k != (int)strlen(ver_buf)) { printf("SSL_write error\n"); return -1; } k = SSL_read(ssl, temp, MAXLINE); if(k < 0) { printf("SSL_read error"); return -1; } temp[k] = '\0'; if(strcmp(temp, "verify client unsuccessfully") == 0) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client"); return -1; } free(ver_buf); sleep_us(500000); /* * Listen to the transmit port to upload/download files */ snprintf(temp, MAXLINE, "listen to transmit port: %s", transmit_port); int listenfd = server_listen(transmit_port); if(listenfd == -1) { printf("%-60s[\033[;31mFAILED\033[0m]\n", temp); return -1; } printf("%-60s[\033[;32mOK\033[0m]\n", temp); sleep_us(500000); /* * create transmit_thread to handle upload/download files request * from the slave server. */ pthread_t thread; int ret = pthread_create(&thread, NULL, transmit_thread, static_cast<void*>(new int(listenfd))); if(ret == 0) printf("%-60s[\033[;32mOK\033[0m]\n", "transmit_thread create"); else { printf("%-60s[\033[;31FAILED\033[0m]\n", "transmit_thread create"); return -1; } /* * initialize the download/upload mutex. */ pthread_mutex_init(&download_mutex, NULL); pthread_mutex_init(&upload_mutex, NULL); char command_line[MAXLINE]; snprintf(cmd_line, MAXLINE,"%s:%s> ", argv[1], master_port); while(!stop) { printf(cmd_line); fflush(stdin); //read the command inputed by the user. fgets(command_line, MAXLINE, stdin); int len = strlen(command_line); if(command_line[len-1] == '\n') command_line[len-1] = '\0'; command_parse(ssl, command_line); } SSL_shutdown(ssl); // send SSL/TLS close_notify */ close(masterfd); SSL_free(ssl); SSL_CTX_free(ctx_server); SSL_CTX_free(ctx_client); return 0; }
static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) { STACK_OF(SSL_CIPHER) *ciphers; method_const SSL_METHOD *dtls_method; SSL_CIPHER *dtls_cipher; SSL *dtls_ssl; BIO *dtls_bio; if (!vpninfo->dtls_ctx) { dtls_method = DTLSv1_client_method(); vpninfo->dtls_ctx = SSL_CTX_new(dtls_method); if (!vpninfo->dtls_ctx) { vpn_progress(vpninfo, PRG_ERR, _("Initialise DTLSv1 CTX failed\n")); openconnect_report_ssl_errors(vpninfo); vpninfo->dtls_attempt_period = 0; return -EINVAL; } /* If we don't readahead, then we do short reads and throw away the tail of data packets. */ SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1); if (!SSL_CTX_set_cipher_list(vpninfo->dtls_ctx, vpninfo->dtls_cipher)) { vpn_progress(vpninfo, PRG_ERR, _("Set DTLS cipher list failed\n")); SSL_CTX_free(vpninfo->dtls_ctx); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; return -EINVAL; } } if (!vpninfo->dtls_session) { /* We're going to "resume" a session which never existed. Fake it... */ vpninfo->dtls_session = SSL_SESSION_new(); if (!vpninfo->dtls_session) { vpn_progress(vpninfo, PRG_ERR, _("Initialise DTLSv1 session failed\n")); vpninfo->dtls_attempt_period = 0; return -EINVAL; } vpninfo->dtls_session->ssl_version = 0x0100; /* DTLS1_BAD_VER */ } /* Do this every time; it may have changed due to a rekey */ vpninfo->dtls_session->master_key_length = sizeof(vpninfo->dtls_secret); memcpy(vpninfo->dtls_session->master_key, vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret)); vpninfo->dtls_session->session_id_length = sizeof(vpninfo->dtls_session_id); memcpy(vpninfo->dtls_session->session_id, vpninfo->dtls_session_id, sizeof(vpninfo->dtls_session_id)); dtls_ssl = SSL_new(vpninfo->dtls_ctx); SSL_set_connect_state(dtls_ssl); ciphers = SSL_get_ciphers(dtls_ssl); if (sk_SSL_CIPHER_num(ciphers) != 1) { vpn_progress(vpninfo, PRG_ERR, _("Not precisely one DTLS cipher\n")); SSL_CTX_free(vpninfo->dtls_ctx); SSL_free(dtls_ssl); SSL_SESSION_free(vpninfo->dtls_session); vpninfo->dtls_ctx = NULL; vpninfo->dtls_session = NULL; vpninfo->dtls_attempt_period = 0; return -EINVAL; } dtls_cipher = sk_SSL_CIPHER_value(ciphers, 0); /* Set the appropriate cipher on our session to be resumed */ vpninfo->dtls_session->cipher = dtls_cipher; vpninfo->dtls_session->cipher_id = dtls_cipher->id; /* Add the generated session to the SSL */ if (!SSL_set_session(dtls_ssl, vpninfo->dtls_session)) { vpn_progress(vpninfo, PRG_ERR, _("SSL_set_session() failed with old protocol version 0x%x\n" "Are you using a version of OpenSSL older than 0.9.8m?\n" "See http://rt.openssl.org/Ticket/Display.html?id=1751\n" "Use the --no-dtls command line option to avoid this message\n"), vpninfo->dtls_session->ssl_version); vpninfo->dtls_attempt_period = 0; return -EINVAL; } dtls_bio = BIO_new_socket(dtls_fd, BIO_NOCLOSE); /* Set non-blocking */ BIO_set_nbio(dtls_bio, 1); SSL_set_bio(dtls_ssl, dtls_bio, dtls_bio); SSL_set_options(dtls_ssl, SSL_OP_CISCO_ANYCONNECT); vpninfo->new_dtls_ssl = dtls_ssl; return 0; }