10 #include <cyassl/ssl.h>
11 #include <cyassl/ctaocrypt/types.h>
13 #ifdef USE_WINDOWS_API
16 #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */
25 #include <netinet/in.h>
26 #include <netinet/tcp.h>
27 #include <arpa/inet.h>
28 #include <sys/ioctl.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
39 #define SOCKET_T unsigned int
40 #endif /* USE_WINDOWS_API */
43 /* disable conversion warning */
44 /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
45 #pragma warning(disable:4244 4996)
49 #if defined(__MACH__) || defined(USE_WINDOWS_API)
51 typedef int socklen_t;
56 /* HPUX doesn't use socklent_t for third parameter to accept */
57 #if !defined(__hpux__)
58 typedef socklen_t* ACCEPT_THIRD_T;
60 typedef int* ACCEPT_THIRD_T;
64 #ifdef USE_WINDOWS_API
65 #define CloseSocket(s) closesocket(s)
66 #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); }
68 #define CloseSocket(s) close(s)
73 #ifdef SINGLE_THREADED
74 typedef unsigned int THREAD_RETURN;
75 typedef void* THREAD_TYPE;
79 typedef void* THREAD_RETURN;
80 typedef pthread_t THREAD_TYPE;
83 #define WAIT_OBJECT_0 0L
85 typedef unsigned int THREAD_RETURN;
86 typedef HANDLE THREAD_TYPE;
87 #define CYASSL_THREAD __stdcall
93 typedef struct sockaddr_in6 SOCKADDR_IN_T;
94 #define AF_INET_V AF_INET6
96 typedef struct sockaddr_in SOCKADDR_IN_T;
97 #define AF_INET_V AF_INET
101 #define SERVER_DEFAULT_VERSION 3
102 #define CLIENT_DEFAULT_VERSION 3
104 /* all certs relative to CyaSSL home directory now */
105 #define caCert "./certs/ca-cert.pem"
106 #define eccCert "./certs/server-ecc.pem"
107 #define eccKey "./certs/ecc-key.pem"
108 #define svrCert "./certs/server-cert.pem"
109 #define svrKey "./certs/server-key.pem"
110 #define cliCert "./certs/client-cert.pem"
111 #define cliKey "./certs/client-key.pem"
112 #define ntruCert "./certs/ntru-cert.pem"
113 #define ntruKey "./certs/ntru-key.raw"
114 #define dhParam "./certs/dh2048.pem"
115 #define cliEccKey "./certs/ecc-client-key.pem"
116 #define cliEccCert "./certs/client-ecc-cert.pem"
117 #define crlPemDir "./certs/crl"
119 typedef struct tcp_ready {
120 int ready; /* predicate */
121 #ifdef _POSIX_THREADS
122 pthread_mutex_t mutex;
128 void InitTcpReady(tcp_ready*);
129 void FreeTcpReady(tcp_ready*);
132 typedef struct func_args {
139 void wait_tcp_ready(func_args*);
141 typedef THREAD_RETURN CYASSL_THREAD THREAD_FUNC(void*);
143 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
144 void join_thread(THREAD_TYPE);
147 static const char* const yasslIP = "127.0.0.1";
148 static const word16 yasslPort = 11111;
151 static INLINE void err_sys(const char* msg)
153 printf("yassl error: %s\n", msg);
158 #define MY_EX_USAGE 2
161 extern char* myoptarg;
163 static INLINE int mygetopt(int argc, char** argv, char* optstring)
165 static char* next = NULL;
171 next = NULL; /* we're starting new/over */
173 if (next == NULL || *next == '\0') {
177 if (myoptind >= argc || argv[myoptind][0] != '-' ||
178 argv[myoptind][1] == '\0') {
181 myoptarg = argv[myoptind];
186 if (strcmp(argv[myoptind], "--") == 0) {
191 myoptarg = argv[myoptind];
196 next = argv[myoptind];
202 cp = strchr(optstring, c);
204 if (cp == NULL || c == ':')
214 else if (myoptind < argc) {
215 myoptarg = argv[myoptind];
228 static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
230 strncpy(passwd, "yassl123", sz);
237 static INLINE void showPeer(CYASSL* ssl)
241 CYASSL_CIPHER* cipher;
242 CYASSL_X509* peer = CyaSSL_get_peer_certificate(ssl);
245 char* issuer = CyaSSL_X509_NAME_oneline(
246 CyaSSL_X509_get_issuer_name(peer), 0, 0);
247 char* subject = CyaSSL_X509_NAME_oneline(
248 CyaSSL_X509_get_subject_name(peer), 0, 0);
251 int sz = sizeof(serial);
253 printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
256 while ( (altName = CyaSSL_X509_get_next_altname(peer)) )
257 printf(" altname = %s\n", altName);
259 ret = CyaSSL_X509_get_serial_number(peer, serial, &sz);
265 /* testsuite has multiple threads writing to stdout, get output
266 message ready to write once */
267 strLen = sprintf(serialMsg, " serial number");
268 for (i = 0; i < sz; i++)
269 sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
270 printf("%s\n", serialMsg);
273 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
274 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
277 printf("peer has no cert!\n");
278 printf("SSL version is %s\n", CyaSSL_get_version(ssl));
280 cipher = CyaSSL_get_current_cipher(ssl);
281 printf("SSL cipher suite is %s\n", CyaSSL_CIPHER_get_name(cipher));
284 #if defined(SESSION_CERTS) && defined(SHOW_CERTS)
286 CYASSL_X509_CHAIN* chain = CyaSSL_get_peer_chain(ssl);
287 int count = CyaSSL_get_chain_count(chain);
290 for (i = 0; i < count; i++) {
292 unsigned char buffer[3072];
294 CyaSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length);
296 printf("cert %d has length %d data = \n%s\n", i, length, buffer);
304 static INLINE void tcp_socket(SOCKET_T* sockfd, SOCKADDR_IN_T* addr,
305 const char* peer, word16 port, int udp)
308 const char* host = peer;
310 /* peer could be in human readable form */
311 if (peer != INADDR_ANY && isalpha(peer[0])) {
312 struct hostent* entry = gethostbyname(peer);
315 struct sockaddr_in tmp;
316 memset(&tmp, 0, sizeof(struct sockaddr_in));
317 memcpy(&tmp.sin_addr.s_addr, entry->h_addr_list[0],
319 host = inet_ntoa(tmp.sin_addr);
322 err_sys("no entry for host");
327 *sockfd = socket(AF_INET_V, SOCK_DGRAM, 0);
329 *sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
330 memset(addr, 0, sizeof(SOCKADDR_IN_T));
333 addr->sin_family = AF_INET_V;
334 addr->sin_port = htons(port);
335 if (host == INADDR_ANY)
336 addr->sin_addr.s_addr = INADDR_ANY;
338 addr->sin_addr.s_addr = inet_addr(host);
340 addr->sin6_family = AF_INET_V;
341 addr->sin6_port = htons(port);
342 addr->sin6_addr = in6addr_loopback;
345 #ifndef USE_WINDOWS_API
349 socklen_t len = sizeof(on);
350 int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
352 err_sys("setsockopt SO_NOSIGPIPE failed\n");
356 #if defined(TCP_NODELAY)
360 socklen_t len = sizeof(on);
361 int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
363 err_sys("setsockopt TCP_NODELAY failed\n");
366 #endif /* USE_WINDOWS_API */
370 static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
374 tcp_socket(sockfd, &addr, ip, port, udp);
376 if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
377 err_sys("tcp connect failed");
381 static INLINE void tcp_listen(SOCKET_T* sockfd, int port, int useAnyAddr,
386 /* don't use INADDR_ANY by default, firewall may block, make user switch
389 tcp_socket(sockfd, &addr, INADDR_ANY, port, udp);
391 tcp_socket(sockfd, &addr, yasslIP, port, udp);
393 #ifndef USE_WINDOWS_API
396 socklen_t len = sizeof(on);
397 setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
401 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
402 err_sys("tcp bind failed");
404 if (listen(*sockfd, 5) != 0)
405 err_sys("tcp listen failed");
410 static INLINE int udp_read_connect(SOCKET_T sockfd)
412 SOCKADDR_IN_T cliaddr;
415 socklen_t len = sizeof(cliaddr);
417 n = recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
418 (struct sockaddr*)&cliaddr, &len);
420 if (connect(sockfd, (const struct sockaddr*)&cliaddr,
421 sizeof(cliaddr)) != 0)
422 err_sys("udp connect failed");
425 err_sys("recvfrom failed");
430 static INLINE void udp_accept(SOCKET_T* sockfd, int* clientfd, func_args* args)
434 tcp_socket(sockfd, &addr, yasslIP, yasslPort, 1);
437 #ifndef USE_WINDOWS_API
440 socklen_t len = sizeof(on);
441 setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
445 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
446 err_sys("tcp bind failed");
448 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER)
449 /* signal ready to accept data */
451 tcp_ready* ready = args->signal;
452 pthread_mutex_lock(&ready->mutex);
454 pthread_cond_signal(&ready->cond);
455 pthread_mutex_unlock(&ready->mutex);
459 *clientfd = udp_read_connect(*sockfd);
462 static INLINE void tcp_accept(SOCKET_T* sockfd, int* clientfd, func_args* args,
463 int port, int useAnyAddr, int udp)
465 SOCKADDR_IN_T client;
466 socklen_t client_len = sizeof(client);
469 udp_accept(sockfd, clientfd, args);
473 tcp_listen(sockfd, port, useAnyAddr, udp);
475 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER)
476 /* signal ready to tcp_accept */
478 tcp_ready* ready = args->signal;
479 pthread_mutex_lock(&ready->mutex);
481 pthread_cond_signal(&ready->cond);
482 pthread_mutex_unlock(&ready->mutex);
486 *clientfd = accept(*sockfd, (struct sockaddr*)&client,
487 (ACCEPT_THIRD_T)&client_len);
489 err_sys("tcp accept failed");
493 static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
496 #ifdef USE_WINDOWS_API
497 unsigned long blocking = 1;
498 int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
500 int flags = fcntl(*sockfd, F_GETFL, 0);
501 int ret = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
509 static INLINE unsigned int my_psk_client_cb(CYASSL* ssl, const char* hint,
510 char* identity, unsigned int id_max_len, unsigned char* key,
511 unsigned int key_max_len)
513 /* identity is OpenSSL testing default for openssl s_client, keep same */
514 strncpy(identity, "Client_identity", id_max_len);
517 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
524 return 4; /* length of key in octets or 0 for error */
528 static INLINE unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity,
529 unsigned char* key, unsigned int key_max_len)
531 /* identity is OpenSSL testing default for openssl s_client, keep same */
532 if (strncmp(identity, "Client_identity", 15) != 0)
535 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
542 return 4; /* length of key in octets or 0 for error */
548 #ifdef USE_WINDOWS_API
550 #define WIN32_LEAN_AND_MEAN
553 static INLINE double current_time()
556 static LARGE_INTEGER freq;
561 QueryPerformanceFrequency(&freq);
565 QueryPerformanceCounter(&count);
567 return (double)count.QuadPart / freq.QuadPart;
572 #include <sys/time.h>
574 static INLINE double current_time()
577 gettimeofday(&tv, 0);
579 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
582 #endif /* USE_WINDOWS_API */
593 static INLINE void load_buffer(CYASSL_CTX* ctx, const char* fname, int type)
595 /* test buffer load */
598 FILE* file = fopen(fname, "rb");
601 err_sys("can't open file for buffer load "
602 "Please run from CyaSSL home directory if not");
603 fseek(file, 0, SEEK_END);
606 fread(buff, sizeof(buff), 1, file);
608 if (type == CYASSL_CA) {
609 if (CyaSSL_CTX_load_verify_buffer(ctx, buff, sz, SSL_FILETYPE_PEM)
611 err_sys("can't load buffer ca file");
613 else if (type == CYASSL_CERT) {
614 if (CyaSSL_CTX_use_certificate_buffer(ctx, buff, sz,
615 SSL_FILETYPE_PEM) != SSL_SUCCESS)
616 err_sys("can't load buffer cert file");
618 else if (type == CYASSL_KEY) {
619 if (CyaSSL_CTX_use_PrivateKey_buffer(ctx, buff, sz,
620 SSL_FILETYPE_PEM) != SSL_SUCCESS)
621 err_sys("can't load buffer key file");
625 #endif /* NO_FILESYSTEM */
627 #ifdef VERIFY_CALLBACK
629 static INLINE int myVerify(int preverify, CYASSL_X509_STORE_CTX* store)
633 printf("In verification callback, error = %d, %s\n", store->error,
634 CyaSSL_ERR_error_string(store->error, buffer));
636 CYASSL_X509* peer = store->current_cert;
638 char* issuer = CyaSSL_X509_NAME_oneline(
639 CyaSSL_X509_get_issuer_name(peer), 0, 0);
640 char* subject = CyaSSL_X509_NAME_oneline(
641 CyaSSL_X509_get_subject_name(peer), 0, 0);
642 printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
644 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
645 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
648 printf("peer has no cert!\n");
650 printf("Subject's domain name is %s\n", store->domain);
652 printf("Allowing to continue anyway (shouldn't do this, EVER!!!)\n");
656 #endif /* VERIFY_CALLBACK */
661 static void INLINE CRL_CallBack(const char* url)
663 printf("CRL callback url = %s\n", url);
669 static INLINE void CaCb(unsigned char* der, int sz, int type)
671 printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
675 static INLINE void SetDH(CYASSL* ssl)
678 static unsigned char p[] =
680 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
681 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
682 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
683 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
684 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
685 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
686 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
687 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
688 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
689 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
690 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
694 static unsigned char g[] =
699 CyaSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
702 static INLINE void SetDHCtx(CYASSL_CTX* ctx)
705 static unsigned char p[] =
707 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
708 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
709 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
710 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
711 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
712 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
713 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
714 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
715 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
716 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
717 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
721 static unsigned char g[] =
726 CyaSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
729 #ifdef USE_WINDOWS_API
731 /* do back x number of directories */
732 static INLINE void ChangeDirBack(int x)
737 strncpy(path, "..\\", MAX_PATH);
739 strncpy(path, "..\\..\\", MAX_PATH);
741 strncpy(path, "..\\..\\..\\", MAX_PATH);
743 strncpy(path, "..\\..\\..\\..\\", MAX_PATH);
745 strncpy(path, ".\\", MAX_PATH);
747 SetCurrentDirectoryA(path);
750 /* does current dir contain str */
751 static INLINE int CurrentDir(const char* str)
755 GetCurrentDirectoryA(sizeof(path), path);
756 if (strstr(path, str))
768 /* do back x number of directories */
769 static INLINE void ChangeDirBack(int x)
774 strncpy(path, "../", MAX_PATH);
776 strncpy(path, "../../", MAX_PATH);
778 strncpy(path, "../../../", MAX_PATH);
780 strncpy(path, "../../../../", MAX_PATH);
782 strncpy(path, "./", MAX_PATH);
785 printf("chdir to %s failed\n", path);
788 /* does current dir contain str */
789 static INLINE int CurrentDir(const char* str)
793 if (getcwd(path, sizeof(path)) == NULL) {
794 printf("no current dir?\n");
797 if (strstr(path, str))
803 #endif /* USE_WINDOWS_API */
805 #endif /* CyaSSL_TEST_H */