Annotation of embedaddon/axTLS/samples/c/axssl.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (c) 2007, Cameron Rich
3: *
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions are met:
8: *
9: * * Redistributions of source code must retain the above copyright notice,
10: * this list of conditions and the following disclaimer.
11: * * Redistributions in binary form must reproduce the above copyright notice,
12: * this list of conditions and the following disclaimer in the documentation
13: * and/or other materials provided with the distribution.
14: * * Neither the name of the axTLS project nor the names of its contributors
15: * may be used to endorse or promote products derived from this software
16: * without specific prior written permission.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29: */
30:
31: /**
32: * Demonstrate the use of the axTLS library in C with a set of
33: * command-line parameters similar to openssl. In fact, openssl clients
34: * should be able to communicate with axTLS servers and visa-versa.
35: *
36: * This code has various bits enabled depending on the configuration. To enable
37: * the most interesting version, compile with the 'full mode' enabled.
38: *
39: * To see what options you have, run the following:
40: * > axssl s_server -?
41: * > axssl s_client -?
42: *
43: * The axtls shared library must be in the same directory or be found
44: * by the OS.
45: */
46: #include <string.h>
47: #include <stdio.h>
48: #include <stdlib.h>
49: #include <signal.h>
50: #include "os_port.h"
51: #include "ssl.h"
52:
53: /* define standard input */
54: #ifndef STDIN_FILENO
55: #define STDIN_FILENO 0
56: #endif
57:
58: static void do_server(int argc, char *argv[]);
59: static void print_options(char *option);
60: static void print_server_options(char *option);
61: static void do_client(int argc, char *argv[]);
62: static void print_client_options(char *option);
63: static void display_cipher(SSL *ssl);
64: static void display_session_id(SSL *ssl);
65:
66: /**
67: * Main entry point. Doesn't do much except works out whether we are a client
68: * or a server.
69: */
70: int main(int argc, char *argv[])
71: {
72: #ifdef WIN32
73: WSADATA wsaData;
74: WORD wVersionRequested = MAKEWORD(2, 2);
75: WSAStartup(wVersionRequested, &wsaData);
76: #elif !defined(CONFIG_PLATFORM_SOLARIS)
77: signal(SIGPIPE, SIG_IGN); /* ignore pipe errors */
78: #endif
79:
80: if (argc == 2 && strcmp(argv[1], "version") == 0)
81: {
82: printf("axssl %s %s\n", ssl_version(), __DATE__);
83: exit(0);
84: }
85:
86: if (argc < 2 || (
87: strcmp(argv[1], "s_server") && strcmp(argv[1], "s_client")))
88: print_options(argc > 1 ? argv[1] : "");
89:
90: strcmp(argv[1], "s_server") ?
91: do_client(argc, argv) : do_server(argc, argv);
92: return 0;
93: }
94:
95: /**
96: * Implement the SSL server logic.
97: */
98: static void do_server(int argc, char *argv[])
99: {
100: int i = 2;
101: uint16_t port = 4433;
102: uint32_t options = SSL_DISPLAY_CERTS;
103: int client_fd;
104: SSL_CTX *ssl_ctx;
105: int server_fd, res = 0;
106: socklen_t client_len;
107: #ifndef CONFIG_SSL_SKELETON_MODE
108: char *private_key_file = NULL;
109: const char *password = NULL;
110: char **cert;
111: int cert_index = 0;
112: int cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET);
113: #endif
114: #ifdef WIN32
115: char yes = 1;
116: #else
117: int yes = 1;
118: #endif
119: struct sockaddr_in serv_addr;
120: struct sockaddr_in client_addr;
121: int quiet = 0;
122: #ifdef CONFIG_SSL_CERT_VERIFICATION
123: int ca_cert_index = 0;
124: int ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET);
125: char **ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size);
126: #endif
127: fd_set read_set;
128:
129: #ifndef CONFIG_SSL_SKELETON_MODE
130: cert = (char **)calloc(1, sizeof(char *)*cert_size);
131: #endif
132:
133: while (i < argc)
134: {
135: if (strcmp(argv[i], "-accept") == 0)
136: {
137: if (i >= argc-1)
138: {
139: print_server_options(argv[i]);
140: }
141:
142: port = atoi(argv[++i]);
143: }
144: #ifndef CONFIG_SSL_SKELETON_MODE
145: else if (strcmp(argv[i], "-cert") == 0)
146: {
147: if (i >= argc-1 || cert_index >= cert_size)
148: {
149: print_server_options(argv[i]);
150: }
151:
152: cert[cert_index++] = argv[++i];
153: }
154: else if (strcmp(argv[i], "-key") == 0)
155: {
156: if (i >= argc-1)
157: {
158: print_server_options(argv[i]);
159: }
160:
161: private_key_file = argv[++i];
162: options |= SSL_NO_DEFAULT_KEY;
163: }
164: else if (strcmp(argv[i], "-pass") == 0)
165: {
166: if (i >= argc-1)
167: {
168: print_server_options(argv[i]);
169: }
170:
171: password = argv[++i];
172: }
173: #endif
174: else if (strcmp(argv[i], "-quiet") == 0)
175: {
176: quiet = 1;
177: options &= ~SSL_DISPLAY_CERTS;
178: }
179: #ifdef CONFIG_SSL_CERT_VERIFICATION
180: else if (strcmp(argv[i], "-verify") == 0)
181: {
182: options |= SSL_CLIENT_AUTHENTICATION;
183: }
184: else if (strcmp(argv[i], "-CAfile") == 0)
185: {
186: if (i >= argc-1 || ca_cert_index >= ca_cert_size)
187: {
188: print_server_options(argv[i]);
189: }
190:
191: ca_cert[ca_cert_index++] = argv[++i];
192: }
193: #endif
194: #ifdef CONFIG_SSL_FULL_MODE
195: else if (strcmp(argv[i], "-debug") == 0)
196: {
197: options |= SSL_DISPLAY_BYTES;
198: }
199: else if (strcmp(argv[i], "-state") == 0)
200: {
201: options |= SSL_DISPLAY_STATES;
202: }
203: else if (strcmp(argv[i], "-show-rsa") == 0)
204: {
205: options |= SSL_DISPLAY_RSA;
206: }
207: #endif
208: else /* don't know what this is */
209: {
210: print_server_options(argv[i]);
211: }
212:
213: i++;
214: }
215:
216: if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_SVR_SESS)) == NULL)
217: {
218: fprintf(stderr, "Error: Server context is invalid\n");
219: exit(1);
220: }
221:
222: #ifndef CONFIG_SSL_SKELETON_MODE
223: if (private_key_file)
224: {
225: int obj_type = SSL_OBJ_RSA_KEY;
226:
227: /* auto-detect the key type from the file extension */
228: if (strstr(private_key_file, ".p8"))
229: obj_type = SSL_OBJ_PKCS8;
230: else if (strstr(private_key_file, ".p12"))
231: obj_type = SSL_OBJ_PKCS12;
232:
233: if (ssl_obj_load(ssl_ctx, obj_type, private_key_file, password))
234: {
235: fprintf(stderr, "Error: Private key '%s' is undefined.\n",
236: private_key_file);
237: exit(1);
238: }
239: }
240:
241: for (i = 0; i < cert_index; i++)
242: {
243: if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL))
244: {
245: printf("Certificate '%s' is undefined.\n", cert[i]);
246: exit(1);
247: }
248: }
249: #endif
250:
251: #ifdef CONFIG_SSL_CERT_VERIFICATION
252: for (i = 0; i < ca_cert_index; i++)
253: {
254: if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL))
255: {
256: printf("Certificate '%s' is undefined.\n", ca_cert[i]);
257: exit(1);
258: }
259: }
260:
261: free(ca_cert);
262: #endif
263: #ifndef CONFIG_SSL_SKELETON_MODE
264: free(cert);
265: #endif
266:
267: /* Create socket for incoming connections */
268: if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
269: {
270: perror("socket");
271: return;
272: }
273:
274: setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
275:
276: /* Construct local address structure */
277: memset(&serv_addr, 0, sizeof(serv_addr)); /* Zero out structure */
278: serv_addr.sin_family = AF_INET; /* Internet address family */
279: serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
280: serv_addr.sin_port = htons(port); /* Local port */
281:
282: /* Bind to the local address */
283: if (bind(server_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
284: {
285: perror("bind");
286: exit(1);
287: }
288:
289: if (listen(server_fd, 5) < 0)
290: {
291: perror("listen");
292: exit(1);
293: }
294:
295: client_len = sizeof(client_addr);
296:
297: /*************************************************************************
298: * This is where the interesting stuff happens. Up until now we've
299: * just been setting up sockets etc. Now we do the SSL handshake.
300: *************************************************************************/
301: for (;;)
302: {
303: SSL *ssl;
304: int reconnected = 0;
305:
306: if (!quiet)
307: {
308: printf("ACCEPT\n");
309: TTY_FLUSH();
310: }
311:
312: if ((client_fd = accept(server_fd,
313: (struct sockaddr *)&client_addr, &client_len)) < 0)
314: {
315: break;
316: }
317:
318: ssl = ssl_server_new(ssl_ctx, client_fd);
319:
320: /* now read (and display) whatever the client sends us */
321: for (;;)
322: {
323: /* allow parallel reading of client and standard input */
324: FD_ZERO(&read_set);
325: FD_SET(client_fd, &read_set);
326:
327: #ifndef WIN32
328: /* win32 doesn't like mixing up stdin and sockets */
329: if (isatty(STDIN_FILENO))/* but only if we are in an active shell */
330: {
331: FD_SET(STDIN_FILENO, &read_set);
332: }
333:
334: if ((res = select(client_fd+1, &read_set, NULL, NULL, NULL)) > 0)
335: {
336: uint8_t buf[1024];
337:
338: /* read standard input? */
339: if (FD_ISSET(STDIN_FILENO, &read_set))
340: {
341: if (fgets((char *)buf, sizeof(buf), stdin) == NULL)
342: {
343: res = SSL_ERROR_CONN_LOST;
344: }
345: else
346: {
347: /* small hack to check renegotiation */
348: if (buf[0] == 'r' && (buf[1] == '\n' || buf[1] == '\r'))
349: {
350: res = ssl_renegotiate(ssl);
351: }
352: else /* write our ramblings to the client */
353: {
354: res = ssl_write(ssl, buf, strlen((char *)buf)+1);
355: }
356: }
357: }
358: else /* a socket read */
359: #endif
360: {
361: /* keep reading until we get something interesting */
362: uint8_t *read_buf;
363:
364: if ((res = ssl_read(ssl, &read_buf)) == SSL_OK)
365: {
366: /* are we in the middle of doing a handshake? */
367: if (ssl_handshake_status(ssl) != SSL_OK)
368: {
369: reconnected = 0;
370: }
371: else if (!reconnected)
372: {
373: /* we are connected/reconnected */
374: if (!quiet)
375: {
376: display_session_id(ssl);
377: display_cipher(ssl);
378: }
379:
380: reconnected = 1;
381: }
382: }
383:
384: if (res > SSL_OK) /* display our interesting output */
385: {
386: printf("%s", read_buf);
387: TTY_FLUSH();
388: }
389: else if (res == SSL_CLOSE_NOTIFY)
390: {
391: printf("shutting down SSL\n");
392: TTY_FLUSH();
393: }
394: else if (res < SSL_OK && !quiet)
395: {
396: ssl_display_error(res);
397: }
398: }
399: #ifndef WIN32
400: }
401: #endif
402:
403: if (res < SSL_OK)
404: {
405: if (!quiet)
406: {
407: printf("CONNECTION CLOSED\n");
408: TTY_FLUSH();
409: }
410:
411: break;
412: }
413: }
414:
415: /* client was disconnected or the handshake failed. */
416: ssl_free(ssl);
417: SOCKET_CLOSE(client_fd);
418: }
419:
420: ssl_ctx_free(ssl_ctx);
421: }
422:
423: /**
424: * Implement the SSL client logic.
425: */
426: static void do_client(int argc, char *argv[])
427: {
428: #ifdef CONFIG_SSL_ENABLE_CLIENT
429: int res, i = 2;
430: uint16_t port = 4433;
431: uint32_t options = SSL_SERVER_VERIFY_LATER|SSL_DISPLAY_CERTS;
432: int client_fd;
433: char *private_key_file = NULL;
434: struct sockaddr_in client_addr;
435: struct hostent *hostent;
436: int reconnect = 0;
437: uint32_t sin_addr;
438: SSL_CTX *ssl_ctx;
439: SSL *ssl = NULL;
440: int quiet = 0;
441: int cert_index = 0, ca_cert_index = 0;
442: int cert_size, ca_cert_size;
443: char **ca_cert, **cert;
444: uint8_t session_id[SSL_SESSION_ID_SIZE];
445: fd_set read_set;
446: const char *password = NULL;
447:
448: FD_ZERO(&read_set);
449: sin_addr = inet_addr("127.0.0.1");
450: cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET);
451: ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET);
452: ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size);
453: cert = (char **)calloc(1, sizeof(char *)*cert_size);
454:
455: while (i < argc)
456: {
457: if (strcmp(argv[i], "-connect") == 0)
458: {
459: char *host, *ptr;
460:
461: if (i >= argc-1)
462: {
463: print_client_options(argv[i]);
464: }
465:
466: host = argv[++i];
467: if ((ptr = strchr(host, ':')) == NULL)
468: {
469: print_client_options(argv[i]);
470: }
471:
472: *ptr++ = 0;
473: port = atoi(ptr);
474: hostent = gethostbyname(host);
475:
476: if (hostent == NULL)
477: {
478: print_client_options(argv[i]);
479: }
480:
481: sin_addr = *((uint32_t **)hostent->h_addr_list)[0];
482: }
483: else if (strcmp(argv[i], "-cert") == 0)
484: {
485: if (i >= argc-1 || cert_index >= cert_size)
486: {
487: print_client_options(argv[i]);
488: }
489:
490: cert[cert_index++] = argv[++i];
491: }
492: else if (strcmp(argv[i], "-key") == 0)
493: {
494: if (i >= argc-1)
495: {
496: print_client_options(argv[i]);
497: }
498:
499: private_key_file = argv[++i];
500: options |= SSL_NO_DEFAULT_KEY;
501: }
502: else if (strcmp(argv[i], "-CAfile") == 0)
503: {
504: if (i >= argc-1 || ca_cert_index >= ca_cert_size)
505: {
506: print_client_options(argv[i]);
507: }
508:
509: ca_cert[ca_cert_index++] = argv[++i];
510: }
511: else if (strcmp(argv[i], "-verify") == 0)
512: {
513: options &= ~SSL_SERVER_VERIFY_LATER;
514: }
515: else if (strcmp(argv[i], "-reconnect") == 0)
516: {
517: reconnect = 4;
518: }
519: else if (strcmp(argv[i], "-quiet") == 0)
520: {
521: quiet = 1;
522: options &= ~SSL_DISPLAY_CERTS;
523: }
524: else if (strcmp(argv[i], "-pass") == 0)
525: {
526: if (i >= argc-1)
527: {
528: print_client_options(argv[i]);
529: }
530:
531: password = argv[++i];
532: }
533: #ifdef CONFIG_SSL_FULL_MODE
534: else if (strcmp(argv[i], "-debug") == 0)
535: {
536: options |= SSL_DISPLAY_BYTES;
537: }
538: else if (strcmp(argv[i], "-state") == 0)
539: {
540: options |= SSL_DISPLAY_STATES;
541: }
542: else if (strcmp(argv[i], "-show-rsa") == 0)
543: {
544: options |= SSL_DISPLAY_RSA;
545: }
546: #endif
547: else /* don't know what this is */
548: {
549: print_client_options(argv[i]);
550: }
551:
552: i++;
553: }
554:
555: if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL)
556: {
557: fprintf(stderr, "Error: Client context is invalid\n");
558: exit(1);
559: }
560:
561: if (private_key_file)
562: {
563: int obj_type = SSL_OBJ_RSA_KEY;
564:
565: /* auto-detect the key type from the file extension */
566: if (strstr(private_key_file, ".p8"))
567: obj_type = SSL_OBJ_PKCS8;
568: else if (strstr(private_key_file, ".p12"))
569: obj_type = SSL_OBJ_PKCS12;
570:
571: if (ssl_obj_load(ssl_ctx, obj_type, private_key_file, password))
572: {
573: fprintf(stderr, "Error: Private key '%s' is undefined.\n",
574: private_key_file);
575: exit(1);
576: }
577: }
578:
579: for (i = 0; i < cert_index; i++)
580: {
581: if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL))
582: {
583: printf("Certificate '%s' is undefined.\n", cert[i]);
584: exit(1);
585: }
586: }
587:
588: for (i = 0; i < ca_cert_index; i++)
589: {
590: if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL))
591: {
592: printf("Certificate '%s' is undefined.\n", ca_cert[i]);
593: exit(1);
594: }
595: }
596:
597: free(cert);
598: free(ca_cert);
599:
600: /*************************************************************************
601: * This is where the interesting stuff happens. Up until now we've
602: * just been setting up sockets etc. Now we do the SSL handshake.
603: *************************************************************************/
604: client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
605: memset(&client_addr, 0, sizeof(client_addr));
606: client_addr.sin_family = AF_INET;
607: client_addr.sin_port = htons(port);
608: client_addr.sin_addr.s_addr = sin_addr;
609:
610: if (connect(client_fd, (struct sockaddr *)&client_addr,
611: sizeof(client_addr)) < 0)
612: {
613: perror("connect");
614: exit(1);
615: }
616:
617: if (!quiet)
618: {
619: printf("CONNECTED\n");
620: TTY_FLUSH();
621: }
622:
623: /* Try session resumption? */
624: if (reconnect)
625: {
626: while (reconnect--)
627: {
628: ssl = ssl_client_new(ssl_ctx, client_fd, session_id,
629: sizeof(session_id));
630: if ((res = ssl_handshake_status(ssl)) != SSL_OK)
631: {
632: if (!quiet)
633: {
634: ssl_display_error(res);
635: }
636:
637: ssl_free(ssl);
638: exit(1);
639: }
640:
641: display_session_id(ssl);
642: memcpy(session_id, ssl_get_session_id(ssl), SSL_SESSION_ID_SIZE);
643:
644: if (reconnect)
645: {
646: ssl_free(ssl);
647: SOCKET_CLOSE(client_fd);
648:
649: client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
650: connect(client_fd, (struct sockaddr *)&client_addr,
651: sizeof(client_addr));
652: }
653: }
654: }
655: else
656: {
657: ssl = ssl_client_new(ssl_ctx, client_fd, NULL, 0);
658: }
659:
660: /* check the return status */
661: if ((res = ssl_handshake_status(ssl)) != SSL_OK)
662: {
663: if (!quiet)
664: {
665: ssl_display_error(res);
666: }
667:
668: exit(1);
669: }
670:
671: if (!quiet)
672: {
673: const char *common_name = ssl_get_cert_dn(ssl,
674: SSL_X509_CERT_COMMON_NAME);
675: if (common_name)
676: {
677: printf("Common Name:\t\t\t%s\n", common_name);
678: }
679:
680: display_session_id(ssl);
681: display_cipher(ssl);
682: }
683:
684: for (;;)
685: {
686: uint8_t buf[1024];
687:
688: /* allow parallel reading of server and standard input */
689: FD_SET(client_fd, &read_set);
690: #ifndef WIN32
691: /* win32 doesn't like mixing up stdin and sockets */
692: FD_SET(STDIN_FILENO, &read_set);
693:
694: if ((res = select(client_fd+1, &read_set, NULL, NULL, NULL)) > 0)
695: {
696: /* read standard input? */
697: if (FD_ISSET(STDIN_FILENO, &read_set))
698: #endif
699: {
700: if (fgets((char *)buf, sizeof(buf), stdin) == NULL)
701: {
702: /* bomb out of here */
703: ssl_free(ssl);
704: break;
705: }
706: else
707: {
708: /* small hack to check renegotiation */
709: if (buf[0] == 'R' && (buf[1] == '\n' || buf[1] == '\r'))
710: {
711: res = ssl_renegotiate(ssl);
712: }
713: else
714: {
715: res = ssl_write(ssl, buf, strlen((char *)buf)+1);
716: }
717: }
718: }
719: #ifndef WIN32
720: else /* a socket read */
721: {
722: uint8_t *read_buf;
723:
724: res = ssl_read(ssl, &read_buf);
725:
726: if (res > 0) /* display our interesting output */
727: {
728: printf("%s", read_buf);
729: TTY_FLUSH();
730: }
731: }
732: }
733: #endif
734:
735: if (res < 0)
736: {
737: if (!quiet)
738: {
739: ssl_display_error(res);
740: }
741:
742: break; /* get outta here */
743: }
744: }
745:
746: ssl_ctx_free(ssl_ctx);
747: SOCKET_CLOSE(client_fd);
748: #else
749: print_client_options(argv[1]);
750: #endif
751: }
752:
753: /**
754: * We've had some sort of command-line error. Print out the basic options.
755: */
756: static void print_options(char *option)
757: {
758: printf("axssl: Error: '%s' is an invalid command.\n", option);
759: printf("usage: axssl [s_server|s_client|version] [args ...]\n");
760: exit(1);
761: }
762:
763: /**
764: * We've had some sort of command-line error. Print out the server options.
765: */
766: static void print_server_options(char *option)
767: {
768: #ifndef CONFIG_SSL_SKELETON_MODE
769: int cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET);
770: #endif
771: #ifdef CONFIG_SSL_CERT_VERIFICATION
772: int ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET);
773: #endif
774:
775: printf("unknown option %s\n", option);
776: printf("usage: s_server [args ...]\n");
777: printf(" -accept arg\t- port to accept on (default is 4433)\n");
778: #ifndef CONFIG_SSL_SKELETON_MODE
779: printf(" -cert arg\t- certificate file to add (in addition to default)"
780: " to chain -\n"
781: "\t\t Can repeat up to %d times\n", cert_size);
782: printf(" -key arg\t- Private key file to use\n");
783: printf(" -pass\t\t- private key file pass phrase source\n");
784: #endif
785: printf(" -quiet\t\t- No server output\n");
786: #ifdef CONFIG_SSL_CERT_VERIFICATION
787: printf(" -verify\t- turn on peer certificate verification\n");
788: printf(" -CAfile arg\t- Certificate authority\n");
789: printf("\t\t Can repeat up to %d times\n", ca_cert_size);
790: #endif
791: #ifdef CONFIG_SSL_FULL_MODE
792: printf(" -debug\t\t- Print more output\n");
793: printf(" -state\t\t- Show state messages\n");
794: printf(" -show-rsa\t- Show RSA state\n");
795: #endif
796: exit(1);
797: }
798:
799: /**
800: * We've had some sort of command-line error. Print out the client options.
801: */
802: static void print_client_options(char *option)
803: {
804: #ifdef CONFIG_SSL_ENABLE_CLIENT
805: int cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET);
806: int ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET);
807: #endif
808:
809: printf("unknown option %s\n", option);
810: #ifdef CONFIG_SSL_ENABLE_CLIENT
811: printf("usage: s_client [args ...]\n");
812: printf(" -connect host:port - who to connect to (default "
813: "is localhost:4433)\n");
814: printf(" -verify\t- turn on peer certificate verification\n");
815: printf(" -cert arg\t- certificate file to use\n");
816: printf("\t\t Can repeat up to %d times\n", cert_size);
817: printf(" -key arg\t- Private key file to use\n");
818: printf(" -CAfile arg\t- Certificate authority\n");
819: printf("\t\t Can repeat up to %d times\n", ca_cert_size);
820: printf(" -quiet\t\t- No client output\n");
821: printf(" -reconnect\t- Drop and re-make the connection "
822: "with the same Session-ID\n");
823: printf(" -pass\t\t- private key file pass phrase source\n");
824: #ifdef CONFIG_SSL_FULL_MODE
825: printf(" -debug\t\t- Print more output\n");
826: printf(" -state\t\t- Show state messages\n");
827: printf(" -show-rsa\t- Show RSA state\n");
828: #endif
829: #else
830: printf("Change configuration to allow this feature\n");
831: #endif
832: exit(1);
833: }
834:
835: /**
836: * Display what cipher we are using
837: */
838: static void display_cipher(SSL *ssl)
839: {
840: printf("CIPHER is ");
841: switch (ssl_get_cipher_id(ssl))
842: {
843: case SSL_AES128_SHA:
844: printf("AES128-SHA");
845: break;
846:
847: case SSL_AES256_SHA:
848: printf("AES256-SHA");
849: break;
850:
851: case SSL_RC4_128_SHA:
852: printf("RC4-SHA");
853: break;
854:
855: case SSL_RC4_128_MD5:
856: printf("RC4-MD5");
857: break;
858:
859: default:
860: printf("Unknown - %d", ssl_get_cipher_id(ssl));
861: break;
862: }
863:
864: printf("\n");
865: TTY_FLUSH();
866: }
867:
868: /**
869: * Display what session id we have.
870: */
871: static void display_session_id(SSL *ssl)
872: {
873: int i;
874: const uint8_t *session_id = ssl_get_session_id(ssl);
875: int sess_id_size = ssl_get_session_id_size(ssl);
876:
877: if (sess_id_size > 0)
878: {
879: printf("-----BEGIN SSL SESSION PARAMETERS-----\n");
880: for (i = 0; i < sess_id_size; i++)
881: {
882: printf("%02x", session_id[i]);
883: }
884:
885: printf("\n-----END SSL SESSION PARAMETERS-----\n");
886: TTY_FLUSH();
887: }
888: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>