diff --git a/IDE/IAR-EWARM/CyaSSL/tcp-conn-nb.c b/IDE/IAR-EWARM/CyaSSL/tcp-conn-nb.c new file mode 100644 index 000000000..ad60b6689 --- /dev/null +++ b/IDE/IAR-EWARM/CyaSSL/tcp-conn-nb.c @@ -0,0 +1,167 @@ +/* tcp-conn-nb.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +/*** Simulating tcp_connect by LwIP Native TCP ***/ + + +#if defined(HAVE_LWIP_NATIVE) +#include +#include +#include "lwip/tcp.h" +#include "lwip/sockets.h" +#include "lwip/inet.h" +#include "lwip/ip_addr.h" + +#include "cyassl/ssl.h" +#include "tcp-conn-nb.h" + +int myoptind; +char* myoptarg; + + +static struct tcp_cb { + enum TCP_stat stat ; + struct tcp_pcb *pcb ; + unsigned long localPort; + ip_addr_t localIP_em ; + unsigned long serverPort ; + ip_addr_t serverIP_em ; +} tcp ; + +#define LOCAL_PORT 11111 + +#if 0 +/*Enable debug*/ +#include +#define DBG_PRINTF(x, ...) printf("[HTTPSClient : DBG]"x"\r\n", ##__VA_ARGS__); +#define ERR_PRINTF(x, ...) printf("[HTTPSClient:ERROR]"x"\r\n", ##__VA_ARGS__); +#else +/*Disable debug*/ +#define DBG_PRINTF(x, ...) +#define ERR_PRINTF(x, ...) +#endif + + +static err_t TcpConnectedCallback (void *arg, struct tcp_pcb *pcb, s8_t err) +{ + DBG_PRINTF("TcpConnectedCallback(arg=%x, pcb=%x, err=%x)\n", arg, pcb, err) ; + //if(*(int *)arg == TCP_WAITING) + *(int *)arg = TCP_CONNECTED ; + return ERR_OK; +} + +/** strictly IPV4 ***/ +#define IP_ADDR(a,b,c,d) (((a)|((b)<<8)|((c)<<16)|(d)<<24)) +ip_addr_t ip_addr_s2i(const char *ip_s) { + unsigned int ip[4] ; + ip_addr_t ip_addr ; + + sscanf(ip_s, "%d.%d.%d.%d", + &(ip[0]), &(ip[1]), &(ip[2]), &(ip[3])) ; + ip_addr.addr = IP_ADDR(ip[0], ip[1], ip[2], ip[3]) ; + return ip_addr ; +} + +/** Placeholders for now **/ +void tcp_socket(SOCKET_T *s, int flag) { } +void build_addr(int *addr, char *host, int port, int mode) { } +void tcp_CloseSocket_nb(SOCKET_T *sockfd) { } +void tcp_select(SOCKET_T *s, int flag) { } +unsigned long current_time(void) { return 0 ; } + +int tcp_connect_nb(struct tcp_pcb **pcb, const char* ip, word16 port, + int udp) +{ + int ret ; + + switch(tcp.stat) { + case TCP_BEGIN: + tcp.pcb = tcp_new(); + if(tcp.pcb) { + tcp_arg(tcp.pcb, (void *)&(tcp.stat)) ; + DBG_PRINTF("New PCB(tcp_new=%x), &https->stat=%x\n", + tcp.pcb, &tcp.stat) ; + } else { + ERR_PRINTF("tcp_new, ret=%d\n", tcp.pcb) ; + tcp.stat = TCP_IDLE ; + return TCP_ERROR ; + } + + *pcb = tcp.pcb ; + tcp_arg(tcp.pcb, (void *)&tcp.stat) ; + + tcp.localPort = LOCAL_PORT ; + DBG_PRINTF("local Port=%d\n", tcp.localPort) ; + ret = tcp_bind (tcp.pcb, &(tcp.localIP_em), + tcp.localPort) ; + if(ret == ERR_OK) { + tcp.stat = TCP_CONNECTING ; + return TCP_CONNECTING ; + } else { + ERR_PRINTF("tcp_bind, ret=%d\n", ret) ; + tcp.stat = TCP_CLOSE ; + return TCP_CONNECTING ; + } + + case TCP_CONNECTING: + tcp.serverPort = port ; + tcp.serverIP_em = ip_addr_s2i(ip) ; + DBG_PRINTF("TCP_CONNECT(%x)\n", tcp.pcb) ; + + ret = tcp_connect(tcp.pcb, &(tcp.serverIP_em), + tcp.serverPort, TcpConnectedCallback); + if(ret == ERR_OK) { + tcp.stat = TCP_WAITING ; + return TCP_CONNECTING ; + } else { + ERR_PRINTF("tcp_connect, ret=%d\n", ret) ; + tcp.stat = TCP_CLOSE ; + return TCP_ERROR ; + } + + case TCP_WAITING: + return TCP_CONNECTING ; + + case TCP_CONNECTED: + *pcb = tcp.pcb ; + return TCP_CONNECTED ; + + case TCP_CLOSE: + tcp_close(tcp.pcb) ; + tcp.stat = TCP_IDLE ; + return TCP_CONNECTING ; + + case TCP_IDLE: + default: + return TCP_CONNECTING ; + } +} + + +#endif + + \ No newline at end of file diff --git a/IDE/IAR-EWARM/CyaSSL/tcp-conn-nb.h b/IDE/IAR-EWARM/CyaSSL/tcp-conn-nb.h new file mode 100644 index 000000000..0f8d6d0a9 --- /dev/null +++ b/IDE/IAR-EWARM/CyaSSL/tcp-conn-nb.h @@ -0,0 +1,202 @@ +/* tcp-conn-nb.h + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef TCP_CONN_NB_H +#define TCP_CONN_NB_H + +/* Options for LwIP native socket client example */ + #define NO_MAIN_DRIVER + #define NO_SESSION_CACHE + #define NO_PSK + #define NO_BENCHMARK + #undef USE_CYASSL_MEMORY +/******/ + + #include + #include + #include "lwip/tcp.h" + #include "lwip/sockets.h" + #include "lwip/inet.h" + #include "lwip/ip_addr.h" + + #define THREAD_RETURN int + #define CYASSL_THREAD + #define SOCKET_T struct tcp_pcb * + #define SOCKADDR_IN_T int + //#define ip_addr_t char * + #define err_sys(msg) puts(msg) + #define exit(code) return(code) ; + +enum TCP_stat { + TCP_BEGIN, + TCP_CONNECTING, /* return code */ + TCP_CONNECTED, /* return code */ + TCP_WAITING, + TCP_CLOSE, + TCP_IDLE, + TCP_ERROR, +} ; + + + +/*** from test.h ***/ + #define CYASSL_MAX_ERROR_SZ 128 + #define CLIENT_DEFAULT_VERSION 3 + #define CLIENT_DTLS_DEFAULT_VERSION (-2) + #define CLIENT_INVALID_VERSION (-99) + static const char* const yasslIP = "127.0.0.1"; + static const word16 yasslPort = 11111; + #define caCert "./certs/ca-cert.pem" + #define cliCert "./certs/client-cert.pem" + #define cliKey "./certs/client-key.pem" + #define MY_EX_USAGE 2 + #define StackTrap(a) + #define InitMemoryTracker(a) + + typedef struct func_args { + int argc; + char** argv; + int return_code; + } func_args; + + extern int myoptind; + extern char* myoptarg; + + void build_addr(int *addr, char *host, int port, int mode) ; + void tcp_socket(SOCKET_T *s, int flag) ; + +enum { + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_ERROR_READY +}; + + static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd){ } + + +static INLINE int mygetopt(int argc, char** argv, const char* optstring) +{ + static char* next = NULL; + + char c; + char* cp; + + if (myoptind == 0) + next = NULL; /* we're starting new/over */ + + if (next == NULL || *next == '\0') { + if (myoptind == 0) + myoptind++; + + if (myoptind >= argc || argv[myoptind][0] != '-' || + argv[myoptind][1] == '\0') { + myoptarg = NULL; + if (myoptind < argc) + myoptarg = argv[myoptind]; + + return -1; + } + + if (strcmp(argv[myoptind], "--") == 0) { + myoptind++; + myoptarg = NULL; + + if (myoptind < argc) + myoptarg = argv[myoptind]; + + return -1; + } + + next = argv[myoptind]; + next++; /* skip - */ + myoptind++; + } + + c = *next++; + /* The C++ strchr can return a different value */ + cp = (char*)strchr(optstring, c); + + if (cp == NULL || c == ':') + return '?'; + + cp++; + + if (*cp == ':') { + if (*next != '\0') { + myoptarg = next; + next = NULL; + } + else if (myoptind < argc) { + myoptarg = argv[myoptind]; + myoptind++; + } + else + return '?'; + } + + return c; +} + +static INLINE void showPeer(CYASSL* ssl) +{ + + CYASSL_CIPHER* cipher; +#ifdef KEEP_PEER_CERT + CYASSL_X509* peer = CyaSSL_get_peer_certificate(ssl); + if (peer) + ShowX509(peer, "peer's cert info:"); + else + printf("peer has no cert!\n"); +#endif + printf("SSL version is %s\n", CyaSSL_get_version(ssl)); + + cipher = CyaSSL_get_current_cipher(ssl); + printf("SSL cipher suite is %s\n", CyaSSL_CIPHER_get_name(cipher)); + +#if defined(SESSION_CERTS) && defined(SHOW_CERTS) + { + CYASSL_X509_CHAIN* chain = CyaSSL_get_peer_chain(ssl); + int count = CyaSSL_get_chain_count(chain); + int i; + + for (i = 0; i < count; i++) { + int length; + unsigned char buffer[3072]; + CYASSL_X509* chainX509; + + CyaSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length); + buffer[length] = 0; + printf("cert %d has length %d data = \n%s\n", i, length, buffer); + + chainX509 = CyaSSL_get_chain_X509(chain, i); + if (chainX509) + ShowX509(chainX509, "session cert info:"); + else + printf("get_chain_X509 failed\n"); + CyaSSL_FreeX509(chainX509); + } + } +#endif + (void)ssl; +} + +#endif diff --git a/IDE/IAR-EWARM/Projects/client/client.ewp b/IDE/IAR-EWARM/Projects/client/client.ewp new file mode 100644 index 000000000..6bd4889ce --- /dev/null +++ b/IDE/IAR-EWARM/Projects/client/client.ewp @@ -0,0 +1,1886 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + Apps + + $PROJ_DIR$\..\..\..\..\examples\client\client.c + + + $PROJ_DIR$\..\..\CyaSSL\tcp-conn-nb.c + + + + + diff --git a/IDE/IAR-EWARM/Projects/client/client.eww b/IDE/IAR-EWARM/Projects/client/client.eww new file mode 100644 index 000000000..3d83b971b --- /dev/null +++ b/IDE/IAR-EWARM/Projects/client/client.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\client.ewp + + + + + diff --git a/examples/client/client.c b/examples/client/client.c index ac6f935a8..52763d143 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -38,7 +38,12 @@ #endif #include -#include + +#if defined(HAVE_LWIP_NATIVE) + #include "tcp-conn-nb.h" +#else + #include +#endif #include "examples/client/client.h" @@ -49,7 +54,6 @@ Timeval timeout; #endif - static void NonBlockingSSL_Connect(CYASSL* ssl) { #ifndef CYASSL_CALLBACKS @@ -159,11 +163,10 @@ static void Usage(void) THREAD_RETURN CYASSL_THREAD client_test(void* args) { - SOCKET_T sockfd = 0; - + STATIC_NB SOCKET_T sockfd = 0 ; CYASSL_METHOD* method = 0; - CYASSL_CTX* ctx = 0; - CYASSL* ssl = 0; + STATIC_NB CYASSL_CTX* ctx = 0; + STATIC_NB CYASSL* ssl = 0; CYASSL* sslResume = 0; CYASSL_SESSION* session = 0; @@ -389,7 +392,9 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) } myoptind = 0; /* reset for test cases */ - + +SWITCH_STAT { + /* sort out DTLS versus TLS versions */ if (version == CLIENT_INVALID_VERSION) { if (doDTLS) @@ -595,13 +600,15 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) exit(EXIT_SUCCESS); } - #if defined(CYASSL_MDK_ARM) + #if defined(CYASSL_MDK_ARM) || defined(HAVE_LWIP_NATIVE) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); #endif ssl = CyaSSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL object"); + +CASE(CLIENT_TCP_CONN): if (doDTLS) { SOCKADDR_IN_T addr; build_addr(&addr, host, port, 1); @@ -609,7 +616,15 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) tcp_socket(&sockfd, 1); } else { - tcp_connect(&sockfd, host, port, 0); + #if !defined(HAVE_LWIP_NATIVE) + tcp_connect(&sockfd, host, port, 0); + #else + int err = tcp_connect(&sockfd, host, port, 0); + if(err == TCP_CONNECTED) + CyaSSL_SetIO_LwIP(ssl, sockfd, NULL, NULL, NULL); + else + BREAK ; + #endif } CyaSSL_set_fd(ssl, sockfd); #ifdef HAVE_CRL @@ -631,6 +646,9 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) if (matchName && doPeerCheck) CyaSSL_check_domain_name(ssl, domain); #ifndef CYASSL_CALLBACKS + +CASE(CLIENT_SSL_CONN): + if (nonBlocking) { CyaSSL_set_using_nonblock(ssl, 1); tcp_set_nonblocking(&sockfd); @@ -639,28 +657,37 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) else if (CyaSSL_connect(ssl) != SSL_SUCCESS) { /* see note at top of README */ int err = CyaSSL_get_error(ssl, 0); + #if defined(HAVE_LWIP_NATIVE) + if(err == SSL_ERROR_WANT_READ) + BREAK ; + #endif char buffer[CYASSL_MAX_ERROR_SZ]; printf("err = %d, %s\n", err, CyaSSL_ERR_error_string(err, buffer)); err_sys("SSL_connect failed"); /* if you're getting an error here */ + BREAK ; } #else timeout.tv_sec = 2; timeout.tv_usec = 0; NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */ #endif + showPeer(ssl); if (sendGET) { printf("SSL connect ok, sending GET...\n"); msgSz = 28; - strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz); + //strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz); + strncpy(msg, "GET / HTTP/1.0\r\n\r\n", msgSz); msg[msgSz] = '\0'; } if (CyaSSL_write(ssl, msg, msgSz) != msgSz) err_sys("SSL_write failed"); +CASE(CLIENT_SSL_READ): + input = CyaSSL_read(ssl, reply, sizeof(reply)-1); if (input > 0) { reply[input] = 0; @@ -682,8 +709,9 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) int readErr = CyaSSL_get_error(ssl, 0); if (readErr != SSL_ERROR_WANT_READ) err_sys("CyaSSL_read failed"); + BREAK ; } - + #ifndef NO_SESSION_CACHE if (resumeSession) { if (doDTLS) { @@ -782,6 +810,11 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) #endif /* USE_CYASSL_MEMORY */ return 0; + } + +END_SWITCH ; /* End of SWITCH(stat) */ + + return 0 ; } @@ -831,7 +864,6 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) #endif /* NO_MAIN_DRIVER */ - #ifdef CYASSL_CALLBACKS int handShakeCB(HandShakeInfo* info) diff --git a/examples/client/client.h b/examples/client/client.h index 2d051fb2d..a243b6601 100644 --- a/examples/client/client.h +++ b/examples/client/client.h @@ -23,3 +23,34 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args); +#if defined(HAVE_LWIP_NATIVE) + +static enum Client_Stat { + CLIENT_BEGIN , + CLIENT_TCP_CONN , + CLIENT_SSL_CONN , + CLIENT_SSL_READ , + } client_stat ; + + int tcp_connect_nb(struct tcp_pcb **pcb, const char* ip, word16 port, int udp); + void tcp_CloseSocket_nb(struct tcp_pcb *pcb) ; + #define tcp_connect(s, h, p, f) tcp_connect_nb(s, h, p, f) + #define CloseSocket(s) tcp_CloseSocket_nb(s) + #define CyaSSL_set_fd(ssl, s) +#endif + +#if defined(HAVE_LWIP_NATIVE) +#define SWITCH_STAT switch(client_stat) { case CLIENT_BEGIN: +#define CASE(stat) client_stat = stat ; case stat +#define BREAK break +#define END_SWITCH } +#define STATIC_NB static +#else +#define SWITCH_STAT +#define CASE(value) +#define BREAK +#define END_SWITHCH +#define STATIC_NB +#endif + +