s_client.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. /* apps/s_client.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <assert.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #ifdef OPENSSL_NO_STDIO
  63. #define APPS_WIN16
  64. #endif
  65. /* With IPv6, it looks like Digital has mixed up the proper order of
  66. recursive header file inclusion, resulting in the compiler complaining
  67. that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
  68. is needed to have fileno() declared correctly... So let's define u_int */
  69. #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
  70. #define __U_INT
  71. typedef unsigned int u_int;
  72. #endif
  73. #define USE_SOCKETS
  74. #include "apps.h"
  75. #include <openssl/x509.h>
  76. #include <openssl/ssl.h>
  77. #include <openssl/err.h>
  78. #include <openssl/pem.h>
  79. #include <openssl/engine.h>
  80. #include "s_apps.h"
  81. #ifdef OPENSSL_SYS_WINDOWS
  82. #include <conio.h>
  83. #endif
  84. #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
  85. /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
  86. #undef FIONBIO
  87. #endif
  88. #undef PROG
  89. #define PROG s_client_main
  90. /*#define SSL_HOST_NAME "www.netscape.com" */
  91. /*#define SSL_HOST_NAME "193.118.187.102" */
  92. #define SSL_HOST_NAME "localhost"
  93. /*#define TEST_CERT "client.pem" */ /* no default cert. */
  94. #undef BUFSIZZ
  95. #define BUFSIZZ 1024*8
  96. extern int verify_depth;
  97. extern int verify_error;
  98. #ifdef FIONBIO
  99. static int c_nbio=0;
  100. #endif
  101. static int c_Pause=0;
  102. static int c_debug=0;
  103. static int c_showcerts=0;
  104. static void sc_usage(void);
  105. static void print_stuff(BIO *berr,SSL *con,int full);
  106. static BIO *bio_c_out=NULL;
  107. static int c_quiet=0;
  108. static int c_ign_eof=0;
  109. static void sc_usage(void)
  110. {
  111. BIO_printf(bio_err,"usage: s_client args\n");
  112. BIO_printf(bio_err,"\n");
  113. BIO_printf(bio_err," -host host - use -connect instead\n");
  114. BIO_printf(bio_err," -port port - use -connect instead\n");
  115. BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
  116. BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n");
  117. BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n");
  118. BIO_printf(bio_err," -key arg - Private key file to use, PEM format assumed, in cert file if\n");
  119. BIO_printf(bio_err," not specified but cert file is.\n");
  120. BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
  121. BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
  122. BIO_printf(bio_err," -reconnect - Drop and re-make the connection with the same Session-ID\n");
  123. BIO_printf(bio_err," -pause - sleep(1) after each read(2) and write(2) system call\n");
  124. BIO_printf(bio_err," -showcerts - show all certificates in the chain\n");
  125. BIO_printf(bio_err," -debug - extra output\n");
  126. BIO_printf(bio_err," -nbio_test - more ssl protocol testing\n");
  127. BIO_printf(bio_err," -state - print the 'ssl' states\n");
  128. #ifdef FIONBIO
  129. BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
  130. #endif
  131. BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n");
  132. BIO_printf(bio_err," -quiet - no s_client output\n");
  133. BIO_printf(bio_err," -ign_eof - ignore input eof (default when -quiet)\n");
  134. BIO_printf(bio_err," -ssl2 - just use SSLv2\n");
  135. BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
  136. BIO_printf(bio_err," -tls1 - just use TLSv1\n");
  137. BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
  138. BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
  139. BIO_printf(bio_err," -serverpref - Use server's cipher preferences (only SSLv2)\n");
  140. BIO_printf(bio_err," -cipher - preferred cipher to use, use the 'openssl ciphers'\n");
  141. BIO_printf(bio_err," command to see what is available\n");
  142. BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n");
  143. BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
  144. }
  145. int MAIN(int, char **);
  146. int MAIN(int argc, char **argv)
  147. {
  148. int off=0;
  149. SSL *con=NULL,*con2=NULL;
  150. int s,k,width,state=0;
  151. char *cbuf=NULL,*sbuf=NULL;
  152. int cbuf_len,cbuf_off;
  153. int sbuf_len,sbuf_off;
  154. fd_set readfds,writefds;
  155. short port=PORT;
  156. int full_log=1;
  157. char *host=SSL_HOST_NAME;
  158. char *cert_file=NULL,*key_file=NULL;
  159. char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
  160. int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
  161. int crlf=0;
  162. int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
  163. SSL_CTX *ctx=NULL;
  164. int ret=1,in_init=1,i,nbio_test=0;
  165. int prexit = 0;
  166. SSL_METHOD *meth=NULL;
  167. BIO *sbio;
  168. char *inrand=NULL;
  169. char *engine_id=NULL;
  170. ENGINE *e=NULL;
  171. #ifdef OPENSSL_SYS_WINDOWS
  172. struct timeval tv;
  173. #endif
  174. #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
  175. meth=SSLv23_client_method();
  176. #elif !defined(OPENSSL_NO_SSL3)
  177. meth=SSLv3_client_method();
  178. #elif !defined(OPENSSL_NO_SSL2)
  179. meth=SSLv2_client_method();
  180. #endif
  181. apps_startup();
  182. c_Pause=0;
  183. c_quiet=0;
  184. c_ign_eof=0;
  185. c_debug=0;
  186. c_showcerts=0;
  187. if (bio_err == NULL)
  188. bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
  189. if ( ((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
  190. ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
  191. {
  192. BIO_printf(bio_err,"out of memory\n");
  193. goto end;
  194. }
  195. verify_depth=0;
  196. verify_error=X509_V_OK;
  197. #ifdef FIONBIO
  198. c_nbio=0;
  199. #endif
  200. argc--;
  201. argv++;
  202. while (argc >= 1)
  203. {
  204. if (strcmp(*argv,"-host") == 0)
  205. {
  206. if (--argc < 1) goto bad;
  207. host= *(++argv);
  208. }
  209. else if (strcmp(*argv,"-port") == 0)
  210. {
  211. if (--argc < 1) goto bad;
  212. port=atoi(*(++argv));
  213. if (port == 0) goto bad;
  214. }
  215. else if (strcmp(*argv,"-connect") == 0)
  216. {
  217. if (--argc < 1) goto bad;
  218. if (!extract_host_port(*(++argv),&host,NULL,&port))
  219. goto bad;
  220. }
  221. else if (strcmp(*argv,"-verify") == 0)
  222. {
  223. verify=SSL_VERIFY_PEER;
  224. if (--argc < 1) goto bad;
  225. verify_depth=atoi(*(++argv));
  226. BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
  227. }
  228. else if (strcmp(*argv,"-cert") == 0)
  229. {
  230. if (--argc < 1) goto bad;
  231. cert_file= *(++argv);
  232. }
  233. else if (strcmp(*argv,"-prexit") == 0)
  234. prexit=1;
  235. else if (strcmp(*argv,"-crlf") == 0)
  236. crlf=1;
  237. else if (strcmp(*argv,"-quiet") == 0)
  238. {
  239. c_quiet=1;
  240. c_ign_eof=1;
  241. }
  242. else if (strcmp(*argv,"-ign_eof") == 0)
  243. c_ign_eof=1;
  244. else if (strcmp(*argv,"-pause") == 0)
  245. c_Pause=1;
  246. else if (strcmp(*argv,"-debug") == 0)
  247. c_debug=1;
  248. else if (strcmp(*argv,"-showcerts") == 0)
  249. c_showcerts=1;
  250. else if (strcmp(*argv,"-nbio_test") == 0)
  251. nbio_test=1;
  252. else if (strcmp(*argv,"-state") == 0)
  253. state=1;
  254. #ifndef OPENSSL_NO_SSL2
  255. else if (strcmp(*argv,"-ssl2") == 0)
  256. meth=SSLv2_client_method();
  257. #endif
  258. #ifndef OPENSSL_NO_SSL3
  259. else if (strcmp(*argv,"-ssl3") == 0)
  260. meth=SSLv3_client_method();
  261. #endif
  262. #ifndef OPENSSL_NO_TLS1
  263. else if (strcmp(*argv,"-tls1") == 0)
  264. meth=TLSv1_client_method();
  265. #endif
  266. else if (strcmp(*argv,"-bugs") == 0)
  267. bugs=1;
  268. else if (strcmp(*argv,"-key") == 0)
  269. {
  270. if (--argc < 1) goto bad;
  271. key_file= *(++argv);
  272. }
  273. else if (strcmp(*argv,"-reconnect") == 0)
  274. {
  275. reconnect=5;
  276. }
  277. else if (strcmp(*argv,"-CApath") == 0)
  278. {
  279. if (--argc < 1) goto bad;
  280. CApath= *(++argv);
  281. }
  282. else if (strcmp(*argv,"-CAfile") == 0)
  283. {
  284. if (--argc < 1) goto bad;
  285. CAfile= *(++argv);
  286. }
  287. else if (strcmp(*argv,"-no_tls1") == 0)
  288. off|=SSL_OP_NO_TLSv1;
  289. else if (strcmp(*argv,"-no_ssl3") == 0)
  290. off|=SSL_OP_NO_SSLv3;
  291. else if (strcmp(*argv,"-no_ssl2") == 0)
  292. off|=SSL_OP_NO_SSLv2;
  293. else if (strcmp(*argv,"-serverpref") == 0)
  294. off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
  295. else if (strcmp(*argv,"-cipher") == 0)
  296. {
  297. if (--argc < 1) goto bad;
  298. cipher= *(++argv);
  299. }
  300. #ifdef FIONBIO
  301. else if (strcmp(*argv,"-nbio") == 0)
  302. { c_nbio=1; }
  303. #endif
  304. else if (strcmp(*argv,"-engine") == 0)
  305. {
  306. if (--argc < 1) goto bad;
  307. engine_id = *(++argv);
  308. }
  309. else if (strcmp(*argv,"-rand") == 0)
  310. {
  311. if (--argc < 1) goto bad;
  312. inrand= *(++argv);
  313. }
  314. else
  315. {
  316. BIO_printf(bio_err,"unknown option %s\n",*argv);
  317. badop=1;
  318. break;
  319. }
  320. argc--;
  321. argv++;
  322. }
  323. if (badop)
  324. {
  325. bad:
  326. sc_usage();
  327. goto end;
  328. }
  329. if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
  330. && !RAND_status())
  331. {
  332. BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
  333. }
  334. if (inrand != NULL)
  335. BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
  336. app_RAND_load_files(inrand));
  337. if (bio_c_out == NULL)
  338. {
  339. if (c_quiet)
  340. {
  341. bio_c_out=BIO_new(BIO_s_null());
  342. }
  343. else
  344. {
  345. if (bio_c_out == NULL)
  346. bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
  347. }
  348. }
  349. OpenSSL_add_ssl_algorithms();
  350. SSL_load_error_strings();
  351. if (engine_id != NULL)
  352. {
  353. if((e = ENGINE_by_id(engine_id)) == NULL)
  354. {
  355. BIO_printf(bio_err,"invalid engine\n");
  356. ERR_print_errors(bio_err);
  357. goto end;
  358. }
  359. if (c_debug)
  360. {
  361. ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
  362. 0, bio_err, 0);
  363. }
  364. if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
  365. {
  366. BIO_printf(bio_err,"can't use that engine\n");
  367. ERR_print_errors(bio_err);
  368. goto end;
  369. }
  370. BIO_printf(bio_err,"engine \"%s\" set.\n", engine_id);
  371. ENGINE_free(e);
  372. }
  373. ctx=SSL_CTX_new(meth);
  374. if (ctx == NULL)
  375. {
  376. ERR_print_errors(bio_err);
  377. goto end;
  378. }
  379. if (bugs)
  380. SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
  381. else
  382. SSL_CTX_set_options(ctx,off);
  383. if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
  384. if (cipher != NULL)
  385. if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
  386. BIO_printf(bio_err,"error setting cipher list\n");
  387. ERR_print_errors(bio_err);
  388. goto end;
  389. }
  390. #if 0
  391. else
  392. SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
  393. #endif
  394. SSL_CTX_set_verify(ctx,verify,verify_callback);
  395. if (!set_cert_stuff(ctx,cert_file,key_file))
  396. goto end;
  397. if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
  398. (!SSL_CTX_set_default_verify_paths(ctx)))
  399. {
  400. /* BIO_printf(bio_err,"error setting default verify locations\n"); */
  401. ERR_print_errors(bio_err);
  402. /* goto end; */
  403. }
  404. con=SSL_new(ctx);
  405. #ifndef OPENSSL_NO_KRB5
  406. if (con && (con->kssl_ctx = kssl_ctx_new()) != NULL)
  407. {
  408. kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
  409. }
  410. #endif /* OPENSSL_NO_KRB5 */
  411. /* SSL_set_cipher_list(con,"RC4-MD5"); */
  412. re_start:
  413. if (init_client(&s,host,port) == 0)
  414. {
  415. BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
  416. SHUTDOWN(s);
  417. goto end;
  418. }
  419. BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
  420. #ifdef FIONBIO
  421. if (c_nbio)
  422. {
  423. unsigned long l=1;
  424. BIO_printf(bio_c_out,"turning on non blocking io\n");
  425. if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
  426. {
  427. ERR_print_errors(bio_err);
  428. goto end;
  429. }
  430. }
  431. #endif
  432. if (c_Pause & 0x01) con->debug=1;
  433. sbio=BIO_new_socket(s,BIO_NOCLOSE);
  434. if (nbio_test)
  435. {
  436. BIO *test;
  437. test=BIO_new(BIO_f_nbio_test());
  438. sbio=BIO_push(test,sbio);
  439. }
  440. if (c_debug)
  441. {
  442. con->debug=1;
  443. BIO_set_callback(sbio,bio_dump_cb);
  444. BIO_set_callback_arg(sbio,bio_c_out);
  445. }
  446. SSL_set_bio(con,sbio,sbio);
  447. SSL_set_connect_state(con);
  448. /* ok, lets connect */
  449. width=SSL_get_fd(con)+1;
  450. read_tty=1;
  451. write_tty=0;
  452. tty_on=0;
  453. read_ssl=1;
  454. write_ssl=1;
  455. cbuf_len=0;
  456. cbuf_off=0;
  457. sbuf_len=0;
  458. sbuf_off=0;
  459. for (;;)
  460. {
  461. FD_ZERO(&readfds);
  462. FD_ZERO(&writefds);
  463. if (SSL_in_init(con) && !SSL_total_renegotiations(con))
  464. {
  465. in_init=1;
  466. tty_on=0;
  467. }
  468. else
  469. {
  470. tty_on=1;
  471. if (in_init)
  472. {
  473. in_init=0;
  474. print_stuff(bio_c_out,con,full_log);
  475. if (full_log > 0) full_log--;
  476. if (reconnect)
  477. {
  478. reconnect--;
  479. BIO_printf(bio_c_out,"drop connection and then reconnect\n");
  480. SSL_shutdown(con);
  481. SSL_set_connect_state(con);
  482. SHUTDOWN(SSL_get_fd(con));
  483. goto re_start;
  484. }
  485. }
  486. }
  487. ssl_pending = read_ssl && SSL_pending(con);
  488. if (!ssl_pending)
  489. {
  490. #ifndef OPENSSL_SYS_WINDOWS
  491. if (tty_on)
  492. {
  493. if (read_tty) FD_SET(fileno(stdin),&readfds);
  494. if (write_tty) FD_SET(fileno(stdout),&writefds);
  495. }
  496. if (read_ssl)
  497. FD_SET(SSL_get_fd(con),&readfds);
  498. if (write_ssl)
  499. FD_SET(SSL_get_fd(con),&writefds);
  500. #else
  501. if(!tty_on || !write_tty) {
  502. if (read_ssl)
  503. FD_SET(SSL_get_fd(con),&readfds);
  504. if (write_ssl)
  505. FD_SET(SSL_get_fd(con),&writefds);
  506. }
  507. #endif
  508. /* printf("mode tty(%d %d%d) ssl(%d%d)\n",
  509. tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
  510. /* Note: under VMS with SOCKETSHR the second parameter
  511. * is currently of type (int *) whereas under other
  512. * systems it is (void *) if you don't have a cast it
  513. * will choke the compiler: if you do have a cast then
  514. * you can either go for (int *) or (void *).
  515. */
  516. #ifdef OPENSSL_SYS_WINDOWS
  517. /* Under Windows we make the assumption that we can
  518. * always write to the tty: therefore if we need to
  519. * write to the tty we just fall through. Otherwise
  520. * we timeout the select every second and see if there
  521. * are any keypresses. Note: this is a hack, in a proper
  522. * Windows application we wouldn't do this.
  523. */
  524. i=0;
  525. if(!write_tty) {
  526. if(read_tty) {
  527. tv.tv_sec = 1;
  528. tv.tv_usec = 0;
  529. i=select(width,(void *)&readfds,(void *)&writefds,
  530. NULL,&tv);
  531. if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
  532. } else i=select(width,(void *)&readfds,(void *)&writefds,
  533. NULL,NULL);
  534. }
  535. #else
  536. i=select(width,(void *)&readfds,(void *)&writefds,
  537. NULL,NULL);
  538. #endif
  539. if ( i < 0)
  540. {
  541. BIO_printf(bio_err,"bad select %d\n",
  542. get_last_socket_error());
  543. goto shut;
  544. /* goto end; */
  545. }
  546. }
  547. if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
  548. {
  549. k=SSL_write(con,&(cbuf[cbuf_off]),
  550. (unsigned int)cbuf_len);
  551. switch (SSL_get_error(con,k))
  552. {
  553. case SSL_ERROR_NONE:
  554. cbuf_off+=k;
  555. cbuf_len-=k;
  556. if (k <= 0) goto end;
  557. /* we have done a write(con,NULL,0); */
  558. if (cbuf_len <= 0)
  559. {
  560. read_tty=1;
  561. write_ssl=0;
  562. }
  563. else /* if (cbuf_len > 0) */
  564. {
  565. read_tty=0;
  566. write_ssl=1;
  567. }
  568. break;
  569. case SSL_ERROR_WANT_WRITE:
  570. BIO_printf(bio_c_out,"write W BLOCK\n");
  571. write_ssl=1;
  572. read_tty=0;
  573. break;
  574. case SSL_ERROR_WANT_READ:
  575. BIO_printf(bio_c_out,"write R BLOCK\n");
  576. write_tty=0;
  577. read_ssl=1;
  578. write_ssl=0;
  579. break;
  580. case SSL_ERROR_WANT_X509_LOOKUP:
  581. BIO_printf(bio_c_out,"write X BLOCK\n");
  582. break;
  583. case SSL_ERROR_ZERO_RETURN:
  584. if (cbuf_len != 0)
  585. {
  586. BIO_printf(bio_c_out,"shutdown\n");
  587. goto shut;
  588. }
  589. else
  590. {
  591. read_tty=1;
  592. write_ssl=0;
  593. break;
  594. }
  595. case SSL_ERROR_SYSCALL:
  596. if ((k != 0) || (cbuf_len != 0))
  597. {
  598. BIO_printf(bio_err,"write:errno=%d\n",
  599. get_last_socket_error());
  600. goto shut;
  601. }
  602. else
  603. {
  604. read_tty=1;
  605. write_ssl=0;
  606. }
  607. break;
  608. case SSL_ERROR_SSL:
  609. ERR_print_errors(bio_err);
  610. goto shut;
  611. }
  612. }
  613. #ifdef OPENSSL_SYS_WINDOWS
  614. /* Assume Windows can always write */
  615. else if (!ssl_pending && write_tty)
  616. #else
  617. else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
  618. #endif
  619. {
  620. #ifdef CHARSET_EBCDIC
  621. ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
  622. #endif
  623. i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
  624. if (i <= 0)
  625. {
  626. BIO_printf(bio_c_out,"DONE\n");
  627. goto shut;
  628. /* goto end; */
  629. }
  630. sbuf_len-=i;;
  631. sbuf_off+=i;
  632. if (sbuf_len <= 0)
  633. {
  634. read_ssl=1;
  635. write_tty=0;
  636. }
  637. }
  638. else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
  639. {
  640. #ifdef RENEG
  641. { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
  642. #endif
  643. #if 1
  644. k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
  645. #else
  646. /* Demo for pending and peek :-) */
  647. k=SSL_read(con,sbuf,16);
  648. { char zbuf[10240];
  649. printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
  650. }
  651. #endif
  652. switch (SSL_get_error(con,k))
  653. {
  654. case SSL_ERROR_NONE:
  655. if (k <= 0)
  656. goto end;
  657. sbuf_off=0;
  658. sbuf_len=k;
  659. read_ssl=0;
  660. write_tty=1;
  661. break;
  662. case SSL_ERROR_WANT_WRITE:
  663. BIO_printf(bio_c_out,"read W BLOCK\n");
  664. write_ssl=1;
  665. read_tty=0;
  666. break;
  667. case SSL_ERROR_WANT_READ:
  668. BIO_printf(bio_c_out,"read R BLOCK\n");
  669. write_tty=0;
  670. read_ssl=1;
  671. if ((read_tty == 0) && (write_ssl == 0))
  672. write_ssl=1;
  673. break;
  674. case SSL_ERROR_WANT_X509_LOOKUP:
  675. BIO_printf(bio_c_out,"read X BLOCK\n");
  676. break;
  677. case SSL_ERROR_SYSCALL:
  678. BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
  679. goto shut;
  680. case SSL_ERROR_ZERO_RETURN:
  681. BIO_printf(bio_c_out,"closed\n");
  682. goto shut;
  683. case SSL_ERROR_SSL:
  684. ERR_print_errors(bio_err);
  685. goto shut;
  686. /* break; */
  687. }
  688. }
  689. #ifdef OPENSSL_SYS_WINDOWS
  690. else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
  691. #else
  692. else if (FD_ISSET(fileno(stdin),&readfds))
  693. #endif
  694. {
  695. if (crlf)
  696. {
  697. int j, lf_num;
  698. i=read(fileno(stdin),cbuf,BUFSIZZ/2);
  699. lf_num = 0;
  700. /* both loops are skipped when i <= 0 */
  701. for (j = 0; j < i; j++)
  702. if (cbuf[j] == '\n')
  703. lf_num++;
  704. for (j = i-1; j >= 0; j--)
  705. {
  706. cbuf[j+lf_num] = cbuf[j];
  707. if (cbuf[j] == '\n')
  708. {
  709. lf_num--;
  710. i++;
  711. cbuf[j+lf_num] = '\r';
  712. }
  713. }
  714. assert(lf_num == 0);
  715. }
  716. else
  717. i=read(fileno(stdin),cbuf,BUFSIZZ);
  718. if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
  719. {
  720. BIO_printf(bio_err,"DONE\n");
  721. goto shut;
  722. }
  723. if ((!c_ign_eof) && (cbuf[0] == 'R'))
  724. {
  725. BIO_printf(bio_err,"RENEGOTIATING\n");
  726. SSL_renegotiate(con);
  727. cbuf_len=0;
  728. }
  729. else
  730. {
  731. cbuf_len=i;
  732. cbuf_off=0;
  733. #ifdef CHARSET_EBCDIC
  734. ebcdic2ascii(cbuf, cbuf, i);
  735. #endif
  736. }
  737. write_ssl=1;
  738. read_tty=0;
  739. }
  740. }
  741. shut:
  742. SSL_shutdown(con);
  743. SHUTDOWN(SSL_get_fd(con));
  744. ret=0;
  745. end:
  746. if(prexit) print_stuff(bio_c_out,con,1);
  747. if (con != NULL) SSL_free(con);
  748. if (con2 != NULL) SSL_free(con2);
  749. if (ctx != NULL) SSL_CTX_free(ctx);
  750. if (cbuf != NULL) { memset(cbuf,0,BUFSIZZ); OPENSSL_free(cbuf); }
  751. if (sbuf != NULL) { memset(sbuf,0,BUFSIZZ); OPENSSL_free(sbuf); }
  752. if (bio_c_out != NULL)
  753. {
  754. BIO_free(bio_c_out);
  755. bio_c_out=NULL;
  756. }
  757. EXIT(ret);
  758. }
  759. static void print_stuff(BIO *bio, SSL *s, int full)
  760. {
  761. X509 *peer=NULL;
  762. char *p;
  763. static char *space=" ";
  764. char buf[BUFSIZ];
  765. STACK_OF(X509) *sk;
  766. STACK_OF(X509_NAME) *sk2;
  767. SSL_CIPHER *c;
  768. X509_NAME *xn;
  769. int j,i;
  770. if (full)
  771. {
  772. int got_a_chain = 0;
  773. sk=SSL_get_peer_cert_chain(s);
  774. if (sk != NULL)
  775. {
  776. got_a_chain = 1; /* we don't have it for SSL2 (yet) */
  777. BIO_printf(bio,"---\nCertificate chain\n");
  778. for (i=0; i<sk_X509_num(sk); i++)
  779. {
  780. X509_NAME_oneline(X509_get_subject_name(
  781. sk_X509_value(sk,i)),buf,BUFSIZ);
  782. BIO_printf(bio,"%2d s:%s\n",i,buf);
  783. X509_NAME_oneline(X509_get_issuer_name(
  784. sk_X509_value(sk,i)),buf,BUFSIZ);
  785. BIO_printf(bio," i:%s\n",buf);
  786. if (c_showcerts)
  787. PEM_write_bio_X509(bio,sk_X509_value(sk,i));
  788. }
  789. }
  790. BIO_printf(bio,"---\n");
  791. peer=SSL_get_peer_certificate(s);
  792. if (peer != NULL)
  793. {
  794. BIO_printf(bio,"Server certificate\n");
  795. if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
  796. PEM_write_bio_X509(bio,peer);
  797. X509_NAME_oneline(X509_get_subject_name(peer),
  798. buf,BUFSIZ);
  799. BIO_printf(bio,"subject=%s\n",buf);
  800. X509_NAME_oneline(X509_get_issuer_name(peer),
  801. buf,BUFSIZ);
  802. BIO_printf(bio,"issuer=%s\n",buf);
  803. }
  804. else
  805. BIO_printf(bio,"no peer certificate available\n");
  806. sk2=SSL_get_client_CA_list(s);
  807. if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
  808. {
  809. BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
  810. for (i=0; i<sk_X509_NAME_num(sk2); i++)
  811. {
  812. xn=sk_X509_NAME_value(sk2,i);
  813. X509_NAME_oneline(xn,buf,sizeof(buf));
  814. BIO_write(bio,buf,strlen(buf));
  815. BIO_write(bio,"\n",1);
  816. }
  817. }
  818. else
  819. {
  820. BIO_printf(bio,"---\nNo client certificate CA names sent\n");
  821. }
  822. p=SSL_get_shared_ciphers(s,buf,BUFSIZ);
  823. if (p != NULL)
  824. {
  825. /* This works only for SSL 2. In later protocol
  826. * versions, the client does not know what other
  827. * ciphers (in addition to the one to be used
  828. * in the current connection) the server supports. */
  829. BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
  830. j=i=0;
  831. while (*p)
  832. {
  833. if (*p == ':')
  834. {
  835. BIO_write(bio,space,15-j%25);
  836. i++;
  837. j=0;
  838. BIO_write(bio,((i%3)?" ":"\n"),1);
  839. }
  840. else
  841. {
  842. BIO_write(bio,p,1);
  843. j++;
  844. }
  845. p++;
  846. }
  847. BIO_write(bio,"\n",1);
  848. }
  849. BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
  850. BIO_number_read(SSL_get_rbio(s)),
  851. BIO_number_written(SSL_get_wbio(s)));
  852. }
  853. BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
  854. c=SSL_get_current_cipher(s);
  855. BIO_printf(bio,"%s, Cipher is %s\n",
  856. SSL_CIPHER_get_version(c),
  857. SSL_CIPHER_get_name(c));
  858. if (peer != NULL) {
  859. EVP_PKEY *pktmp;
  860. pktmp = X509_get_pubkey(peer);
  861. BIO_printf(bio,"Server public key is %d bit\n",
  862. EVP_PKEY_bits(pktmp));
  863. EVP_PKEY_free(pktmp);
  864. }
  865. SSL_SESSION_print(bio,SSL_get_session(s));
  866. BIO_printf(bio,"---\n");
  867. if (peer != NULL)
  868. X509_free(peer);
  869. }