wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Fri Jun 26 00:39:20 2015 +0000
Revision:
0:d92f9d21154c
wolfSSL 3.6.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:d92f9d21154c 1 /* io.c
wolfSSL 0:d92f9d21154c 2 *
wolfSSL 0:d92f9d21154c 3 * Copyright (C) 2006-2015 wolfSSL Inc.
wolfSSL 0:d92f9d21154c 4 *
wolfSSL 0:d92f9d21154c 5 * This file is part of wolfSSL. (formerly known as CyaSSL)
wolfSSL 0:d92f9d21154c 6 *
wolfSSL 0:d92f9d21154c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 0:d92f9d21154c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:d92f9d21154c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:d92f9d21154c 10 * (at your option) any later version.
wolfSSL 0:d92f9d21154c 11 *
wolfSSL 0:d92f9d21154c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 0:d92f9d21154c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:d92f9d21154c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:d92f9d21154c 15 * GNU General Public License for more details.
wolfSSL 0:d92f9d21154c 16 *
wolfSSL 0:d92f9d21154c 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:d92f9d21154c 18 * along with this program; if not, write to the Free Software
wolfSSL 0:d92f9d21154c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
wolfSSL 0:d92f9d21154c 20 */
wolfSSL 0:d92f9d21154c 21
wolfSSL 0:d92f9d21154c 22
wolfSSL 0:d92f9d21154c 23 #ifdef HAVE_CONFIG_H
wolfSSL 0:d92f9d21154c 24 #include <config.h>
wolfSSL 0:d92f9d21154c 25 #endif
wolfSSL 0:d92f9d21154c 26
wolfSSL 0:d92f9d21154c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 0:d92f9d21154c 28
wolfSSL 0:d92f9d21154c 29 #ifdef _WIN32_WCE
wolfSSL 0:d92f9d21154c 30 /* On WinCE winsock2.h must be included before windows.h for socket stuff */
wolfSSL 0:d92f9d21154c 31 #include <winsock2.h>
wolfSSL 0:d92f9d21154c 32 #endif
wolfSSL 0:d92f9d21154c 33
wolfSSL 0:d92f9d21154c 34 #include <wolfssl/internal.h>
wolfSSL 0:d92f9d21154c 35 #include <wolfssl/error-ssl.h>
wolfSSL 0:d92f9d21154c 36
wolfSSL 0:d92f9d21154c 37
wolfSSL 0:d92f9d21154c 38 /* if user writes own I/O callbacks they can define WOLFSSL_USER_IO to remove
wolfSSL 0:d92f9d21154c 39 automatic setting of default I/O functions EmbedSend() and EmbedReceive()
wolfSSL 0:d92f9d21154c 40 but they'll still need SetCallback xxx() at end of file
wolfSSL 0:d92f9d21154c 41 */
wolfSSL 0:d92f9d21154c 42 #ifndef WOLFSSL_USER_IO
wolfSSL 0:d92f9d21154c 43
wolfSSL 0:d92f9d21154c 44 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 45 #include "zlib.h"
wolfSSL 0:d92f9d21154c 46 #endif
wolfSSL 0:d92f9d21154c 47
wolfSSL 0:d92f9d21154c 48 #ifndef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 49 #ifdef WOLFSSL_LWIP
wolfSSL 0:d92f9d21154c 50 /* lwIP needs to be configured to use sockets API in this mode */
wolfSSL 0:d92f9d21154c 51 /* LWIP_SOCKET 1 in lwip/opt.h or in build */
wolfSSL 0:d92f9d21154c 52 #include "lwip/sockets.h"
wolfSSL 0:d92f9d21154c 53 #include <errno.h>
wolfSSL 0:d92f9d21154c 54 #ifndef LWIP_PROVIDE_ERRNO
wolfSSL 0:d92f9d21154c 55 #define LWIP_PROVIDE_ERRNO 1
wolfSSL 0:d92f9d21154c 56 #endif
wolfSSL 0:d92f9d21154c 57 #elif defined(FREESCALE_MQX)
wolfSSL 0:d92f9d21154c 58 #include <posix.h>
wolfSSL 0:d92f9d21154c 59 #include <rtcs.h>
wolfSSL 0:d92f9d21154c 60 #elif defined(WOLFSSL_MDK_ARM)
wolfSSL 0:d92f9d21154c 61 #if defined(WOLFSSL_MDK5)
wolfSSL 0:d92f9d21154c 62 #include "cmsis_os.h"
wolfSSL 0:d92f9d21154c 63 #include "rl_fs.h"
wolfSSL 0:d92f9d21154c 64 #include "rl_net.h"
wolfSSL 0:d92f9d21154c 65 #else
wolfSSL 0:d92f9d21154c 66 #include <rtl.h>
wolfSSL 0:d92f9d21154c 67 #endif
wolfSSL 0:d92f9d21154c 68 #undef RNG
wolfSSL 0:d92f9d21154c 69 #include "WOLFSSL_MDK_ARM.h"
wolfSSL 0:d92f9d21154c 70 #undef RNG
wolfSSL 0:d92f9d21154c 71 #define RNG wolfSSL_RNG
wolfSSL 0:d92f9d21154c 72 /* for avoiding name conflict in "stm32f2xx.h" */
wolfSSL 0:d92f9d21154c 73 static int errno;
wolfSSL 0:d92f9d21154c 74 #elif defined(WOLFSSL_TIRTOS)
wolfSSL 0:d92f9d21154c 75 #include <sys/socket.h>
wolfSSL 0:d92f9d21154c 76 #elif defined(WOLFSSL_IAR_ARM)
wolfSSL 0:d92f9d21154c 77 /* nothing */
wolfSSL 0:d92f9d21154c 78 #else
wolfSSL 0:d92f9d21154c 79 #include <sys/types.h>
wolfSSL 0:d92f9d21154c 80 #include <errno.h>
wolfSSL 0:d92f9d21154c 81 #ifndef EBSNET
wolfSSL 0:d92f9d21154c 82 #include <unistd.h>
wolfSSL 0:d92f9d21154c 83 #endif
wolfSSL 0:d92f9d21154c 84 #include <fcntl.h>
wolfSSL 0:d92f9d21154c 85 #if !(defined(DEVKITPRO) || defined(HAVE_RTP_SYS) || defined(EBSNET)) \
wolfSSL 0:d92f9d21154c 86 && !(defined(WOLFSSL_PICOTCP))
wolfSSL 0:d92f9d21154c 87 #include <sys/socket.h>
wolfSSL 0:d92f9d21154c 88 #include <arpa/inet.h>
wolfSSL 0:d92f9d21154c 89 #include <netinet/in.h>
wolfSSL 0:d92f9d21154c 90 #include <netdb.h>
wolfSSL 0:d92f9d21154c 91 #ifdef __PPU
wolfSSL 0:d92f9d21154c 92 #include <netex/errno.h>
wolfSSL 0:d92f9d21154c 93 #else
wolfSSL 0:d92f9d21154c 94 #include <sys/ioctl.h>
wolfSSL 0:d92f9d21154c 95 #endif
wolfSSL 0:d92f9d21154c 96 #endif
wolfSSL 0:d92f9d21154c 97 #ifdef HAVE_RTP_SYS
wolfSSL 0:d92f9d21154c 98 #include <socket.h>
wolfSSL 0:d92f9d21154c 99 #endif
wolfSSL 0:d92f9d21154c 100 #ifdef EBSNET
wolfSSL 0:d92f9d21154c 101 #include "rtipapi.h" /* errno */
wolfSSL 0:d92f9d21154c 102 #include "socket.h"
wolfSSL 0:d92f9d21154c 103 #endif
wolfSSL 0:d92f9d21154c 104 #endif
wolfSSL 0:d92f9d21154c 105 #endif /* USE_WINDOWS_API */
wolfSSL 0:d92f9d21154c 106
wolfSSL 0:d92f9d21154c 107 #ifdef __sun
wolfSSL 0:d92f9d21154c 108 #include <sys/filio.h>
wolfSSL 0:d92f9d21154c 109 #endif
wolfSSL 0:d92f9d21154c 110
wolfSSL 0:d92f9d21154c 111 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 112 /* no epipe yet */
wolfSSL 0:d92f9d21154c 113 #ifndef WSAEPIPE
wolfSSL 0:d92f9d21154c 114 #define WSAEPIPE -12345
wolfSSL 0:d92f9d21154c 115 #endif
wolfSSL 0:d92f9d21154c 116 #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
wolfSSL 0:d92f9d21154c 117 #define SOCKET_EAGAIN WSAETIMEDOUT
wolfSSL 0:d92f9d21154c 118 #define SOCKET_ECONNRESET WSAECONNRESET
wolfSSL 0:d92f9d21154c 119 #define SOCKET_EINTR WSAEINTR
wolfSSL 0:d92f9d21154c 120 #define SOCKET_EPIPE WSAEPIPE
wolfSSL 0:d92f9d21154c 121 #define SOCKET_ECONNREFUSED WSAENOTCONN
wolfSSL 0:d92f9d21154c 122 #define SOCKET_ECONNABORTED WSAECONNABORTED
wolfSSL 0:d92f9d21154c 123 #define close(s) closesocket(s)
wolfSSL 0:d92f9d21154c 124 #elif defined(__PPU)
wolfSSL 0:d92f9d21154c 125 #define SOCKET_EWOULDBLOCK SYS_NET_EWOULDBLOCK
wolfSSL 0:d92f9d21154c 126 #define SOCKET_EAGAIN SYS_NET_EAGAIN
wolfSSL 0:d92f9d21154c 127 #define SOCKET_ECONNRESET SYS_NET_ECONNRESET
wolfSSL 0:d92f9d21154c 128 #define SOCKET_EINTR SYS_NET_EINTR
wolfSSL 0:d92f9d21154c 129 #define SOCKET_EPIPE SYS_NET_EPIPE
wolfSSL 0:d92f9d21154c 130 #define SOCKET_ECONNREFUSED SYS_NET_ECONNREFUSED
wolfSSL 0:d92f9d21154c 131 #define SOCKET_ECONNABORTED SYS_NET_ECONNABORTED
wolfSSL 0:d92f9d21154c 132 #elif defined(FREESCALE_MQX)
wolfSSL 0:d92f9d21154c 133 /* RTCS doesn't have an EWOULDBLOCK error */
wolfSSL 0:d92f9d21154c 134 #define SOCKET_EWOULDBLOCK EAGAIN
wolfSSL 0:d92f9d21154c 135 #define SOCKET_EAGAIN EAGAIN
wolfSSL 0:d92f9d21154c 136 #define SOCKET_ECONNRESET RTCSERR_TCP_CONN_RESET
wolfSSL 0:d92f9d21154c 137 #define SOCKET_EINTR EINTR
wolfSSL 0:d92f9d21154c 138 #define SOCKET_EPIPE EPIPE
wolfSSL 0:d92f9d21154c 139 #define SOCKET_ECONNREFUSED RTCSERR_TCP_CONN_REFUSED
wolfSSL 0:d92f9d21154c 140 #define SOCKET_ECONNABORTED RTCSERR_TCP_CONN_ABORTED
wolfSSL 0:d92f9d21154c 141 #elif defined(WOLFSSL_MDK_ARM)
wolfSSL 0:d92f9d21154c 142 #if defined(WOLFSSL_MDK5)
wolfSSL 0:d92f9d21154c 143 #define SOCKET_EWOULDBLOCK BSD_ERROR_WOULDBLOCK
wolfSSL 0:d92f9d21154c 144 #define SOCKET_EAGAIN BSD_ERROR_LOCKED
wolfSSL 0:d92f9d21154c 145 #define SOCKET_ECONNRESET BSD_ERROR_CLOSED
wolfSSL 0:d92f9d21154c 146 #define SOCKET_EINTR BSD_ERROR
wolfSSL 0:d92f9d21154c 147 #define SOCKET_EPIPE BSD_ERROR
wolfSSL 0:d92f9d21154c 148 #define SOCKET_ECONNREFUSED BSD_ERROR
wolfSSL 0:d92f9d21154c 149 #define SOCKET_ECONNABORTED BSD_ERROR
wolfSSL 0:d92f9d21154c 150 #else
wolfSSL 0:d92f9d21154c 151 #define SOCKET_EWOULDBLOCK SCK_EWOULDBLOCK
wolfSSL 0:d92f9d21154c 152 #define SOCKET_EAGAIN SCK_ELOCKED
wolfSSL 0:d92f9d21154c 153 #define SOCKET_ECONNRESET SCK_ECLOSED
wolfSSL 0:d92f9d21154c 154 #define SOCKET_EINTR SCK_ERROR
wolfSSL 0:d92f9d21154c 155 #define SOCKET_EPIPE SCK_ERROR
wolfSSL 0:d92f9d21154c 156 #define SOCKET_ECONNREFUSED SCK_ERROR
wolfSSL 0:d92f9d21154c 157 #define SOCKET_ECONNABORTED SCK_ERROR
wolfSSL 0:d92f9d21154c 158 #endif
wolfSSL 0:d92f9d21154c 159 #elif defined(WOLFSSL_PICOTCP)
wolfSSL 0:d92f9d21154c 160 #define SOCKET_EWOULDBLOCK PICO_ERR_EAGAIN
wolfSSL 0:d92f9d21154c 161 #define SOCKET_EAGAIN PICO_ERR_EAGAIN
wolfSSL 0:d92f9d21154c 162 #define SOCKET_ECONNRESET PICO_ERR_ECONNRESET
wolfSSL 0:d92f9d21154c 163 #define SOCKET_EINTR PICO_ERR_EINTR
wolfSSL 0:d92f9d21154c 164 #define SOCKET_EPIPE PICO_ERR_EIO
wolfSSL 0:d92f9d21154c 165 #define SOCKET_ECONNREFUSED PICO_ERR_ECONNREFUSED
wolfSSL 0:d92f9d21154c 166 #define SOCKET_ECONNABORTED PICO_ERR_ESHUTDOWN
wolfSSL 0:d92f9d21154c 167 #else
wolfSSL 0:d92f9d21154c 168 #define SOCKET_EWOULDBLOCK EWOULDBLOCK
wolfSSL 0:d92f9d21154c 169 #define SOCKET_EAGAIN EAGAIN
wolfSSL 0:d92f9d21154c 170 #define SOCKET_ECONNRESET ECONNRESET
wolfSSL 0:d92f9d21154c 171 #define SOCKET_EINTR EINTR
wolfSSL 0:d92f9d21154c 172 #define SOCKET_EPIPE EPIPE
wolfSSL 0:d92f9d21154c 173 #define SOCKET_ECONNREFUSED ECONNREFUSED
wolfSSL 0:d92f9d21154c 174 #define SOCKET_ECONNABORTED ECONNABORTED
wolfSSL 0:d92f9d21154c 175 #endif /* USE_WINDOWS_API */
wolfSSL 0:d92f9d21154c 176
wolfSSL 0:d92f9d21154c 177
wolfSSL 0:d92f9d21154c 178 #ifdef DEVKITPRO
wolfSSL 0:d92f9d21154c 179 /* from network.h */
wolfSSL 0:d92f9d21154c 180 int net_send(int, const void*, int, unsigned int);
wolfSSL 0:d92f9d21154c 181 int net_recv(int, void*, int, unsigned int);
wolfSSL 0:d92f9d21154c 182 #define SEND_FUNCTION net_send
wolfSSL 0:d92f9d21154c 183 #define RECV_FUNCTION net_recv
wolfSSL 0:d92f9d21154c 184 #elif defined(WOLFSSL_LWIP)
wolfSSL 0:d92f9d21154c 185 #define SEND_FUNCTION lwip_send
wolfSSL 0:d92f9d21154c 186 #define RECV_FUNCTION lwip_recv
wolfSSL 0:d92f9d21154c 187 #elif defined(WOLFSSL_PICOTCP)
wolfSSL 0:d92f9d21154c 188 #define SEND_FUNCTION pico_send
wolfSSL 0:d92f9d21154c 189 #define RECV_FUNCTION pico_recv
wolfSSL 0:d92f9d21154c 190 #else
wolfSSL 0:d92f9d21154c 191 #define SEND_FUNCTION send
wolfSSL 0:d92f9d21154c 192 #define RECV_FUNCTION recv
wolfSSL 0:d92f9d21154c 193 #endif
wolfSSL 0:d92f9d21154c 194
wolfSSL 0:d92f9d21154c 195
wolfSSL 0:d92f9d21154c 196 /* Translates return codes returned from
wolfSSL 0:d92f9d21154c 197 * send() and recv() if need be.
wolfSSL 0:d92f9d21154c 198 */
wolfSSL 0:d92f9d21154c 199 static INLINE int TranslateReturnCode(int old, int sd)
wolfSSL 0:d92f9d21154c 200 {
wolfSSL 0:d92f9d21154c 201 (void)sd;
wolfSSL 0:d92f9d21154c 202
wolfSSL 0:d92f9d21154c 203 #ifdef FREESCALE_MQX
wolfSSL 0:d92f9d21154c 204 if (old == 0) {
wolfSSL 0:d92f9d21154c 205 errno = SOCKET_EWOULDBLOCK;
wolfSSL 0:d92f9d21154c 206 return -1; /* convert to BSD style wouldblock as error */
wolfSSL 0:d92f9d21154c 207 }
wolfSSL 0:d92f9d21154c 208
wolfSSL 0:d92f9d21154c 209 if (old < 0) {
wolfSSL 0:d92f9d21154c 210 errno = RTCS_geterror(sd);
wolfSSL 0:d92f9d21154c 211 if (errno == RTCSERR_TCP_CONN_CLOSING)
wolfSSL 0:d92f9d21154c 212 return 0; /* convert to BSD style closing */
wolfSSL 0:d92f9d21154c 213 }
wolfSSL 0:d92f9d21154c 214 #endif
wolfSSL 0:d92f9d21154c 215
wolfSSL 0:d92f9d21154c 216 return old;
wolfSSL 0:d92f9d21154c 217 }
wolfSSL 0:d92f9d21154c 218
wolfSSL 0:d92f9d21154c 219 static INLINE int LastError(void)
wolfSSL 0:d92f9d21154c 220 {
wolfSSL 0:d92f9d21154c 221 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 222 return WSAGetLastError();
wolfSSL 0:d92f9d21154c 223 #elif defined(EBSNET)
wolfSSL 0:d92f9d21154c 224 return xn_getlasterror();
wolfSSL 0:d92f9d21154c 225 #else
wolfSSL 0:d92f9d21154c 226 return errno;
wolfSSL 0:d92f9d21154c 227 #endif
wolfSSL 0:d92f9d21154c 228 }
wolfSSL 0:d92f9d21154c 229
wolfSSL 0:d92f9d21154c 230 /* The receive embedded callback
wolfSSL 0:d92f9d21154c 231 * return : nb bytes read, or error
wolfSSL 0:d92f9d21154c 232 */
wolfSSL 0:d92f9d21154c 233 int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
wolfSSL 0:d92f9d21154c 234 {
wolfSSL 0:d92f9d21154c 235 int recvd;
wolfSSL 0:d92f9d21154c 236 int err;
wolfSSL 0:d92f9d21154c 237 int sd = *(int*)ctx;
wolfSSL 0:d92f9d21154c 238
wolfSSL 0:d92f9d21154c 239 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 240 {
wolfSSL 0:d92f9d21154c 241 int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
wolfSSL 0:d92f9d21154c 242 if (wolfSSL_dtls(ssl)
wolfSSL 0:d92f9d21154c 243 && !wolfSSL_get_using_nonblock(ssl)
wolfSSL 0:d92f9d21154c 244 && dtls_timeout != 0) {
wolfSSL 0:d92f9d21154c 245 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 246 DWORD timeout = dtls_timeout * 1000;
wolfSSL 0:d92f9d21154c 247 #else
wolfSSL 0:d92f9d21154c 248 struct timeval timeout;
wolfSSL 0:d92f9d21154c 249 XMEMSET(&timeout, 0, sizeof(timeout));
wolfSSL 0:d92f9d21154c 250 timeout.tv_sec = dtls_timeout;
wolfSSL 0:d92f9d21154c 251 #endif
wolfSSL 0:d92f9d21154c 252 if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
wolfSSL 0:d92f9d21154c 253 sizeof(timeout)) != 0) {
wolfSSL 0:d92f9d21154c 254 WOLFSSL_MSG("setsockopt rcvtimeo failed");
wolfSSL 0:d92f9d21154c 255 }
wolfSSL 0:d92f9d21154c 256 }
wolfSSL 0:d92f9d21154c 257 }
wolfSSL 0:d92f9d21154c 258 #endif
wolfSSL 0:d92f9d21154c 259
wolfSSL 0:d92f9d21154c 260 recvd = (int)RECV_FUNCTION(sd, buf, sz, ssl->rflags);
wolfSSL 0:d92f9d21154c 261
wolfSSL 0:d92f9d21154c 262 recvd = TranslateReturnCode(recvd, sd);
wolfSSL 0:d92f9d21154c 263
wolfSSL 0:d92f9d21154c 264 if (recvd < 0) {
wolfSSL 0:d92f9d21154c 265 err = LastError();
wolfSSL 0:d92f9d21154c 266 WOLFSSL_MSG("Embed Receive error");
wolfSSL 0:d92f9d21154c 267
wolfSSL 0:d92f9d21154c 268 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 0:d92f9d21154c 269 if (!wolfSSL_dtls(ssl) || wolfSSL_get_using_nonblock(ssl)) {
wolfSSL 0:d92f9d21154c 270 WOLFSSL_MSG(" Would block");
wolfSSL 0:d92f9d21154c 271 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 0:d92f9d21154c 272 }
wolfSSL 0:d92f9d21154c 273 else {
wolfSSL 0:d92f9d21154c 274 WOLFSSL_MSG(" Socket timeout");
wolfSSL 0:d92f9d21154c 275 return WOLFSSL_CBIO_ERR_TIMEOUT;
wolfSSL 0:d92f9d21154c 276 }
wolfSSL 0:d92f9d21154c 277 }
wolfSSL 0:d92f9d21154c 278 else if (err == SOCKET_ECONNRESET) {
wolfSSL 0:d92f9d21154c 279 WOLFSSL_MSG(" Connection reset");
wolfSSL 0:d92f9d21154c 280 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 0:d92f9d21154c 281 }
wolfSSL 0:d92f9d21154c 282 else if (err == SOCKET_EINTR) {
wolfSSL 0:d92f9d21154c 283 WOLFSSL_MSG(" Socket interrupted");
wolfSSL 0:d92f9d21154c 284 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 0:d92f9d21154c 285 }
wolfSSL 0:d92f9d21154c 286 else if (err == SOCKET_ECONNREFUSED) {
wolfSSL 0:d92f9d21154c 287 WOLFSSL_MSG(" Connection refused");
wolfSSL 0:d92f9d21154c 288 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 0:d92f9d21154c 289 }
wolfSSL 0:d92f9d21154c 290 else if (err == SOCKET_ECONNABORTED) {
wolfSSL 0:d92f9d21154c 291 WOLFSSL_MSG(" Connection aborted");
wolfSSL 0:d92f9d21154c 292 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 0:d92f9d21154c 293 }
wolfSSL 0:d92f9d21154c 294 else {
wolfSSL 0:d92f9d21154c 295 WOLFSSL_MSG(" General error");
wolfSSL 0:d92f9d21154c 296 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 297 }
wolfSSL 0:d92f9d21154c 298 }
wolfSSL 0:d92f9d21154c 299 else if (recvd == 0) {
wolfSSL 0:d92f9d21154c 300 WOLFSSL_MSG("Embed receive connection closed");
wolfSSL 0:d92f9d21154c 301 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 0:d92f9d21154c 302 }
wolfSSL 0:d92f9d21154c 303
wolfSSL 0:d92f9d21154c 304 return recvd;
wolfSSL 0:d92f9d21154c 305 }
wolfSSL 0:d92f9d21154c 306
wolfSSL 0:d92f9d21154c 307 /* The send embedded callback
wolfSSL 0:d92f9d21154c 308 * return : nb bytes sent, or error
wolfSSL 0:d92f9d21154c 309 */
wolfSSL 0:d92f9d21154c 310 int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
wolfSSL 0:d92f9d21154c 311 {
wolfSSL 0:d92f9d21154c 312 int sd = *(int*)ctx;
wolfSSL 0:d92f9d21154c 313 int sent;
wolfSSL 0:d92f9d21154c 314 int len = sz;
wolfSSL 0:d92f9d21154c 315 int err;
wolfSSL 0:d92f9d21154c 316
wolfSSL 0:d92f9d21154c 317 sent = (int)SEND_FUNCTION(sd, &buf[sz - len], len, ssl->wflags);
wolfSSL 0:d92f9d21154c 318
wolfSSL 0:d92f9d21154c 319 if (sent < 0) {
wolfSSL 0:d92f9d21154c 320 err = LastError();
wolfSSL 0:d92f9d21154c 321 WOLFSSL_MSG("Embed Send error");
wolfSSL 0:d92f9d21154c 322
wolfSSL 0:d92f9d21154c 323 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 0:d92f9d21154c 324 WOLFSSL_MSG(" Would Block");
wolfSSL 0:d92f9d21154c 325 return WOLFSSL_CBIO_ERR_WANT_WRITE;
wolfSSL 0:d92f9d21154c 326 }
wolfSSL 0:d92f9d21154c 327 else if (err == SOCKET_ECONNRESET) {
wolfSSL 0:d92f9d21154c 328 WOLFSSL_MSG(" Connection reset");
wolfSSL 0:d92f9d21154c 329 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 0:d92f9d21154c 330 }
wolfSSL 0:d92f9d21154c 331 else if (err == SOCKET_EINTR) {
wolfSSL 0:d92f9d21154c 332 WOLFSSL_MSG(" Socket interrupted");
wolfSSL 0:d92f9d21154c 333 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 0:d92f9d21154c 334 }
wolfSSL 0:d92f9d21154c 335 else if (err == SOCKET_EPIPE) {
wolfSSL 0:d92f9d21154c 336 WOLFSSL_MSG(" Socket EPIPE");
wolfSSL 0:d92f9d21154c 337 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 0:d92f9d21154c 338 }
wolfSSL 0:d92f9d21154c 339 else {
wolfSSL 0:d92f9d21154c 340 WOLFSSL_MSG(" General error");
wolfSSL 0:d92f9d21154c 341 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 342 }
wolfSSL 0:d92f9d21154c 343 }
wolfSSL 0:d92f9d21154c 344
wolfSSL 0:d92f9d21154c 345 return sent;
wolfSSL 0:d92f9d21154c 346 }
wolfSSL 0:d92f9d21154c 347
wolfSSL 0:d92f9d21154c 348
wolfSSL 0:d92f9d21154c 349 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 350
wolfSSL 0:d92f9d21154c 351 #include <wolfssl/wolfcrypt/sha.h>
wolfSSL 0:d92f9d21154c 352
wolfSSL 0:d92f9d21154c 353 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 354 #define XSOCKLENT int
wolfSSL 0:d92f9d21154c 355 #else
wolfSSL 0:d92f9d21154c 356 #define XSOCKLENT socklen_t
wolfSSL 0:d92f9d21154c 357 #endif
wolfSSL 0:d92f9d21154c 358
wolfSSL 0:d92f9d21154c 359 #define SENDTO_FUNCTION sendto
wolfSSL 0:d92f9d21154c 360 #define RECVFROM_FUNCTION recvfrom
wolfSSL 0:d92f9d21154c 361
wolfSSL 0:d92f9d21154c 362
wolfSSL 0:d92f9d21154c 363 /* The receive embedded callback
wolfSSL 0:d92f9d21154c 364 * return : nb bytes read, or error
wolfSSL 0:d92f9d21154c 365 */
wolfSSL 0:d92f9d21154c 366 int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
wolfSSL 0:d92f9d21154c 367 {
wolfSSL 0:d92f9d21154c 368 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
wolfSSL 0:d92f9d21154c 369 int recvd;
wolfSSL 0:d92f9d21154c 370 int err;
wolfSSL 0:d92f9d21154c 371 int sd = dtlsCtx->fd;
wolfSSL 0:d92f9d21154c 372 int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
wolfSSL 0:d92f9d21154c 373 struct sockaddr_storage peer;
wolfSSL 0:d92f9d21154c 374 XSOCKLENT peerSz = sizeof(peer);
wolfSSL 0:d92f9d21154c 375
wolfSSL 0:d92f9d21154c 376 WOLFSSL_ENTER("EmbedReceiveFrom()");
wolfSSL 0:d92f9d21154c 377
wolfSSL 0:d92f9d21154c 378 if (!wolfSSL_get_using_nonblock(ssl) && dtls_timeout != 0) {
wolfSSL 0:d92f9d21154c 379 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 380 DWORD timeout = dtls_timeout * 1000;
wolfSSL 0:d92f9d21154c 381 #else
wolfSSL 0:d92f9d21154c 382 struct timeval timeout;
wolfSSL 0:d92f9d21154c 383 XMEMSET(&timeout, 0, sizeof(timeout));
wolfSSL 0:d92f9d21154c 384 timeout.tv_sec = dtls_timeout;
wolfSSL 0:d92f9d21154c 385 #endif
wolfSSL 0:d92f9d21154c 386 if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
wolfSSL 0:d92f9d21154c 387 sizeof(timeout)) != 0) {
wolfSSL 0:d92f9d21154c 388 WOLFSSL_MSG("setsockopt rcvtimeo failed");
wolfSSL 0:d92f9d21154c 389 }
wolfSSL 0:d92f9d21154c 390 }
wolfSSL 0:d92f9d21154c 391
wolfSSL 0:d92f9d21154c 392 recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
wolfSSL 0:d92f9d21154c 393 (struct sockaddr*)&peer, &peerSz);
wolfSSL 0:d92f9d21154c 394
wolfSSL 0:d92f9d21154c 395 recvd = TranslateReturnCode(recvd, sd);
wolfSSL 0:d92f9d21154c 396
wolfSSL 0:d92f9d21154c 397 if (recvd < 0) {
wolfSSL 0:d92f9d21154c 398 err = LastError();
wolfSSL 0:d92f9d21154c 399 WOLFSSL_MSG("Embed Receive From error");
wolfSSL 0:d92f9d21154c 400
wolfSSL 0:d92f9d21154c 401 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 0:d92f9d21154c 402 if (wolfSSL_get_using_nonblock(ssl)) {
wolfSSL 0:d92f9d21154c 403 WOLFSSL_MSG(" Would block");
wolfSSL 0:d92f9d21154c 404 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 0:d92f9d21154c 405 }
wolfSSL 0:d92f9d21154c 406 else {
wolfSSL 0:d92f9d21154c 407 WOLFSSL_MSG(" Socket timeout");
wolfSSL 0:d92f9d21154c 408 return WOLFSSL_CBIO_ERR_TIMEOUT;
wolfSSL 0:d92f9d21154c 409 }
wolfSSL 0:d92f9d21154c 410 }
wolfSSL 0:d92f9d21154c 411 else if (err == SOCKET_ECONNRESET) {
wolfSSL 0:d92f9d21154c 412 WOLFSSL_MSG(" Connection reset");
wolfSSL 0:d92f9d21154c 413 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 0:d92f9d21154c 414 }
wolfSSL 0:d92f9d21154c 415 else if (err == SOCKET_EINTR) {
wolfSSL 0:d92f9d21154c 416 WOLFSSL_MSG(" Socket interrupted");
wolfSSL 0:d92f9d21154c 417 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 0:d92f9d21154c 418 }
wolfSSL 0:d92f9d21154c 419 else if (err == SOCKET_ECONNREFUSED) {
wolfSSL 0:d92f9d21154c 420 WOLFSSL_MSG(" Connection refused");
wolfSSL 0:d92f9d21154c 421 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 0:d92f9d21154c 422 }
wolfSSL 0:d92f9d21154c 423 else {
wolfSSL 0:d92f9d21154c 424 WOLFSSL_MSG(" General error");
wolfSSL 0:d92f9d21154c 425 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 426 }
wolfSSL 0:d92f9d21154c 427 }
wolfSSL 0:d92f9d21154c 428 else {
wolfSSL 0:d92f9d21154c 429 if (dtlsCtx->peer.sz > 0
wolfSSL 0:d92f9d21154c 430 && peerSz != (XSOCKLENT)dtlsCtx->peer.sz
wolfSSL 0:d92f9d21154c 431 && memcmp(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
wolfSSL 0:d92f9d21154c 432 WOLFSSL_MSG(" Ignored packet from invalid peer");
wolfSSL 0:d92f9d21154c 433 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 0:d92f9d21154c 434 }
wolfSSL 0:d92f9d21154c 435 }
wolfSSL 0:d92f9d21154c 436
wolfSSL 0:d92f9d21154c 437 return recvd;
wolfSSL 0:d92f9d21154c 438 }
wolfSSL 0:d92f9d21154c 439
wolfSSL 0:d92f9d21154c 440
wolfSSL 0:d92f9d21154c 441 /* The send embedded callback
wolfSSL 0:d92f9d21154c 442 * return : nb bytes sent, or error
wolfSSL 0:d92f9d21154c 443 */
wolfSSL 0:d92f9d21154c 444 int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
wolfSSL 0:d92f9d21154c 445 {
wolfSSL 0:d92f9d21154c 446 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
wolfSSL 0:d92f9d21154c 447 int sd = dtlsCtx->fd;
wolfSSL 0:d92f9d21154c 448 int sent;
wolfSSL 0:d92f9d21154c 449 int len = sz;
wolfSSL 0:d92f9d21154c 450 int err;
wolfSSL 0:d92f9d21154c 451
wolfSSL 0:d92f9d21154c 452 WOLFSSL_ENTER("EmbedSendTo()");
wolfSSL 0:d92f9d21154c 453
wolfSSL 0:d92f9d21154c 454 sent = (int)SENDTO_FUNCTION(sd, &buf[sz - len], len, ssl->wflags,
wolfSSL 0:d92f9d21154c 455 (const struct sockaddr*)dtlsCtx->peer.sa,
wolfSSL 0:d92f9d21154c 456 dtlsCtx->peer.sz);
wolfSSL 0:d92f9d21154c 457 if (sent < 0) {
wolfSSL 0:d92f9d21154c 458 err = LastError();
wolfSSL 0:d92f9d21154c 459 WOLFSSL_MSG("Embed Send To error");
wolfSSL 0:d92f9d21154c 460
wolfSSL 0:d92f9d21154c 461 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 0:d92f9d21154c 462 WOLFSSL_MSG(" Would Block");
wolfSSL 0:d92f9d21154c 463 return WOLFSSL_CBIO_ERR_WANT_WRITE;
wolfSSL 0:d92f9d21154c 464 }
wolfSSL 0:d92f9d21154c 465 else if (err == SOCKET_ECONNRESET) {
wolfSSL 0:d92f9d21154c 466 WOLFSSL_MSG(" Connection reset");
wolfSSL 0:d92f9d21154c 467 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 0:d92f9d21154c 468 }
wolfSSL 0:d92f9d21154c 469 else if (err == SOCKET_EINTR) {
wolfSSL 0:d92f9d21154c 470 WOLFSSL_MSG(" Socket interrupted");
wolfSSL 0:d92f9d21154c 471 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 0:d92f9d21154c 472 }
wolfSSL 0:d92f9d21154c 473 else if (err == SOCKET_EPIPE) {
wolfSSL 0:d92f9d21154c 474 WOLFSSL_MSG(" Socket EPIPE");
wolfSSL 0:d92f9d21154c 475 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 0:d92f9d21154c 476 }
wolfSSL 0:d92f9d21154c 477 else {
wolfSSL 0:d92f9d21154c 478 WOLFSSL_MSG(" General error");
wolfSSL 0:d92f9d21154c 479 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 480 }
wolfSSL 0:d92f9d21154c 481 }
wolfSSL 0:d92f9d21154c 482
wolfSSL 0:d92f9d21154c 483 return sent;
wolfSSL 0:d92f9d21154c 484 }
wolfSSL 0:d92f9d21154c 485
wolfSSL 0:d92f9d21154c 486
wolfSSL 0:d92f9d21154c 487 /* The DTLS Generate Cookie callback
wolfSSL 0:d92f9d21154c 488 * return : number of bytes copied into buf, or error
wolfSSL 0:d92f9d21154c 489 */
wolfSSL 0:d92f9d21154c 490 int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
wolfSSL 0:d92f9d21154c 491 {
wolfSSL 0:d92f9d21154c 492 int sd = ssl->wfd;
wolfSSL 0:d92f9d21154c 493 struct sockaddr_storage peer;
wolfSSL 0:d92f9d21154c 494 XSOCKLENT peerSz = sizeof(peer);
wolfSSL 0:d92f9d21154c 495 byte digest[SHA_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 496 int ret = 0;
wolfSSL 0:d92f9d21154c 497
wolfSSL 0:d92f9d21154c 498 (void)ctx;
wolfSSL 0:d92f9d21154c 499
wolfSSL 0:d92f9d21154c 500 XMEMSET(&peer, 0, sizeof(peer));
wolfSSL 0:d92f9d21154c 501 if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) {
wolfSSL 0:d92f9d21154c 502 WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie");
wolfSSL 0:d92f9d21154c 503 return GEN_COOKIE_E;
wolfSSL 0:d92f9d21154c 504 }
wolfSSL 0:d92f9d21154c 505
wolfSSL 0:d92f9d21154c 506 ret = wc_ShaHash((byte*)&peer, peerSz, digest);
wolfSSL 0:d92f9d21154c 507 if (ret != 0)
wolfSSL 0:d92f9d21154c 508 return ret;
wolfSSL 0:d92f9d21154c 509
wolfSSL 0:d92f9d21154c 510 if (sz > SHA_DIGEST_SIZE)
wolfSSL 0:d92f9d21154c 511 sz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 512 XMEMCPY(buf, digest, sz);
wolfSSL 0:d92f9d21154c 513
wolfSSL 0:d92f9d21154c 514 return sz;
wolfSSL 0:d92f9d21154c 515 }
wolfSSL 0:d92f9d21154c 516
wolfSSL 0:d92f9d21154c 517 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 518
wolfSSL 0:d92f9d21154c 519 #ifdef HAVE_OCSP
wolfSSL 0:d92f9d21154c 520
wolfSSL 0:d92f9d21154c 521
wolfSSL 0:d92f9d21154c 522 static int Word16ToString(char* d, word16 number)
wolfSSL 0:d92f9d21154c 523 {
wolfSSL 0:d92f9d21154c 524 int i = 0;
wolfSSL 0:d92f9d21154c 525
wolfSSL 0:d92f9d21154c 526 if (d != NULL) {
wolfSSL 0:d92f9d21154c 527 word16 order = 10000;
wolfSSL 0:d92f9d21154c 528 word16 digit;
wolfSSL 0:d92f9d21154c 529
wolfSSL 0:d92f9d21154c 530 if (number == 0) {
wolfSSL 0:d92f9d21154c 531 d[i++] = '0';
wolfSSL 0:d92f9d21154c 532 }
wolfSSL 0:d92f9d21154c 533 else {
wolfSSL 0:d92f9d21154c 534 while (order) {
wolfSSL 0:d92f9d21154c 535 digit = number / order;
wolfSSL 0:d92f9d21154c 536 if (i > 0 || digit != 0) {
wolfSSL 0:d92f9d21154c 537 d[i++] = (char)digit + '0';
wolfSSL 0:d92f9d21154c 538 }
wolfSSL 0:d92f9d21154c 539 if (digit != 0)
wolfSSL 0:d92f9d21154c 540 number %= digit * order;
wolfSSL 0:d92f9d21154c 541 if (order > 1)
wolfSSL 0:d92f9d21154c 542 order /= 10;
wolfSSL 0:d92f9d21154c 543 else
wolfSSL 0:d92f9d21154c 544 order = 0;
wolfSSL 0:d92f9d21154c 545 }
wolfSSL 0:d92f9d21154c 546 }
wolfSSL 0:d92f9d21154c 547 d[i] = 0;
wolfSSL 0:d92f9d21154c 548 }
wolfSSL 0:d92f9d21154c 549
wolfSSL 0:d92f9d21154c 550 return i;
wolfSSL 0:d92f9d21154c 551 }
wolfSSL 0:d92f9d21154c 552
wolfSSL 0:d92f9d21154c 553
wolfSSL 0:d92f9d21154c 554 static int tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
wolfSSL 0:d92f9d21154c 555 {
wolfSSL 0:d92f9d21154c 556 struct sockaddr_storage addr;
wolfSSL 0:d92f9d21154c 557 int sockaddr_len = sizeof(struct sockaddr_in);
wolfSSL 0:d92f9d21154c 558 XMEMSET(&addr, 0, sizeof(addr));
wolfSSL 0:d92f9d21154c 559
wolfSSL 0:d92f9d21154c 560 #ifdef HAVE_GETADDRINFO
wolfSSL 0:d92f9d21154c 561 {
wolfSSL 0:d92f9d21154c 562 struct addrinfo hints;
wolfSSL 0:d92f9d21154c 563 struct addrinfo* answer = NULL;
wolfSSL 0:d92f9d21154c 564 char strPort[6];
wolfSSL 0:d92f9d21154c 565
wolfSSL 0:d92f9d21154c 566 XMEMSET(&hints, 0, sizeof(hints));
wolfSSL 0:d92f9d21154c 567 hints.ai_family = AF_UNSPEC;
wolfSSL 0:d92f9d21154c 568 hints.ai_socktype = SOCK_STREAM;
wolfSSL 0:d92f9d21154c 569 hints.ai_protocol = IPPROTO_TCP;
wolfSSL 0:d92f9d21154c 570
wolfSSL 0:d92f9d21154c 571 if (Word16ToString(strPort, port) == 0) {
wolfSSL 0:d92f9d21154c 572 WOLFSSL_MSG("invalid port number for OCSP responder");
wolfSSL 0:d92f9d21154c 573 return -1;
wolfSSL 0:d92f9d21154c 574 }
wolfSSL 0:d92f9d21154c 575
wolfSSL 0:d92f9d21154c 576 if (getaddrinfo(ip, strPort, &hints, &answer) < 0 || answer == NULL) {
wolfSSL 0:d92f9d21154c 577 WOLFSSL_MSG("no addr info for OCSP responder");
wolfSSL 0:d92f9d21154c 578 return -1;
wolfSSL 0:d92f9d21154c 579 }
wolfSSL 0:d92f9d21154c 580
wolfSSL 0:d92f9d21154c 581 sockaddr_len = answer->ai_addrlen;
wolfSSL 0:d92f9d21154c 582 XMEMCPY(&addr, answer->ai_addr, sockaddr_len);
wolfSSL 0:d92f9d21154c 583 freeaddrinfo(answer);
wolfSSL 0:d92f9d21154c 584
wolfSSL 0:d92f9d21154c 585 }
wolfSSL 0:d92f9d21154c 586 #else /* HAVE_GETADDRINFO */
wolfSSL 0:d92f9d21154c 587 {
wolfSSL 0:d92f9d21154c 588 struct hostent* entry = gethostbyname(ip);
wolfSSL 0:d92f9d21154c 589 struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
wolfSSL 0:d92f9d21154c 590
wolfSSL 0:d92f9d21154c 591 if (entry) {
wolfSSL 0:d92f9d21154c 592 sin->sin_family = AF_INET;
wolfSSL 0:d92f9d21154c 593 sin->sin_port = htons(port);
wolfSSL 0:d92f9d21154c 594 XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0],
wolfSSL 0:d92f9d21154c 595 entry->h_length);
wolfSSL 0:d92f9d21154c 596 }
wolfSSL 0:d92f9d21154c 597 else {
wolfSSL 0:d92f9d21154c 598 WOLFSSL_MSG("no addr info for OCSP responder");
wolfSSL 0:d92f9d21154c 599 return -1;
wolfSSL 0:d92f9d21154c 600 }
wolfSSL 0:d92f9d21154c 601 }
wolfSSL 0:d92f9d21154c 602 #endif /* HAVE_GETADDRINFO */
wolfSSL 0:d92f9d21154c 603
wolfSSL 0:d92f9d21154c 604 *sockfd = socket(addr.ss_family, SOCK_STREAM, 0);
wolfSSL 0:d92f9d21154c 605
wolfSSL 0:d92f9d21154c 606 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 607 if (*sockfd == INVALID_SOCKET) {
wolfSSL 0:d92f9d21154c 608 WOLFSSL_MSG("bad socket fd, out of fds?");
wolfSSL 0:d92f9d21154c 609 return -1;
wolfSSL 0:d92f9d21154c 610 }
wolfSSL 0:d92f9d21154c 611 #else
wolfSSL 0:d92f9d21154c 612 if (*sockfd < 0) {
wolfSSL 0:d92f9d21154c 613 WOLFSSL_MSG("bad socket fd, out of fds?");
wolfSSL 0:d92f9d21154c 614 return -1;
wolfSSL 0:d92f9d21154c 615 }
wolfSSL 0:d92f9d21154c 616 #endif
wolfSSL 0:d92f9d21154c 617
wolfSSL 0:d92f9d21154c 618 if (connect(*sockfd, (struct sockaddr *)&addr, sockaddr_len) != 0) {
wolfSSL 0:d92f9d21154c 619 WOLFSSL_MSG("OCSP responder tcp connect failed");
wolfSSL 0:d92f9d21154c 620 return -1;
wolfSSL 0:d92f9d21154c 621 }
wolfSSL 0:d92f9d21154c 622
wolfSSL 0:d92f9d21154c 623 return 0;
wolfSSL 0:d92f9d21154c 624 }
wolfSSL 0:d92f9d21154c 625
wolfSSL 0:d92f9d21154c 626
wolfSSL 0:d92f9d21154c 627 static int build_http_request(const char* domainName, const char* path,
wolfSSL 0:d92f9d21154c 628 int ocspReqSz, byte* buf, int bufSize)
wolfSSL 0:d92f9d21154c 629 {
wolfSSL 0:d92f9d21154c 630 word32 domainNameLen, pathLen, ocspReqSzStrLen, completeLen;
wolfSSL 0:d92f9d21154c 631 char ocspReqSzStr[6];
wolfSSL 0:d92f9d21154c 632
wolfSSL 0:d92f9d21154c 633 domainNameLen = (word32)XSTRLEN(domainName);
wolfSSL 0:d92f9d21154c 634 pathLen = (word32)XSTRLEN(path);
wolfSSL 0:d92f9d21154c 635 ocspReqSzStrLen = Word16ToString(ocspReqSzStr, (word16)ocspReqSz);
wolfSSL 0:d92f9d21154c 636
wolfSSL 0:d92f9d21154c 637 completeLen = domainNameLen + pathLen + ocspReqSzStrLen + 84;
wolfSSL 0:d92f9d21154c 638 if (completeLen > (word32)bufSize)
wolfSSL 0:d92f9d21154c 639 return 0;
wolfSSL 0:d92f9d21154c 640
wolfSSL 0:d92f9d21154c 641 XSTRNCPY((char*)buf, "POST ", 5);
wolfSSL 0:d92f9d21154c 642 buf += 5;
wolfSSL 0:d92f9d21154c 643 XSTRNCPY((char*)buf, path, pathLen);
wolfSSL 0:d92f9d21154c 644 buf += pathLen;
wolfSSL 0:d92f9d21154c 645 XSTRNCPY((char*)buf, " HTTP/1.1\r\nHost: ", 17);
wolfSSL 0:d92f9d21154c 646 buf += 17;
wolfSSL 0:d92f9d21154c 647 XSTRNCPY((char*)buf, domainName, domainNameLen);
wolfSSL 0:d92f9d21154c 648 buf += domainNameLen;
wolfSSL 0:d92f9d21154c 649 XSTRNCPY((char*)buf, "\r\nContent-Length: ", 18);
wolfSSL 0:d92f9d21154c 650 buf += 18;
wolfSSL 0:d92f9d21154c 651 XSTRNCPY((char*)buf, ocspReqSzStr, ocspReqSzStrLen);
wolfSSL 0:d92f9d21154c 652 buf += ocspReqSzStrLen;
wolfSSL 0:d92f9d21154c 653 XSTRNCPY((char*)buf,
wolfSSL 0:d92f9d21154c 654 "\r\nContent-Type: application/ocsp-request\r\n\r\n", 44);
wolfSSL 0:d92f9d21154c 655
wolfSSL 0:d92f9d21154c 656 return completeLen;
wolfSSL 0:d92f9d21154c 657 }
wolfSSL 0:d92f9d21154c 658
wolfSSL 0:d92f9d21154c 659
wolfSSL 0:d92f9d21154c 660 static int decode_url(const char* url, int urlSz,
wolfSSL 0:d92f9d21154c 661 char* outName, char* outPath, word16* outPort)
wolfSSL 0:d92f9d21154c 662 {
wolfSSL 0:d92f9d21154c 663 int result = -1;
wolfSSL 0:d92f9d21154c 664
wolfSSL 0:d92f9d21154c 665 if (outName != NULL && outPath != NULL && outPort != NULL)
wolfSSL 0:d92f9d21154c 666 {
wolfSSL 0:d92f9d21154c 667 if (url == NULL || urlSz == 0)
wolfSSL 0:d92f9d21154c 668 {
wolfSSL 0:d92f9d21154c 669 *outName = 0;
wolfSSL 0:d92f9d21154c 670 *outPath = 0;
wolfSSL 0:d92f9d21154c 671 *outPort = 0;
wolfSSL 0:d92f9d21154c 672 }
wolfSSL 0:d92f9d21154c 673 else
wolfSSL 0:d92f9d21154c 674 {
wolfSSL 0:d92f9d21154c 675 int i, cur;
wolfSSL 0:d92f9d21154c 676
wolfSSL 0:d92f9d21154c 677 /* need to break the url down into scheme, address, and port */
wolfSSL 0:d92f9d21154c 678 /* "http://example.com:8080/" */
wolfSSL 0:d92f9d21154c 679 /* "http://[::1]:443/" */
wolfSSL 0:d92f9d21154c 680 if (XSTRNCMP(url, "http://", 7) == 0) {
wolfSSL 0:d92f9d21154c 681 cur = 7;
wolfSSL 0:d92f9d21154c 682 } else cur = 0;
wolfSSL 0:d92f9d21154c 683
wolfSSL 0:d92f9d21154c 684 i = 0;
wolfSSL 0:d92f9d21154c 685 if (url[cur] == '[') {
wolfSSL 0:d92f9d21154c 686 cur++;
wolfSSL 0:d92f9d21154c 687 /* copy until ']' */
wolfSSL 0:d92f9d21154c 688 while (url[cur] != 0 && url[cur] != ']' && cur < urlSz) {
wolfSSL 0:d92f9d21154c 689 outName[i++] = url[cur++];
wolfSSL 0:d92f9d21154c 690 }
wolfSSL 0:d92f9d21154c 691 cur++; /* skip ']' */
wolfSSL 0:d92f9d21154c 692 }
wolfSSL 0:d92f9d21154c 693 else {
wolfSSL 0:d92f9d21154c 694 while (url[cur] != 0 && url[cur] != ':' &&
wolfSSL 0:d92f9d21154c 695 url[cur] != '/' && cur < urlSz) {
wolfSSL 0:d92f9d21154c 696 outName[i++] = url[cur++];
wolfSSL 0:d92f9d21154c 697 }
wolfSSL 0:d92f9d21154c 698 }
wolfSSL 0:d92f9d21154c 699 outName[i] = 0;
wolfSSL 0:d92f9d21154c 700 /* Need to pick out the path after the domain name */
wolfSSL 0:d92f9d21154c 701
wolfSSL 0:d92f9d21154c 702 if (cur < urlSz && url[cur] == ':') {
wolfSSL 0:d92f9d21154c 703 char port[6];
wolfSSL 0:d92f9d21154c 704 int j;
wolfSSL 0:d92f9d21154c 705 word32 bigPort = 0;
wolfSSL 0:d92f9d21154c 706 i = 0;
wolfSSL 0:d92f9d21154c 707 cur++;
wolfSSL 0:d92f9d21154c 708 while (cur < urlSz && url[cur] != 0 && url[cur] != '/' &&
wolfSSL 0:d92f9d21154c 709 i < 6) {
wolfSSL 0:d92f9d21154c 710 port[i++] = url[cur++];
wolfSSL 0:d92f9d21154c 711 }
wolfSSL 0:d92f9d21154c 712
wolfSSL 0:d92f9d21154c 713 for (j = 0; j < i; j++) {
wolfSSL 0:d92f9d21154c 714 if (port[j] < '0' || port[j] > '9') return -1;
wolfSSL 0:d92f9d21154c 715 bigPort = (bigPort * 10) + (port[j] - '0');
wolfSSL 0:d92f9d21154c 716 }
wolfSSL 0:d92f9d21154c 717 *outPort = (word16)bigPort;
wolfSSL 0:d92f9d21154c 718 }
wolfSSL 0:d92f9d21154c 719 else
wolfSSL 0:d92f9d21154c 720 *outPort = 80;
wolfSSL 0:d92f9d21154c 721
wolfSSL 0:d92f9d21154c 722 if (cur < urlSz && url[cur] == '/') {
wolfSSL 0:d92f9d21154c 723 i = 0;
wolfSSL 0:d92f9d21154c 724 while (cur < urlSz && url[cur] != 0 && i < 80) {
wolfSSL 0:d92f9d21154c 725 outPath[i++] = url[cur++];
wolfSSL 0:d92f9d21154c 726 }
wolfSSL 0:d92f9d21154c 727 outPath[i] = 0;
wolfSSL 0:d92f9d21154c 728 }
wolfSSL 0:d92f9d21154c 729 else {
wolfSSL 0:d92f9d21154c 730 outPath[0] = '/';
wolfSSL 0:d92f9d21154c 731 outPath[1] = 0;
wolfSSL 0:d92f9d21154c 732 }
wolfSSL 0:d92f9d21154c 733 result = 0;
wolfSSL 0:d92f9d21154c 734 }
wolfSSL 0:d92f9d21154c 735 }
wolfSSL 0:d92f9d21154c 736
wolfSSL 0:d92f9d21154c 737 return result;
wolfSSL 0:d92f9d21154c 738 }
wolfSSL 0:d92f9d21154c 739
wolfSSL 0:d92f9d21154c 740
wolfSSL 0:d92f9d21154c 741 /* return: >0 OCSP Response Size
wolfSSL 0:d92f9d21154c 742 * -1 error */
wolfSSL 0:d92f9d21154c 743 static int process_http_response(int sfd, byte** respBuf,
wolfSSL 0:d92f9d21154c 744 byte* httpBuf, int httpBufSz)
wolfSSL 0:d92f9d21154c 745 {
wolfSSL 0:d92f9d21154c 746 int result;
wolfSSL 0:d92f9d21154c 747 int len = 0;
wolfSSL 0:d92f9d21154c 748 char *start, *end;
wolfSSL 0:d92f9d21154c 749 byte *recvBuf = NULL;
wolfSSL 0:d92f9d21154c 750 int recvBufSz = 0;
wolfSSL 0:d92f9d21154c 751 enum phr_state { phr_init, phr_http_start, phr_have_length,
wolfSSL 0:d92f9d21154c 752 phr_have_type, phr_wait_end, phr_http_end
wolfSSL 0:d92f9d21154c 753 } state = phr_init;
wolfSSL 0:d92f9d21154c 754
wolfSSL 0:d92f9d21154c 755 start = end = NULL;
wolfSSL 0:d92f9d21154c 756 do {
wolfSSL 0:d92f9d21154c 757 if (end == NULL) {
wolfSSL 0:d92f9d21154c 758 result = (int)recv(sfd, (char*)httpBuf+len, httpBufSz-len-1, 0);
wolfSSL 0:d92f9d21154c 759 if (result > 0) {
wolfSSL 0:d92f9d21154c 760 len += result;
wolfSSL 0:d92f9d21154c 761 start = (char*)httpBuf;
wolfSSL 0:d92f9d21154c 762 start[len] = 0;
wolfSSL 0:d92f9d21154c 763 }
wolfSSL 0:d92f9d21154c 764 else {
wolfSSL 0:d92f9d21154c 765 WOLFSSL_MSG("process_http_response recv http from peer failed");
wolfSSL 0:d92f9d21154c 766 return -1;
wolfSSL 0:d92f9d21154c 767 }
wolfSSL 0:d92f9d21154c 768 }
wolfSSL 0:d92f9d21154c 769 end = XSTRSTR(start, "\r\n");
wolfSSL 0:d92f9d21154c 770
wolfSSL 0:d92f9d21154c 771 if (end == NULL) {
wolfSSL 0:d92f9d21154c 772 if (len != 0)
wolfSSL 0:d92f9d21154c 773 XMEMMOVE(httpBuf, start, len);
wolfSSL 0:d92f9d21154c 774 start = end = NULL;
wolfSSL 0:d92f9d21154c 775 }
wolfSSL 0:d92f9d21154c 776 else if (end == start) {
wolfSSL 0:d92f9d21154c 777 if (state == phr_wait_end) {
wolfSSL 0:d92f9d21154c 778 state = phr_http_end;
wolfSSL 0:d92f9d21154c 779 len -= 2;
wolfSSL 0:d92f9d21154c 780 start += 2;
wolfSSL 0:d92f9d21154c 781 }
wolfSSL 0:d92f9d21154c 782 else {
wolfSSL 0:d92f9d21154c 783 WOLFSSL_MSG("process_http_response header ended early");
wolfSSL 0:d92f9d21154c 784 return -1;
wolfSSL 0:d92f9d21154c 785 }
wolfSSL 0:d92f9d21154c 786 }
wolfSSL 0:d92f9d21154c 787 else {
wolfSSL 0:d92f9d21154c 788 *end = 0;
wolfSSL 0:d92f9d21154c 789 len -= (int)(end - start) + 2;
wolfSSL 0:d92f9d21154c 790 /* adjust len to remove the first line including the /r/n */
wolfSSL 0:d92f9d21154c 791
wolfSSL 0:d92f9d21154c 792 if (XSTRNCASECMP(start, "HTTP/1", 6) == 0) {
wolfSSL 0:d92f9d21154c 793 start += 9;
wolfSSL 0:d92f9d21154c 794 if (XSTRNCASECMP(start, "200 OK", 6) != 0 ||
wolfSSL 0:d92f9d21154c 795 state != phr_init) {
wolfSSL 0:d92f9d21154c 796 WOLFSSL_MSG("process_http_response not OK");
wolfSSL 0:d92f9d21154c 797 return -1;
wolfSSL 0:d92f9d21154c 798 }
wolfSSL 0:d92f9d21154c 799 state = phr_http_start;
wolfSSL 0:d92f9d21154c 800 }
wolfSSL 0:d92f9d21154c 801 else if (XSTRNCASECMP(start, "Content-Type:", 13) == 0) {
wolfSSL 0:d92f9d21154c 802 start += 13;
wolfSSL 0:d92f9d21154c 803 while (*start == ' ' && *start != '\0') start++;
wolfSSL 0:d92f9d21154c 804 if (XSTRNCASECMP(start, "application/ocsp-response", 25) != 0) {
wolfSSL 0:d92f9d21154c 805 WOLFSSL_MSG("process_http_response not ocsp-response");
wolfSSL 0:d92f9d21154c 806 return -1;
wolfSSL 0:d92f9d21154c 807 }
wolfSSL 0:d92f9d21154c 808
wolfSSL 0:d92f9d21154c 809 if (state == phr_http_start) state = phr_have_type;
wolfSSL 0:d92f9d21154c 810 else if (state == phr_have_length) state = phr_wait_end;
wolfSSL 0:d92f9d21154c 811 else {
wolfSSL 0:d92f9d21154c 812 WOLFSSL_MSG("process_http_response type invalid state");
wolfSSL 0:d92f9d21154c 813 return -1;
wolfSSL 0:d92f9d21154c 814 }
wolfSSL 0:d92f9d21154c 815 }
wolfSSL 0:d92f9d21154c 816 else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) {
wolfSSL 0:d92f9d21154c 817 start += 15;
wolfSSL 0:d92f9d21154c 818 while (*start == ' ' && *start != '\0') start++;
wolfSSL 0:d92f9d21154c 819 recvBufSz = atoi(start);
wolfSSL 0:d92f9d21154c 820
wolfSSL 0:d92f9d21154c 821 if (state == phr_http_start) state = phr_have_length;
wolfSSL 0:d92f9d21154c 822 else if (state == phr_have_type) state = phr_wait_end;
wolfSSL 0:d92f9d21154c 823 else {
wolfSSL 0:d92f9d21154c 824 WOLFSSL_MSG("process_http_response length invalid state");
wolfSSL 0:d92f9d21154c 825 return -1;
wolfSSL 0:d92f9d21154c 826 }
wolfSSL 0:d92f9d21154c 827 }
wolfSSL 0:d92f9d21154c 828
wolfSSL 0:d92f9d21154c 829 start = end + 2;
wolfSSL 0:d92f9d21154c 830 }
wolfSSL 0:d92f9d21154c 831 } while (state != phr_http_end);
wolfSSL 0:d92f9d21154c 832
wolfSSL 0:d92f9d21154c 833 recvBuf = (byte*)XMALLOC(recvBufSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
wolfSSL 0:d92f9d21154c 834 if (recvBuf == NULL) {
wolfSSL 0:d92f9d21154c 835 WOLFSSL_MSG("process_http_response couldn't create response buffer");
wolfSSL 0:d92f9d21154c 836 return -1;
wolfSSL 0:d92f9d21154c 837 }
wolfSSL 0:d92f9d21154c 838
wolfSSL 0:d92f9d21154c 839 /* copy the remainder of the httpBuf into the respBuf */
wolfSSL 0:d92f9d21154c 840 if (len != 0)
wolfSSL 0:d92f9d21154c 841 XMEMCPY(recvBuf, start, len);
wolfSSL 0:d92f9d21154c 842
wolfSSL 0:d92f9d21154c 843 /* receive the OCSP response data */
wolfSSL 0:d92f9d21154c 844 do {
wolfSSL 0:d92f9d21154c 845 result = (int)recv(sfd, (char*)recvBuf+len, recvBufSz-len, 0);
wolfSSL 0:d92f9d21154c 846 if (result > 0)
wolfSSL 0:d92f9d21154c 847 len += result;
wolfSSL 0:d92f9d21154c 848 else {
wolfSSL 0:d92f9d21154c 849 WOLFSSL_MSG("process_http_response recv ocsp from peer failed");
wolfSSL 0:d92f9d21154c 850 return -1;
wolfSSL 0:d92f9d21154c 851 }
wolfSSL 0:d92f9d21154c 852 } while (len != recvBufSz);
wolfSSL 0:d92f9d21154c 853
wolfSSL 0:d92f9d21154c 854 *respBuf = recvBuf;
wolfSSL 0:d92f9d21154c 855 return recvBufSz;
wolfSSL 0:d92f9d21154c 856 }
wolfSSL 0:d92f9d21154c 857
wolfSSL 0:d92f9d21154c 858
wolfSSL 0:d92f9d21154c 859 #define SCRATCH_BUFFER_SIZE 512
wolfSSL 0:d92f9d21154c 860
wolfSSL 0:d92f9d21154c 861 int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
wolfSSL 0:d92f9d21154c 862 byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
wolfSSL 0:d92f9d21154c 863 {
wolfSSL 0:d92f9d21154c 864 SOCKET_T sfd = 0;
wolfSSL 0:d92f9d21154c 865 word16 port;
wolfSSL 0:d92f9d21154c 866 int ret = -1;
wolfSSL 0:d92f9d21154c 867 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 868 char* path;
wolfSSL 0:d92f9d21154c 869 char* domainName;
wolfSSL 0:d92f9d21154c 870 #else
wolfSSL 0:d92f9d21154c 871 char path[80];
wolfSSL 0:d92f9d21154c 872 char domainName[80];
wolfSSL 0:d92f9d21154c 873 #endif
wolfSSL 0:d92f9d21154c 874
wolfSSL 0:d92f9d21154c 875 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 876 path = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 877 if (path == NULL)
wolfSSL 0:d92f9d21154c 878 return -1;
wolfSSL 0:d92f9d21154c 879
wolfSSL 0:d92f9d21154c 880 domainName = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 881 if (domainName == NULL) {
wolfSSL 0:d92f9d21154c 882 XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 883 return -1;
wolfSSL 0:d92f9d21154c 884 }
wolfSSL 0:d92f9d21154c 885 #endif
wolfSSL 0:d92f9d21154c 886
wolfSSL 0:d92f9d21154c 887 (void)ctx;
wolfSSL 0:d92f9d21154c 888
wolfSSL 0:d92f9d21154c 889 if (ocspReqBuf == NULL || ocspReqSz == 0) {
wolfSSL 0:d92f9d21154c 890 WOLFSSL_MSG("OCSP request is required for lookup");
wolfSSL 0:d92f9d21154c 891 }
wolfSSL 0:d92f9d21154c 892 else if (ocspRespBuf == NULL) {
wolfSSL 0:d92f9d21154c 893 WOLFSSL_MSG("Cannot save OCSP response");
wolfSSL 0:d92f9d21154c 894 }
wolfSSL 0:d92f9d21154c 895 else if (decode_url(url, urlSz, domainName, path, &port) < 0) {
wolfSSL 0:d92f9d21154c 896 WOLFSSL_MSG("Unable to decode OCSP URL");
wolfSSL 0:d92f9d21154c 897 }
wolfSSL 0:d92f9d21154c 898 else {
wolfSSL 0:d92f9d21154c 899 /* Note, the library uses the EmbedOcspRespFree() callback to
wolfSSL 0:d92f9d21154c 900 * free this buffer. */
wolfSSL 0:d92f9d21154c 901 int httpBufSz = SCRATCH_BUFFER_SIZE;
wolfSSL 0:d92f9d21154c 902 byte* httpBuf = (byte*)XMALLOC(httpBufSz, NULL,
wolfSSL 0:d92f9d21154c 903 DYNAMIC_TYPE_IN_BUFFER);
wolfSSL 0:d92f9d21154c 904
wolfSSL 0:d92f9d21154c 905 if (httpBuf == NULL) {
wolfSSL 0:d92f9d21154c 906 WOLFSSL_MSG("Unable to create OCSP response buffer");
wolfSSL 0:d92f9d21154c 907 }
wolfSSL 0:d92f9d21154c 908 else {
wolfSSL 0:d92f9d21154c 909 httpBufSz = build_http_request(domainName, path, ocspReqSz,
wolfSSL 0:d92f9d21154c 910 httpBuf, httpBufSz);
wolfSSL 0:d92f9d21154c 911
wolfSSL 0:d92f9d21154c 912 if ((tcp_connect(&sfd, domainName, port) != 0) || (sfd <= 0)) {
wolfSSL 0:d92f9d21154c 913 WOLFSSL_MSG("OCSP Responder connection failed");
wolfSSL 0:d92f9d21154c 914 }
wolfSSL 0:d92f9d21154c 915 else if ((int)send(sfd, (char*)httpBuf, httpBufSz, 0) !=
wolfSSL 0:d92f9d21154c 916 httpBufSz) {
wolfSSL 0:d92f9d21154c 917 WOLFSSL_MSG("OCSP http request failed");
wolfSSL 0:d92f9d21154c 918 }
wolfSSL 0:d92f9d21154c 919 else if ((int)send(sfd, (char*)ocspReqBuf, ocspReqSz, 0) !=
wolfSSL 0:d92f9d21154c 920 ocspReqSz) {
wolfSSL 0:d92f9d21154c 921 WOLFSSL_MSG("OCSP ocsp request failed");
wolfSSL 0:d92f9d21154c 922 }
wolfSSL 0:d92f9d21154c 923 else {
wolfSSL 0:d92f9d21154c 924 ret = process_http_response(sfd, ocspRespBuf, httpBuf,
wolfSSL 0:d92f9d21154c 925 SCRATCH_BUFFER_SIZE);
wolfSSL 0:d92f9d21154c 926 }
wolfSSL 0:d92f9d21154c 927
wolfSSL 0:d92f9d21154c 928 close(sfd);
wolfSSL 0:d92f9d21154c 929 XFREE(httpBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
wolfSSL 0:d92f9d21154c 930 }
wolfSSL 0:d92f9d21154c 931 }
wolfSSL 0:d92f9d21154c 932
wolfSSL 0:d92f9d21154c 933 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 934 XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 935 XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 936 #endif
wolfSSL 0:d92f9d21154c 937
wolfSSL 0:d92f9d21154c 938 return ret;
wolfSSL 0:d92f9d21154c 939 }
wolfSSL 0:d92f9d21154c 940
wolfSSL 0:d92f9d21154c 941
wolfSSL 0:d92f9d21154c 942 void EmbedOcspRespFree(void* ctx, byte *resp)
wolfSSL 0:d92f9d21154c 943 {
wolfSSL 0:d92f9d21154c 944 (void)ctx;
wolfSSL 0:d92f9d21154c 945
wolfSSL 0:d92f9d21154c 946 if (resp)
wolfSSL 0:d92f9d21154c 947 XFREE(resp, NULL, DYNAMIC_TYPE_IN_BUFFER);
wolfSSL 0:d92f9d21154c 948 }
wolfSSL 0:d92f9d21154c 949
wolfSSL 0:d92f9d21154c 950
wolfSSL 0:d92f9d21154c 951 #endif
wolfSSL 0:d92f9d21154c 952
wolfSSL 0:d92f9d21154c 953 #endif /* WOLFSSL_USER_IO */
wolfSSL 0:d92f9d21154c 954
wolfSSL 0:d92f9d21154c 955 WOLFSSL_API void wolfSSL_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv)
wolfSSL 0:d92f9d21154c 956 {
wolfSSL 0:d92f9d21154c 957 ctx->CBIORecv = CBIORecv;
wolfSSL 0:d92f9d21154c 958 }
wolfSSL 0:d92f9d21154c 959
wolfSSL 0:d92f9d21154c 960
wolfSSL 0:d92f9d21154c 961 WOLFSSL_API void wolfSSL_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend)
wolfSSL 0:d92f9d21154c 962 {
wolfSSL 0:d92f9d21154c 963 ctx->CBIOSend = CBIOSend;
wolfSSL 0:d92f9d21154c 964 }
wolfSSL 0:d92f9d21154c 965
wolfSSL 0:d92f9d21154c 966
wolfSSL 0:d92f9d21154c 967 WOLFSSL_API void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
wolfSSL 0:d92f9d21154c 968 {
wolfSSL 0:d92f9d21154c 969 ssl->IOCB_ReadCtx = rctx;
wolfSSL 0:d92f9d21154c 970 }
wolfSSL 0:d92f9d21154c 971
wolfSSL 0:d92f9d21154c 972
wolfSSL 0:d92f9d21154c 973 WOLFSSL_API void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx)
wolfSSL 0:d92f9d21154c 974 {
wolfSSL 0:d92f9d21154c 975 ssl->IOCB_WriteCtx = wctx;
wolfSSL 0:d92f9d21154c 976 }
wolfSSL 0:d92f9d21154c 977
wolfSSL 0:d92f9d21154c 978
wolfSSL 0:d92f9d21154c 979 WOLFSSL_API void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 980 {
wolfSSL 0:d92f9d21154c 981 if (ssl)
wolfSSL 0:d92f9d21154c 982 return ssl->IOCB_ReadCtx;
wolfSSL 0:d92f9d21154c 983
wolfSSL 0:d92f9d21154c 984 return NULL;
wolfSSL 0:d92f9d21154c 985 }
wolfSSL 0:d92f9d21154c 986
wolfSSL 0:d92f9d21154c 987
wolfSSL 0:d92f9d21154c 988 WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 989 {
wolfSSL 0:d92f9d21154c 990 if (ssl)
wolfSSL 0:d92f9d21154c 991 return ssl->IOCB_WriteCtx;
wolfSSL 0:d92f9d21154c 992
wolfSSL 0:d92f9d21154c 993 return NULL;
wolfSSL 0:d92f9d21154c 994 }
wolfSSL 0:d92f9d21154c 995
wolfSSL 0:d92f9d21154c 996
wolfSSL 0:d92f9d21154c 997 WOLFSSL_API void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags)
wolfSSL 0:d92f9d21154c 998 {
wolfSSL 0:d92f9d21154c 999 ssl->rflags = flags;
wolfSSL 0:d92f9d21154c 1000 }
wolfSSL 0:d92f9d21154c 1001
wolfSSL 0:d92f9d21154c 1002
wolfSSL 0:d92f9d21154c 1003 WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags)
wolfSSL 0:d92f9d21154c 1004 {
wolfSSL 0:d92f9d21154c 1005 ssl->wflags = flags;
wolfSSL 0:d92f9d21154c 1006 }
wolfSSL 0:d92f9d21154c 1007
wolfSSL 0:d92f9d21154c 1008
wolfSSL 0:d92f9d21154c 1009 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 1010
wolfSSL 0:d92f9d21154c 1011 WOLFSSL_API void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb)
wolfSSL 0:d92f9d21154c 1012 {
wolfSSL 0:d92f9d21154c 1013 ctx->CBIOCookie = cb;
wolfSSL 0:d92f9d21154c 1014 }
wolfSSL 0:d92f9d21154c 1015
wolfSSL 0:d92f9d21154c 1016
wolfSSL 0:d92f9d21154c 1017 WOLFSSL_API void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx)
wolfSSL 0:d92f9d21154c 1018 {
wolfSSL 0:d92f9d21154c 1019 ssl->IOCB_CookieCtx = ctx;
wolfSSL 0:d92f9d21154c 1020 }
wolfSSL 0:d92f9d21154c 1021
wolfSSL 0:d92f9d21154c 1022
wolfSSL 0:d92f9d21154c 1023 WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 1024 {
wolfSSL 0:d92f9d21154c 1025 if (ssl)
wolfSSL 0:d92f9d21154c 1026 return ssl->IOCB_CookieCtx;
wolfSSL 0:d92f9d21154c 1027
wolfSSL 0:d92f9d21154c 1028 return NULL;
wolfSSL 0:d92f9d21154c 1029 }
wolfSSL 0:d92f9d21154c 1030
wolfSSL 0:d92f9d21154c 1031 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 1032
wolfSSL 0:d92f9d21154c 1033
wolfSSL 0:d92f9d21154c 1034 #ifdef HAVE_NETX
wolfSSL 0:d92f9d21154c 1035
wolfSSL 0:d92f9d21154c 1036 /* The NetX receive callback
wolfSSL 0:d92f9d21154c 1037 * return : bytes read, or error
wolfSSL 0:d92f9d21154c 1038 */
wolfSSL 0:d92f9d21154c 1039 int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
wolfSSL 0:d92f9d21154c 1040 {
wolfSSL 0:d92f9d21154c 1041 NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
wolfSSL 0:d92f9d21154c 1042 ULONG left;
wolfSSL 0:d92f9d21154c 1043 ULONG total;
wolfSSL 0:d92f9d21154c 1044 ULONG copied = 0;
wolfSSL 0:d92f9d21154c 1045 UINT status;
wolfSSL 0:d92f9d21154c 1046
wolfSSL 0:d92f9d21154c 1047 if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
wolfSSL 0:d92f9d21154c 1048 WOLFSSL_MSG("NetX Recv NULL parameters");
wolfSSL 0:d92f9d21154c 1049 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1050 }
wolfSSL 0:d92f9d21154c 1051
wolfSSL 0:d92f9d21154c 1052 if (nxCtx->nxPacket == NULL) {
wolfSSL 0:d92f9d21154c 1053 status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket,
wolfSSL 0:d92f9d21154c 1054 nxCtx->nxWait);
wolfSSL 0:d92f9d21154c 1055 if (status != NX_SUCCESS) {
wolfSSL 0:d92f9d21154c 1056 WOLFSSL_MSG("NetX Recv receive error");
wolfSSL 0:d92f9d21154c 1057 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1058 }
wolfSSL 0:d92f9d21154c 1059 }
wolfSSL 0:d92f9d21154c 1060
wolfSSL 0:d92f9d21154c 1061 if (nxCtx->nxPacket) {
wolfSSL 0:d92f9d21154c 1062 status = nx_packet_length_get(nxCtx->nxPacket, &total);
wolfSSL 0:d92f9d21154c 1063 if (status != NX_SUCCESS) {
wolfSSL 0:d92f9d21154c 1064 WOLFSSL_MSG("NetX Recv length get error");
wolfSSL 0:d92f9d21154c 1065 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1066 }
wolfSSL 0:d92f9d21154c 1067
wolfSSL 0:d92f9d21154c 1068 left = total - nxCtx->nxOffset;
wolfSSL 0:d92f9d21154c 1069 status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset,
wolfSSL 0:d92f9d21154c 1070 buf, sz, &copied);
wolfSSL 0:d92f9d21154c 1071 if (status != NX_SUCCESS) {
wolfSSL 0:d92f9d21154c 1072 WOLFSSL_MSG("NetX Recv data extract offset error");
wolfSSL 0:d92f9d21154c 1073 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1074 }
wolfSSL 0:d92f9d21154c 1075
wolfSSL 0:d92f9d21154c 1076 nxCtx->nxOffset += copied;
wolfSSL 0:d92f9d21154c 1077
wolfSSL 0:d92f9d21154c 1078 if (copied == left) {
wolfSSL 0:d92f9d21154c 1079 WOLFSSL_MSG("NetX Recv Drained packet");
wolfSSL 0:d92f9d21154c 1080 nx_packet_release(nxCtx->nxPacket);
wolfSSL 0:d92f9d21154c 1081 nxCtx->nxPacket = NULL;
wolfSSL 0:d92f9d21154c 1082 nxCtx->nxOffset = 0;
wolfSSL 0:d92f9d21154c 1083 }
wolfSSL 0:d92f9d21154c 1084 }
wolfSSL 0:d92f9d21154c 1085
wolfSSL 0:d92f9d21154c 1086 return copied;
wolfSSL 0:d92f9d21154c 1087 }
wolfSSL 0:d92f9d21154c 1088
wolfSSL 0:d92f9d21154c 1089
wolfSSL 0:d92f9d21154c 1090 /* The NetX send callback
wolfSSL 0:d92f9d21154c 1091 * return : bytes sent, or error
wolfSSL 0:d92f9d21154c 1092 */
wolfSSL 0:d92f9d21154c 1093 int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
wolfSSL 0:d92f9d21154c 1094 {
wolfSSL 0:d92f9d21154c 1095 NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
wolfSSL 0:d92f9d21154c 1096 NX_PACKET* packet;
wolfSSL 0:d92f9d21154c 1097 NX_PACKET_POOL* pool; /* shorthand */
wolfSSL 0:d92f9d21154c 1098 UINT status;
wolfSSL 0:d92f9d21154c 1099
wolfSSL 0:d92f9d21154c 1100 if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
wolfSSL 0:d92f9d21154c 1101 WOLFSSL_MSG("NetX Send NULL parameters");
wolfSSL 0:d92f9d21154c 1102 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1103 }
wolfSSL 0:d92f9d21154c 1104
wolfSSL 0:d92f9d21154c 1105 pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool;
wolfSSL 0:d92f9d21154c 1106 status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET,
wolfSSL 0:d92f9d21154c 1107 nxCtx->nxWait);
wolfSSL 0:d92f9d21154c 1108 if (status != NX_SUCCESS) {
wolfSSL 0:d92f9d21154c 1109 WOLFSSL_MSG("NetX Send packet alloc error");
wolfSSL 0:d92f9d21154c 1110 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1111 }
wolfSSL 0:d92f9d21154c 1112
wolfSSL 0:d92f9d21154c 1113 status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait);
wolfSSL 0:d92f9d21154c 1114 if (status != NX_SUCCESS) {
wolfSSL 0:d92f9d21154c 1115 nx_packet_release(packet);
wolfSSL 0:d92f9d21154c 1116 WOLFSSL_MSG("NetX Send data append error");
wolfSSL 0:d92f9d21154c 1117 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1118 }
wolfSSL 0:d92f9d21154c 1119
wolfSSL 0:d92f9d21154c 1120 status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait);
wolfSSL 0:d92f9d21154c 1121 if (status != NX_SUCCESS) {
wolfSSL 0:d92f9d21154c 1122 nx_packet_release(packet);
wolfSSL 0:d92f9d21154c 1123 WOLFSSL_MSG("NetX Send socket send error");
wolfSSL 0:d92f9d21154c 1124 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 0:d92f9d21154c 1125 }
wolfSSL 0:d92f9d21154c 1126
wolfSSL 0:d92f9d21154c 1127 return sz;
wolfSSL 0:d92f9d21154c 1128 }
wolfSSL 0:d92f9d21154c 1129
wolfSSL 0:d92f9d21154c 1130
wolfSSL 0:d92f9d21154c 1131 /* like set_fd, but for default NetX context */
wolfSSL 0:d92f9d21154c 1132 void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption)
wolfSSL 0:d92f9d21154c 1133 {
wolfSSL 0:d92f9d21154c 1134 if (ssl) {
wolfSSL 0:d92f9d21154c 1135 ssl->nxCtx.nxSocket = nxSocket;
wolfSSL 0:d92f9d21154c 1136 ssl->nxCtx.nxWait = waitOption;
wolfSSL 0:d92f9d21154c 1137 }
wolfSSL 0:d92f9d21154c 1138 }
wolfSSL 0:d92f9d21154c 1139
wolfSSL 0:d92f9d21154c 1140 #endif /* HAVE_NETX */
wolfSSL 0:d92f9d21154c 1141
wolfSSL 0:d92f9d21154c 1142