12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555 |
- /* client.c
- *
- * Copyright (C) 2006-2017 wolfSSL Inc.
- *
- * This file is part of wolfSSL.
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <wolfssl/wolfcrypt/settings.h>
- #include <wolfssl/ssl.h>
- #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
- #include <stdio.h>
- #include <string.h>
- #include "cmsis_os.h"
- #include "rl_fs.h"
- #include "rl_net.h"
- #include "wolfssl_MDK_ARM.h"
- #endif
- #include <wolfssl/test.h>
- #include <examples/client/client.h>
- #ifndef NO_WOLFSSL_CLIENT
- #ifdef WOLFSSL_ASYNC_CRYPT
- static int devId = INVALID_DEVID;
- #endif
- #define DEFAULT_TIMEOUT_SEC 2
- /* Note on using port 0: the client standalone example doesn't utilize the
- * port 0 port sharing; that is used by (1) the server in external control
- * test mode and (2) the testsuite which uses this code and sets up the correct
- * port numbers when the internal thread using the server code using port 0. */
- #ifdef WOLFSSL_CALLBACKS
- Timeval timeout;
- static int handShakeCB(HandShakeInfo* info)
- {
- (void)info;
- return 0;
- }
- static int timeoutCB(TimeoutInfo* info)
- {
- (void)info;
- return 0;
- }
- #endif
- #ifdef HAVE_SESSION_TICKET
- static int sessionTicketCB(WOLFSSL* ssl,
- const unsigned char* ticket, int ticketSz,
- void* ctx)
- {
- (void)ssl;
- (void)ticket;
- printf("Session Ticket CB: ticketSz = %d, ctx = %s\n",
- ticketSz, (char*)ctx);
- return 0;
- }
- #endif
- static int NonBlockingSSL_Connect(WOLFSSL* ssl)
- {
- int ret;
- int error;
- SOCKET_T sockfd;
- int select_ret = 0;
- #ifndef WOLFSSL_CALLBACKS
- ret = wolfSSL_connect(ssl);
- #else
- ret = wolfSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
- #endif
- error = wolfSSL_get_error(ssl, 0);
- sockfd = (SOCKET_T)wolfSSL_get_fd(ssl);
- while (ret != WOLFSSL_SUCCESS && (error == WOLFSSL_ERROR_WANT_READ ||
- error == WOLFSSL_ERROR_WANT_WRITE ||
- error == WC_PENDING_E)) {
- int currTimeout = 1;
-
- if (error == WOLFSSL_ERROR_WANT_READ)
- printf("... client would read block\n");
- else if (error == WOLFSSL_ERROR_WANT_WRITE)
- printf("... client would write block\n");
- #ifdef WOLFSSL_ASYNC_CRYPT
- else if (error == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- if (error != WC_PENDING_E) {
- #ifdef WOLFSSL_DTLS
- currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
- #endif
- select_ret = tcp_select(sockfd, currTimeout);
- }
- if ((select_ret == TEST_RECV_READY) ||
- (select_ret == TEST_ERROR_READY) || error == WC_PENDING_E) {
- #ifndef WOLFSSL_CALLBACKS
- ret = wolfSSL_connect(ssl);
- #else
- ret = wolfSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
- #endif
- error = wolfSSL_get_error(ssl, 0);
- }
- else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
- error = WOLFSSL_ERROR_WANT_READ;
- }
- #ifdef WOLFSSL_DTLS
- else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
- wolfSSL_dtls_got_timeout(ssl) >= 0) {
- error = WOLFSSL_ERROR_WANT_READ;
- }
- #endif
- else {
- error = WOLFSSL_FATAL_ERROR;
- }
- }
- return ret;
- }
- static void ShowCiphers(void)
- {
- char ciphers[4096];
- int ret = wolfSSL_get_ciphers(ciphers, (int)sizeof(ciphers));
- if (ret == WOLFSSL_SUCCESS)
- printf("%s\n", ciphers);
- }
- /* Shows which versions are valid */
- static void ShowVersions(void)
- {
- #ifndef NO_OLD_TLS
- #ifdef WOLFSSL_ALLOW_SSLV3
- printf("0:");
- #endif
- #ifdef WOLFSSL_ALLOW_TLSV10
- printf("1:");
- #endif
- printf("2:");
- #endif /* NO_OLD_TLS */
- printf("3:");
- #ifdef WOLFSSL_TLS13
- printf("4:");
- #endif
- printf("\n");
- }
- /* Measures average time to create, connect and disconnect a connection (TPS).
- Benchmark = number of connections. */
- static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
- int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519,
- int helloRetry)
- {
- /* time passed in number of connects give average */
- int times = benchmark;
- int loops = resumeSession ? 2 : 1;
- int i = 0, err, ret;
- #ifndef NO_SESSION_CACHE
- WOLFSSL_SESSION* benchSession = NULL;
- #endif
- #ifdef WOLFSSL_TLS13
- byte* reply[80];
- static const char msg[] = "hello wolfssl!";
- #endif
- (void)resumeSession;
- (void)useX25519;
- (void)helloRetry;
- while (loops--) {
- #ifndef NO_SESSION_CACHE
- int benchResume = resumeSession && loops == 0;
- #endif
- double start = current_time(1), avg;
- for (i = 0; i < times; i++) {
- SOCKET_T sockfd;
- WOLFSSL* ssl = wolfSSL_new(ctx);
- if (ssl == NULL)
- err_sys("unable to get SSL object");
- #ifdef WOLFSSL_TLS13
- if (helloRetry)
- wolfSSL_NoKeyShares(ssl);
- #endif
- tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
- #ifndef NO_SESSION_CACHE
- if (benchResume)
- wolfSSL_set_session(ssl, benchSession);
- #endif
- #ifdef WOLFSSL_TLS13
- #ifdef HAVE_CURVE25519
- #ifndef NO_SESSION_CACHE
- if (benchResume) {
- }
- else
- #endif
- if (useX25519) {
- if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve x25519");
- }
- }
- #endif
- #endif
- if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
- err_sys("error in setting fd");
- }
- do {
- err = 0; /* reset error */
- ret = wolfSSL_connect(ssl);
- if (ret != WOLFSSL_SUCCESS) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret != WOLFSSL_SUCCESS) {
- err_sys("SSL_connect failed");
- }
- #ifdef WOLFSSL_TLS13
- if (resumeSession) {
- if (wolfSSL_write(ssl, msg, sizeof(msg)-1) <= 0)
- err_sys("SSL_write failed");
- if (wolfSSL_read(ssl, reply, sizeof(reply)-1) <= 0)
- err_sys("SSL_read failed");
- }
- #endif
- wolfSSL_shutdown(ssl);
- #ifndef NO_SESSION_CACHE
- if (i == (times-1) && resumeSession) {
- benchSession = wolfSSL_get_session(ssl);
- }
- #endif
- wolfSSL_free(ssl);
- CloseSocket(sockfd);
- }
- avg = current_time(0) - start;
- avg /= times;
- avg *= 1000; /* milliseconds */
- #ifndef NO_SESSION_CACHE
- if (benchResume)
- printf("wolfSSL_resume avg took: %8.3f milliseconds\n", avg);
- else
- #endif
- printf("wolfSSL_connect avg took: %8.3f milliseconds\n", avg);
- }
- return EXIT_SUCCESS;
- }
- /* Measures throughput in kbps. Throughput = number of bytes */
- static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
- int dtlsUDP, int dtlsSCTP, int throughput, int useX25519)
- {
- double start, conn_time = 0, tx_time = 0, rx_time = 0;
- SOCKET_T sockfd;
- WOLFSSL* ssl;
- int ret = 0, err = 0;
- start = current_time(1);
- ssl = wolfSSL_new(ctx);
- if (ssl == NULL)
- err_sys("unable to get SSL object");
- tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
- if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
- err_sys("error in setting fd");
- }
- (void)useX25519;
- #ifdef WOLFSSL_TLS13
- #ifdef HAVE_CURVE25519
- if (useX25519) {
- if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve x25519");
- }
- }
- #endif
- #endif
- do {
- err = 0; /* reset error */
- ret = wolfSSL_connect(ssl);
- if (ret != WOLFSSL_SUCCESS) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret == WOLFSSL_SUCCESS) {
- /* Perform throughput test */
- char *tx_buffer, *rx_buffer;
- /* Record connection time */
- conn_time = current_time(0) - start;
- /* Allocate TX/RX buffers */
- tx_buffer = (char*)XMALLOC(TEST_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- rx_buffer = (char*)XMALLOC(TEST_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (tx_buffer && rx_buffer) {
- WC_RNG rng;
- /* Startup the RNG */
- #if !defined(HAVE_FIPS) && defined(WOLFSSL_ASYNC_CRYPT)
- ret = wc_InitRng_ex(&rng, NULL, devId);
- #else
- ret = wc_InitRng(&rng);
- #endif
- if (ret == 0) {
- int xfer_bytes;
- /* Generate random data to send */
- ret = wc_RNG_GenerateBlock(&rng, (byte*)tx_buffer, TEST_BUFFER_SIZE);
- wc_FreeRng(&rng);
- if(ret != 0) {
- err_sys("wc_RNG_GenerateBlock failed");
- }
- /* Perform TX and RX of bytes */
- xfer_bytes = 0;
- while (throughput > xfer_bytes) {
- int len, rx_pos, select_ret;
- /* Determine packet size */
- len = min(TEST_BUFFER_SIZE, throughput - xfer_bytes);
- /* Perform TX */
- start = current_time(1);
- do {
- err = 0; /* reset error */
- ret = wolfSSL_write(ssl, tx_buffer, len);
- if (ret <= 0) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret != len) {
- printf("SSL_write bench error %d!\n", err);
- err_sys("SSL_write failed");
- }
- tx_time += current_time(0) - start;
- /* Perform RX */
- select_ret = tcp_select(sockfd, DEFAULT_TIMEOUT_SEC);
- if (select_ret == TEST_RECV_READY) {
- start = current_time(1);
- rx_pos = 0;
- while (rx_pos < len) {
- ret = wolfSSL_read(ssl, &rx_buffer[rx_pos],
- len - rx_pos);
- if (ret <= 0) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- else
- #endif
- if (err != WOLFSSL_ERROR_WANT_READ) {
- printf("SSL_read bench error %d\n", err);
- err_sys("SSL_read failed");
- }
- }
- else {
- rx_pos += ret;
- }
- }
- rx_time += current_time(0) - start;
- }
- /* Compare TX and RX buffers */
- if(XMEMCMP(tx_buffer, rx_buffer, len) != 0) {
- free(tx_buffer);
- tx_buffer = NULL;
- free(rx_buffer);
- rx_buffer = NULL;
- err_sys("Compare TX and RX buffers failed");
- }
- /* Update overall position */
- xfer_bytes += len;
- }
- }
- else {
- err_sys("wc_InitRng failed");
- }
- }
- else {
- err_sys("Client buffer malloc failed");
- }
- if(tx_buffer) XFREE(tx_buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if(rx_buffer) XFREE(rx_buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- }
- else {
- err_sys("wolfSSL_connect failed");
- }
- wolfSSL_shutdown(ssl);
- wolfSSL_free(ssl);
- CloseSocket(sockfd);
- printf("wolfSSL Client Benchmark %d bytes\n"
- "\tConnect %8.3f ms\n"
- "\tTX %8.3f ms (%8.3f MBps)\n"
- "\tRX %8.3f ms (%8.3f MBps)\n",
- throughput,
- conn_time * 1000,
- tx_time * 1000, throughput / tx_time / 1024 / 1024,
- rx_time * 1000, throughput / rx_time / 1024 / 1024
- );
- return EXIT_SUCCESS;
- }
- const char* starttlsCmd[6] = {
- "220",
- "EHLO mail.example.com\r\n",
- "250",
- "STARTTLS\r\n",
- "220",
- "QUIT\r\n",
- };
- /* Initiates the STARTTLS command sequence over TCP */
- static int StartTLS_Init(SOCKET_T* sockfd)
- {
- char tmpBuf[256];
- if (sockfd == NULL)
- return BAD_FUNC_ARG;
- /* S: 220 <host> SMTP service ready */
- XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
- if (recv(*sockfd, tmpBuf, sizeof(tmpBuf)-1, 0) < 0)
- err_sys("failed to read STARTTLS command\n");
- if (!XSTRNCMP(tmpBuf, starttlsCmd[0], XSTRLEN(starttlsCmd[0]))) {
- printf("%s\n", tmpBuf);
- } else {
- err_sys("incorrect STARTTLS command received");
- }
- /* C: EHLO mail.example.com */
- if (send(*sockfd, starttlsCmd[1], (int)XSTRLEN(starttlsCmd[1]), 0) !=
- (int)XSTRLEN(starttlsCmd[1]))
- err_sys("failed to send STARTTLS EHLO command\n");
- /* S: 250 <host> offers a warm hug of welcome */
- XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
- if (recv(*sockfd, tmpBuf, sizeof(tmpBuf)-1, 0) < 0)
- err_sys("failed to read STARTTLS command\n");
- if (!XSTRNCMP(tmpBuf, starttlsCmd[2], XSTRLEN(starttlsCmd[2]))) {
- printf("%s\n", tmpBuf);
- } else {
- err_sys("incorrect STARTTLS command received");
- }
- /* C: STARTTLS */
- if (send(*sockfd, starttlsCmd[3], (int)XSTRLEN(starttlsCmd[3]), 0) !=
- (int)XSTRLEN(starttlsCmd[3])) {
- err_sys("failed to send STARTTLS command\n");
- }
- /* S: 220 Go ahead */
- XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
- if (recv(*sockfd, tmpBuf, sizeof(tmpBuf)-1, 0) < 0)
- err_sys("failed to read STARTTLS command\n");
- if (!XSTRNCMP(tmpBuf, starttlsCmd[4], XSTRLEN(starttlsCmd[4]))) {
- printf("%s\n", tmpBuf);
- } else {
- err_sys("incorrect STARTTLS command received, expected 220");
- }
- return WOLFSSL_SUCCESS;
- }
- /* Closes down the SMTP connection */
- static int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown)
- {
- int ret, err = 0;
- char tmpBuf[256];
- if (ssl == NULL)
- return BAD_FUNC_ARG;
- printf("\nwolfSSL client shutting down SMTP connection\n");
- XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
- /* C: QUIT */
- do {
- ret = wolfSSL_write(ssl, starttlsCmd[5], (int)XSTRLEN(starttlsCmd[5]));
- if (ret < 0) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret != (int)XSTRLEN(starttlsCmd[5])) {
- err_sys("failed to send SMTP QUIT command\n");
- }
- /* S: 221 2.0.0 Service closing transmission channel */
- do {
- ret = wolfSSL_read(ssl, tmpBuf, sizeof(tmpBuf));
- if (ret < 0) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret < 0) {
- err_sys("failed to read SMTP closing down response\n");
- }
- printf("%s\n", tmpBuf);
- ret = wolfSSL_shutdown(ssl);
- if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE)
- wolfSSL_shutdown(ssl); /* bidirectional shutdown */
- return WOLFSSL_SUCCESS;
- }
- static void ClientWrite(WOLFSSL* ssl, char* msg, int msgSz)
- {
- int ret, err;
- char buffer[WOLFSSL_MAX_ERROR_SZ];
- do {
- err = 0; /* reset error */
- ret = wolfSSL_write(ssl, msg, msgSz);
- if (ret <= 0) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret != msgSz) {
- printf("SSL_write msg error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- err_sys("SSL_write failed");
- }
- }
- static void ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead)
- {
- int ret, err;
- char buffer[WOLFSSL_MAX_ERROR_SZ];
- do {
- err = 0; /* reset error */
- ret = wolfSSL_read(ssl, reply, replyLen);
- if (ret <= 0) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- else
- #endif
- if (err != WOLFSSL_ERROR_WANT_READ) {
- printf("SSL_read reply error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- err_sys("SSL_read failed");
- }
- }
- } while (err == WC_PENDING_E || (mustRead && err == WOLFSSL_ERROR_WANT_READ));
- if (ret > 0) {
- reply[ret] = 0;
- printf("%s\n", reply);
- }
- }
- static void Usage(void)
- {
- printf("client " LIBWOLFSSL_VERSION_STRING
- " NOTE: All files relative to wolfSSL home dir\n");
- printf("-? Help, print this usage\n");
- printf("-h <host> Host to connect to, default %s\n", wolfSSLIP);
- printf("-p <num> Port to connect on, not 0, default %d\n", wolfSSLPort);
- #ifndef WOLFSSL_TLS13
- printf("-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
- CLIENT_DEFAULT_VERSION);
- printf("-V Prints valid ssl version numbers, SSLv3(0) - TLS1.2(3)\n");
- #else
- printf("-v <num> SSL version [0-4], SSLv3(0) - TLS1.3(4)), default %d\n",
- CLIENT_DEFAULT_VERSION);
- printf("-V Prints valid ssl version numbers, SSLv3(0) - TLS1.3(4)\n");
- #endif
- printf("-l <str> Cipher suite list (: delimited)\n");
- printf("-c <file> Certificate file, default %s\n", cliCertFile);
- printf("-k <file> Key file, default %s\n", cliKeyFile);
- printf("-A <file> Certificate Authority file, default %s\n", caCertFile);
- #ifndef NO_DH
- printf("-Z <num> Minimum DH key bits, default %d\n",
- DEFAULT_MIN_DHKEY_BITS);
- #endif
- printf("-b <num> Benchmark <num> connections and print stats\n");
- #ifdef HAVE_ALPN
- printf("-L <str> Application-Layer Protocol Negotiation ({C,F}:<list>)\n");
- #endif
- printf("-B <num> Benchmark throughput using <num> bytes and print stats\n");
- printf("-s Use pre Shared keys\n");
- printf("-d Disable peer checks\n");
- printf("-D Override Date Errors example\n");
- printf("-e List Every cipher suite available, \n");
- printf("-g Send server HTTP GET\n");
- printf("-u Use UDP DTLS,"
- " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n");
- #ifdef WOLFSSL_SCTP
- printf("-G Use SCTP DTLS,"
- " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n");
- #endif
- printf("-m Match domain name in cert\n");
- printf("-N Use Non-blocking sockets\n");
- #ifndef NO_SESSION_CACHE
- printf("-r Resume session\n");
- #endif
- printf("-w Wait for bidirectional shutdown\n");
- printf("-M <prot> Use STARTTLS, using <prot> protocol (smtp)\n");
- #ifdef HAVE_SECURE_RENEGOTIATION
- printf("-R Allow Secure Renegotiation\n");
- printf("-i Force client Initiated Secure Renegotiation\n");
- #endif
- printf("-f Fewer packets/group messages\n");
- printf("-x Disable client cert/key loading\n");
- printf("-X Driven by eXternal test case\n");
- printf("-j Use verify callback override\n");
- #ifdef SHOW_SIZES
- printf("-z Print structure sizes\n");
- #endif
- #ifdef HAVE_SNI
- printf("-S <str> Use Host Name Indication\n");
- #endif
- #ifdef HAVE_MAX_FRAGMENT
- printf("-F <num> Use Maximum Fragment Length [1-5]\n");
- #endif
- #ifdef HAVE_TRUNCATED_HMAC
- printf("-T Use Truncated HMAC\n");
- #endif
- #ifdef HAVE_EXTENDED_MASTER
- printf("-n Disable Extended Master Secret\n");
- #endif
- #ifdef HAVE_OCSP
- printf("-o Perform OCSP lookup on peer certificate\n");
- printf("-O <url> Perform OCSP lookup using <url> as responder\n");
- #endif
- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
- || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
- printf("-W Use OCSP Stapling\n");
- #endif
- #ifdef ATOMIC_USER
- printf("-U Atomic User Record Layer Callbacks\n");
- #endif
- #ifdef HAVE_PK_CALLBACKS
- printf("-P Public Key Callbacks\n");
- #endif
- #ifdef HAVE_ANON
- printf("-a Anonymous client\n");
- #endif
- #ifdef HAVE_CRL
- printf("-C Disable CRL\n");
- #endif
- #ifdef WOLFSSL_TRUST_PEER_CERT
- printf("-E <file> Path to load trusted peer cert\n");
- #endif
- #ifdef HAVE_WNR
- printf("-q <file> Whitewood config file, default %s\n", wnrConfig);
- #endif
- printf("-H <arg> Internal tests [defCipherList, badCert]\n");
- #ifdef WOLFSSL_TLS13
- printf("-J Use HelloRetryRequest to choose group for KE\n");
- printf("-K Key Exchange for PSK not using (EC)DHE\n");
- printf("-I Update keys and IVs before sending data\n");
- #ifndef NO_DH
- printf("-y Key Share with FFDHE named groups only\n");
- #endif
- #ifdef HAVE_ECC
- printf("-Y Key Share with ECC named groups only\n");
- #endif
- #endif /* WOLFSSL_TLS13 */
- #ifdef HAVE_CURVE25519
- printf("-t Use X25519 for key exchange\n");
- #endif
- #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
- printf("-Q Support requesting certificate post-handshake\n");
- #endif
- #ifdef WOLFSSL_EARLY_DATA
- printf("-0 Early data sent to server (0-RTT handshake)\n");
- #endif
- #ifdef WOLFSSL_MULTICAST
- printf("-3 <grpid> Multicast, grpid < 256\n");
- #endif
- }
- THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
- {
- SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
- wolfSSL_method_func method = NULL;
- WOLFSSL_CTX* ctx = 0;
- WOLFSSL* ssl = 0;
- WOLFSSL* sslResume = 0;
- WOLFSSL_SESSION* session = 0;
- #ifndef WOLFSSL_ALT_TEST_STRINGS
- char msg[32] = "hello wolfssl!"; /* GET may make bigger */
- char resumeMsg[32] = "resuming wolfssl!";
- #else
- char msg[32] = "hello wolfssl!\n";
- char resumeMsg[32] = "resuming wolfssl!\n";
- #endif
- char reply[80];
- int msgSz = (int)XSTRLEN(msg);
- int resumeSz = (int)XSTRLEN(resumeMsg);
- word16 port = wolfSSLPort;
- char* host = (char*)wolfSSLIP;
- const char* domain = "localhost"; /* can't default to www.wolfssl.com
- because can't tell if we're really
- going there to detect old chacha-poly
- */
- int ch;
- int version = CLIENT_INVALID_VERSION;
- int usePsk = 0;
- int useAnon = 0;
- int sendGET = 0;
- int benchmark = 0;
- int throughput = 0;
- int doDTLS = 0;
- int dtlsUDP = 0;
- int dtlsSCTP = 0;
- int doMcast = 0;
- int matchName = 0;
- int doPeerCheck = 1;
- int nonBlocking = 0;
- int resumeSession = 0;
- int wc_shutdown = 0;
- int disableCRL = 0;
- int externalTest = 0;
- int ret;
- int err = 0;
- int scr = 0; /* allow secure renegotiation */
- int forceScr = 0; /* force client initiaed scr */
- int useClientCert = 1;
- int fewerPackets = 0;
- int atomicUser = 0;
- int pkCallbacks = 0;
- int overrideDateErrors = 0;
- int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
- char* alpnList = NULL;
- unsigned char alpn_opt = 0;
- char* cipherList = NULL;
- int useDefCipherList = 0;
- int useBadCert = 0;
- const char* verifyCert = caCertFile;
- const char* ourCert = cliCertFile;
- const char* ourKey = cliKeyFile;
- int doSTARTTLS = 0;
- char* starttlsProt = NULL;
- int useVerifyCb = 0;
- #ifdef WOLFSSL_TRUST_PEER_CERT
- const char* trustCert = NULL;
- #endif
- #ifdef HAVE_SNI
- char* sniHostName = NULL;
- #endif
- #ifdef HAVE_MAX_FRAGMENT
- byte maxFragment = 0;
- #endif
- #ifdef HAVE_TRUNCATED_HMAC
- byte truncatedHMAC = 0;
- #endif
- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
- || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
- byte statusRequest = 0;
- #endif
- #ifdef HAVE_EXTENDED_MASTER
- byte disableExtMasterSecret = 0;
- #endif
- int helloRetry = 0;
- #ifdef WOLFSSL_TLS13
- int onlyKeyShare = 0;
- int noPskDheKe = 0;
- #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
- int postHandAuth = 0;
- #endif
- #endif
- int updateKeysIVs = 0;
- #ifdef WOLFSSL_EARLY_DATA
- int earlyData = 0;
- #endif
- #ifdef WOLFSSL_MULTICAST
- byte mcastID = 0;
- #endif
- #ifdef HAVE_OCSP
- int useOcsp = 0;
- char* ocspUrl = NULL;
- #endif
- int useX25519 = 0;
- #ifdef HAVE_WNR
- const char* wnrConfigFile = wnrConfig;
- #endif
- char buffer[WOLFSSL_MAX_ERROR_SZ];
- int argc = ((func_args*)args)->argc;
- char** argv = ((func_args*)args)->argv;
- #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[320000];
- #else
- byte memory[80000];
- #endif
- byte memoryIO[34500]; /* max for IO buffer (TLS packet can be 16k) */
- WOLFSSL_MEM_CONN_STATS ssl_stats;
- #ifdef DEBUG_WOLFSSL
- WOLFSSL_MEM_STATS mem_stats;
- #endif
- #endif
- ((func_args*)args)->return_code = -1; /* error state */
- #ifdef NO_RSA
- verifyCert = (char*)caEccCertFile;
- ourCert = (char*)cliEccCertFile;
- ourKey = (char*)cliEccKeyFile;
- #endif
- (void)resumeSz;
- (void)session;
- (void)sslResume;
- (void)atomicUser;
- (void)pkCallbacks;
- (void)scr;
- (void)forceScr;
- (void)ourKey;
- (void)ourCert;
- (void)verifyCert;
- (void)useClientCert;
- (void)overrideDateErrors;
- (void)disableCRL;
- (void)minDhKeyBits;
- (void)alpnList;
- (void)alpn_opt;
- (void)updateKeysIVs;
- (void)useX25519;
- (void)helloRetry;
- (void)useBadCert;
- StackTrap();
- #ifndef WOLFSSL_VXWORKS
- /* Not used: All used */
- while ((ch = mygetopt(argc, argv, "?"
- "ab:c:defgh:ijk:l:mnop:q:rstuv:wxyz"
- "A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:"
- "03:")) != -1) {
- switch (ch) {
- case '?' :
- Usage();
- exit(EXIT_SUCCESS);
- case 'g' :
- sendGET = 1;
- break;
- case 'd' :
- doPeerCheck = 0;
- break;
- case 'e' :
- ShowCiphers();
- exit(EXIT_SUCCESS);
- case 'D' :
- overrideDateErrors = 1;
- break;
- case 'C' :
- #ifdef HAVE_CRL
- disableCRL = 1;
- #endif
- break;
- case 'u' :
- doDTLS = 1;
- dtlsUDP = 1;
- break;
- case 'G' :
- #ifdef WOLFSSL_SCTP
- doDTLS = 1;
- dtlsSCTP = 1;
- #endif
- break;
- case 's' :
- usePsk = 1;
- break;
- #ifdef WOLFSSL_TRUST_PEER_CERT
- case 'E' :
- trustCert = myoptarg;
- break;
- #endif
- case 'm' :
- matchName = 1;
- break;
- case 'x' :
- useClientCert = 0;
- break;
- case 'X' :
- externalTest = 1;
- break;
- case 'f' :
- fewerPackets = 1;
- break;
- case 'U' :
- #ifdef ATOMIC_USER
- atomicUser = 1;
- #endif
- break;
- case 'P' :
- #ifdef HAVE_PK_CALLBACKS
- pkCallbacks = 1;
- #endif
- break;
- case 'h' :
- host = myoptarg;
- domain = myoptarg;
- break;
- case 'p' :
- port = (word16)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 > 4) {
- Usage();
- exit(MY_EX_USAGE);
- }
- break;
- case 'V' :
- ShowVersions();
- exit(EXIT_SUCCESS);
- case 'l' :
- cipherList = myoptarg;
- break;
- case 'H' :
- if (XSTRNCMP(myoptarg, "defCipherList", 13) == 0) {
- printf("Using default cipher list for testing\n");
- useDefCipherList = 1;
- }
- else if (XSTRNCMP(myoptarg, "badCert", 7) == 0) {
- printf("Using bad certificate for testing\n");
- useBadCert = 1;
- }
- else {
- Usage();
- exit(MY_EX_USAGE);
- }
- break;
- case 'A' :
- verifyCert = myoptarg;
- break;
- case 'c' :
- ourCert = myoptarg;
- break;
- case 'k' :
- ourKey = myoptarg;
- break;
- case 'Z' :
- #ifndef NO_DH
- minDhKeyBits = atoi(myoptarg);
- if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
- Usage();
- exit(MY_EX_USAGE);
- }
- #endif
- break;
- case 'b' :
- benchmark = atoi(myoptarg);
- if (benchmark < 0 || benchmark > 1000000) {
- Usage();
- exit(MY_EX_USAGE);
- }
- break;
- case 'B' :
- throughput = atoi(myoptarg);
- if (throughput <= 0) {
- Usage();
- exit(MY_EX_USAGE);
- }
- break;
- case 'N' :
- nonBlocking = 1;
- break;
- case 'r' :
- resumeSession = 1;
- break;
- case 'w' :
- wc_shutdown = 1;
- break;
- case 'R' :
- #ifdef HAVE_SECURE_RENEGOTIATION
- scr = 1;
- #endif
- break;
- case 'i' :
- #ifdef HAVE_SECURE_RENEGOTIATION
- scr = 1;
- forceScr = 1;
- #endif
- break;
- case 'z' :
- #ifndef WOLFSSL_LEANPSK
- wolfSSL_GetObjectSize();
- #endif
- break;
- case 'S' :
- #ifdef HAVE_SNI
- sniHostName = myoptarg;
- #endif
- break;
- case 'F' :
- #ifdef HAVE_MAX_FRAGMENT
- maxFragment = atoi(myoptarg);
- if (maxFragment < WOLFSSL_MFL_2_9 ||
- maxFragment > WOLFSSL_MFL_2_13) {
- Usage();
- exit(MY_EX_USAGE);
- }
- #endif
- break;
- case 'T' :
- #ifdef HAVE_TRUNCATED_HMAC
- truncatedHMAC = 1;
- #endif
- break;
- case 'n' :
- #ifdef HAVE_EXTENDED_MASTER
- disableExtMasterSecret = 1;
- #endif
- break;
- case 'W' :
- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
- || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
- statusRequest = atoi(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 '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 'M' :
- doSTARTTLS = 1;
- starttlsProt = myoptarg;
- if (XSTRNCMP(starttlsProt, "smtp", 4) != 0) {
- Usage();
- exit(MY_EX_USAGE);
- }
- break;
- case 'q' :
- #ifdef HAVE_WNR
- wnrConfigFile = myoptarg;
- #endif
- break;
- case 'J' :
- #ifdef WOLFSSL_TLS13
- helloRetry = 1;
- #endif
- break;
- case 'K' :
- #ifdef WOLFSSL_TLS13
- noPskDheKe = 1;
- #endif
- break;
- case 'I' :
- #ifdef WOLFSSL_TLS13
- updateKeysIVs = 1;
- #endif
- break;
- case 'y' :
- #if defined(WOLFSSL_TLS13) && !defined(NO_DH)
- onlyKeyShare = 1;
- #endif
- break;
- case 'Y' :
- #if defined(WOLFSSL_TLS13) && defined(HAVE_ECC)
- onlyKeyShare = 2;
- #endif
- break;
- case 'j' :
- useVerifyCb = 1;
- break;
- case 't' :
- #ifdef HAVE_CURVE25519
- useX25519 = 1;
- #if defined(WOLFSSL_TLS13) && defined(HAVE_ECC)
- onlyKeyShare = 2;
- #endif
- #endif
- break;
- case 'Q' :
- #if defined(WOLFSSL_TLS13) && \
- defined(WOLFSSL_POST_HANDSHAKE_AUTH)
- postHandAuth = 1;
- #endif
- break;
- case '0' :
- #ifdef WOLFSSL_EARLY_DATA
- earlyData = 1;
- #endif
- break;
- case '3' :
- #ifdef WOLFSSL_MULTICAST
- doMcast = 1;
- mcastID = (byte)(atoi(myoptarg) & 0xFF);
- #endif
- break;
- default:
- Usage();
- exit(MY_EX_USAGE);
- }
- }
- myoptind = 0; /* reset for test cases */
- #endif /* !WOLFSSL_VXWORKS */
- if (externalTest) {
- /* detect build cases that wouldn't allow test against wolfssl.com */
- int done = 0;
- #ifdef NO_RSA
- done += 1;
- #endif
- /* www.globalsign.com does not respond to ipv6 ocsp requests */
- #if defined(TEST_IPV6) && defined(HAVE_OCSP)
- done += 1;
- #endif
- /* www.globalsign.com has limited supported cipher suites */
- #if defined(NO_AES) && defined(HAVE_OCSP)
- done += 1;
- #endif
- /* www.globalsign.com only supports static RSA or ECDHE with AES */
- /* We cannot expect users to have on static RSA so test for ECC only
- * as some users will most likely be on 32-bit systems where ECC
- * is not enabled by default */
- #if defined(HAVE_OCSP) && !defined(HAVE_ECC)
- done += 1;
- #endif
- #ifndef NO_PSK
- done += 1;
- #endif
- #ifdef NO_SHA
- done += 1; /* external cert chain most likely has SHA */
- #endif
- #if !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
- || ( defined(HAVE_ECC) && !defined(HAVE_SUPPORTED_CURVES) \
- && !defined(WOLFSSL_STATIC_RSA) )
- /* google needs ECDHE+Supported Curves or static RSA */
- if (!XSTRNCMP(domain, "www.google.com", 14))
- done += 1;
- #endif
- #if !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA)
- /* wolfssl needs ECDHE or static RSA */
- if (!XSTRNCMP(domain, "www.wolfssl.com", 15))
- done += 1;
- #endif
- #if !defined(WOLFSSL_SHA384)
- if (!XSTRNCMP(domain, "www.wolfssl.com", 15)) {
- /* wolfssl need sha384 for cert chain verify */
- done += 1;
- }
- #endif
- #if !defined(HAVE_AESGCM) && defined(NO_AES) && \
- !(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
- /* need at least on of these for external tests */
- done += 1;
- #endif
- #if defined(HAVE_QSH)
- /*currently google server rejects client hello with QSH extension.*/
- done += 1;
- #endif
- if (done) {
- printf("external test can't be run in this mode");
- ((func_args*)args)->return_code = 0;
- exit(EXIT_SUCCESS);
- }
- }
- /* 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 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_client_method_ex;
- break;
- #endif
- #ifndef NO_TLS
- #ifdef WOLFSSL_ALLOW_TLSV10
- case 1:
- method = wolfTLSv1_client_method_ex;
- break;
- #endif
- case 2:
- method = wolfTLSv1_1_client_method_ex;
- break;
- #endif /* !NO_TLS */
- #endif /* !NO_OLD_TLS */
- #ifndef NO_TLS
- case 3:
- method = wolfTLSv1_2_client_method_ex;
- break;
- #ifdef WOLFSSL_TLS13
- case 4:
- method = wolfTLSv1_3_client_method_ex;
- break;
- #endif
- #endif /* NO_TLS */
- #ifdef WOLFSSL_DTLS
- #ifndef NO_OLD_TLS
- case -1:
- method = wolfDTLSv1_client_method_ex;
- break;
- #endif
- case -2:
- method = wolfDTLSv1_2_client_method_ex;
- break;
- #endif
- default:
- err_sys("Bad SSL version");
- break;
- }
- 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) != WOLFSSL_SUCCESS) {
- err_sys("unable to load static memory");
- }
- if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO),
- WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1) != WOLFSSL_SUCCESS) {
- err_sys("unable to load static memory");
- }
- #else
- ctx = wolfSSL_CTX_new(method(NULL));
- #endif
- if (ctx == NULL)
- err_sys("unable to get ctx");
- #ifdef SINGLE_THREADED
- if (wolfSSL_CTX_new_rng(ctx) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("Single Threaded new rng at CTX failed");
- }
- #endif
- if (cipherList && !useDefCipherList) {
- if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("client can't set cipher list 1");
- }
- }
- #ifdef WOLFSSL_LEANPSK
- if (!usePsk) {
- usePsk = 1;
- }
- #endif
- #if defined(NO_RSA) && !defined(HAVE_ECC)
- if (!usePsk) {
- usePsk = 1;
- }
- #endif
- if (fewerPackets)
- wolfSSL_CTX_set_group_messages(ctx);
- #ifndef NO_DH
- wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits);
- #endif
- if (usePsk) {
- #ifndef NO_PSK
- wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
- if (cipherList == NULL) {
- const char *defaultCipherList;
- #if defined(HAVE_AESGCM) && !defined(NO_DH)
- #ifdef WOLFSSL_TLS13
- defaultCipherList = "DHE-PSK-AES128-GCM-SHA256:"
- "TLS13-AES128-GCM-SHA256";
- #else
- defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
- #endif
- #elif defined(HAVE_NULL_CIPHER)
- defaultCipherList = "PSK-NULL-SHA256";
- #else
- defaultCipherList = "PSK-AES128-CBC-SHA256";
- #endif
- if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)
- !=WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("client can't set cipher list 2");
- }
- }
- #endif
- if (useClientCert) {
- useClientCert = 0;
- }
- }
- if (useAnon) {
- #ifdef HAVE_ANON
- if (cipherList == NULL || (cipherList && useDefCipherList)) {
- wolfSSL_CTX_allow_anon_cipher(ctx);
- if (wolfSSL_CTX_set_cipher_list(ctx,"ADH-AES128-SHA")
- != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("client can't set cipher list 4");
- }
- }
- #endif
- if (useClientCert) {
- useClientCert = 0;
- }
- }
- #ifdef WOLFSSL_SCTP
- if (dtlsSCTP)
- wolfSSL_CTX_dtls_set_sctp(ctx);
- #endif
- #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
- wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
- #endif
- #if defined(WOLFSSL_SNIFFER)
- if (cipherList == NULL) {
- /* don't use EDH, can't sniff tmp keys */
- if (wolfSSL_CTX_set_cipher_list(ctx, "AES128-SHA") != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("client can't set cipher list 3");
- }
- }
- #endif
- #ifdef HAVE_OCSP
- if (useOcsp) {
- #ifdef HAVE_IO_TIMEOUT
- wolfIO_SetTimeout(DEFAULT_TIMEOUT_SEC);
- #endif
- if (ocspUrl != NULL) {
- wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
- wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE
- | WOLFSSL_OCSP_URL_OVERRIDE);
- }
- else {
- wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL);
- }
- #ifdef WOLFSSL_NONBLOCK_OCSP
- wolfSSL_CTX_SetOCSP_Cb(ctx, OCSPIOCb, OCSPRespFreeCb, NULL);
- #endif
- }
- #endif
- #ifdef USER_CA_CB
- wolfSSL_CTX_SetCACb(ctx, CaCb);
- #endif
- #if !defined(NO_CERTS)
- if (useClientCert){
- #if !defined(NO_FILESYSTEM)
- if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert)
- != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("can't load client cert file, check file and run from"
- " wolfSSL home dir");
- }
- if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, WOLFSSL_FILETYPE_PEM)
- != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("can't load client private key file, check file and run "
- "from wolfSSL home dir");
- }
- #else
- load_buffer(ctx, ourCert, WOLFSSL_CERT_CHAIN);
- load_buffer(ctx, ourKey, WOLFSSL_KEY);
- #endif /* !defined(NO_FILESYSTEM) */
- }
- /* for testing only - use client cert as CA to force no signer error */
- if (useBadCert) {
- #if !defined(NO_RSA)
- verifyCert = "./certs/client-cert.pem";
- #elif defined(HAVE_ECC)
- verifyCert = "./certs/client-ecc-cert.pem";
- #endif
- }
- if (!usePsk && !useAnon && !useVerifyCb) {
- #if !defined(NO_FILESYSTEM)
- if (wolfSSL_CTX_load_verify_locations(ctx, verifyCert,0)
- != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("can't load ca file, Please run from wolfSSL home dir");
- }
- #else
- load_buffer(ctx, verifyCert, WOLFSSL_CA);
- #endif /* !defined(NO_FILESYSTEM) */
- #ifdef HAVE_ECC
- /* load ecc verify too, echoserver uses it by default w/ ecc */
- #if !defined(NO_FILESYSTEM)
- if (wolfSSL_CTX_load_verify_locations(ctx, eccCertFile, 0)
- != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("can't load ecc ca file, Please run from wolfSSL home dir");
- }
- #else
- load_buffer(ctx, eccCertFile, WOLFSSL_CA);
- #endif /* !defined(NO_FILESYSTEM) */
- #endif /* HAVE_ECC */
- #if defined(WOLFSSL_TRUST_PEER_CERT) && !defined(NO_FILESYSTEM)
- if (trustCert) {
- if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
- WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("can't load trusted peer cert file");
- }
- }
- #endif /* WOLFSSL_TRUST_PEER_CERT && !NO_FILESYSTEM */
- }
- if (useVerifyCb)
- wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
- else if (!usePsk && !useAnon && doPeerCheck == 0)
- wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
- else if (!usePsk && !useAnon && overrideDateErrors == 1)
- wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myDateCb);
- #endif /* !defined(NO_CERTS) */
- #ifdef WOLFSSL_ASYNC_CRYPT
- ret = wolfAsync_DevOpen(&devId);
- if (ret < 0) {
- printf("Async device open failed\nRunning without async\n");
- }
- wolfSSL_CTX_UseAsync(ctx, devId);
- #endif /* WOLFSSL_ASYNC_CRYPT */
- #ifdef HAVE_SNI
- if (sniHostName)
- if (wolfSSL_CTX_UseSNI(ctx, 0, sniHostName,
- (word16) XSTRLEN(sniHostName)) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("UseSNI failed");
- }
- #endif
- #ifdef HAVE_MAX_FRAGMENT
- if (maxFragment)
- if (wolfSSL_CTX_UseMaxFragment(ctx, maxFragment) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("UseMaxFragment failed");
- }
- #endif
- #ifdef HAVE_TRUNCATED_HMAC
- if (truncatedHMAC)
- if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("UseTruncatedHMAC failed");
- }
- #endif
- #ifdef HAVE_SESSION_TICKET
- if (wolfSSL_CTX_UseSessionTicket(ctx) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("UseSessionTicket failed");
- }
- #endif
- #ifdef HAVE_EXTENDED_MASTER
- if (disableExtMasterSecret)
- if (wolfSSL_CTX_DisableExtendedMasterSecret(ctx) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("DisableExtendedMasterSecret failed");
- }
- #endif
- #if defined(HAVE_CURVE25519) && defined(HAVE_SUPPORTED_CURVES)
- if (useX25519) {
- if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_X25519)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to support X25519");
- }
- if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_SECP256R1)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to support secp256r1");
- }
- }
- #endif /* HAVE_CURVE25519 && HAVE_SUPPORTED_CURVES */
- if (benchmark) {
- ((func_args*)args)->return_code =
- ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP,
- benchmark, resumeSession, useX25519,
- helloRetry);
- wolfSSL_CTX_free(ctx);
- exit(EXIT_SUCCESS);
- }
- if(throughput) {
- ((func_args*)args)->return_code =
- ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP,
- throughput, useX25519);
- wolfSSL_CTX_free(ctx);
- exit(EXIT_SUCCESS);
- }
- #if defined(WOLFSSL_MDK_ARM)
- wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
- #endif
- #if defined(OPENSSL_EXTRA)
- if (wolfSSL_CTX_get_read_ahead(ctx) != 0) {
- wolfSSL_CTX_free(ctx);
- err_sys("bad read ahead default value");
- }
- if (wolfSSL_CTX_set_read_ahead(ctx, 1) != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("error setting read ahead value");
- }
- #endif
- #ifdef WOLFSSL_TLS13
- if (noPskDheKe)
- wolfSSL_CTX_no_dhe_psk(ctx);
- #endif
- #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
- if (postHandAuth)
- wolfSSL_CTX_allow_post_handshake_auth(ctx);
- #endif
- #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
- 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
- if (doMcast) {
- #ifdef WOLFSSL_MULTICAST
- wolfSSL_CTX_mcast_set_member_id(ctx, mcastID);
- if (wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256")
- != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("Couldn't set multicast cipher list.");
- }
- #endif
- }
- ssl = wolfSSL_new(ctx);
- if (ssl == NULL) {
- wolfSSL_CTX_free(ctx);
- err_sys("unable to get SSL object");
- }
- #ifdef OPENSSL_EXTRA
- wolfSSL_KeepArrays(ssl);
- #endif
- #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
- 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
- #ifdef WOLFSSL_TLS13
- if (!helloRetry) {
- if (onlyKeyShare == 0 || onlyKeyShare == 2) {
- #ifdef HAVE_CURVE25519
- if (useX25519) {
- if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve x25519");
- }
- }
- #endif
- #ifdef HAVE_ECC
- #if defined(HAVE_ECC256) || defined(HAVE_ALL_CURVES)
- if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve secp256r1");
- }
- #endif
- #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
- if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP384R1)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve secp384r1");
- }
- #endif
- #endif
- }
- if (onlyKeyShare == 0 || onlyKeyShare == 1) {
- #ifdef HAVE_FFDHE_2048
- if (wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048)
- != WOLFSSL_SUCCESS) {
- err_sys("unable to use DH 2048-bit parameters");
- }
- #endif
- }
- }
- else {
- wolfSSL_NoKeyShares(ssl);
- }
- #endif
- if (doMcast) {
- #ifdef WOLFSSL_MULTICAST
- byte pms[512]; /* pre master secret */
- byte cr[32]; /* client random */
- byte sr[32]; /* server random */
- const byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */
- XMEMSET(pms, 0x23, sizeof(pms));
- XMEMSET(cr, 0xA5, sizeof(cr));
- XMEMSET(sr, 0x5A, sizeof(sr));
- if (wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite)
- != WOLFSSL_SUCCESS) {
- wolfSSL_CTX_free(ctx);
- err_sys("unable to set mcast secret");
- }
- #endif
- }
- #ifdef HAVE_SESSION_TICKET
- wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session");
- #endif
- #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 HAVE_CERTIFICATE_STATUS_REQUEST
- if (statusRequest) {
- if (wolfSSL_CTX_EnableOCSPStapling(ctx) != WOLFSSL_SUCCESS)
- err_sys("can't enable OCSP Stapling Certificate Manager");
- switch (statusRequest) {
- case WOLFSSL_CSR_OCSP:
- if (wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR_OCSP,
- WOLFSSL_CSR_OCSP_USE_NONCE) != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("UseCertificateStatusRequest failed");
- }
- break;
- }
- wolfSSL_CTX_EnableOCSP(ctx, 0);
- }
- #endif
- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
- if (statusRequest) {
- if (wolfSSL_CTX_EnableOCSPStapling(ctx) != WOLFSSL_SUCCESS)
- err_sys("can't enable OCSP Stapling Certificate Manager");
- switch (statusRequest) {
- case WOLFSSL_CSR2_OCSP:
- if (wolfSSL_UseOCSPStaplingV2(ssl,
- WOLFSSL_CSR2_OCSP, WOLFSSL_CSR2_OCSP_USE_NONCE)
- != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("UseCertificateStatusRequest failed");
- }
- break;
- case WOLFSSL_CSR2_OCSP_MULTI:
- if (wolfSSL_UseOCSPStaplingV2(ssl,
- WOLFSSL_CSR2_OCSP_MULTI, 0)
- != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("UseCertificateStatusRequest failed");
- }
- break;
- }
- wolfSSL_CTX_EnableOCSP(ctx, 0);
- }
- #endif
- tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
- if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("error in setting fd");
- }
- /* STARTTLS */
- if (doSTARTTLS) {
- if (StartTLS_Init(&sockfd) != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("error during STARTTLS protocol");
- }
- }
- #ifdef HAVE_CRL
- if (disableCRL == 0 && !useVerifyCb) {
- #ifdef HAVE_IO_TIMEOUT
- wolfIO_SetTimeout(DEFAULT_TIMEOUT_SEC);
- #endif
- if (wolfSSL_EnableCRL(ssl, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("can't enable crl check");
- }
- if (wolfSSL_LoadCRL(ssl, crlPemDir, WOLFSSL_FILETYPE_PEM, 0)
- != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("can't load crl, check crlfile and date validity");
- }
- if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("can't set crl callback");
- }
- }
- #endif
- #ifdef HAVE_SECURE_RENEGOTIATION
- if (scr) {
- if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("can't enable secure renegotiation");
- }
- }
- #endif
- #ifdef ATOMIC_USER
- if (atomicUser)
- SetupAtomicUser(ctx, ssl);
- #endif
- #ifdef HAVE_PK_CALLBACKS
- if (pkCallbacks)
- SetupPkCallbacks(ctx, ssl);
- #endif
- if (matchName && doPeerCheck)
- wolfSSL_check_domain_name(ssl, domain);
- #ifndef WOLFSSL_CALLBACKS
- if (nonBlocking) {
- wolfSSL_set_using_nonblock(ssl, 1);
- tcp_set_nonblocking(&sockfd);
- ret = NonBlockingSSL_Connect(ssl);
- }
- else {
- do {
- err = 0; /* reset error */
- ret = wolfSSL_connect(ssl);
- if (ret != WOLFSSL_SUCCESS) {
- err = wolfSSL_get_error(ssl, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- }
- #else
- timeout.tv_sec = DEFAULT_TIMEOUT_SEC;
- timeout.tv_usec = 0;
- ret = NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */
- #endif
- if (ret != WOLFSSL_SUCCESS) {
- printf("wolfSSL_connect error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("wolfSSL_connect failed");
- /* see note at top of README */
- /* if you're getting an error here */
- }
- showPeer(ssl);
- #ifdef OPENSSL_EXTRA
- {
- byte* rnd;
- byte* pt;
- size_t size;
- /* get size of buffer then print */
- size = wolfSSL_get_client_random(NULL, NULL, 0);
- if (size == 0) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("error getting client random buffer size");
- }
- rnd = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (rnd == NULL) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("error creating client random buffer");
- }
- size = wolfSSL_get_client_random(ssl, rnd, size);
- if (size == 0) {
- XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("error getting client random buffer");
- }
- printf("Client Random : ");
- for (pt = rnd; pt < rnd + size; pt++) printf("%02X", *pt);
- printf("\n");
- XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- }
- #endif
- if (doSTARTTLS) {
- if (XSTRNCMP(starttlsProt, "smtp", 4) == 0) {
- if (SMTP_Shutdown(ssl, wc_shutdown) != WOLFSSL_SUCCESS) {
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("error closing STARTTLS connection");
- }
- }
- wolfSSL_free(ssl);
- CloseSocket(sockfd);
- wolfSSL_CTX_free(ctx);
- ((func_args*)args)->return_code = 0;
- return 0;
- }
- #ifdef HAVE_ALPN
- if (alpnList != NULL) {
- char *protocol_name = NULL;
- word16 protocol_nameSz = 0;
- err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
- if (err == WOLFSSL_SUCCESS)
- printf("Received ALPN protocol : %s (%d)\n",
- protocol_name, protocol_nameSz);
- else if (err == WOLFSSL_ALPN_NOT_FOUND)
- printf("No ALPN response received (no match with server)\n");
- else
- printf("Getting ALPN protocol name failed\n");
- }
- #endif
- #ifdef HAVE_SECURE_RENEGOTIATION
- if (scr && forceScr) {
- if (nonBlocking) {
- printf("not doing secure renegotiation on example with"
- " nonblocking yet");
- } else {
- if (wolfSSL_Rehandshake(ssl) != WOLFSSL_SUCCESS) {
- err = wolfSSL_get_error(ssl, 0);
- printf("err = %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- wolfSSL_free(ssl);
- wolfSSL_CTX_free(ctx);
- err_sys("wolfSSL_Rehandshake failed");
- }
- }
- }
- #endif /* HAVE_SECURE_RENEGOTIATION */
- if (sendGET) {
- printf("SSL connect ok, sending GET...\n");
- msgSz = 28;
- strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
- msg[msgSz] = '\0';
- resumeSz = msgSz;
- strncpy(resumeMsg, "GET /index.html HTTP/1.0\r\n\r\n", resumeSz);
- resumeMsg[resumeSz] = '\0';
- }
- /* allow some time for exporting the session */
- #ifdef WOLFSSL_SESSION_EXPORT_DEBUG
- #ifdef USE_WINDOWS_API
- Sleep(500);
- #elif defined(WOLFSSL_TIRTOS)
- Task_sleep(1);
- #else
- sleep(1);
- #endif
- #endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
- #ifdef WOLFSSL_TLS13
- if (updateKeysIVs)
- wolfSSL_update_keys(ssl);
- #endif
- ClientWrite(ssl, msg, msgSz);
- ClientRead(ssl, reply, sizeof(reply)-1, 1);
- #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
- if (postHandAuth)
- ClientWrite(ssl, msg, msgSz);
- #endif
- if (sendGET) { /* get html */
- ClientRead(ssl, reply, sizeof(reply)-1, 0);
- }
- #ifndef NO_SESSION_CACHE
- if (resumeSession) {
- session = wolfSSL_get_session(ssl);
- }
- #endif
- if (dtlsUDP == 0) { /* don't send alert after "break" command */
- ret = wolfSSL_shutdown(ssl);
- if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE)
- wolfSSL_shutdown(ssl); /* bidirectional shutdown */
- }
- #ifdef ATOMIC_USER
- if (atomicUser)
- FreeAtomicUser(ssl);
- #endif
- /* 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
- wolfSSL_free(ssl);
- CloseSocket(sockfd);
- #ifndef NO_SESSION_CACHE
- if (resumeSession) {
- sslResume = wolfSSL_new(ctx);
- if (sslResume == NULL) {
- wolfSSL_CTX_free(ctx);
- err_sys("unable to get SSL object");
- }
- if (dtlsUDP) {
- #ifdef USE_WINDOWS_API
- Sleep(500);
- #elif defined(WOLFSSL_TIRTOS)
- Task_sleep(1);
- #else
- sleep(1);
- #endif
- }
- tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, sslResume);
- if (wolfSSL_set_fd(sslResume, sockfd) != WOLFSSL_SUCCESS) {
- wolfSSL_free(sslResume);
- wolfSSL_CTX_free(ctx);
- err_sys("error in setting fd");
- }
- #ifdef HAVE_ALPN
- if (alpnList != NULL) {
- printf("ALPN accepted protocols list : %s\n", alpnList);
- wolfSSL_UseALPN(sslResume, alpnList, (word32)XSTRLEN(alpnList),
- alpn_opt);
- }
- #endif
- #ifdef HAVE_SECURE_RENEGOTIATION
- if (scr) {
- if (wolfSSL_UseSecureRenegotiation(sslResume) != WOLFSSL_SUCCESS) {
- wolfSSL_free(sslResume);
- wolfSSL_CTX_free(ctx);
- err_sys("can't enable secure renegotiation");
- }
- }
- #endif
- wolfSSL_set_session(sslResume, session);
- #ifdef HAVE_SESSION_TICKET
- wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB,
- (void*)"resumed session");
- #endif
- #ifdef WOLFSSL_TLS13
- #ifdef HAVE_CURVE25519
- if (useX25519) {
- if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve x25519");
- }
- }
- #endif
- #ifdef HAVE_ECC
- if (wolfSSL_UseKeyShare(sslResume,
- WOLFSSL_ECC_SECP256R1) != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve secp256r1");
- }
- if (wolfSSL_UseKeyShare(sslResume,
- WOLFSSL_ECC_SECP384R1) != WOLFSSL_SUCCESS) {
- err_sys("unable to use curve secp384r1");
- }
- #endif
- #ifdef HAVE_FFDHE_2048
- if (wolfSSL_UseKeyShare(sslResume, WOLFSSL_FFDHE_2048) != WOLFSSL_SUCCESS) {
- err_sys("unable to use DH 2048-bit parameters");
- }
- #endif
- #endif
- #ifndef WOLFSSL_CALLBACKS
- if (nonBlocking) {
- wolfSSL_set_using_nonblock(sslResume, 1);
- tcp_set_nonblocking(&sockfd);
- ret = NonBlockingSSL_Connect(sslResume);
- }
- else {
- #ifdef WOLFSSL_EARLY_DATA
- #ifndef HAVE_SESSION_TICKET
- if (!usePsk) {
- }
- else
- #endif
- if (earlyData) {
- do {
- err = 0; /* reset error */
- ret = wolfSSL_write_early_data(sslResume, msg, msgSz,
- &msgSz);
- if (ret <= 0) {
- err = wolfSSL_get_error(sslResume, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(sslResume,
- WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret != msgSz) {
- printf("SSL_write_early_data msg error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- wolfSSL_free(sslResume);
- wolfSSL_CTX_free(ctx);
- err_sys("SSL_write_early_data failed");
- }
- do {
- err = 0; /* reset error */
- ret = wolfSSL_write_early_data(sslResume, msg, msgSz,
- &msgSz);
- if (ret <= 0) {
- err = wolfSSL_get_error(sslResume, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(sslResume,
- WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret != msgSz) {
- printf("SSL_write_early_data msg error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- wolfSSL_free(sslResume);
- wolfSSL_CTX_free(ctx);
- err_sys("SSL_write_early_data failed");
- }
- }
- #endif
- do {
- err = 0; /* reset error */
- ret = wolfSSL_connect(sslResume);
- if (ret != WOLFSSL_SUCCESS) {
- err = wolfSSL_get_error(sslResume, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(sslResume,
- WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- }
- #else
- timeout.tv_sec = DEFAULT_TIMEOUT_SEC;
- timeout.tv_usec = 0;
- ret = NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */
- #endif
- if (ret != WOLFSSL_SUCCESS) {
- printf("wolfSSL_connect resume error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- wolfSSL_free(sslResume);
- wolfSSL_CTX_free(ctx);
- err_sys("wolfSSL_connect resume failed");
- }
- showPeer(sslResume);
- if (wolfSSL_session_reused(sslResume))
- printf("reused session id\n");
- else
- printf("didn't reuse session id!!!\n");
- #ifdef HAVE_ALPN
- if (alpnList != NULL) {
- char *protocol_name = NULL;
- word16 protocol_nameSz = 0;
- printf("Sending ALPN accepted list : %s\n", alpnList);
- err = wolfSSL_ALPN_GetProtocol(sslResume, &protocol_name,
- &protocol_nameSz);
- if (err == WOLFSSL_SUCCESS)
- printf("Received ALPN protocol : %s (%d)\n",
- protocol_name, protocol_nameSz);
- else if (err == WOLFSSL_ALPN_NOT_FOUND)
- printf("Not received ALPN response (no match with server)\n");
- else
- printf("Getting ALPN protocol name failed\n");
- }
- #endif
- /* allow some time for exporting the session */
- #ifdef WOLFSSL_SESSION_EXPORT_DEBUG
- #ifdef USE_WINDOWS_API
- Sleep(500);
- #elif defined(WOLFSSL_TIRTOS)
- Task_sleep(1);
- #else
- sleep(1);
- #endif
- #endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
- do {
- err = 0; /* reset error */
- ret = wolfSSL_write(sslResume, resumeMsg, resumeSz);
- if (ret <= 0) {
- err = wolfSSL_get_error(sslResume, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(sslResume, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret != resumeSz) {
- printf("SSL_write resume error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- wolfSSL_free(sslResume);
- wolfSSL_CTX_free(ctx);
- err_sys("SSL_write failed");
- }
- if (nonBlocking) {
- /* give server a chance to bounce a message back to client */
- #ifdef USE_WINDOWS_API
- Sleep(500);
- #elif defined(WOLFSSL_TIRTOS)
- Task_sleep(1);
- #else
- sleep(1);
- #endif
- }
- do {
- err = 0; /* reset error */
- ret = wolfSSL_read(sslResume, reply, sizeof(reply)-1);
- if (ret <= 0) {
- err = wolfSSL_get_error(sslResume, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(sslResume, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret > 0) {
- reply[ret] = 0;
- printf("Server resume response: %s\n", reply);
- if (sendGET) { /* get html */
- while (1) {
- do {
- err = 0; /* reset error */
- ret = wolfSSL_read(sslResume, reply, sizeof(reply)-1);
- if (ret <= 0) {
- err = wolfSSL_get_error(sslResume, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(sslResume,
- WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- if (ret > 0) {
- reply[ret] = 0;
- printf("%s\n", reply);
- }
- else
- break;
- }
- }
- }
- if (ret < 0) {
- if (err != WOLFSSL_ERROR_WANT_READ) {
- printf("SSL_read resume error %d, %s\n", err,
- wolfSSL_ERR_error_string(err, buffer));
- wolfSSL_free(sslResume);
- wolfSSL_CTX_free(ctx);
- err_sys("SSL_read failed");
- }
- }
- /* try to send session break */
- do {
- err = 0; /* reset error */
- ret = wolfSSL_write(sslResume, msg, msgSz);
- if (ret <= 0) {
- err = wolfSSL_get_error(sslResume, 0);
- #ifdef WOLFSSL_ASYNC_CRYPT
- if (err == WC_PENDING_E) {
- ret = wolfSSL_AsyncPoll(sslResume, WOLF_POLL_FLAG_CHECK_HW);
- if (ret < 0) break;
- }
- #endif
- }
- } while (err == WC_PENDING_E);
- ret = wolfSSL_shutdown(sslResume);
- if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE)
- wolfSSL_shutdown(sslResume); /* bidirectional shutdown */
- /* display collected statistics */
- #ifdef WOLFSSL_STATIC_MEMORY
- if (wolfSSL_is_static_memory(sslResume, &ssl_stats) != 1)
- err_sys("static memory was not used with ssl");
- fprintf(stderr, "\nprint off SSLresume 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
- wolfSSL_free(sslResume);
- CloseSocket(sockfd);
- }
- #endif /* NO_SESSION_CACHE */
- wolfSSL_CTX_free(ctx);
- ((func_args*)args)->return_code = 0;
- #ifdef WOLFSSL_ASYNC_CRYPT
- wolfAsync_DevClose(&devId);
- #endif
- /* There are use cases when these assignments are not read. To avoid
- * potential confusion those warnings have been handled here.
- */
- (void) overrideDateErrors;
- (void) useClientCert;
- (void) verifyCert;
- (void) ourCert;
- (void) ourKey;
- (void) useVerifyCb;
- #if !defined(WOLFSSL_TIRTOS)
- return 0;
- #endif
- }
- #endif /* !NO_WOLFSSL_CLIENT */
- /* so overall tests can pull in test function */
- #ifndef NO_MAIN_DRIVER
- int main(int argc, char** argv)
- {
- func_args args;
- StartTCP();
- args.argc = argc;
- args.argv = argv;
- #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL) && !defined(STACK_TRAP)
- wolfSSL_Debugging_ON();
- #endif
- wolfSSL_Init();
- ChangeToWolfRoot();
- #ifndef NO_WOLFSSL_CLIENT
- #ifdef HAVE_STACK_SIZE
- StackSizeCheck(&args, client_test);
- #else
- client_test(&args);
- #endif
- #endif
- wolfSSL_Cleanup();
- #ifdef HAVE_WNR
- if (wc_FreeNetRandom() < 0)
- err_sys("Failed to free netRandom context");
- #endif /* HAVE_WNR */
- return args.return_code;
- }
- int myoptind = 0;
- char* myoptarg = NULL;
- #endif /* NO_MAIN_DRIVER */
|