diff options
| author | auth12 <[email protected]> | 2020-07-22 08:40:38 -0700 |
|---|---|---|
| committer | auth12 <[email protected]> | 2020-07-22 08:40:38 -0700 |
| commit | 4ff89e85e74884e8f04edb5c31a94b4323e895e9 (patch) | |
| tree | 65f98ebf9af0d0947e44bf397b1fac0f107d7a2f /client/wolfssl/src/wolfio.c | |
| parent | Client injection. (diff) | |
| download | loader-4ff89e85e74884e8f04edb5c31a94b4323e895e9.tar.xz loader-4ff89e85e74884e8f04edb5c31a94b4323e895e9.zip | |
Removed wolfssl
Diffstat (limited to 'client/wolfssl/src/wolfio.c')
| -rw-r--r-- | client/wolfssl/src/wolfio.c | 2375 |
1 files changed, 0 insertions, 2375 deletions
diff --git a/client/wolfssl/src/wolfio.c b/client/wolfssl/src/wolfio.c deleted file mode 100644 index b7032ca..0000000 --- a/client/wolfssl/src/wolfio.c +++ /dev/null @@ -1,2375 +0,0 @@ -/* wolfio.c - * - * Copyright (C) 2006-2020 wolfSSL Inc. - * - * This file is part of wolfSSL. - * - * wolfSSL 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. - * - * wolfSSL 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA - */ - - - -#ifdef HAVE_CONFIG_H - #include <config.h> -#endif - -#include <wolfssl/wolfcrypt/settings.h> - -#ifndef WOLFCRYPT_ONLY - -#ifdef _WIN32_WCE - /* On WinCE winsock2.h must be included before windows.h for socket stuff */ - #include <winsock2.h> -#endif - -#include <wolfssl/internal.h> -#include <wolfssl/error-ssl.h> -#include <wolfssl/wolfio.h> - -#if defined(HAVE_HTTP_CLIENT) - #include <stdlib.h> /* strtol() */ -#endif - -/* -Possible IO enable options: - * WOLFSSL_USER_IO: Disables default Embed* callbacks and default: off - allows user to define their own using - wolfSSL_CTX_SetIORecv and wolfSSL_CTX_SetIOSend - * USE_WOLFSSL_IO: Enables the wolfSSL IO functions default: off - * HAVE_HTTP_CLIENT: Enables HTTP client API's default: off - (unless HAVE_OCSP or HAVE_CRL_IO defined) - * HAVE_IO_TIMEOUT: Enables support for connect timeout default: off - */ - - -/* if user writes own I/O callbacks they can define WOLFSSL_USER_IO to remove - automatic setting of default I/O functions EmbedSend() and EmbedReceive() - but they'll still need SetCallback xxx() at end of file -*/ - -#if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT) - -/* Translates return codes returned from - * send() and recv() if need be. - */ -static WC_INLINE int TranslateReturnCode(int old, int sd) -{ - (void)sd; - -#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) - if (old == 0) { - errno = SOCKET_EWOULDBLOCK; - return -1; /* convert to BSD style wouldblock as error */ - } - - if (old < 0) { - errno = RTCS_geterror(sd); - if (errno == RTCSERR_TCP_CONN_CLOSING) - return 0; /* convert to BSD style closing */ - if (errno == RTCSERR_TCP_CONN_RLSD) - errno = SOCKET_ECONNRESET; - if (errno == RTCSERR_TCP_TIMED_OUT) - errno = SOCKET_EAGAIN; - } -#endif - - return old; -} - -static WC_INLINE int wolfSSL_LastError(void) -{ -#ifdef USE_WINDOWS_API - return WSAGetLastError(); -#elif defined(EBSNET) - return xn_getlasterror(); -#else - return errno; -#endif -} - -#endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */ - - -#ifdef OPENSSL_EXTRA -/* Use the WOLFSSL read BIO for receiving data. This is set by the function - * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIORecv. - * - * ssl WOLFSSL struct passed in that has this function set as the receive - * callback. - * buf buffer to fill with data read - * sz size of buf buffer - * ctx a user set context - * - * returns the amount of data read or want read. See WOLFSSL_CBIO_ERR_* values. - */ -int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx) -{ - int recvd = WOLFSSL_CBIO_ERR_GENERAL; - - WOLFSSL_ENTER("BioReceive"); - - if (ssl->biord == NULL) { - WOLFSSL_MSG("WOLFSSL biord not set"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - if (ssl->biord->method && ssl->biord->method->readCb) { - WOLFSSL_MSG("Calling custom biord"); - recvd = ssl->biord->method->readCb(ssl->biord, buf, sz); - if (recvd < 0 && recvd != WOLFSSL_CBIO_ERR_WANT_READ) - return WOLFSSL_CBIO_ERR_GENERAL; - return recvd; - } - - switch (ssl->biord->type) { - case WOLFSSL_BIO_MEMORY: - case WOLFSSL_BIO_BIO: - if (wolfSSL_BIO_ctrl_pending(ssl->biord) == 0) { - WOLFSSL_MSG("BIO want read"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - recvd = wolfSSL_BIO_read(ssl->biord, buf, sz); - if (recvd <= 0) { - WOLFSSL_MSG("BIO general error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - break; - - default: - WOLFSSL_MSG("This BIO type is unknown / unsupported"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - (void)ctx; - return recvd; -} - - -/* Use the WOLFSSL write BIO for sending data. This is set by the function - * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIOSend. - * - * ssl WOLFSSL struct passed in that has this function set as the send callback. - * buf buffer with data to write out - * sz size of buf buffer - * ctx a user set context - * - * returns the amount of data sent or want send. See WOLFSSL_CBIO_ERR_* values. - */ -int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) -{ - int sent = WOLFSSL_CBIO_ERR_GENERAL; - - WOLFSSL_ENTER("BioSend"); - - if (ssl->biowr == NULL) { - WOLFSSL_MSG("WOLFSSL biowr not set"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - if (ssl->biowr->method && ssl->biowr->method->writeCb) { - WOLFSSL_MSG("Calling custom biowr"); - sent = ssl->biowr->method->writeCb(ssl->biowr, buf, sz); - if (sent < 0) { - return WOLFSSL_CBIO_ERR_GENERAL; - } - return sent; - } - - switch (ssl->biowr->type) { - case WOLFSSL_BIO_MEMORY: - case WOLFSSL_BIO_BIO: - sent = wolfSSL_BIO_write(ssl->biowr, buf, sz); - if (sent < 0) { - return WOLFSSL_CBIO_ERR_GENERAL; - } - break; - - default: - WOLFSSL_MSG("This BIO type is unknown / unsupported"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - (void)ctx; - - return sent; -} -#endif - - -#ifdef USE_WOLFSSL_IO - -/* The receive embedded callback - * return : nb bytes read, or error - */ -int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) -{ - int sd = *(int*)ctx; - int recvd; - - recvd = wolfIO_Recv(sd, buf, sz, ssl->rflags); - if (recvd < 0) { - int err = wolfSSL_LastError(); - WOLFSSL_MSG("Embed Receive error"); - - if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { - WOLFSSL_MSG("\tWould block"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - else if (err == SOCKET_ECONNRESET) { - WOLFSSL_MSG("\tConnection reset"); - return WOLFSSL_CBIO_ERR_CONN_RST; - } - else if (err == SOCKET_EINTR) { - WOLFSSL_MSG("\tSocket interrupted"); - return WOLFSSL_CBIO_ERR_ISR; - } - else if (err == SOCKET_ECONNABORTED) { - WOLFSSL_MSG("\tConnection aborted"); - return WOLFSSL_CBIO_ERR_CONN_CLOSE; - } - else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - else if (recvd == 0) { - WOLFSSL_MSG("Embed receive connection closed"); - return WOLFSSL_CBIO_ERR_CONN_CLOSE; - } - - return recvd; -} - -/* The send embedded callback - * return : nb bytes sent, or error - */ -int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) -{ - int sd = *(int*)ctx; - int sent; - -#ifdef WOLFSSL_MAX_SEND_SZ - if (sz > WOLFSSL_MAX_SEND_SZ) - sz = WOLFSSL_MAX_SEND_SZ; -#endif - - sent = wolfIO_Send(sd, buf, sz, ssl->wflags); - if (sent < 0) { - int err = wolfSSL_LastError(); - WOLFSSL_MSG("Embed Send error"); - - if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { - WOLFSSL_MSG("\tWould Block"); - return WOLFSSL_CBIO_ERR_WANT_WRITE; - } - else if (err == SOCKET_ECONNRESET) { - WOLFSSL_MSG("\tConnection reset"); - return WOLFSSL_CBIO_ERR_CONN_RST; - } - else if (err == SOCKET_EINTR) { - WOLFSSL_MSG("\tSocket interrupted"); - return WOLFSSL_CBIO_ERR_ISR; - } - else if (err == SOCKET_EPIPE) { - WOLFSSL_MSG("\tSocket EPIPE"); - return WOLFSSL_CBIO_ERR_CONN_CLOSE; - } - else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - - return sent; -} - - -#ifdef WOLFSSL_DTLS - -#include <wolfssl/wolfcrypt/sha.h> - -#define SENDTO_FUNCTION sendto -#define RECVFROM_FUNCTION recvfrom - - -/* The receive embedded callback - * return : nb bytes read, or error - */ -int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) -{ - WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; - int recvd; - int err; - int sd = dtlsCtx->rfd; - int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); - SOCKADDR_S peer; - XSOCKLENT peerSz = sizeof(peer); - - WOLFSSL_ENTER("EmbedReceiveFrom()"); - - if (ssl->options.handShakeDone) - dtls_timeout = 0; - - if (!wolfSSL_get_using_nonblock(ssl)) { - #ifdef USE_WINDOWS_API - DWORD timeout = dtls_timeout * 1000; - #else - struct timeval timeout; - XMEMSET(&timeout, 0, sizeof(timeout)); - timeout.tv_sec = dtls_timeout; - #endif - if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, - sizeof(timeout)) != 0) { - WOLFSSL_MSG("setsockopt rcvtimeo failed"); - } - } - - recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags, - (SOCKADDR*)&peer, &peerSz); - - recvd = TranslateReturnCode(recvd, sd); - - if (recvd < 0) { - err = wolfSSL_LastError(); - WOLFSSL_MSG("Embed Receive From error"); - - if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { - if (wolfSSL_dtls_get_using_nonblock(ssl)) { - WOLFSSL_MSG("\tWould block"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - else { - WOLFSSL_MSG("\tSocket timeout"); - return WOLFSSL_CBIO_ERR_TIMEOUT; - } - } - else if (err == SOCKET_ECONNRESET) { - WOLFSSL_MSG("\tConnection reset"); - return WOLFSSL_CBIO_ERR_CONN_RST; - } - else if (err == SOCKET_EINTR) { - WOLFSSL_MSG("\tSocket interrupted"); - return WOLFSSL_CBIO_ERR_ISR; - } - else if (err == SOCKET_ECONNREFUSED) { - WOLFSSL_MSG("\tConnection refused"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - else { - if (dtlsCtx->peer.sz > 0 - && peerSz != (XSOCKLENT)dtlsCtx->peer.sz - && XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) { - WOLFSSL_MSG(" Ignored packet from invalid peer"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - } - - return recvd; -} - - -/* The send embedded callback - * return : nb bytes sent, or error - */ -int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) -{ - WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; - int sd = dtlsCtx->wfd; - int sent; - int err; - - WOLFSSL_ENTER("EmbedSendTo()"); - - sent = (int)SENDTO_FUNCTION(sd, buf, sz, ssl->wflags, - (const SOCKADDR*)dtlsCtx->peer.sa, - dtlsCtx->peer.sz); - - sent = TranslateReturnCode(sent, sd); - - if (sent < 0) { - err = wolfSSL_LastError(); - WOLFSSL_MSG("Embed Send To error"); - - if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { - WOLFSSL_MSG("\tWould Block"); - return WOLFSSL_CBIO_ERR_WANT_WRITE; - } - else if (err == SOCKET_ECONNRESET) { - WOLFSSL_MSG("\tConnection reset"); - return WOLFSSL_CBIO_ERR_CONN_RST; - } - else if (err == SOCKET_EINTR) { - WOLFSSL_MSG("\tSocket interrupted"); - return WOLFSSL_CBIO_ERR_ISR; - } - else if (err == SOCKET_EPIPE) { - WOLFSSL_MSG("\tSocket EPIPE"); - return WOLFSSL_CBIO_ERR_CONN_CLOSE; - } - else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - - return sent; -} - - -#ifdef WOLFSSL_MULTICAST - -/* The alternate receive embedded callback for Multicast - * return : nb bytes read, or error - */ -int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, int sz, void *ctx) -{ - WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; - int recvd; - int err; - int sd = dtlsCtx->rfd; - - WOLFSSL_ENTER("EmbedReceiveFromMcast()"); - - recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags, NULL, NULL); - - recvd = TranslateReturnCode(recvd, sd); - - if (recvd < 0) { - err = wolfSSL_LastError(); - WOLFSSL_MSG("Embed Receive From error"); - - if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { - if (wolfSSL_dtls_get_using_nonblock(ssl)) { - WOLFSSL_MSG("\tWould block"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - else { - WOLFSSL_MSG("\tSocket timeout"); - return WOLFSSL_CBIO_ERR_TIMEOUT; - } - } - else if (err == SOCKET_ECONNRESET) { - WOLFSSL_MSG("\tConnection reset"); - return WOLFSSL_CBIO_ERR_CONN_RST; - } - else if (err == SOCKET_EINTR) { - WOLFSSL_MSG("\tSocket interrupted"); - return WOLFSSL_CBIO_ERR_ISR; - } - else if (err == SOCKET_ECONNREFUSED) { - WOLFSSL_MSG("\tConnection refused"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - - return recvd; -} -#endif /* WOLFSSL_MULTICAST */ - - -/* The DTLS Generate Cookie callback - * return : number of bytes copied into buf, or error - */ -int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) -{ - int sd = ssl->wfd; - SOCKADDR_S peer; - XSOCKLENT peerSz = sizeof(peer); - byte digest[WC_SHA256_DIGEST_SIZE]; - int ret = 0; - - (void)ctx; - - XMEMSET(&peer, 0, sizeof(peer)); - if (getpeername(sd, (SOCKADDR*)&peer, &peerSz) != 0) { - WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie"); - return GEN_COOKIE_E; - } - - ret = wc_Sha256Hash((byte*)&peer, peerSz, digest); - if (ret != 0) - return ret; - - if (sz > WC_SHA256_DIGEST_SIZE) - sz = WC_SHA256_DIGEST_SIZE; - XMEMCPY(buf, digest, sz); - - return sz; -} - -#ifdef WOLFSSL_SESSION_EXPORT - - /* get the peer information in human readable form (ip, port, family) - * default function assumes BSD sockets - * can be overridden with wolfSSL_CTX_SetIOGetPeer - */ - int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz, - unsigned short* port, int* fam) - { - SOCKADDR_S peer; - word32 peerSz; - int ret; - - if (ssl == NULL || ip == NULL || ipSz == NULL || - port == NULL || fam == NULL) { - return BAD_FUNC_ARG; - } - - /* get peer information stored in ssl struct */ - peerSz = sizeof(SOCKADDR_S); - if ((ret = wolfSSL_dtls_get_peer(ssl, (void*)&peer, &peerSz)) - != WOLFSSL_SUCCESS) { - return ret; - } - - /* extract family, ip, and port */ - *fam = ((SOCKADDR_S*)&peer)->ss_family; - switch (*fam) { - case WOLFSSL_IP4: - if (XINET_NTOP(*fam, &(((SOCKADDR_IN*)&peer)->sin_addr), - ip, *ipSz) == NULL) { - WOLFSSL_MSG("XINET_NTOP error"); - return SOCKET_ERROR_E; - } - *port = XNTOHS(((SOCKADDR_IN*)&peer)->sin_port); - break; - - case WOLFSSL_IP6: - #ifdef WOLFSSL_IPV6 - if (XINET_NTOP(*fam, &(((SOCKADDR_IN6*)&peer)->sin6_addr), - ip, *ipSz) == NULL) { - WOLFSSL_MSG("XINET_NTOP error"); - return SOCKET_ERROR_E; - } - *port = XNTOHS(((SOCKADDR_IN6*)&peer)->sin6_port); - #endif /* WOLFSSL_IPV6 */ - break; - - default: - WOLFSSL_MSG("Unknown family type"); - return SOCKET_ERROR_E; - } - ip[*ipSz - 1] = '\0'; /* make sure has terminator */ - *ipSz = (word16)XSTRLEN(ip); - - return WOLFSSL_SUCCESS; - } - - /* set the peer information in human readable form (ip, port, family) - * default function assumes BSD sockets - * can be overridden with wolfSSL_CTX_SetIOSetPeer - */ - int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz, - unsigned short port, int fam) - { - int ret; - SOCKADDR_S addr; - - /* sanity checks on arguments */ - if (ssl == NULL || ip == NULL || ipSz < 0 || ipSz > DTLS_EXPORT_IP) { - return BAD_FUNC_ARG; - } - - addr.ss_family = fam; - switch (addr.ss_family) { - case WOLFSSL_IP4: - if (XINET_PTON(addr.ss_family, ip, - &(((SOCKADDR_IN*)&addr)->sin_addr)) <= 0) { - WOLFSSL_MSG("XINET_PTON error"); - return SOCKET_ERROR_E; - } - ((SOCKADDR_IN*)&addr)->sin_port = XHTONS(port); - - /* peer sa is free'd in SSL_ResourceFree */ - if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN*)&addr, - sizeof(SOCKADDR_IN)))!= WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Import DTLS peer info error"); - return ret; - } - break; - - case WOLFSSL_IP6: - #ifdef WOLFSSL_IPV6 - if (XINET_PTON(addr.ss_family, ip, - &(((SOCKADDR_IN6*)&addr)->sin6_addr)) <= 0) { - WOLFSSL_MSG("XINET_PTON error"); - return SOCKET_ERROR_E; - } - ((SOCKADDR_IN6*)&addr)->sin6_port = XHTONS(port); - - /* peer sa is free'd in SSL_ResourceFree */ - if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN6*)&addr, - sizeof(SOCKADDR_IN6)))!= WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Import DTLS peer info error"); - return ret; - } - #endif /* WOLFSSL_IPV6 */ - break; - - default: - WOLFSSL_MSG("Unknown address family"); - return BUFFER_E; - } - - return WOLFSSL_SUCCESS; - } -#endif /* WOLFSSL_SESSION_EXPORT */ -#endif /* WOLFSSL_DTLS */ - - -int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags) -{ - int recvd; - - recvd = (int)RECV_FUNCTION(sd, buf, sz, rdFlags); - recvd = TranslateReturnCode(recvd, sd); - - return recvd; -} - -int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags) -{ - int sent; - - sent = (int)SEND_FUNCTION(sd, buf, sz, wrFlags); - sent = TranslateReturnCode(sent, sd); - - return sent; -} - -#endif /* USE_WOLFSSL_IO */ - - -#ifdef HAVE_HTTP_CLIENT - -#ifndef HAVE_IO_TIMEOUT - #define io_timeout_sec 0 -#else - - #ifndef DEFAULT_TIMEOUT_SEC - #define DEFAULT_TIMEOUT_SEC 0 /* no timeout */ - #endif - - static int io_timeout_sec = DEFAULT_TIMEOUT_SEC; - - void wolfIO_SetTimeout(int to_sec) - { - io_timeout_sec = to_sec; - } - - int wolfIO_SetBlockingMode(SOCKET_T sockfd, int non_blocking) - { - int ret = 0; - - #ifdef USE_WINDOWS_API - unsigned long blocking = non_blocking; - ret = ioctlsocket(sockfd, FIONBIO, &blocking); - if (ret == SOCKET_ERROR) - ret = -1; - #else - ret = fcntl(sockfd, F_GETFL, 0); - if (ret >= 0) { - if (non_blocking) - ret |= O_NONBLOCK; - else - ret &= ~O_NONBLOCK; - ret = fcntl(sockfd, F_SETFL, ret); - } - #endif - if (ret < 0) { - WOLFSSL_MSG("wolfIO_SetBlockingMode failed"); - } - - return ret; - } - - int wolfIO_Select(SOCKET_T sockfd, int to_sec) - { - fd_set rfds, wfds; - int nfds = 0; - struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0}; - int ret; - - #ifndef USE_WINDOWS_API - nfds = (int)sockfd + 1; - #endif - - FD_ZERO(&rfds); - FD_SET(sockfd, &rfds); - wfds = rfds; - - ret = select(nfds, &rfds, &wfds, NULL, &timeout); - if (ret == 0) { - #ifdef DEBUG_HTTP - printf("Timeout: %d\n", ret); - #endif - return HTTP_TIMEOUT; - } - else if (ret > 0) { - if (FD_ISSET(sockfd, &wfds)) { - if (!FD_ISSET(sockfd, &rfds)) { - return 0; - } - } - } - return SOCKET_ERROR_E; - } -#endif /* HAVE_IO_TIMEOUT */ - -static int wolfIO_Word16ToString(char* d, word16 number) -{ - int i = 0; - word16 order = 10000; - word16 digit; - - if (d == NULL) - return i; - - if (number == 0) - d[i++] = '0'; - else { - while (order) { - digit = number / order; - if (i > 0 || digit != 0) - d[i++] = (char)digit + '0'; - if (digit != 0) - number %= digit * order; - - order = (order > 1) ? order / 10 : 0; - } - } - d[i] = 0; /* null terminate */ - - return i; -} - -int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) -{ -#ifdef HAVE_SOCKADDR - int ret = 0; - SOCKADDR_S addr; - int sockaddr_len = sizeof(SOCKADDR_IN); - /* use gethostbyname for c99 */ -#if defined(HAVE_GETADDRINFO) && !defined(WOLF_C99) - ADDRINFO hints; - ADDRINFO* answer = NULL; - char strPort[6]; -#else - HOSTENT* entry; - SOCKADDR_IN *sin; -#endif - - XMEMSET(&addr, 0, sizeof(addr)); - -#ifdef WOLFIO_DEBUG - printf("TCP Connect: %s:%d\n", ip, port); -#endif - - /* use gethostbyname for c99 */ -#if defined(HAVE_GETADDRINFO) && !defined(WOLF_C99) - XMEMSET(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - if (wolfIO_Word16ToString(strPort, port) == 0) { - WOLFSSL_MSG("invalid port number for responder"); - return -1; - } - - if (getaddrinfo(ip, strPort, &hints, &answer) < 0 || answer == NULL) { - WOLFSSL_MSG("no addr info for responder"); - return -1; - } - - sockaddr_len = answer->ai_addrlen; - XMEMCPY(&addr, answer->ai_addr, sockaddr_len); - freeaddrinfo(answer); -#else - entry = gethostbyname(ip); - sin = (SOCKADDR_IN *)&addr; - - if (entry) { - sin->sin_family = AF_INET; - sin->sin_port = XHTONS(port); - XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0], entry->h_length); - } - else { - WOLFSSL_MSG("no addr info for responder"); - return -1; - } -#endif - - *sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM, 0); - -#ifdef USE_WINDOWS_API - if (*sockfd == INVALID_SOCKET) { - WOLFSSL_MSG("bad socket fd, out of fds?"); - return -1; - } -#else - if (*sockfd < 0) { - WOLFSSL_MSG("bad socket fd, out of fds?"); - return -1; - } -#endif - -#ifdef HAVE_IO_TIMEOUT - /* if timeout value provided then set socket non-blocking */ - if (to_sec > 0) { - wolfIO_SetBlockingMode(*sockfd, 1); - } -#else - (void)to_sec; -#endif - - ret = connect(*sockfd, (SOCKADDR *)&addr, sockaddr_len); -#ifdef HAVE_IO_TIMEOUT - if (ret != 0) { - if ((errno == EINPROGRESS) && (to_sec > 0)) { - /* wait for connect to complete */ - ret = wolfIO_Select(*sockfd, to_sec); - - /* restore blocking mode */ - wolfIO_SetBlockingMode(*sockfd, 0); - } - } -#endif - if (ret != 0) { - WOLFSSL_MSG("Responder tcp connect failed"); - return -1; - } - return ret; -#else - (void)sockfd; - (void)ip; - (void)port; - (void)to_sec; - return -1; -#endif /* HAVE_SOCKADDR */ -} - -#ifndef HTTP_SCRATCH_BUFFER_SIZE - #define HTTP_SCRATCH_BUFFER_SIZE 512 -#endif -#ifndef MAX_URL_ITEM_SIZE - #define MAX_URL_ITEM_SIZE 80 -#endif - -int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath, - word16* outPort) -{ - int result = -1; - - if (url == NULL || urlSz == 0) { - if (outName) - *outName = 0; - if (outPath) - *outPath = 0; - if (outPort) - *outPort = 0; - } - else { - int i, cur; - - /* need to break the url down into scheme, address, and port */ - /* "http://example.com:8080/" */ - /* "http://[::1]:443/" */ - if (XSTRNCMP(url, "http://", 7) == 0) { - cur = 7; - } else cur = 0; - - i = 0; - if (url[cur] == '[') { - cur++; - /* copy until ']' */ - while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0 && - url[cur] != ']') { - if (outName) - outName[i] = url[cur]; - i++; cur++; - } - cur++; /* skip ']' */ - } - else { - while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0 && - url[cur] != ':' && url[cur] != '/') { - if (outName) - outName[i] = url[cur]; - i++; cur++; - } - } - if (outName) - outName[i] = 0; - /* Need to pick out the path after the domain name */ - - if (cur < urlSz && url[cur] == ':') { - char port[6]; - int j; - word32 bigPort = 0; - i = 0; - cur++; - while (i < 6 && cur < urlSz && url[cur] != 0 && url[cur] != '/') { - port[i] = url[cur]; - i++; cur++; - } - - for (j = 0; j < i; j++) { - if (port[j] < '0' || port[j] > '9') return -1; - bigPort = (bigPort * 10) + (port[j] - '0'); - } - if (outPort) - *outPort = (word16)bigPort; - } - else if (outPort) - *outPort = 80; - - - if (cur < urlSz && url[cur] == '/') { - i = 0; - while (i < MAX_URL_ITEM_SIZE-1 && cur < urlSz && url[cur] != 0) { - if (outPath) - outPath[i] = url[cur]; - i++; cur++; - } - if (outPath) - outPath[i] = 0; - } - else if (outPath) { - outPath[0] = '/'; - outPath[1] = 0; - } - - result = 0; - } - - return result; -} - -static int wolfIO_HttpProcessResponseBuf(int sfd, byte **recvBuf, - int* recvBufSz, int chunkSz, char* start, int len, int dynType, void* heap) -{ - byte* newRecvBuf = NULL; - int newRecvSz = *recvBufSz + chunkSz; - int pos = 0; - - WOLFSSL_MSG("Processing HTTP response"); -#ifdef WOLFIO_DEBUG - printf("HTTP Chunk %d->%d\n", *recvBufSz, chunkSz); -#endif - - (void)heap; - (void)dynType; - - if (chunkSz < 0 || len < 0) { - WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf invalid chunk or length size"); - return MEMORY_E; - } - - if (newRecvSz <= 0) { - WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf new receive size overflow"); - return MEMORY_E; - } - - newRecvBuf = (byte*)XMALLOC(newRecvSz, heap, dynType); - if (newRecvBuf == NULL) { - WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf malloc failed"); - return MEMORY_E; - } - - /* if buffer already exists, then we are growing it */ - if (*recvBuf) { - XMEMCPY(&newRecvBuf[pos], *recvBuf, *recvBufSz); - XFREE(*recvBuf, heap, dynType); - pos += *recvBufSz; - *recvBuf = NULL; - } - - /* copy the remainder of the httpBuf into the respBuf */ - if (len != 0) { - if (pos + len <= newRecvSz) { - XMEMCPY(&newRecvBuf[pos], start, len); - pos += len; - } - else { - WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf bad size"); - XFREE(newRecvBuf, heap, dynType); - return -1; - } - } - - /* receive the remainder of chunk */ - while (len < chunkSz) { - int rxSz = wolfIO_Recv(sfd, (char*)&newRecvBuf[pos], chunkSz-len, 0); - if (rxSz > 0) { - len += rxSz; - pos += rxSz; - } - else { - WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf recv failed"); - XFREE(newRecvBuf, heap, dynType); - return -1; - } - } - - *recvBuf = newRecvBuf; - *recvBufSz = newRecvSz; - - return 0; -} - -int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, - byte** respBuf, byte* httpBuf, int httpBufSz, int dynType, void* heap) -{ - int result = 0; - int len = 0; - char *start, *end; - int respBufSz = 0; - int isChunked = 0, chunkSz = 0; - enum phr_state { phr_init, phr_http_start, phr_have_length, phr_have_type, - phr_wait_end, phr_get_chunk_len, phr_get_chunk_data, - phr_http_end - } state = phr_init; - - *respBuf = NULL; - start = end = NULL; - do { - if (state == phr_get_chunk_data) { - /* get chunk of data */ - result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz, - chunkSz, start, len, dynType, heap); - - state = (result != 0) ? phr_http_end : phr_get_chunk_len; - end = NULL; - len = 0; - } - - /* read data if no \r\n or first time */ - if (end == NULL) { - result = wolfIO_Recv(sfd, (char*)httpBuf+len, httpBufSz-len-1, 0); - if (result > 0) { - len += result; - start = (char*)httpBuf; - start[len] = 0; - } - else { - WOLFSSL_MSG("wolfIO_HttpProcessResponse recv http from peer failed"); - return -1; - } - } - end = XSTRSTR(start, "\r\n"); /* locate end */ - - /* handle incomplete rx */ - if (end == NULL) { - if (len != 0) - XMEMMOVE(httpBuf, start, len); - start = end = NULL; - } - /* when start is "\r\n" */ - else if (end == start) { - /* if waiting for end or need chunk len */ - if (state == phr_wait_end || state == phr_get_chunk_len) { - state = (isChunked) ? phr_get_chunk_len : phr_http_end; - len -= 2; start += 2; /* skip \r\n */ - } - else { - WOLFSSL_MSG("wolfIO_HttpProcessResponse header ended early"); - return -1; - } - } - else { - *end = 0; /* null terminate */ - len -= (int)(end - start) + 2; - /* adjust len to remove the first line including the /r/n */ - - #ifdef WOLFIO_DEBUG - printf("HTTP Resp: %s\n", start); - #endif - - switch (state) { - case phr_init: - if (XSTRLEN(start) < 15) { /* 15 is the length of the two - constant strings we're about to - compare against. */ - WOLFSSL_MSG("wolfIO_HttpProcessResponse HTTP header too short."); - return -1; - } - if (XSTRNCASECMP(start, "HTTP/1", 6) == 0) { - start += 9; - if (XSTRNCASECMP(start, "200 OK", 6) != 0) { - WOLFSSL_MSG("wolfIO_HttpProcessResponse not OK"); - return -1; - } - state = phr_http_start; - } - break; - case phr_http_start: - case phr_have_length: - case phr_have_type: - if (XSTRLEN(start) < 13) { /* 13 is the shortest of the following - next lines we're checking for. */ - WOLFSSL_MSG("wolfIO_HttpProcessResponse content type is too short."); - return -1; - } - - if (XSTRNCASECMP(start, "Content-Type:", 13) == 0) { - int i; - - start += 13; - while (*start == ' ') start++; - - /* try and match against appStrList */ - i = 0; - while (appStrList[i] != NULL) { - if (XSTRNCASECMP(start, appStrList[i], - XSTRLEN(appStrList[i])) == 0) { - break; - } - i++; - } - if (appStrList[i] == NULL) { - WOLFSSL_MSG("wolfIO_HttpProcessResponse appstr mismatch"); - return -1; - } - state = (state == phr_http_start) ? phr_have_type : phr_wait_end; - } - else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) { - start += 15; - while (*start == ' ') start++; - chunkSz = XATOI(start); - state = (state == phr_http_start) ? phr_have_length : phr_wait_end; - } - else if (XSTRNCASECMP(start, "Transfer-Encoding:", 18) == 0) { - start += 18; - while (*start == ' ') start++; - if (XSTRNCASECMP(start, "chunked", 7) == 0) { - isChunked = 1; - state = (state == phr_http_start) ? phr_have_length : phr_wait_end; - } - } - break; - case phr_get_chunk_len: - chunkSz = (int)strtol(start, NULL, 16); /* hex format */ - state = (chunkSz == 0) ? phr_http_end : phr_get_chunk_data; - break; - case phr_get_chunk_data: - /* processing for chunk data done above, since \r\n isn't required */ - case phr_wait_end: - case phr_http_end: - /* do nothing */ - break; - } /* switch (state) */ - - /* skip to end plus \r\n */ - start = end + 2; - } - } while (state != phr_http_end); - - if (!isChunked) { - result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz, chunkSz, - start, len, dynType, heap); - } - - if (result >= 0) { - result = respBufSz; - } - else { - WOLFSSL_ERROR(result); - } - - return result; -} -int wolfIO_HttpBuildRequest(const char *reqType, const char *domainName, - const char *path, int pathLen, int reqSz, const char *contentType, - byte *buf, int bufSize) -{ - return wolfIO_HttpBuildRequest_ex(reqType, domainName, path, pathLen, reqSz, contentType, "", buf, bufSize); -} - - int wolfIO_HttpBuildRequest_ex(const char *reqType, const char *domainName, - const char *path, int pathLen, int reqSz, const char *contentType, - const char *exHdrs, byte *buf, int bufSize) - { - word32 reqTypeLen, domainNameLen, reqSzStrLen, contentTypeLen, exHdrsLen, maxLen; - char reqSzStr[6]; - char* req = (char*)buf; - const char* blankStr = " "; - const char* http11Str = " HTTP/1.1"; - const char* hostStr = "\r\nHost: "; - const char* contentLenStr = "\r\nContent-Length: "; - const char* contentTypeStr = "\r\nContent-Type: "; - const char* singleCrLfStr = "\r\n"; - const char* doubleCrLfStr = "\r\n\r\n"; - word32 blankStrLen, http11StrLen, hostStrLen, contentLenStrLen, - contentTypeStrLen, singleCrLfStrLen, doubleCrLfStrLen; - - reqTypeLen = (word32)XSTRLEN(reqType); - domainNameLen = (word32)XSTRLEN(domainName); - reqSzStrLen = wolfIO_Word16ToString(reqSzStr, (word16)reqSz); - contentTypeLen = (word32)XSTRLEN(contentType); - - blankStrLen = (word32)XSTRLEN(blankStr); - http11StrLen = (word32)XSTRLEN(http11Str); - hostStrLen = (word32)XSTRLEN(hostStr); - contentLenStrLen = (word32)XSTRLEN(contentLenStr); - contentTypeStrLen = (word32)XSTRLEN(contentTypeStr); - - if(exHdrs){ - singleCrLfStrLen = (word32)XSTRLEN(singleCrLfStr); - exHdrsLen = (word32)XSTRLEN(exHdrs); - } else { - singleCrLfStrLen = 0; - exHdrsLen = 0; - } - - doubleCrLfStrLen = (word32)XSTRLEN(doubleCrLfStr); - - /* determine max length and check it */ - maxLen = - reqTypeLen + - blankStrLen + - pathLen + - http11StrLen + - hostStrLen + - domainNameLen + - contentLenStrLen + - reqSzStrLen + - contentTypeStrLen + - contentTypeLen + - singleCrLfStrLen + - exHdrsLen + - doubleCrLfStrLen + - 1 /* null term */; - if (maxLen > (word32)bufSize) - return 0; - - XSTRNCPY((char*)buf, reqType, bufSize); - buf += reqTypeLen; bufSize -= reqTypeLen; - XSTRNCPY((char*)buf, blankStr, bufSize); - buf += blankStrLen; bufSize -= blankStrLen; - XSTRNCPY((char*)buf, path, bufSize); - buf += pathLen; bufSize -= pathLen; - XSTRNCPY((char*)buf, http11Str, bufSize); - buf += http11StrLen; bufSize -= http11StrLen; - if (domainNameLen > 0) { - XSTRNCPY((char*)buf, hostStr, bufSize); - buf += hostStrLen; bufSize -= hostStrLen; - XSTRNCPY((char*)buf, domainName, bufSize); - buf += domainNameLen; bufSize -= domainNameLen; - } - if (reqSz > 0 && reqSzStrLen > 0) { - XSTRNCPY((char*)buf, contentLenStr, bufSize); - buf += contentLenStrLen; bufSize -= contentLenStrLen; - XSTRNCPY((char*)buf, reqSzStr, bufSize); - buf += reqSzStrLen; bufSize -= reqSzStrLen; - } - if (contentTypeLen > 0) { - XSTRNCPY((char*)buf, contentTypeStr, bufSize); - buf += contentTypeStrLen; bufSize -= contentTypeStrLen; - XSTRNCPY((char*)buf, contentType, bufSize); - buf += contentTypeLen; bufSize -= contentTypeLen; - } - if (exHdrsLen > 0) - { - XSTRNCPY((char *)buf, singleCrLfStr, bufSize); - buf += singleCrLfStrLen; - bufSize -= singleCrLfStrLen; - XSTRNCPY((char *)buf, exHdrs, bufSize); - buf += exHdrsLen; - bufSize -= exHdrsLen; - } - XSTRNCPY((char*)buf, doubleCrLfStr, bufSize); - buf += doubleCrLfStrLen; - -#ifdef WOLFIO_DEBUG - printf("HTTP %s: %s", reqType, req); -#endif - - /* calculate actual length based on original and new pointer */ - return (int)((char*)buf - req); -} - - -#ifdef HAVE_OCSP - -int wolfIO_HttpBuildRequestOcsp(const char* domainName, const char* path, - int ocspReqSz, byte* buf, int bufSize) -{ - const char *cacheCtl = "Cache-Control: no-cache"; - return wolfIO_HttpBuildRequest_ex("POST", domainName, path, (int)XSTRLEN(path), - ocspReqSz, "application/ocsp-request", cacheCtl, buf, bufSize); -} - -/* return: >0 OCSP Response Size - * -1 error */ -int wolfIO_HttpProcessResponseOcsp(int sfd, byte** respBuf, - byte* httpBuf, int httpBufSz, void* heap) -{ - const char* appStrList[] = { - "application/ocsp-response", - NULL - }; - - return wolfIO_HttpProcessResponse(sfd, appStrList, - respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_OCSP, heap); -} - -/* in default wolfSSL callback ctx is the heap pointer */ -int EmbedOcspLookup(void* ctx, const char* url, int urlSz, - byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf) -{ - SOCKET_T sfd = 0; - word16 port; - int ret = -1; -#ifdef WOLFSSL_SMALL_STACK - char* path; - char* domainName; -#else - char path[MAX_URL_ITEM_SIZE]; - char domainName[MAX_URL_ITEM_SIZE]; -#endif - -#ifdef WOLFSSL_SMALL_STACK - path = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (path == NULL) - return MEMORY_E; - - domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (domainName == NULL) { - XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - if (ocspReqBuf == NULL || ocspReqSz == 0) { - WOLFSSL_MSG("OCSP request is required for lookup"); - } - else if (ocspRespBuf == NULL) { - WOLFSSL_MSG("Cannot save OCSP response"); - } - else if (wolfIO_DecodeUrl(url, urlSz, domainName, path, &port) < 0) { - WOLFSSL_MSG("Unable to decode OCSP URL"); - } - else { - /* Note, the library uses the EmbedOcspRespFree() callback to - * free this buffer. */ - int httpBufSz = HTTP_SCRATCH_BUFFER_SIZE; - byte* httpBuf = (byte*)XMALLOC(httpBufSz, ctx, DYNAMIC_TYPE_OCSP); - - if (httpBuf == NULL) { - WOLFSSL_MSG("Unable to create OCSP response buffer"); - } - else { - httpBufSz = wolfIO_HttpBuildRequestOcsp(domainName, path, ocspReqSz, - httpBuf, httpBufSz); - - ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec); - if ((ret != 0) || ((int)sfd < 0)) { - WOLFSSL_MSG("OCSP Responder connection failed"); - } - else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0) != - httpBufSz) { - WOLFSSL_MSG("OCSP http request failed"); - } - else if (wolfIO_Send(sfd, (char*)ocspReqBuf, ocspReqSz, 0) != - ocspReqSz) { - WOLFSSL_MSG("OCSP ocsp request failed"); - } - else { - ret = wolfIO_HttpProcessResponseOcsp(sfd, ocspRespBuf, httpBuf, - HTTP_SCRATCH_BUFFER_SIZE, ctx); - } - - CloseSocket(sfd); - XFREE(httpBuf, ctx, DYNAMIC_TYPE_OCSP); - } - } - -#ifdef WOLFSSL_SMALL_STACK - XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - -/* in default callback ctx is heap hint */ -void EmbedOcspRespFree(void* ctx, byte *resp) -{ - if (resp) - XFREE(resp, ctx, DYNAMIC_TYPE_OCSP); - - (void)ctx; -} -#endif /* HAVE_OCSP */ - - -#if defined(HAVE_CRL) && defined(HAVE_CRL_IO) - -int wolfIO_HttpBuildRequestCrl(const char* url, int urlSz, - const char* domainName, byte* buf, int bufSize) -{ - const char *cacheCtl = "Cache-Control: no-cache"; - return wolfIO_HttpBuildRequest_ex("GET", domainName, url, urlSz, 0, "", - cacheCtl, buf, bufSize); -} - -int wolfIO_HttpProcessResponseCrl(WOLFSSL_CRL* crl, int sfd, byte* httpBuf, - int httpBufSz) -{ - int result; - byte *respBuf = NULL; - - const char* appStrList[] = { - "application/pkix-crl", - "application/x-pkcs7-crl", - NULL - }; - - result = wolfIO_HttpProcessResponse(sfd, appStrList, - &respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_CRL, crl->heap); - if (result >= 0) { - result = BufferLoadCRL(crl, respBuf, result, WOLFSSL_FILETYPE_ASN1, 0); - } - XFREE(respBuf, crl->heap, DYNAMIC_TYPE_CRL); - - return result; -} - -int EmbedCrlLookup(WOLFSSL_CRL* crl, const char* url, int urlSz) -{ - SOCKET_T sfd = 0; - word16 port; - int ret = -1; -#ifdef WOLFSSL_SMALL_STACK - char* domainName; -#else - char domainName[MAX_URL_ITEM_SIZE]; -#endif - -#ifdef WOLFSSL_SMALL_STACK - domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, crl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (domainName == NULL) { - return MEMORY_E; - } -#endif - - if (wolfIO_DecodeUrl(url, urlSz, domainName, NULL, &port) < 0) { - WOLFSSL_MSG("Unable to decode CRL URL"); - } - else { - int httpBufSz = HTTP_SCRATCH_BUFFER_SIZE; - byte* httpBuf = (byte*)XMALLOC(httpBufSz, crl->heap, - DYNAMIC_TYPE_CRL); - if (httpBuf == NULL) { - WOLFSSL_MSG("Unable to create CRL response buffer"); - } - else { - httpBufSz = wolfIO_HttpBuildRequestCrl(url, urlSz, domainName, - httpBuf, httpBufSz); - - ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec); - if ((ret != 0) || (sfd < 0)) { - WOLFSSL_MSG("CRL connection failed"); - } - else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0) - != httpBufSz) { - WOLFSSL_MSG("CRL http get failed"); - } - else { - ret = wolfIO_HttpProcessResponseCrl(crl, sfd, httpBuf, - HTTP_SCRATCH_BUFFER_SIZE); - } - - CloseSocket(sfd); - XFREE(httpBuf, crl->heap, DYNAMIC_TYPE_CRL); - } - } - -#ifdef WOLFSSL_SMALL_STACK - XFREE(domainName, crl->heap, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} -#endif /* HAVE_CRL && HAVE_CRL_IO */ - -#endif /* HAVE_HTTP_CLIENT */ - - - -void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv) -{ - if (ctx) { - ctx->CBIORecv = CBIORecv; - #ifdef OPENSSL_EXTRA - ctx->cbioFlag |= WOLFSSL_CBIO_RECV; - #endif - } -} - - -void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend) -{ - if (ctx) { - ctx->CBIOSend = CBIOSend; - #ifdef OPENSSL_EXTRA - ctx->cbioFlag |= WOLFSSL_CBIO_SEND; - #endif - } -} - - -/* sets the IO callback to use for receives at WOLFSSL level */ -void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv) -{ - if (ssl) { - ssl->CBIORecv = CBIORecv; - #ifdef OPENSSL_EXTRA - ssl->cbioFlag |= WOLFSSL_CBIO_RECV; - #endif - } -} - - -/* sets the IO callback to use for sends at WOLFSSL level */ -void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend) -{ - if (ssl) { - ssl->CBIOSend = CBIOSend; - #ifdef OPENSSL_EXTRA - ssl->cbioFlag |= WOLFSSL_CBIO_SEND; - #endif - } -} - - -void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx) -{ - if (ssl) - ssl->IOCB_ReadCtx = rctx; -} - - -void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx) -{ - if (ssl) - ssl->IOCB_WriteCtx = wctx; -} - - -void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl) -{ - if (ssl) - return ssl->IOCB_ReadCtx; - - return NULL; -} - - -void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl) -{ - if (ssl) - return ssl->IOCB_WriteCtx; - - return NULL; -} - - -void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags) -{ - if (ssl) - ssl->rflags = flags; -} - - -void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags) -{ - if (ssl) - ssl->wflags = flags; -} - - -#ifdef WOLFSSL_DTLS - -void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb) -{ - if (ctx) - ctx->CBIOCookie = cb; -} - - -void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx) -{ - if (ssl) - ssl->IOCB_CookieCtx = ctx; -} - - -void* wolfSSL_GetCookieCtx(WOLFSSL* ssl) -{ - if (ssl) - return ssl->IOCB_CookieCtx; - - return NULL; -} - -#ifdef WOLFSSL_SESSION_EXPORT - -void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX* ctx, CallbackGetPeer cb) -{ - if (ctx) - ctx->CBGetPeer = cb; -} - - -void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb) -{ - if (ctx) - ctx->CBSetPeer = cb; -} - -#endif /* WOLFSSL_SESSION_EXPORT */ -#endif /* WOLFSSL_DTLS */ - - -#ifdef HAVE_NETX - -/* The NetX receive callback - * return : bytes read, or error - */ -int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) -{ - NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; - ULONG left; - ULONG total; - ULONG copied = 0; - UINT status; - - (void)ssl; - - if (nxCtx == NULL || nxCtx->nxSocket == NULL) { - WOLFSSL_MSG("NetX Recv NULL parameters"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - if (nxCtx->nxPacket == NULL) { - status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket, - nxCtx->nxWait); - if (status != NX_SUCCESS) { - WOLFSSL_MSG("NetX Recv receive error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - - if (nxCtx->nxPacket) { - status = nx_packet_length_get(nxCtx->nxPacket, &total); - if (status != NX_SUCCESS) { - WOLFSSL_MSG("NetX Recv length get error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - left = total - nxCtx->nxOffset; - status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset, - buf, sz, &copied); - if (status != NX_SUCCESS) { - WOLFSSL_MSG("NetX Recv data extract offset error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - nxCtx->nxOffset += copied; - - if (copied == left) { - WOLFSSL_MSG("NetX Recv Drained packet"); - nx_packet_release(nxCtx->nxPacket); - nxCtx->nxPacket = NULL; - nxCtx->nxOffset = 0; - } - } - - return copied; -} - - -/* The NetX send callback - * return : bytes sent, or error - */ -int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) -{ - NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; - NX_PACKET* packet; - NX_PACKET_POOL* pool; /* shorthand */ - UINT status; - - (void)ssl; - - if (nxCtx == NULL || nxCtx->nxSocket == NULL) { - WOLFSSL_MSG("NetX Send NULL parameters"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool; - status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET, - nxCtx->nxWait); - if (status != NX_SUCCESS) { - WOLFSSL_MSG("NetX Send packet alloc error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait); - if (status != NX_SUCCESS) { - nx_packet_release(packet); - WOLFSSL_MSG("NetX Send data append error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait); - if (status != NX_SUCCESS) { - nx_packet_release(packet); - WOLFSSL_MSG("NetX Send socket send error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - return sz; -} - - -/* like set_fd, but for default NetX context */ -void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption) -{ - if (ssl) { - ssl->nxCtx.nxSocket = nxSocket; - ssl->nxCtx.nxWait = waitOption; - } -} - -#endif /* HAVE_NETX */ - - -#ifdef MICRIUM - -/* Micrium uTCP/IP port, using the NetSock API - * TCP and UDP are currently supported with the callbacks below. - * - * WOLFSSL_SESSION_EXPORT is not yet supported, would need EmbedGetPeer() - * and EmbedSetPeer() callbacks implemented. - * - * HAVE_CRL is not yet supported, would need an EmbedCrlLookup() - * callback implemented. - * - * HAVE_OCSP is not yet supported, would need an EmbedOCSPLookup() - * callback implemented. - */ - -/* The Micrium uTCP/IP send callback - * return : bytes sent, or error - */ -int MicriumSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) -{ - NET_SOCK_ID sd = *(int*)ctx; - NET_SOCK_RTN_CODE ret; - NET_ERR err; - - ret = NetSock_TxData(sd, buf, sz, ssl->wflags, &err); - if (ret < 0) { - WOLFSSL_MSG("Embed Send error"); - - if (err == NET_ERR_TX) { - WOLFSSL_MSG("\tWould block"); - return WOLFSSL_CBIO_ERR_WANT_WRITE; - - } else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - - return ret; -} - -/* The Micrium uTCP/IP receive callback - * return : nb bytes read, or error - */ -int MicriumReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) -{ - NET_SOCK_ID sd = *(int*)ctx; - NET_SOCK_RTN_CODE ret; - NET_ERR err; - -#ifdef WOLFSSL_DTLS - { - int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); - if (wolfSSL_dtls(ssl) - && !wolfSSL_dtls_get_using_nonblock(ssl) - && dtls_timeout != 0) { - /* needs timeout in milliseconds */ - NetSock_CfgTimeoutRxQ_Set(sd, dtls_timeout * 1000, &err); - if (err != NET_SOCK_ERR_NONE) { - WOLFSSL_MSG("NetSock_CfgTimeoutRxQ_Set failed"); - } - } - } -#endif - - ret = NetSock_RxData(sd, buf, sz, ssl->rflags, &err); - if (ret < 0) { - WOLFSSL_MSG("Embed Receive error"); - - if (err == NET_ERR_RX || err == NET_SOCK_ERR_RX_Q_EMPTY || - err == NET_ERR_FAULT_LOCK_ACQUIRE) { - if (!wolfSSL_dtls(ssl) || wolfSSL_dtls_get_using_nonblock(ssl)) { - WOLFSSL_MSG("\tWould block"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - else { - WOLFSSL_MSG("\tSocket timeout"); - return WOLFSSL_CBIO_ERR_TIMEOUT; - } - - } else if (err == NET_SOCK_ERR_CLOSED) { - WOLFSSL_MSG("Embed receive connection closed"); - return WOLFSSL_CBIO_ERR_CONN_CLOSE; - - } else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - - return ret; -} - -/* The Micrium uTCP/IP receivefrom callback - * return : nb bytes read, or error - */ -int MicriumReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) -{ - WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; - NET_SOCK_ID sd = dtlsCtx->rfd; - NET_SOCK_ADDR peer; - NET_SOCK_ADDR_LEN peerSz = sizeof(peer); - NET_SOCK_RTN_CODE ret; - NET_ERR err; - int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); - - WOLFSSL_ENTER("MicriumReceiveFrom()"); - - if (ssl->options.handShakeDone) - dtls_timeout = 0; - - if (!wolfSSL_dtls_get_using_nonblock(ssl)) { - /* needs timeout in milliseconds */ - NetSock_CfgTimeoutRxQ_Set(sd, dtls_timeout * 1000, &err); - if (err != NET_SOCK_ERR_NONE) { - WOLFSSL_MSG("NetSock_CfgTimeoutRxQ_Set failed"); - } - } - - ret = NetSock_RxDataFrom(sd, buf, sz, ssl->rflags, &peer, &peerSz, - 0, 0, 0, &err); - if (ret < 0) { - WOLFSSL_MSG("Embed Receive From error"); - - if (err == NET_ERR_RX || err == NET_SOCK_ERR_RX_Q_EMPTY || - err == NET_ERR_FAULT_LOCK_ACQUIRE) { - if (wolfSSL_dtls_get_using_nonblock(ssl)) { - WOLFSSL_MSG("\tWould block"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - else { - WOLFSSL_MSG("\tSocket timeout"); - return WOLFSSL_CBIO_ERR_TIMEOUT; - } - } else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - else { - if (dtlsCtx->peer.sz > 0 - && peerSz != (NET_SOCK_ADDR_LEN)dtlsCtx->peer.sz - && XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) { - WOLFSSL_MSG("\tIgnored packet from invalid peer"); - return WOLFSSL_CBIO_ERR_WANT_READ; - } - } - - return ret; -} - -/* The Micrium uTCP/IP sendto callback - * return : nb bytes sent, or error - */ -int MicriumSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) -{ - WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; - NET_SOCK_ID sd = dtlsCtx->wfd; - NET_SOCK_RTN_CODE ret; - NET_ERR err; - - WOLFSSL_ENTER("MicriumSendTo()"); - - ret = NetSock_TxDataTo(sd, buf, sz, ssl->wflags, - (NET_SOCK_ADDR*)dtlsCtx->peer.sa, - (NET_SOCK_ADDR_LEN)dtlsCtx->peer.sz, - &err); - if (err < 0) { - WOLFSSL_MSG("Embed Send To error"); - - if (err == NET_ERR_TX) { - WOLFSSL_MSG("\tWould block"); - return WOLFSSL_CBIO_ERR_WANT_WRITE; - - } else { - WOLFSSL_MSG("\tGeneral error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - } - - return ret; -} - -/* Micrium DTLS Generate Cookie callback - * return : number of bytes copied into buf, or error - */ -int MicriumGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) -{ - NET_SOCK_ADDR peer; - NET_SOCK_ADDR_LEN peerSz = sizeof(peer); - byte digest[WC_SHA_DIGEST_SIZE]; - int ret = 0; - - (void)ctx; - - XMEMSET(&peer, 0, sizeof(peer)); - if (wolfSSL_dtls_get_peer(ssl, (void*)&peer, - (unsigned int*)&peerSz) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("getpeername failed in MicriumGenerateCookie"); - return GEN_COOKIE_E; - } - - ret = wc_ShaHash((byte*)&peer, peerSz, digest); - if (ret != 0) - return ret; - - if (sz > WC_SHA_DIGEST_SIZE) - sz = WC_SHA_DIGEST_SIZE; - XMEMCPY(buf, digest, sz); - - return sz; -} - -#endif /* MICRIUM */ - -#if defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) - -#include <os/os_error.h> -#include <os/os_mbuf.h> -#include <os/os_mempool.h> - -#define MB_NAME "wolfssl_mb" - -typedef struct Mynewt_Ctx { - struct mn_socket *mnSocket; /* send/recv socket handler */ - struct mn_sockaddr_in mnSockAddrIn; /* socket address */ - struct os_mbuf *mnPacket; /* incoming packet handle - for short reads */ - int reading; /* reading flag */ - - /* private */ - void *mnMemBuffer; /* memory buffer for mempool */ - struct os_mempool mnMempool; /* mempool */ - struct os_mbuf_pool mnMbufpool; /* mbuf pool */ -} Mynewt_Ctx; - -void mynewt_ctx_clear(void *ctx) { - Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx; - if(!mynewt_ctx) return; - - if(mynewt_ctx->mnPacket) { - os_mbuf_free_chain(mynewt_ctx->mnPacket); - mynewt_ctx->mnPacket = NULL; - } - os_mempool_clear(&mynewt_ctx->mnMempool); - XFREE(mynewt_ctx->mnMemBuffer, 0, 0); - XFREE(mynewt_ctx, 0, 0); -} - -/* return Mynewt_Ctx instance */ -void* mynewt_ctx_new() { - int rc = 0; - Mynewt_Ctx *mynewt_ctx; - int mem_buf_count = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_COUNT); - int mem_buf_size = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_SIZE); - int mempool_bytes = OS_MEMPOOL_BYTES(mem_buf_count, mem_buf_size); - - mynewt_ctx = (Mynewt_Ctx *)XMALLOC(sizeof(struct Mynewt_Ctx), - NULL, DYNAMIC_TYPE_TMP_BUFFER); - if(!mynewt_ctx) return NULL; - - XMEMSET(mynewt_ctx, 0, sizeof(Mynewt_Ctx)); - mynewt_ctx->mnMemBuffer = XMALLOC(mempool_bytes, 0, 0); - if(!mynewt_ctx->mnMemBuffer) { - mynewt_ctx_clear((void*)mynewt_ctx); - return NULL; - } - - rc = os_mempool_init(&mynewt_ctx->mnMempool, - mem_buf_count, mem_buf_size, - mynewt_ctx->mnMemBuffer, MB_NAME); - if(rc != 0) { - mynewt_ctx_clear((void*)mynewt_ctx); - return NULL; - } - rc = os_mbuf_pool_init(&mynewt_ctx->mnMbufpool, &mynewt_ctx->mnMempool, - mem_buf_count, mem_buf_size); - if(rc != 0) { - mynewt_ctx_clear((void*)mynewt_ctx); - return NULL; - } - - return mynewt_ctx; -} - -static void mynewt_sock_writable(void *arg, int err); -static void mynewt_sock_readable(void *arg, int err); -static const union mn_socket_cb mynewt_sock_cbs = { - .socket.writable = mynewt_sock_writable, - .socket.readable = mynewt_sock_readable, -}; -static void mynewt_sock_writable(void *arg, int err) -{ - /* do nothing */ -} -static void mynewt_sock_readable(void *arg, int err) -{ - Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx *)arg; - if (err && mynewt_ctx->reading) { - mynewt_ctx->reading = 0; - } -} - -/* The Mynewt receive callback - * return : bytes read, or error - */ -int Mynewt_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) -{ - Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx; - int rc = 0; - struct mn_sockaddr_in from; - struct os_mbuf *m; - int read_sz = 0; - uint16_t total; - - if (mynewt_ctx == NULL || mynewt_ctx->mnSocket == NULL) { - WOLFSSL_MSG("Mynewt Recv NULL parameters"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - - if(mynewt_ctx->mnPacket == NULL) { - mynewt_ctx->mnPacket = os_mbuf_get_pkthdr(&mynewt_ctx->mnMbufpool, 0); - if(mynewt_ctx->mnPacket == NULL) { - return MEMORY_E; - } - - mynewt_ctx->reading = 1; - while(mynewt_ctx->reading && rc == 0) { - rc = mn_recvfrom(mynewt_ctx->mnSocket, &m, (struct mn_sockaddr *) &from); - if(rc == MN_ECONNABORTED) { - rc = 0; - mynewt_ctx->reading = 0; - break; - } - if (!(rc == 0 || rc == MN_EAGAIN)) { - WOLFSSL_MSG("Mynewt Recv receive error"); - mynewt_ctx->reading = 0; - break; - } - if(rc == 0) { - int len = OS_MBUF_PKTLEN(m); - if(len == 0) { - break; - } - rc = os_mbuf_appendfrom(mynewt_ctx->mnPacket, m, 0, len); - if(rc != 0) { - WOLFSSL_MSG("Mynewt Recv os_mbuf_appendfrom error"); - break; - } - os_mbuf_free_chain(m); - m = NULL; - } else if(rc == MN_EAGAIN) { - /* continue to until reading all of packet data. */ - rc = 0; - break; - } - } - if(rc != 0) { - mynewt_ctx->reading = 0; - os_mbuf_free_chain(mynewt_ctx->mnPacket); - mynewt_ctx->mnPacket = NULL; - return rc; - } - } - - if(mynewt_ctx->mnPacket) { - total = OS_MBUF_PKTLEN(mynewt_ctx->mnPacket); - read_sz = (total >= sz)? sz : total; - - os_mbuf_copydata(mynewt_ctx->mnPacket, 0, read_sz, (void*)buf); - os_mbuf_adj(mynewt_ctx->mnPacket, read_sz); - - if (read_sz == total) { - WOLFSSL_MSG("Mynewt Recv Drained packet"); - os_mbuf_free_chain(mynewt_ctx->mnPacket); - mynewt_ctx->mnPacket = NULL; - } - } - - return read_sz; -} - -/* The Mynewt send callback - * return : bytes sent, or error - */ -int Mynewt_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) -{ - Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx; - int rc = 0; - struct os_mbuf *m; - int write_sz = 0; - m = os_msys_get_pkthdr(sz, 0); - if (!m) { - WOLFSSL_MSG("Mynewt Send os_msys_get_pkthdr error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - rc = os_mbuf_copyinto(m, 0, buf, sz); - if (rc != 0) { - WOLFSSL_MSG("Mynewt Send os_mbuf_copyinto error"); - os_mbuf_free_chain(m); - return rc; - } - rc = mn_sendto(mynewt_ctx->mnSocket, m, (struct mn_sockaddr *)&mynewt_ctx->mnSockAddrIn); - if(rc != 0) { - WOLFSSL_MSG("Mynewt Send mn_sendto error"); - os_mbuf_free_chain(m); - return rc; - } - write_sz = sz; - return write_sz; -} - -/* like set_fd, but for default NetX context */ -void wolfSSL_SetIO_Mynewt(WOLFSSL* ssl, struct mn_socket* mnSocket, struct mn_sockaddr_in* mnSockAddrIn) -{ - if (ssl && ssl->mnCtx) { - Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx *)ssl->mnCtx; - mynewt_ctx->mnSocket = mnSocket; - memcpy(&mynewt_ctx->mnSockAddrIn, mnSockAddrIn, sizeof(struct mn_sockaddr_in)); - mn_socket_set_cbs(mynewt_ctx->mnSocket, mnSocket, &mynewt_sock_cbs); - } -} - -#endif /* defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) */ - -#ifdef WOLFSSL_UIP -#include <uip.h> -#include <stdio.h> - -/* uIP TCP/IP port, using the native tcp/udp socket api. - * TCP and UDP are currently supported with the callbacks below. - * - */ -/* The uIP tcp send callback - * return : bytes sent, or error - */ -int uIPSend(WOLFSSL* ssl, char* buf, int sz, void* _ctx) -{ - uip_wolfssl_ctx *ctx = (struct uip_wolfssl_ctx *)_ctx; - int ret; - unsigned int max_sendlen; - int total_written = 0; - (void)ssl; - do { - unsigned int bytes_left = sz - total_written; - max_sendlen = tcp_socket_max_sendlen(&ctx->conn.tcp); - if (bytes_left > max_sendlen) { - printf("Send limited by buffer\r\n"); - bytes_left = max_sendlen; - } - if (bytes_left == 0) { - printf("Buffer full!\r\n"); - break; - } - ret = tcp_socket_send(&ctx->conn.tcp, (unsigned char *)buf + total_written, bytes_left); - if (ret <= 0) - break; - total_written += ret; - } while(total_written < sz); - if (total_written == 0) - return WOLFSSL_CBIO_ERR_WANT_WRITE; - return total_written; -} - -int uIPSendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx) -{ - uip_wolfssl_ctx *ctx = (struct uip_wolfssl_ctx *)_ctx; - int ret = 0; - (void)ssl; - ret = udp_socket_sendto(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr, ctx->peer_port ); - if (ret == 0) - return WOLFSSL_CBIO_ERR_WANT_WRITE; - return ret; -} - -/* The uIP uTCP/IP receive callback - * return : nb bytes read, or error - */ -int uIPReceive(WOLFSSL *ssl, char *buf, int sz, void *_ctx) -{ - uip_wolfssl_ctx *ctx = (uip_wolfssl_ctx *)_ctx; - if (!ctx || !ctx->ssl_rx_databuf) - return -1; - (void)ssl; - if (ctx->ssl_rb_len > 0) { - if (sz > ctx->ssl_rb_len - ctx->ssl_rb_off) - sz = ctx->ssl_rb_len - ctx->ssl_rb_off; - XMEMCPY(buf, ctx->ssl_rx_databuf + ctx->ssl_rb_off, sz); - ctx->ssl_rb_off += sz; - if (ctx->ssl_rb_off >= ctx->ssl_rb_len) { - ctx->ssl_rb_len = 0; - ctx->ssl_rb_off = 0; - } - return sz; - } else { - return WOLFSSL_CBIO_ERR_WANT_READ; - } -} - -/* uIP DTLS Generate Cookie callback - * return : number of bytes copied into buf, or error - */ -int uIPGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx) -{ - uip_wolfssl_ctx *ctx = (uip_wolfssl_ctx *)_ctx; - byte token[32]; - byte digest[WC_SHA_DIGEST_SIZE]; - int ret = 0; - XMEMSET(token, 0, sizeof(token)); - XMEMCPY(token, &ctx->peer_addr, sizeof(uip_ipaddr_t)); - XMEMCPY(token + sizeof(uip_ipaddr_t), &ctx->peer_port, sizeof(word16)); - ret = wc_ShaHash(token, sizeof(uip_ipaddr_t) + sizeof(word16), digest); - if (ret != 0) - return ret; - if (sz > WC_SHA_DIGEST_SIZE) - sz = WC_SHA_DIGEST_SIZE; - XMEMCPY(buf, digest, sz); - return sz; -} - -#endif /* WOLFSSL_UIP */ - -#ifdef WOLFSSL_GNRC - -#include <net/sock.h> -#include <net/sock/tcp.h> -#include <stdio.h> - -/* GNRC TCP/IP port, using the native tcp/udp socket api. - * TCP and UDP are currently supported with the callbacks below. - * - */ -/* The GNRC tcp send callback - * return : bytes sent, or error - */ - -int GNRC_SendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx) -{ - sock_tls_t *ctx = (sock_tls_t *)_ctx; - int ret = 0; - (void)ssl; - if (!ctx) - return WOLFSSL_CBIO_ERR_GENERAL; - ret = sock_udp_send(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr); - if (ret == 0) - return WOLFSSL_CBIO_ERR_WANT_WRITE; - return ret; -} - -/* The GNRC TCP/IP receive callback - * return : nb bytes read, or error - */ -int GNRC_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *_ctx) -{ - sock_udp_ep_t ep; - int ret; - uint32_t timeout = wolfSSL_dtls_get_current_timeout(ssl) * 1000000; - sock_tls_t *ctx = (sock_tls_t *)_ctx; - if (!ctx) - return WOLFSSL_CBIO_ERR_GENERAL; - (void)ssl; - if (wolfSSL_get_using_nonblock(ctx->ssl)) { - timeout = 0; - } - ret = sock_udp_recv(&ctx->conn.udp, buf, sz, timeout, &ep); - if (ret > 0) { - if (ctx->peer_addr.port == 0) - XMEMCPY(&ctx->peer_addr, &ep, sizeof(sock_udp_ep_t)); - } - if (ret == -ETIMEDOUT) { - return WOLFSSL_CBIO_ERR_WANT_READ; - } - return ret; -} - -/* GNRC DTLS Generate Cookie callback - * return : number of bytes copied into buf, or error - */ -#define GNRC_MAX_TOKEN_SIZE (32) -int GNRC_GenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx) -{ - sock_tls_t *ctx = (sock_tls_t *)_ctx; - if (!ctx) - return WOLFSSL_CBIO_ERR_GENERAL; - byte token[GNRC_MAX_TOKEN_SIZE]; - byte digest[WC_SHA_DIGEST_SIZE]; - int ret = 0; - size_t token_size = sizeof(sock_udp_ep_t); - (void)ssl; - if (token_size > GNRC_MAX_TOKEN_SIZE) - token_size = GNRC_MAX_TOKEN_SIZE; - XMEMSET(token, 0, GNRC_MAX_TOKEN_SIZE); - XMEMCPY(token, &ctx->peer_addr, token_size); - ret = wc_ShaHash(token, token_size, digest); - if (ret != 0) - return ret; - if (sz > WC_SHA_DIGEST_SIZE) - sz = WC_SHA_DIGEST_SIZE; - XMEMCPY(buf, digest, sz); - return sz; -} - -#endif /* WOLFSSL_GNRC */ - -#endif /* WOLFCRYPT_ONLY */ |