client.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /* client.c
  2. *
  3. * Copyright (C) 2006-2011 Sawtooth Consulting Ltd.
  4. *
  5. * This file is part of CyaSSL.
  6. *
  7. * CyaSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * CyaSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <cyassl/openssl/ssl.h>
  25. #include <cyassl/test.h>
  26. /*
  27. #define TEST_RESUME
  28. */
  29. #ifdef CYASSL_CALLBACKS
  30. int handShakeCB(HandShakeInfo*);
  31. int timeoutCB(TimeoutInfo*);
  32. Timeval timeout;
  33. #endif
  34. #if defined(NON_BLOCKING) || defined(CYASSL_CALLBACKS)
  35. void NonBlockingSSL_Connect(SSL* ssl)
  36. {
  37. #ifndef CYASSL_CALLBACKS
  38. int ret = SSL_connect(ssl);
  39. #else
  40. int ret = CyaSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
  41. #endif
  42. int error = SSL_get_error(ssl, 0);
  43. while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
  44. error == SSL_ERROR_WANT_WRITE)) {
  45. if (error == SSL_ERROR_WANT_READ)
  46. printf("... client would read block\n");
  47. else
  48. printf("... client would write block\n");
  49. #ifdef USE_WINDOWS_API
  50. Sleep(100);
  51. #else
  52. sleep(1);
  53. #endif
  54. #ifndef CYASSL_CALLBACKS
  55. ret = SSL_connect(ssl);
  56. #else
  57. ret = CyaSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
  58. #endif
  59. error = SSL_get_error(ssl, 0);
  60. }
  61. if (ret != SSL_SUCCESS)
  62. err_sys("SSL_connect failed");
  63. }
  64. #endif
  65. void client_test(void* args)
  66. {
  67. SOCKET_T sockfd = 0;
  68. SSL_METHOD* method = 0;
  69. SSL_CTX* ctx = 0;
  70. SSL* ssl = 0;
  71. #ifdef TEST_RESUME
  72. SSL* sslResume = 0;
  73. SSL_SESSION* session = 0;
  74. char resumeMsg[] = "resuming cyassl!";
  75. int resumeSz = sizeof(resumeMsg);
  76. #endif
  77. char msg[64] = "hello cyassl!";
  78. char reply[1024];
  79. int input;
  80. int msgSz = strlen(msg);
  81. int argc = ((func_args*)args)->argc;
  82. char** argv = ((func_args*)args)->argv;
  83. ((func_args*)args)->return_code = -1; /* error state */
  84. #if defined(CYASSL_DTLS)
  85. method = DTLSv1_client_method();
  86. #elif !defined(NO_TLS)
  87. method = SSLv23_client_method();
  88. #else
  89. method = SSLv3_client_method();
  90. #endif
  91. ctx = SSL_CTX_new(method);
  92. #ifndef NO_PSK
  93. SSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
  94. #endif
  95. #ifdef OPENSSL_EXTRA
  96. SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
  97. #endif
  98. #if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
  99. /* don't use EDH, can't sniff tmp keys */
  100. SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
  101. #endif
  102. #ifndef NO_FILESYSTEM
  103. if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
  104. err_sys("can't load ca file, Please run from CyaSSL home dir");
  105. #ifdef HAVE_ECC
  106. if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
  107. err_sys("can't load ca file, Please run from CyaSSL home dir");
  108. #endif
  109. #else
  110. load_buffer(ctx, caCert, CYASSL_CA);
  111. #endif
  112. #ifdef VERIFY_CALLBACK
  113. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
  114. #endif
  115. if (argc == 3) {
  116. /* ./client server securePort */
  117. SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); /* TODO: add ca cert */
  118. /* this is just to allow easy testing of other servers */
  119. tcp_connect(&sockfd, argv[1], (short)atoi(argv[2]));
  120. }
  121. else if (argc == 1) {
  122. /* ./client // plain mode */
  123. /* for client cert authentication if server requests */
  124. #ifndef NO_FILESYSTEM
  125. if (SSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM)
  126. != SSL_SUCCESS)
  127. err_sys("can't load client cert file, "
  128. "Please run from CyaSSL home dir");
  129. if (SSL_CTX_use_PrivateKey_file(ctx, cliKey, SSL_FILETYPE_PEM)
  130. != SSL_SUCCESS)
  131. err_sys("can't load client key file, "
  132. "Please run from CyaSSL home dir");
  133. #else
  134. load_buffer(ctx, cliCert, CYASSL_CERT);
  135. load_buffer(ctx, cliKey, CYASSL_KEY);
  136. #endif
  137. tcp_connect(&sockfd, yasslIP, yasslPort);
  138. }
  139. else if (argc == 2) {
  140. /* time passed in number of connects give average */
  141. int times = atoi(argv[1]);
  142. int i = 0;
  143. double start = current_time(), avg;
  144. for (i = 0; i < times; i++) {
  145. tcp_connect(&sockfd, yasslIP, yasslPort);
  146. ssl = SSL_new(ctx);
  147. SSL_set_fd(ssl, sockfd);
  148. if (SSL_connect(ssl) != SSL_SUCCESS)
  149. err_sys("SSL_connect failed");
  150. SSL_shutdown(ssl);
  151. SSL_free(ssl);
  152. CloseSocket(sockfd);
  153. }
  154. avg = current_time() - start;
  155. avg /= times;
  156. avg *= 1000; /* milliseconds */
  157. printf("SSL_connect avg took:%6.3f milliseconds\n", avg);
  158. SSL_CTX_free(ctx);
  159. ((func_args*)args)->return_code = 0;
  160. return;
  161. }
  162. else
  163. err_sys("usage: ./client server securePort");
  164. ssl = SSL_new(ctx);
  165. SSL_set_fd(ssl, sockfd);
  166. if (argc != 3)
  167. CyaSSL_check_domain_name(ssl, "www.yassl.com");
  168. #ifdef NON_BLOCKING
  169. tcp_set_nonblocking(&sockfd);
  170. NonBlockingSSL_Connect(ssl);
  171. #else
  172. #ifndef CYASSL_CALLBACKS
  173. if (SSL_connect(ssl) != SSL_SUCCESS) { /* see note at top of README */
  174. int err = SSL_get_error(ssl, 0);
  175. char buffer[80];
  176. printf("err = %d, %s\n", err, ERR_error_string(err, buffer));
  177. err_sys("SSL_connect failed");/* if you're getting an error here */
  178. }
  179. #else
  180. timeout.tv_sec = 2;
  181. timeout.tv_usec = 0;
  182. NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */
  183. #endif
  184. #endif
  185. showPeer(ssl);
  186. if (argc == 3) {
  187. printf("SSL connect ok, sending GET...\n");
  188. msgSz = 28;
  189. strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
  190. }
  191. if (SSL_write(ssl, msg, msgSz) != msgSz)
  192. err_sys("SSL_write failed");
  193. input = SSL_read(ssl, reply, sizeof(reply));
  194. if (input > 0) {
  195. reply[input] = 0;
  196. printf("Server response: %s\n", reply);
  197. if (argc == 3) { /* get html */
  198. while (1) {
  199. input = SSL_read(ssl, reply, sizeof(reply));
  200. if (input > 0) {
  201. reply[input] = 0;
  202. printf("%s\n", reply);
  203. }
  204. else
  205. break;
  206. }
  207. }
  208. }
  209. #ifdef TEST_RESUME
  210. #ifdef CYASSL_DTLS
  211. strncpy(msg, "break", 6);
  212. msgSz = (int)strlen(msg);
  213. /* try to send session close */
  214. SSL_write(ssl, msg, msgSz);
  215. #endif
  216. session = SSL_get_session(ssl);
  217. sslResume = SSL_new(ctx);
  218. #endif
  219. SSL_shutdown(ssl);
  220. SSL_free(ssl);
  221. CloseSocket(sockfd);
  222. #ifdef TEST_RESUME
  223. #ifdef CYASSL_DTLS
  224. #ifdef USE_WINDOWS_API
  225. Sleep(500);
  226. #else
  227. sleep(1);
  228. #endif
  229. #endif
  230. if (argc == 3)
  231. tcp_connect(&sockfd, argv[1], (short)atoi(argv[2]));
  232. else
  233. tcp_connect(&sockfd, yasslIP, yasslPort);
  234. SSL_set_fd(sslResume, sockfd);
  235. SSL_set_session(sslResume, session);
  236. showPeer(sslResume);
  237. if (SSL_connect(sslResume) != SSL_SUCCESS) err_sys("SSL resume failed");
  238. #ifdef OPENSSL_EXTRA
  239. if (SSL_session_reused(sslResume))
  240. printf("reused session id\n");
  241. else
  242. printf("didn't reuse session id!!!\n");
  243. #endif
  244. if (SSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
  245. err_sys("SSL_write failed");
  246. input = SSL_read(sslResume, reply, sizeof(reply));
  247. if (input > 0) {
  248. reply[input] = 0;
  249. printf("Server resume response: %s\n", reply);
  250. }
  251. /* try to send session break */
  252. SSL_write(sslResume, msg, msgSz);
  253. SSL_shutdown(sslResume);
  254. SSL_free(sslResume);
  255. #endif /* TEST_RESUME */
  256. SSL_CTX_free(ctx);
  257. CloseSocket(sockfd);
  258. ((func_args*)args)->return_code = 0;
  259. }
  260. /* so overall tests can pull in test function */
  261. #ifndef NO_MAIN_DRIVER
  262. int main(int argc, char** argv)
  263. {
  264. func_args args;
  265. StartTCP();
  266. args.argc = argc;
  267. args.argv = argv;
  268. CyaSSL_Init();
  269. #ifdef DEBUG_CYASSL
  270. CyaSSL_Debugging_ON();
  271. #endif
  272. if (CurrentDir("client") || CurrentDir("build"))
  273. ChangeDirBack(2);
  274. client_test(&args);
  275. CyaSSL_Cleanup();
  276. return args.return_code;
  277. }
  278. #endif /* NO_MAIN_DRIVER */
  279. #ifdef CYASSL_CALLBACKS
  280. int handShakeCB(HandShakeInfo* info)
  281. {
  282. return 0;
  283. }
  284. int timeoutCB(TimeoutInfo* info)
  285. {
  286. return 0;
  287. }
  288. #endif