wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 01:44:10 2017 +0000
Revision:
11:cee25a834751
wolfSSL 3.11.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 11:cee25a834751 1 /* io.c
wolfSSL 11:cee25a834751 2 *
wolfSSL 11:cee25a834751 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 11:cee25a834751 4 *
wolfSSL 11:cee25a834751 5 * This file is part of wolfSSL.
wolfSSL 11:cee25a834751 6 *
wolfSSL 11:cee25a834751 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 11:cee25a834751 8 * it under the terms of the GNU General Public License as published by
wolfSSL 11:cee25a834751 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 11:cee25a834751 10 * (at your option) any later version.
wolfSSL 11:cee25a834751 11 *
wolfSSL 11:cee25a834751 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 11:cee25a834751 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 11:cee25a834751 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 11:cee25a834751 15 * GNU General Public License for more details.
wolfSSL 11:cee25a834751 16 *
wolfSSL 11:cee25a834751 17 * You should have received a copy of the GNU General Public License
wolfSSL 11:cee25a834751 18 * along with this program; if not, write to the Free Software
wolfSSL 11:cee25a834751 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 11:cee25a834751 20 */
wolfSSL 11:cee25a834751 21
wolfSSL 11:cee25a834751 22
wolfSSL 11:cee25a834751 23
wolfSSL 11:cee25a834751 24 #ifdef HAVE_CONFIG_H
wolfSSL 11:cee25a834751 25 #include <config.h>
wolfSSL 11:cee25a834751 26 #endif
wolfSSL 11:cee25a834751 27
wolfSSL 11:cee25a834751 28 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 11:cee25a834751 29
wolfSSL 11:cee25a834751 30 #ifndef WOLFCRYPT_ONLY
wolfSSL 11:cee25a834751 31
wolfSSL 11:cee25a834751 32 #ifdef _WIN32_WCE
wolfSSL 11:cee25a834751 33 /* On WinCE winsock2.h must be included before windows.h for socket stuff */
wolfSSL 11:cee25a834751 34 #include <winsock2.h>
wolfSSL 11:cee25a834751 35 #endif
wolfSSL 11:cee25a834751 36
wolfSSL 11:cee25a834751 37 #include <wolfssl/internal.h>
wolfSSL 11:cee25a834751 38 #include <wolfssl/error-ssl.h>
wolfSSL 11:cee25a834751 39 #include <wolfssl/io.h>
wolfSSL 11:cee25a834751 40
wolfSSL 11:cee25a834751 41 #if defined(HAVE_HTTP_CLIENT)
wolfSSL 11:cee25a834751 42 #include <stdlib.h> /* atoi(), strtol() */
wolfSSL 11:cee25a834751 43 #endif
wolfSSL 11:cee25a834751 44
wolfSSL 11:cee25a834751 45 /*
wolfSSL 11:cee25a834751 46 Possible IO enable options:
wolfSSL 11:cee25a834751 47 * WOLFSSL_USER_IO: Disables default Embed* callbacks and default: off
wolfSSL 11:cee25a834751 48 allows user to define their own using
wolfSSL 11:cee25a834751 49 wolfSSL_SetIORecv and wolfSSL_SetIOSend
wolfSSL 11:cee25a834751 50 * USE_WOLFSSL_IO: Enables the wolfSSL IO functions default: off
wolfSSL 11:cee25a834751 51 * HAVE_HTTP_CLIENT: Enables HTTP client API's default: off
wolfSSL 11:cee25a834751 52 (unless HAVE_OCSP or HAVE_CRL_IO defined)
wolfSSL 11:cee25a834751 53 * HAVE_IO_TIMEOUT: Enables support for connect timeout default: off
wolfSSL 11:cee25a834751 54 */
wolfSSL 11:cee25a834751 55
wolfSSL 11:cee25a834751 56
wolfSSL 11:cee25a834751 57 /* if user writes own I/O callbacks they can define WOLFSSL_USER_IO to remove
wolfSSL 11:cee25a834751 58 automatic setting of default I/O functions EmbedSend() and EmbedReceive()
wolfSSL 11:cee25a834751 59 but they'll still need SetCallback xxx() at end of file
wolfSSL 11:cee25a834751 60 */
wolfSSL 11:cee25a834751 61
wolfSSL 11:cee25a834751 62 #if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT)
wolfSSL 11:cee25a834751 63
wolfSSL 11:cee25a834751 64 /* Translates return codes returned from
wolfSSL 11:cee25a834751 65 * send() and recv() if need be.
wolfSSL 11:cee25a834751 66 */
wolfSSL 11:cee25a834751 67 static INLINE int TranslateReturnCode(int old, int sd)
wolfSSL 11:cee25a834751 68 {
wolfSSL 11:cee25a834751 69 (void)sd;
wolfSSL 11:cee25a834751 70
wolfSSL 11:cee25a834751 71 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
wolfSSL 11:cee25a834751 72 if (old == 0) {
wolfSSL 11:cee25a834751 73 errno = SOCKET_EWOULDBLOCK;
wolfSSL 11:cee25a834751 74 return -1; /* convert to BSD style wouldblock as error */
wolfSSL 11:cee25a834751 75 }
wolfSSL 11:cee25a834751 76
wolfSSL 11:cee25a834751 77 if (old < 0) {
wolfSSL 11:cee25a834751 78 errno = RTCS_geterror(sd);
wolfSSL 11:cee25a834751 79 if (errno == RTCSERR_TCP_CONN_CLOSING)
wolfSSL 11:cee25a834751 80 return 0; /* convert to BSD style closing */
wolfSSL 11:cee25a834751 81 if (errno == RTCSERR_TCP_CONN_RLSD)
wolfSSL 11:cee25a834751 82 errno = SOCKET_ECONNRESET;
wolfSSL 11:cee25a834751 83 if (errno == RTCSERR_TCP_TIMED_OUT)
wolfSSL 11:cee25a834751 84 errno = SOCKET_EAGAIN;
wolfSSL 11:cee25a834751 85 }
wolfSSL 11:cee25a834751 86 #endif
wolfSSL 11:cee25a834751 87
wolfSSL 11:cee25a834751 88 return old;
wolfSSL 11:cee25a834751 89 }
wolfSSL 11:cee25a834751 90
wolfSSL 11:cee25a834751 91 static INLINE int LastError(void)
wolfSSL 11:cee25a834751 92 {
wolfSSL 11:cee25a834751 93 #ifdef USE_WINDOWS_API
wolfSSL 11:cee25a834751 94 return WSAGetLastError();
wolfSSL 11:cee25a834751 95 #elif defined(EBSNET)
wolfSSL 11:cee25a834751 96 return xn_getlasterror();
wolfSSL 11:cee25a834751 97 #else
wolfSSL 11:cee25a834751 98 return errno;
wolfSSL 11:cee25a834751 99 #endif
wolfSSL 11:cee25a834751 100 }
wolfSSL 11:cee25a834751 101
wolfSSL 11:cee25a834751 102 #endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */
wolfSSL 11:cee25a834751 103
wolfSSL 11:cee25a834751 104
wolfSSL 11:cee25a834751 105 #ifdef USE_WOLFSSL_IO
wolfSSL 11:cee25a834751 106
wolfSSL 11:cee25a834751 107 /* The receive embedded callback
wolfSSL 11:cee25a834751 108 * return : nb bytes read, or error
wolfSSL 11:cee25a834751 109 */
wolfSSL 11:cee25a834751 110 int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
wolfSSL 11:cee25a834751 111 {
wolfSSL 11:cee25a834751 112 int sd = *(int*)ctx;
wolfSSL 11:cee25a834751 113 int recvd;
wolfSSL 11:cee25a834751 114
wolfSSL 11:cee25a834751 115 #ifdef WOLFSSL_DTLS
wolfSSL 11:cee25a834751 116 {
wolfSSL 11:cee25a834751 117 int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
wolfSSL 11:cee25a834751 118 if (wolfSSL_dtls(ssl)
wolfSSL 11:cee25a834751 119 && !wolfSSL_get_using_nonblock(ssl)
wolfSSL 11:cee25a834751 120 && dtls_timeout != 0) {
wolfSSL 11:cee25a834751 121 #ifdef USE_WINDOWS_API
wolfSSL 11:cee25a834751 122 DWORD timeout = dtls_timeout * 1000;
wolfSSL 11:cee25a834751 123 #else
wolfSSL 11:cee25a834751 124 struct timeval timeout;
wolfSSL 11:cee25a834751 125 XMEMSET(&timeout, 0, sizeof(timeout));
wolfSSL 11:cee25a834751 126 timeout.tv_sec = dtls_timeout;
wolfSSL 11:cee25a834751 127 #endif
wolfSSL 11:cee25a834751 128 if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
wolfSSL 11:cee25a834751 129 sizeof(timeout)) != 0) {
wolfSSL 11:cee25a834751 130 WOLFSSL_MSG("setsockopt rcvtimeo failed");
wolfSSL 11:cee25a834751 131 }
wolfSSL 11:cee25a834751 132 }
wolfSSL 11:cee25a834751 133 }
wolfSSL 11:cee25a834751 134 #endif
wolfSSL 11:cee25a834751 135
wolfSSL 11:cee25a834751 136 recvd = wolfIO_Recv(sd, buf, sz, ssl->rflags);
wolfSSL 11:cee25a834751 137 if (recvd < 0) {
wolfSSL 11:cee25a834751 138 int err = LastError();
wolfSSL 11:cee25a834751 139 WOLFSSL_MSG("Embed Receive error");
wolfSSL 11:cee25a834751 140
wolfSSL 11:cee25a834751 141 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 11:cee25a834751 142 if (!wolfSSL_dtls(ssl) || wolfSSL_get_using_nonblock(ssl)) {
wolfSSL 11:cee25a834751 143 WOLFSSL_MSG("\tWould block");
wolfSSL 11:cee25a834751 144 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 11:cee25a834751 145 }
wolfSSL 11:cee25a834751 146 else {
wolfSSL 11:cee25a834751 147 WOLFSSL_MSG("\tSocket timeout");
wolfSSL 11:cee25a834751 148 return WOLFSSL_CBIO_ERR_TIMEOUT;
wolfSSL 11:cee25a834751 149 }
wolfSSL 11:cee25a834751 150 }
wolfSSL 11:cee25a834751 151 else if (err == SOCKET_ECONNRESET) {
wolfSSL 11:cee25a834751 152 WOLFSSL_MSG("\tConnection reset");
wolfSSL 11:cee25a834751 153 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 11:cee25a834751 154 }
wolfSSL 11:cee25a834751 155 else if (err == SOCKET_EINTR) {
wolfSSL 11:cee25a834751 156 WOLFSSL_MSG("\tSocket interrupted");
wolfSSL 11:cee25a834751 157 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 11:cee25a834751 158 }
wolfSSL 11:cee25a834751 159 else if (err == SOCKET_ECONNREFUSED) {
wolfSSL 11:cee25a834751 160 WOLFSSL_MSG("\tConnection refused");
wolfSSL 11:cee25a834751 161 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 11:cee25a834751 162 }
wolfSSL 11:cee25a834751 163 else if (err == SOCKET_ECONNABORTED) {
wolfSSL 11:cee25a834751 164 WOLFSSL_MSG("\tConnection aborted");
wolfSSL 11:cee25a834751 165 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 11:cee25a834751 166 }
wolfSSL 11:cee25a834751 167 else {
wolfSSL 11:cee25a834751 168 WOLFSSL_MSG("\tGeneral error");
wolfSSL 11:cee25a834751 169 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 170 }
wolfSSL 11:cee25a834751 171 }
wolfSSL 11:cee25a834751 172 else if (recvd == 0) {
wolfSSL 11:cee25a834751 173 WOLFSSL_MSG("Embed receive connection closed");
wolfSSL 11:cee25a834751 174 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 11:cee25a834751 175 }
wolfSSL 11:cee25a834751 176
wolfSSL 11:cee25a834751 177 return recvd;
wolfSSL 11:cee25a834751 178 }
wolfSSL 11:cee25a834751 179
wolfSSL 11:cee25a834751 180 /* The send embedded callback
wolfSSL 11:cee25a834751 181 * return : nb bytes sent, or error
wolfSSL 11:cee25a834751 182 */
wolfSSL 11:cee25a834751 183 int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
wolfSSL 11:cee25a834751 184 {
wolfSSL 11:cee25a834751 185 int sd = *(int*)ctx;
wolfSSL 11:cee25a834751 186 int sent;
wolfSSL 11:cee25a834751 187
wolfSSL 11:cee25a834751 188 sent = wolfIO_Send(sd, buf, sz, ssl->wflags);
wolfSSL 11:cee25a834751 189 if (sent < 0) {
wolfSSL 11:cee25a834751 190 int err = LastError();
wolfSSL 11:cee25a834751 191 WOLFSSL_MSG("Embed Send error");
wolfSSL 11:cee25a834751 192
wolfSSL 11:cee25a834751 193 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 11:cee25a834751 194 WOLFSSL_MSG("\tWould Block");
wolfSSL 11:cee25a834751 195 return WOLFSSL_CBIO_ERR_WANT_WRITE;
wolfSSL 11:cee25a834751 196 }
wolfSSL 11:cee25a834751 197 else if (err == SOCKET_ECONNRESET) {
wolfSSL 11:cee25a834751 198 WOLFSSL_MSG("\tConnection reset");
wolfSSL 11:cee25a834751 199 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 11:cee25a834751 200 }
wolfSSL 11:cee25a834751 201 else if (err == SOCKET_EINTR) {
wolfSSL 11:cee25a834751 202 WOLFSSL_MSG("\tSocket interrupted");
wolfSSL 11:cee25a834751 203 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 11:cee25a834751 204 }
wolfSSL 11:cee25a834751 205 else if (err == SOCKET_EPIPE) {
wolfSSL 11:cee25a834751 206 WOLFSSL_MSG("\tSocket EPIPE");
wolfSSL 11:cee25a834751 207 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 11:cee25a834751 208 }
wolfSSL 11:cee25a834751 209 else {
wolfSSL 11:cee25a834751 210 WOLFSSL_MSG("\tGeneral error");
wolfSSL 11:cee25a834751 211 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 212 }
wolfSSL 11:cee25a834751 213 }
wolfSSL 11:cee25a834751 214
wolfSSL 11:cee25a834751 215 return sent;
wolfSSL 11:cee25a834751 216 }
wolfSSL 11:cee25a834751 217
wolfSSL 11:cee25a834751 218
wolfSSL 11:cee25a834751 219 #ifdef WOLFSSL_DTLS
wolfSSL 11:cee25a834751 220
wolfSSL 11:cee25a834751 221 #include <wolfssl/wolfcrypt/sha.h>
wolfSSL 11:cee25a834751 222
wolfSSL 11:cee25a834751 223 #define SENDTO_FUNCTION sendto
wolfSSL 11:cee25a834751 224 #define RECVFROM_FUNCTION recvfrom
wolfSSL 11:cee25a834751 225
wolfSSL 11:cee25a834751 226
wolfSSL 11:cee25a834751 227 /* The receive embedded callback
wolfSSL 11:cee25a834751 228 * return : nb bytes read, or error
wolfSSL 11:cee25a834751 229 */
wolfSSL 11:cee25a834751 230 int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
wolfSSL 11:cee25a834751 231 {
wolfSSL 11:cee25a834751 232 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
wolfSSL 11:cee25a834751 233 int recvd;
wolfSSL 11:cee25a834751 234 int err;
wolfSSL 11:cee25a834751 235 int sd = dtlsCtx->rfd;
wolfSSL 11:cee25a834751 236 int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
wolfSSL 11:cee25a834751 237 SOCKADDR_S peer;
wolfSSL 11:cee25a834751 238 XSOCKLENT peerSz = sizeof(peer);
wolfSSL 11:cee25a834751 239
wolfSSL 11:cee25a834751 240 WOLFSSL_ENTER("EmbedReceiveFrom()");
wolfSSL 11:cee25a834751 241
wolfSSL 11:cee25a834751 242 if (ssl->options.handShakeDone)
wolfSSL 11:cee25a834751 243 dtls_timeout = 0;
wolfSSL 11:cee25a834751 244
wolfSSL 11:cee25a834751 245 if (!wolfSSL_get_using_nonblock(ssl)) {
wolfSSL 11:cee25a834751 246 #ifdef USE_WINDOWS_API
wolfSSL 11:cee25a834751 247 DWORD timeout = dtls_timeout * 1000;
wolfSSL 11:cee25a834751 248 #else
wolfSSL 11:cee25a834751 249 struct timeval timeout;
wolfSSL 11:cee25a834751 250 XMEMSET(&timeout, 0, sizeof(timeout));
wolfSSL 11:cee25a834751 251 timeout.tv_sec = dtls_timeout;
wolfSSL 11:cee25a834751 252 #endif
wolfSSL 11:cee25a834751 253 if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
wolfSSL 11:cee25a834751 254 sizeof(timeout)) != 0) {
wolfSSL 11:cee25a834751 255 WOLFSSL_MSG("setsockopt rcvtimeo failed");
wolfSSL 11:cee25a834751 256 }
wolfSSL 11:cee25a834751 257 }
wolfSSL 11:cee25a834751 258
wolfSSL 11:cee25a834751 259 recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
wolfSSL 11:cee25a834751 260 (SOCKADDR*)&peer, &peerSz);
wolfSSL 11:cee25a834751 261
wolfSSL 11:cee25a834751 262 recvd = TranslateReturnCode(recvd, sd);
wolfSSL 11:cee25a834751 263
wolfSSL 11:cee25a834751 264 if (recvd < 0) {
wolfSSL 11:cee25a834751 265 err = LastError();
wolfSSL 11:cee25a834751 266 WOLFSSL_MSG("Embed Receive From error");
wolfSSL 11:cee25a834751 267
wolfSSL 11:cee25a834751 268 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 11:cee25a834751 269 if (wolfSSL_get_using_nonblock(ssl)) {
wolfSSL 11:cee25a834751 270 WOLFSSL_MSG("\tWould block");
wolfSSL 11:cee25a834751 271 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 11:cee25a834751 272 }
wolfSSL 11:cee25a834751 273 else {
wolfSSL 11:cee25a834751 274 WOLFSSL_MSG("\tSocket timeout");
wolfSSL 11:cee25a834751 275 return WOLFSSL_CBIO_ERR_TIMEOUT;
wolfSSL 11:cee25a834751 276 }
wolfSSL 11:cee25a834751 277 }
wolfSSL 11:cee25a834751 278 else if (err == SOCKET_ECONNRESET) {
wolfSSL 11:cee25a834751 279 WOLFSSL_MSG("\tConnection reset");
wolfSSL 11:cee25a834751 280 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 11:cee25a834751 281 }
wolfSSL 11:cee25a834751 282 else if (err == SOCKET_EINTR) {
wolfSSL 11:cee25a834751 283 WOLFSSL_MSG("\tSocket interrupted");
wolfSSL 11:cee25a834751 284 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 11:cee25a834751 285 }
wolfSSL 11:cee25a834751 286 else if (err == SOCKET_ECONNREFUSED) {
wolfSSL 11:cee25a834751 287 WOLFSSL_MSG("\tConnection refused");
wolfSSL 11:cee25a834751 288 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 11:cee25a834751 289 }
wolfSSL 11:cee25a834751 290 else {
wolfSSL 11:cee25a834751 291 WOLFSSL_MSG("\tGeneral error");
wolfSSL 11:cee25a834751 292 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 293 }
wolfSSL 11:cee25a834751 294 }
wolfSSL 11:cee25a834751 295 else {
wolfSSL 11:cee25a834751 296 if (dtlsCtx->peer.sz > 0
wolfSSL 11:cee25a834751 297 && peerSz != (XSOCKLENT)dtlsCtx->peer.sz
wolfSSL 11:cee25a834751 298 && XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
wolfSSL 11:cee25a834751 299 WOLFSSL_MSG("\tIgnored packet from invalid peer");
wolfSSL 11:cee25a834751 300 return WOLFSSL_CBIO_ERR_WANT_READ;
wolfSSL 11:cee25a834751 301 }
wolfSSL 11:cee25a834751 302 }
wolfSSL 11:cee25a834751 303
wolfSSL 11:cee25a834751 304 return recvd;
wolfSSL 11:cee25a834751 305 }
wolfSSL 11:cee25a834751 306
wolfSSL 11:cee25a834751 307
wolfSSL 11:cee25a834751 308 /* The send embedded callback
wolfSSL 11:cee25a834751 309 * return : nb bytes sent, or error
wolfSSL 11:cee25a834751 310 */
wolfSSL 11:cee25a834751 311 int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
wolfSSL 11:cee25a834751 312 {
wolfSSL 11:cee25a834751 313 WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx;
wolfSSL 11:cee25a834751 314 int sd = dtlsCtx->wfd;
wolfSSL 11:cee25a834751 315 int sent;
wolfSSL 11:cee25a834751 316 int len = sz;
wolfSSL 11:cee25a834751 317 int err;
wolfSSL 11:cee25a834751 318
wolfSSL 11:cee25a834751 319 WOLFSSL_ENTER("EmbedSendTo()");
wolfSSL 11:cee25a834751 320
wolfSSL 11:cee25a834751 321 sent = (int)SENDTO_FUNCTION(sd, &buf[sz - len], len, ssl->wflags,
wolfSSL 11:cee25a834751 322 (const SOCKADDR*)dtlsCtx->peer.sa,
wolfSSL 11:cee25a834751 323 dtlsCtx->peer.sz);
wolfSSL 11:cee25a834751 324
wolfSSL 11:cee25a834751 325 sent = TranslateReturnCode(sent, sd);
wolfSSL 11:cee25a834751 326
wolfSSL 11:cee25a834751 327 if (sent < 0) {
wolfSSL 11:cee25a834751 328 err = LastError();
wolfSSL 11:cee25a834751 329 WOLFSSL_MSG("Embed Send To error");
wolfSSL 11:cee25a834751 330
wolfSSL 11:cee25a834751 331 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
wolfSSL 11:cee25a834751 332 WOLFSSL_MSG("\tWould Block");
wolfSSL 11:cee25a834751 333 return WOLFSSL_CBIO_ERR_WANT_WRITE;
wolfSSL 11:cee25a834751 334 }
wolfSSL 11:cee25a834751 335 else if (err == SOCKET_ECONNRESET) {
wolfSSL 11:cee25a834751 336 WOLFSSL_MSG("\tConnection reset");
wolfSSL 11:cee25a834751 337 return WOLFSSL_CBIO_ERR_CONN_RST;
wolfSSL 11:cee25a834751 338 }
wolfSSL 11:cee25a834751 339 else if (err == SOCKET_EINTR) {
wolfSSL 11:cee25a834751 340 WOLFSSL_MSG("\tSocket interrupted");
wolfSSL 11:cee25a834751 341 return WOLFSSL_CBIO_ERR_ISR;
wolfSSL 11:cee25a834751 342 }
wolfSSL 11:cee25a834751 343 else if (err == SOCKET_EPIPE) {
wolfSSL 11:cee25a834751 344 WOLFSSL_MSG("\tSocket EPIPE");
wolfSSL 11:cee25a834751 345 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
wolfSSL 11:cee25a834751 346 }
wolfSSL 11:cee25a834751 347 else {
wolfSSL 11:cee25a834751 348 WOLFSSL_MSG("\tGeneral error");
wolfSSL 11:cee25a834751 349 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 350 }
wolfSSL 11:cee25a834751 351 }
wolfSSL 11:cee25a834751 352
wolfSSL 11:cee25a834751 353 return sent;
wolfSSL 11:cee25a834751 354 }
wolfSSL 11:cee25a834751 355
wolfSSL 11:cee25a834751 356
wolfSSL 11:cee25a834751 357 /* The DTLS Generate Cookie callback
wolfSSL 11:cee25a834751 358 * return : number of bytes copied into buf, or error
wolfSSL 11:cee25a834751 359 */
wolfSSL 11:cee25a834751 360 int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
wolfSSL 11:cee25a834751 361 {
wolfSSL 11:cee25a834751 362 int sd = ssl->wfd;
wolfSSL 11:cee25a834751 363 SOCKADDR_S peer;
wolfSSL 11:cee25a834751 364 XSOCKLENT peerSz = sizeof(peer);
wolfSSL 11:cee25a834751 365 byte digest[SHA_DIGEST_SIZE];
wolfSSL 11:cee25a834751 366 int ret = 0;
wolfSSL 11:cee25a834751 367
wolfSSL 11:cee25a834751 368 (void)ctx;
wolfSSL 11:cee25a834751 369
wolfSSL 11:cee25a834751 370 XMEMSET(&peer, 0, sizeof(peer));
wolfSSL 11:cee25a834751 371 if (getpeername(sd, (SOCKADDR*)&peer, &peerSz) != 0) {
wolfSSL 11:cee25a834751 372 WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie");
wolfSSL 11:cee25a834751 373 return GEN_COOKIE_E;
wolfSSL 11:cee25a834751 374 }
wolfSSL 11:cee25a834751 375
wolfSSL 11:cee25a834751 376 ret = wc_ShaHash((byte*)&peer, peerSz, digest);
wolfSSL 11:cee25a834751 377 if (ret != 0)
wolfSSL 11:cee25a834751 378 return ret;
wolfSSL 11:cee25a834751 379
wolfSSL 11:cee25a834751 380 if (sz > SHA_DIGEST_SIZE)
wolfSSL 11:cee25a834751 381 sz = SHA_DIGEST_SIZE;
wolfSSL 11:cee25a834751 382 XMEMCPY(buf, digest, sz);
wolfSSL 11:cee25a834751 383
wolfSSL 11:cee25a834751 384 return sz;
wolfSSL 11:cee25a834751 385 }
wolfSSL 11:cee25a834751 386
wolfSSL 11:cee25a834751 387 #ifdef WOLFSSL_SESSION_EXPORT
wolfSSL 11:cee25a834751 388
wolfSSL 11:cee25a834751 389 /* get the peer information in human readable form (ip, port, family)
wolfSSL 11:cee25a834751 390 * default function assumes BSD sockets
wolfSSL 11:cee25a834751 391 * can be overriden with wolfSSL_CTX_SetIOGetPeer
wolfSSL 11:cee25a834751 392 */
wolfSSL 11:cee25a834751 393 int EmbedGetPeer(WOLFSSL* ssl, char* ip, int* ipSz,
wolfSSL 11:cee25a834751 394 unsigned short* port, int* fam)
wolfSSL 11:cee25a834751 395 {
wolfSSL 11:cee25a834751 396 SOCKADDR_S peer;
wolfSSL 11:cee25a834751 397 word32 peerSz;
wolfSSL 11:cee25a834751 398 int ret;
wolfSSL 11:cee25a834751 399
wolfSSL 11:cee25a834751 400 if (ssl == NULL || ip == NULL || ipSz == NULL ||
wolfSSL 11:cee25a834751 401 port == NULL || fam == NULL) {
wolfSSL 11:cee25a834751 402 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 403 }
wolfSSL 11:cee25a834751 404
wolfSSL 11:cee25a834751 405 /* get peer information stored in ssl struct */
wolfSSL 11:cee25a834751 406 peerSz = sizeof(SOCKADDR_S);
wolfSSL 11:cee25a834751 407 if ((ret = wolfSSL_dtls_get_peer(ssl, (void*)&peer, &peerSz))
wolfSSL 11:cee25a834751 408 != SSL_SUCCESS) {
wolfSSL 11:cee25a834751 409 return ret;
wolfSSL 11:cee25a834751 410 }
wolfSSL 11:cee25a834751 411
wolfSSL 11:cee25a834751 412 /* extract family, ip, and port */
wolfSSL 11:cee25a834751 413 *fam = ((SOCKADDR_S*)&peer)->ss_family;
wolfSSL 11:cee25a834751 414 switch (*fam) {
wolfSSL 11:cee25a834751 415 case WOLFSSL_IP4:
wolfSSL 11:cee25a834751 416 if (XINET_NTOP(*fam, &(((SOCKADDR_IN*)&peer)->sin_addr),
wolfSSL 11:cee25a834751 417 ip, *ipSz) == NULL) {
wolfSSL 11:cee25a834751 418 WOLFSSL_MSG("XINET_NTOP error");
wolfSSL 11:cee25a834751 419 return SOCKET_ERROR_E;
wolfSSL 11:cee25a834751 420 }
wolfSSL 11:cee25a834751 421 *port = XNTOHS(((SOCKADDR_IN*)&peer)->sin_port);
wolfSSL 11:cee25a834751 422 break;
wolfSSL 11:cee25a834751 423
wolfSSL 11:cee25a834751 424 case WOLFSSL_IP6:
wolfSSL 11:cee25a834751 425 #ifdef WOLFSSL_IPV6
wolfSSL 11:cee25a834751 426 if (XINET_NTOP(*fam, &(((SOCKADDR_IN6*)&peer)->sin6_addr),
wolfSSL 11:cee25a834751 427 ip, *ipSz) == NULL) {
wolfSSL 11:cee25a834751 428 WOLFSSL_MSG("XINET_NTOP error");
wolfSSL 11:cee25a834751 429 return SOCKET_ERROR_E;
wolfSSL 11:cee25a834751 430 }
wolfSSL 11:cee25a834751 431 *port = XNTOHS(((SOCKADDR_IN6*)&peer)->sin6_port);
wolfSSL 11:cee25a834751 432 #endif /* WOLFSSL_IPV6 */
wolfSSL 11:cee25a834751 433 break;
wolfSSL 11:cee25a834751 434
wolfSSL 11:cee25a834751 435 default:
wolfSSL 11:cee25a834751 436 WOLFSSL_MSG("Unknown family type");
wolfSSL 11:cee25a834751 437 return SOCKET_ERROR_E;
wolfSSL 11:cee25a834751 438 }
wolfSSL 11:cee25a834751 439 ip[*ipSz - 1] = '\0'; /* make sure has terminator */
wolfSSL 11:cee25a834751 440 *ipSz = (word16)XSTRLEN(ip);
wolfSSL 11:cee25a834751 441
wolfSSL 11:cee25a834751 442 return SSL_SUCCESS;
wolfSSL 11:cee25a834751 443 }
wolfSSL 11:cee25a834751 444
wolfSSL 11:cee25a834751 445 /* set the peer information in human readable form (ip, port, family)
wolfSSL 11:cee25a834751 446 * default function assumes BSD sockets
wolfSSL 11:cee25a834751 447 * can be overriden with wolfSSL_CTX_SetIOSetPeer
wolfSSL 11:cee25a834751 448 */
wolfSSL 11:cee25a834751 449 int EmbedSetPeer(WOLFSSL* ssl, char* ip, int ipSz,
wolfSSL 11:cee25a834751 450 unsigned short port, int fam)
wolfSSL 11:cee25a834751 451 {
wolfSSL 11:cee25a834751 452 int ret;
wolfSSL 11:cee25a834751 453 SOCKADDR_S addr;
wolfSSL 11:cee25a834751 454
wolfSSL 11:cee25a834751 455 /* sanity checks on arguments */
wolfSSL 11:cee25a834751 456 if (ssl == NULL || ip == NULL || ipSz < 0 || ipSz > DTLS_EXPORT_IP) {
wolfSSL 11:cee25a834751 457 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 458 }
wolfSSL 11:cee25a834751 459
wolfSSL 11:cee25a834751 460 addr.ss_family = fam;
wolfSSL 11:cee25a834751 461 switch (addr.ss_family) {
wolfSSL 11:cee25a834751 462 case WOLFSSL_IP4:
wolfSSL 11:cee25a834751 463 if (XINET_PTON(addr.ss_family, ip,
wolfSSL 11:cee25a834751 464 &(((SOCKADDR_IN*)&addr)->sin_addr)) <= 0) {
wolfSSL 11:cee25a834751 465 WOLFSSL_MSG("XINET_PTON error");
wolfSSL 11:cee25a834751 466 return SOCKET_ERROR_E;
wolfSSL 11:cee25a834751 467 }
wolfSSL 11:cee25a834751 468 ((SOCKADDR_IN*)&addr)->sin_port = XHTONS(port);
wolfSSL 11:cee25a834751 469
wolfSSL 11:cee25a834751 470 /* peer sa is free'd in SSL_ResourceFree */
wolfSSL 11:cee25a834751 471 if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN*)&addr,
wolfSSL 11:cee25a834751 472 sizeof(SOCKADDR_IN)))!= SSL_SUCCESS) {
wolfSSL 11:cee25a834751 473 WOLFSSL_MSG("Import DTLS peer info error");
wolfSSL 11:cee25a834751 474 return ret;
wolfSSL 11:cee25a834751 475 }
wolfSSL 11:cee25a834751 476 break;
wolfSSL 11:cee25a834751 477
wolfSSL 11:cee25a834751 478 case WOLFSSL_IP6:
wolfSSL 11:cee25a834751 479 #ifdef WOLFSSL_IPV6
wolfSSL 11:cee25a834751 480 if (XINET_PTON(addr.ss_family, ip,
wolfSSL 11:cee25a834751 481 &(((SOCKADDR_IN6*)&addr)->sin6_addr)) <= 0) {
wolfSSL 11:cee25a834751 482 WOLFSSL_MSG("XINET_PTON error");
wolfSSL 11:cee25a834751 483 return SOCKET_ERROR_E;
wolfSSL 11:cee25a834751 484 }
wolfSSL 11:cee25a834751 485 ((SOCKADDR_IN6*)&addr)->sin6_port = XHTONS(port);
wolfSSL 11:cee25a834751 486
wolfSSL 11:cee25a834751 487 /* peer sa is free'd in SSL_ResourceFree */
wolfSSL 11:cee25a834751 488 if ((ret = wolfSSL_dtls_set_peer(ssl, (SOCKADDR_IN6*)&addr,
wolfSSL 11:cee25a834751 489 sizeof(SOCKADDR_IN6)))!= SSL_SUCCESS) {
wolfSSL 11:cee25a834751 490 WOLFSSL_MSG("Import DTLS peer info error");
wolfSSL 11:cee25a834751 491 return ret;
wolfSSL 11:cee25a834751 492 }
wolfSSL 11:cee25a834751 493 #endif /* WOLFSSL_IPV6 */
wolfSSL 11:cee25a834751 494 break;
wolfSSL 11:cee25a834751 495
wolfSSL 11:cee25a834751 496 default:
wolfSSL 11:cee25a834751 497 WOLFSSL_MSG("Unknown address family");
wolfSSL 11:cee25a834751 498 return BUFFER_E;
wolfSSL 11:cee25a834751 499 }
wolfSSL 11:cee25a834751 500
wolfSSL 11:cee25a834751 501 return SSL_SUCCESS;
wolfSSL 11:cee25a834751 502 }
wolfSSL 11:cee25a834751 503 #endif /* WOLFSSL_SESSION_EXPORT */
wolfSSL 11:cee25a834751 504 #endif /* WOLFSSL_DTLS */
wolfSSL 11:cee25a834751 505
wolfSSL 11:cee25a834751 506
wolfSSL 11:cee25a834751 507 int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags)
wolfSSL 11:cee25a834751 508 {
wolfSSL 11:cee25a834751 509 int recvd;
wolfSSL 11:cee25a834751 510
wolfSSL 11:cee25a834751 511 recvd = (int)RECV_FUNCTION(sd, buf, sz, rdFlags);
wolfSSL 11:cee25a834751 512 recvd = TranslateReturnCode(recvd, sd);
wolfSSL 11:cee25a834751 513
wolfSSL 11:cee25a834751 514 return recvd;
wolfSSL 11:cee25a834751 515 }
wolfSSL 11:cee25a834751 516
wolfSSL 11:cee25a834751 517 int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags)
wolfSSL 11:cee25a834751 518 {
wolfSSL 11:cee25a834751 519 int sent;
wolfSSL 11:cee25a834751 520 int len = sz;
wolfSSL 11:cee25a834751 521
wolfSSL 11:cee25a834751 522 sent = (int)SEND_FUNCTION(sd, &buf[sz - len], len, wrFlags);
wolfSSL 11:cee25a834751 523 sent = TranslateReturnCode(sent, sd);
wolfSSL 11:cee25a834751 524
wolfSSL 11:cee25a834751 525 return sent;
wolfSSL 11:cee25a834751 526 }
wolfSSL 11:cee25a834751 527
wolfSSL 11:cee25a834751 528 #endif /* USE_WOLFSSL_IO */
wolfSSL 11:cee25a834751 529
wolfSSL 11:cee25a834751 530
wolfSSL 11:cee25a834751 531 #ifdef HAVE_HTTP_CLIENT
wolfSSL 11:cee25a834751 532
wolfSSL 11:cee25a834751 533 #ifndef HAVE_IO_TIMEOUT
wolfSSL 11:cee25a834751 534 #define io_timeout_sec 0
wolfSSL 11:cee25a834751 535 #else
wolfSSL 11:cee25a834751 536
wolfSSL 11:cee25a834751 537 #ifndef DEFAULT_TIMEOUT_SEC
wolfSSL 11:cee25a834751 538 #define DEFAULT_TIMEOUT_SEC 0 /* no timeout */
wolfSSL 11:cee25a834751 539 #endif
wolfSSL 11:cee25a834751 540
wolfSSL 11:cee25a834751 541 static int io_timeout_sec = DEFAULT_TIMEOUT_SEC;
wolfSSL 11:cee25a834751 542
wolfSSL 11:cee25a834751 543 void wolfIO_SetTimeout(int to_sec)
wolfSSL 11:cee25a834751 544 {
wolfSSL 11:cee25a834751 545 io_timeout_sec = to_sec;
wolfSSL 11:cee25a834751 546 }
wolfSSL 11:cee25a834751 547
wolfSSL 11:cee25a834751 548 int wolfIO_SetBlockingMode(SOCKET_T sockfd, int non_blocking)
wolfSSL 11:cee25a834751 549 {
wolfSSL 11:cee25a834751 550 int ret = 0;
wolfSSL 11:cee25a834751 551
wolfSSL 11:cee25a834751 552 #ifdef USE_WINDOWS_API
wolfSSL 11:cee25a834751 553 unsigned long blocking = non_blocking;
wolfSSL 11:cee25a834751 554 ret = ioctlsocket(sockfd, FIONBIO, &blocking);
wolfSSL 11:cee25a834751 555 if (ret == SOCKET_ERROR)
wolfSSL 11:cee25a834751 556 ret = -1;
wolfSSL 11:cee25a834751 557 #else
wolfSSL 11:cee25a834751 558 ret = fcntl(sockfd, F_GETFL, 0);
wolfSSL 11:cee25a834751 559 if (ret >= 0) {
wolfSSL 11:cee25a834751 560 if (non_blocking)
wolfSSL 11:cee25a834751 561 ret |= O_NONBLOCK;
wolfSSL 11:cee25a834751 562 else
wolfSSL 11:cee25a834751 563 ret &= ~O_NONBLOCK;
wolfSSL 11:cee25a834751 564 ret = fcntl(sockfd, F_SETFL, ret);
wolfSSL 11:cee25a834751 565 }
wolfSSL 11:cee25a834751 566 #endif
wolfSSL 11:cee25a834751 567 if (ret < 0) {
wolfSSL 11:cee25a834751 568 WOLFSSL_MSG("wolfIO_SetBlockingMode failed");
wolfSSL 11:cee25a834751 569 }
wolfSSL 11:cee25a834751 570
wolfSSL 11:cee25a834751 571 return ret;
wolfSSL 11:cee25a834751 572 }
wolfSSL 11:cee25a834751 573
wolfSSL 11:cee25a834751 574 #ifdef _MSC_VER
wolfSSL 11:cee25a834751 575 /* 4204: non-constant aggregate initializer (nfds = sockfd + 1) */
wolfSSL 11:cee25a834751 576 #pragma warning(disable: 4204)
wolfSSL 11:cee25a834751 577 #endif
wolfSSL 11:cee25a834751 578 int wolfIO_Select(SOCKET_T sockfd, int to_sec)
wolfSSL 11:cee25a834751 579 {
wolfSSL 11:cee25a834751 580 fd_set fds;
wolfSSL 11:cee25a834751 581 SOCKET_T nfds = sockfd + 1;
wolfSSL 11:cee25a834751 582 struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
wolfSSL 11:cee25a834751 583 int ret;
wolfSSL 11:cee25a834751 584
wolfSSL 11:cee25a834751 585 FD_ZERO(&fds);
wolfSSL 11:cee25a834751 586 FD_SET(sockfd, &fds);
wolfSSL 11:cee25a834751 587
wolfSSL 11:cee25a834751 588 ret = select(nfds, &fds, &fds, NULL, &timeout);
wolfSSL 11:cee25a834751 589 if (ret == 0) {
wolfSSL 11:cee25a834751 590 #ifdef DEBUG_HTTP
wolfSSL 11:cee25a834751 591 printf("Timeout: %d\n", ret);
wolfSSL 11:cee25a834751 592 #endif
wolfSSL 11:cee25a834751 593 return HTTP_TIMEOUT;
wolfSSL 11:cee25a834751 594 }
wolfSSL 11:cee25a834751 595 else if (ret > 0) {
wolfSSL 11:cee25a834751 596 if (FD_ISSET(sockfd, &fds))
wolfSSL 11:cee25a834751 597 return 0;
wolfSSL 11:cee25a834751 598 }
wolfSSL 11:cee25a834751 599 return SOCKET_ERROR_E;
wolfSSL 11:cee25a834751 600 }
wolfSSL 11:cee25a834751 601 #endif /* HAVE_IO_TIMEOUT */
wolfSSL 11:cee25a834751 602
wolfSSL 11:cee25a834751 603 static int wolfIO_Word16ToString(char* d, word16 number)
wolfSSL 11:cee25a834751 604 {
wolfSSL 11:cee25a834751 605 int i = 0;
wolfSSL 11:cee25a834751 606 word16 order = 10000;
wolfSSL 11:cee25a834751 607 word16 digit;
wolfSSL 11:cee25a834751 608
wolfSSL 11:cee25a834751 609 if (d == NULL)
wolfSSL 11:cee25a834751 610 return i;
wolfSSL 11:cee25a834751 611
wolfSSL 11:cee25a834751 612 if (number == 0)
wolfSSL 11:cee25a834751 613 d[i++] = '0';
wolfSSL 11:cee25a834751 614 else {
wolfSSL 11:cee25a834751 615 while (order) {
wolfSSL 11:cee25a834751 616 digit = number / order;
wolfSSL 11:cee25a834751 617 if (i > 0 || digit != 0)
wolfSSL 11:cee25a834751 618 d[i++] = (char)digit + '0';
wolfSSL 11:cee25a834751 619 if (digit != 0)
wolfSSL 11:cee25a834751 620 number %= digit * order;
wolfSSL 11:cee25a834751 621
wolfSSL 11:cee25a834751 622 order = (order > 1) ? order / 10 : 0;
wolfSSL 11:cee25a834751 623 }
wolfSSL 11:cee25a834751 624 }
wolfSSL 11:cee25a834751 625 d[i] = 0; /* null terminate */
wolfSSL 11:cee25a834751 626
wolfSSL 11:cee25a834751 627 return i;
wolfSSL 11:cee25a834751 628 }
wolfSSL 11:cee25a834751 629
wolfSSL 11:cee25a834751 630 int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec)
wolfSSL 11:cee25a834751 631 {
wolfSSL 11:cee25a834751 632 #ifdef HAVE_SOCKADDR
wolfSSL 11:cee25a834751 633 int ret = 0;
wolfSSL 11:cee25a834751 634 SOCKADDR_S addr;
wolfSSL 11:cee25a834751 635 int sockaddr_len = sizeof(SOCKADDR_IN);
wolfSSL 11:cee25a834751 636 #ifdef HAVE_GETADDRINFO
wolfSSL 11:cee25a834751 637 ADDRINFO hints;
wolfSSL 11:cee25a834751 638 ADDRINFO* answer = NULL;
wolfSSL 11:cee25a834751 639 char strPort[6];
wolfSSL 11:cee25a834751 640 #else
wolfSSL 11:cee25a834751 641 HOSTENT* entry;
wolfSSL 11:cee25a834751 642 SOCKADDR_IN *sin;
wolfSSL 11:cee25a834751 643 #endif
wolfSSL 11:cee25a834751 644
wolfSSL 11:cee25a834751 645 XMEMSET(&addr, 0, sizeof(addr));
wolfSSL 11:cee25a834751 646
wolfSSL 11:cee25a834751 647 #ifdef WOLFIO_DEBUG
wolfSSL 11:cee25a834751 648 printf("TCP Connect: %s:%d\n", ip, port);
wolfSSL 11:cee25a834751 649 #endif
wolfSSL 11:cee25a834751 650
wolfSSL 11:cee25a834751 651 #ifdef HAVE_GETADDRINFO
wolfSSL 11:cee25a834751 652 XMEMSET(&hints, 0, sizeof(hints));
wolfSSL 11:cee25a834751 653 hints.ai_family = AF_UNSPEC;
wolfSSL 11:cee25a834751 654 hints.ai_socktype = SOCK_STREAM;
wolfSSL 11:cee25a834751 655 hints.ai_protocol = IPPROTO_TCP;
wolfSSL 11:cee25a834751 656
wolfSSL 11:cee25a834751 657 if (wolfIO_Word16ToString(strPort, port) == 0) {
wolfSSL 11:cee25a834751 658 WOLFSSL_MSG("invalid port number for responder");
wolfSSL 11:cee25a834751 659 return -1;
wolfSSL 11:cee25a834751 660 }
wolfSSL 11:cee25a834751 661
wolfSSL 11:cee25a834751 662 if (getaddrinfo(ip, strPort, &hints, &answer) < 0 || answer == NULL) {
wolfSSL 11:cee25a834751 663 WOLFSSL_MSG("no addr info for responder");
wolfSSL 11:cee25a834751 664 return -1;
wolfSSL 11:cee25a834751 665 }
wolfSSL 11:cee25a834751 666
wolfSSL 11:cee25a834751 667 sockaddr_len = answer->ai_addrlen;
wolfSSL 11:cee25a834751 668 XMEMCPY(&addr, answer->ai_addr, sockaddr_len);
wolfSSL 11:cee25a834751 669 freeaddrinfo(answer);
wolfSSL 11:cee25a834751 670 #else
wolfSSL 11:cee25a834751 671 entry = gethostbyname(ip);
wolfSSL 11:cee25a834751 672 sin = (SOCKADDR_IN *)&addr;
wolfSSL 11:cee25a834751 673
wolfSSL 11:cee25a834751 674 if (entry) {
wolfSSL 11:cee25a834751 675 sin->sin_family = AF_INET;
wolfSSL 11:cee25a834751 676 sin->sin_port = XHTONS(port);
wolfSSL 11:cee25a834751 677 XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0], entry->h_length);
wolfSSL 11:cee25a834751 678 }
wolfSSL 11:cee25a834751 679 else {
wolfSSL 11:cee25a834751 680 WOLFSSL_MSG("no addr info for responder");
wolfSSL 11:cee25a834751 681 return -1;
wolfSSL 11:cee25a834751 682 }
wolfSSL 11:cee25a834751 683 #endif
wolfSSL 11:cee25a834751 684
wolfSSL 11:cee25a834751 685 *sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM, 0);
wolfSSL 11:cee25a834751 686
wolfSSL 11:cee25a834751 687 #ifdef USE_WINDOWS_API
wolfSSL 11:cee25a834751 688 if (*sockfd == INVALID_SOCKET) {
wolfSSL 11:cee25a834751 689 WOLFSSL_MSG("bad socket fd, out of fds?");
wolfSSL 11:cee25a834751 690 return -1;
wolfSSL 11:cee25a834751 691 }
wolfSSL 11:cee25a834751 692 #else
wolfSSL 11:cee25a834751 693 if (*sockfd < 0) {
wolfSSL 11:cee25a834751 694 WOLFSSL_MSG("bad socket fd, out of fds?");
wolfSSL 11:cee25a834751 695 return -1;
wolfSSL 11:cee25a834751 696 }
wolfSSL 11:cee25a834751 697 #endif
wolfSSL 11:cee25a834751 698
wolfSSL 11:cee25a834751 699 #ifdef HAVE_IO_TIMEOUT
wolfSSL 11:cee25a834751 700 /* if timeout value provided then set socket non-blocking */
wolfSSL 11:cee25a834751 701 if (to_sec > 0) {
wolfSSL 11:cee25a834751 702 wolfIO_SetBlockingMode(*sockfd, 1);
wolfSSL 11:cee25a834751 703 }
wolfSSL 11:cee25a834751 704 #else
wolfSSL 11:cee25a834751 705 (void)to_sec;
wolfSSL 11:cee25a834751 706 #endif
wolfSSL 11:cee25a834751 707
wolfSSL 11:cee25a834751 708 ret = connect(*sockfd, (SOCKADDR *)&addr, sockaddr_len);
wolfSSL 11:cee25a834751 709 #ifdef HAVE_IO_TIMEOUT
wolfSSL 11:cee25a834751 710 if (ret != 0) {
wolfSSL 11:cee25a834751 711 if ((errno == EINPROGRESS) && (to_sec > 0)) {
wolfSSL 11:cee25a834751 712 /* wait for connect to complete */
wolfSSL 11:cee25a834751 713 ret = wolfIO_Select(*sockfd, to_sec);
wolfSSL 11:cee25a834751 714
wolfSSL 11:cee25a834751 715 /* restore blocking mode */
wolfSSL 11:cee25a834751 716 wolfIO_SetBlockingMode(*sockfd, 0);
wolfSSL 11:cee25a834751 717 }
wolfSSL 11:cee25a834751 718 }
wolfSSL 11:cee25a834751 719 #endif
wolfSSL 11:cee25a834751 720 if (ret != 0) {
wolfSSL 11:cee25a834751 721 WOLFSSL_MSG("Responder tcp connect failed");
wolfSSL 11:cee25a834751 722 return -1;
wolfSSL 11:cee25a834751 723 }
wolfSSL 11:cee25a834751 724 return ret;
wolfSSL 11:cee25a834751 725 #else
wolfSSL 11:cee25a834751 726 (void)sockfd;
wolfSSL 11:cee25a834751 727 (void)ip;
wolfSSL 11:cee25a834751 728 (void)port;
wolfSSL 11:cee25a834751 729 (void)to_sec;
wolfSSL 11:cee25a834751 730 return -1;
wolfSSL 11:cee25a834751 731 #endif /* HAVE_SOCKADDR */
wolfSSL 11:cee25a834751 732 }
wolfSSL 11:cee25a834751 733
wolfSSL 11:cee25a834751 734 #ifndef HTTP_SCRATCH_BUFFER_SIZE
wolfSSL 11:cee25a834751 735 #define HTTP_SCRATCH_BUFFER_SIZE 512
wolfSSL 11:cee25a834751 736 #endif
wolfSSL 11:cee25a834751 737 #ifndef MAX_URL_ITEM_SIZE
wolfSSL 11:cee25a834751 738 #define MAX_URL_ITEM_SIZE 80
wolfSSL 11:cee25a834751 739 #endif
wolfSSL 11:cee25a834751 740
wolfSSL 11:cee25a834751 741 int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath,
wolfSSL 11:cee25a834751 742 word16* outPort)
wolfSSL 11:cee25a834751 743 {
wolfSSL 11:cee25a834751 744 int result = -1;
wolfSSL 11:cee25a834751 745
wolfSSL 11:cee25a834751 746 if (url == NULL || urlSz == 0) {
wolfSSL 11:cee25a834751 747 if (outName)
wolfSSL 11:cee25a834751 748 *outName = 0;
wolfSSL 11:cee25a834751 749 if (outPath)
wolfSSL 11:cee25a834751 750 *outPath = 0;
wolfSSL 11:cee25a834751 751 if (outPort)
wolfSSL 11:cee25a834751 752 *outPort = 0;
wolfSSL 11:cee25a834751 753 }
wolfSSL 11:cee25a834751 754 else {
wolfSSL 11:cee25a834751 755 int i, cur;
wolfSSL 11:cee25a834751 756
wolfSSL 11:cee25a834751 757 /* need to break the url down into scheme, address, and port */
wolfSSL 11:cee25a834751 758 /* "http://example.com:8080/" */
wolfSSL 11:cee25a834751 759 /* "http://[::1]:443/" */
wolfSSL 11:cee25a834751 760 if (XSTRNCMP(url, "http://", 7) == 0) {
wolfSSL 11:cee25a834751 761 cur = 7;
wolfSSL 11:cee25a834751 762 } else cur = 0;
wolfSSL 11:cee25a834751 763
wolfSSL 11:cee25a834751 764 i = 0;
wolfSSL 11:cee25a834751 765 if (url[cur] == '[') {
wolfSSL 11:cee25a834751 766 cur++;
wolfSSL 11:cee25a834751 767 /* copy until ']' */
wolfSSL 11:cee25a834751 768 while (url[cur] != 0 && url[cur] != ']' && cur < urlSz) {
wolfSSL 11:cee25a834751 769 if (outName)
wolfSSL 11:cee25a834751 770 outName[i] = url[cur];
wolfSSL 11:cee25a834751 771 i++; cur++;
wolfSSL 11:cee25a834751 772 }
wolfSSL 11:cee25a834751 773 cur++; /* skip ']' */
wolfSSL 11:cee25a834751 774 }
wolfSSL 11:cee25a834751 775 else {
wolfSSL 11:cee25a834751 776 while (url[cur] != 0 && url[cur] != ':' &&
wolfSSL 11:cee25a834751 777 url[cur] != '/' && cur < urlSz) {
wolfSSL 11:cee25a834751 778 if (outName)
wolfSSL 11:cee25a834751 779 outName[i] = url[cur];
wolfSSL 11:cee25a834751 780 i++; cur++;
wolfSSL 11:cee25a834751 781 }
wolfSSL 11:cee25a834751 782 }
wolfSSL 11:cee25a834751 783 if (outName)
wolfSSL 11:cee25a834751 784 outName[i] = 0;
wolfSSL 11:cee25a834751 785 /* Need to pick out the path after the domain name */
wolfSSL 11:cee25a834751 786
wolfSSL 11:cee25a834751 787 if (cur < urlSz && url[cur] == ':') {
wolfSSL 11:cee25a834751 788 char port[6];
wolfSSL 11:cee25a834751 789 int j;
wolfSSL 11:cee25a834751 790 word32 bigPort = 0;
wolfSSL 11:cee25a834751 791 i = 0;
wolfSSL 11:cee25a834751 792 cur++;
wolfSSL 11:cee25a834751 793 while (cur < urlSz && url[cur] != 0 && url[cur] != '/' &&
wolfSSL 11:cee25a834751 794 i < 6) {
wolfSSL 11:cee25a834751 795 port[i++] = url[cur++];
wolfSSL 11:cee25a834751 796 }
wolfSSL 11:cee25a834751 797
wolfSSL 11:cee25a834751 798 for (j = 0; j < i; j++) {
wolfSSL 11:cee25a834751 799 if (port[j] < '0' || port[j] > '9') return -1;
wolfSSL 11:cee25a834751 800 bigPort = (bigPort * 10) + (port[j] - '0');
wolfSSL 11:cee25a834751 801 }
wolfSSL 11:cee25a834751 802 if (outPort)
wolfSSL 11:cee25a834751 803 *outPort = (word16)bigPort;
wolfSSL 11:cee25a834751 804 }
wolfSSL 11:cee25a834751 805 else if (outPort)
wolfSSL 11:cee25a834751 806 *outPort = 80;
wolfSSL 11:cee25a834751 807
wolfSSL 11:cee25a834751 808
wolfSSL 11:cee25a834751 809 if (cur < urlSz && url[cur] == '/') {
wolfSSL 11:cee25a834751 810 i = 0;
wolfSSL 11:cee25a834751 811 while (cur < urlSz && url[cur] != 0 && i < MAX_URL_ITEM_SIZE) {
wolfSSL 11:cee25a834751 812 if (outPath)
wolfSSL 11:cee25a834751 813 outPath[i] = url[cur];
wolfSSL 11:cee25a834751 814 i++; cur++;
wolfSSL 11:cee25a834751 815 }
wolfSSL 11:cee25a834751 816 if (outPath)
wolfSSL 11:cee25a834751 817 outPath[i] = 0;
wolfSSL 11:cee25a834751 818 }
wolfSSL 11:cee25a834751 819 else if (outPath) {
wolfSSL 11:cee25a834751 820 outPath[0] = '/';
wolfSSL 11:cee25a834751 821 outPath[1] = 0;
wolfSSL 11:cee25a834751 822 }
wolfSSL 11:cee25a834751 823
wolfSSL 11:cee25a834751 824 result = 0;
wolfSSL 11:cee25a834751 825 }
wolfSSL 11:cee25a834751 826
wolfSSL 11:cee25a834751 827 return result;
wolfSSL 11:cee25a834751 828 }
wolfSSL 11:cee25a834751 829
wolfSSL 11:cee25a834751 830 static int wolfIO_HttpProcessResponseBuf(int sfd, byte **recvBuf, int* recvBufSz,
wolfSSL 11:cee25a834751 831 int chunkSz, char* start, int len, int dynType, void* heap)
wolfSSL 11:cee25a834751 832 {
wolfSSL 11:cee25a834751 833 byte* newRecvBuf = NULL;
wolfSSL 11:cee25a834751 834 int newRecvSz = *recvBufSz + chunkSz;
wolfSSL 11:cee25a834751 835 int pos = 0;
wolfSSL 11:cee25a834751 836
wolfSSL 11:cee25a834751 837 WOLFSSL_MSG("Processing HTTP response");
wolfSSL 11:cee25a834751 838 #ifdef WOLFIO_DEBUG
wolfSSL 11:cee25a834751 839 printf("HTTP Chunk %d->%d\n", *recvBufSz, chunkSz);
wolfSSL 11:cee25a834751 840 #endif
wolfSSL 11:cee25a834751 841
wolfSSL 11:cee25a834751 842 newRecvBuf = (byte*)XMALLOC(newRecvSz, heap, dynType);
wolfSSL 11:cee25a834751 843 if (newRecvBuf == NULL) {
wolfSSL 11:cee25a834751 844 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf malloc failed");
wolfSSL 11:cee25a834751 845 return MEMORY_E;
wolfSSL 11:cee25a834751 846 }
wolfSSL 11:cee25a834751 847
wolfSSL 11:cee25a834751 848 /* if buffer already exists, then we are growing it */
wolfSSL 11:cee25a834751 849 if (*recvBuf) {
wolfSSL 11:cee25a834751 850 XMEMCPY(&newRecvBuf[pos], *recvBuf, *recvBufSz);
wolfSSL 11:cee25a834751 851 XFREE(*recvBuf, heap, dynType);
wolfSSL 11:cee25a834751 852 pos += *recvBufSz;
wolfSSL 11:cee25a834751 853 *recvBuf = NULL;
wolfSSL 11:cee25a834751 854 }
wolfSSL 11:cee25a834751 855
wolfSSL 11:cee25a834751 856 /* copy the remainder of the httpBuf into the respBuf */
wolfSSL 11:cee25a834751 857 if (len != 0) {
wolfSSL 11:cee25a834751 858 XMEMCPY(&newRecvBuf[pos], start, len);
wolfSSL 11:cee25a834751 859 pos += len;
wolfSSL 11:cee25a834751 860 }
wolfSSL 11:cee25a834751 861
wolfSSL 11:cee25a834751 862 /* receive the remainder of chunk */
wolfSSL 11:cee25a834751 863 while (len < chunkSz) {
wolfSSL 11:cee25a834751 864 int rxSz = wolfIO_Recv(sfd, (char*)&newRecvBuf[pos], chunkSz-len, 0);
wolfSSL 11:cee25a834751 865 if (rxSz > 0) {
wolfSSL 11:cee25a834751 866 len += rxSz;
wolfSSL 11:cee25a834751 867 pos += rxSz;
wolfSSL 11:cee25a834751 868 }
wolfSSL 11:cee25a834751 869 else {
wolfSSL 11:cee25a834751 870 WOLFSSL_MSG("wolfIO_HttpProcessResponseBuf recv failed");
wolfSSL 11:cee25a834751 871 XFREE(newRecvBuf, heap, dynType);
wolfSSL 11:cee25a834751 872 return -1;
wolfSSL 11:cee25a834751 873 }
wolfSSL 11:cee25a834751 874 }
wolfSSL 11:cee25a834751 875
wolfSSL 11:cee25a834751 876 *recvBuf = newRecvBuf;
wolfSSL 11:cee25a834751 877 *recvBufSz = newRecvSz;
wolfSSL 11:cee25a834751 878
wolfSSL 11:cee25a834751 879 return 0;
wolfSSL 11:cee25a834751 880 }
wolfSSL 11:cee25a834751 881
wolfSSL 11:cee25a834751 882 int wolfIO_HttpProcessResponse(int sfd, const char* appStr,
wolfSSL 11:cee25a834751 883 byte** respBuf, byte* httpBuf, int httpBufSz, int dynType, void* heap)
wolfSSL 11:cee25a834751 884 {
wolfSSL 11:cee25a834751 885 int result = 0;
wolfSSL 11:cee25a834751 886 int len = 0;
wolfSSL 11:cee25a834751 887 char *start, *end;
wolfSSL 11:cee25a834751 888 int respBufSz = 0;
wolfSSL 11:cee25a834751 889 int isChunked = 0, chunkSz = 0;
wolfSSL 11:cee25a834751 890 enum phr_state { phr_init, phr_http_start, phr_have_length, phr_have_type,
wolfSSL 11:cee25a834751 891 phr_wait_end, phr_get_chunk_len, phr_get_chunk_data,
wolfSSL 11:cee25a834751 892 phr_http_end
wolfSSL 11:cee25a834751 893 } state = phr_init;
wolfSSL 11:cee25a834751 894
wolfSSL 11:cee25a834751 895 *respBuf = NULL;
wolfSSL 11:cee25a834751 896 start = end = NULL;
wolfSSL 11:cee25a834751 897 do {
wolfSSL 11:cee25a834751 898 if (state == phr_get_chunk_data) {
wolfSSL 11:cee25a834751 899 /* get chunk of data */
wolfSSL 11:cee25a834751 900 result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz,
wolfSSL 11:cee25a834751 901 chunkSz, start, len, dynType, heap);
wolfSSL 11:cee25a834751 902
wolfSSL 11:cee25a834751 903 state = (result != 0) ? phr_http_end : phr_get_chunk_len;
wolfSSL 11:cee25a834751 904 end = NULL;
wolfSSL 11:cee25a834751 905 len = 0;
wolfSSL 11:cee25a834751 906 }
wolfSSL 11:cee25a834751 907
wolfSSL 11:cee25a834751 908 /* read data if no \r\n or first time */
wolfSSL 11:cee25a834751 909 if (end == NULL) {
wolfSSL 11:cee25a834751 910 result = wolfIO_Recv(sfd, (char*)httpBuf+len, httpBufSz-len-1, 0);
wolfSSL 11:cee25a834751 911 if (result > 0) {
wolfSSL 11:cee25a834751 912 len += result;
wolfSSL 11:cee25a834751 913 start = (char*)httpBuf;
wolfSSL 11:cee25a834751 914 start[len] = 0;
wolfSSL 11:cee25a834751 915 }
wolfSSL 11:cee25a834751 916 else {
wolfSSL 11:cee25a834751 917 WOLFSSL_MSG("wolfIO_HttpProcessResponse recv http from peer failed");
wolfSSL 11:cee25a834751 918 return -1;
wolfSSL 11:cee25a834751 919 }
wolfSSL 11:cee25a834751 920 }
wolfSSL 11:cee25a834751 921 end = XSTRSTR(start, "\r\n"); /* locate end */
wolfSSL 11:cee25a834751 922
wolfSSL 11:cee25a834751 923 /* handle incomplete rx */
wolfSSL 11:cee25a834751 924 if (end == NULL) {
wolfSSL 11:cee25a834751 925 if (len != 0)
wolfSSL 11:cee25a834751 926 XMEMMOVE(httpBuf, start, len);
wolfSSL 11:cee25a834751 927 start = end = NULL;
wolfSSL 11:cee25a834751 928 }
wolfSSL 11:cee25a834751 929 /* when start is "\r\n" */
wolfSSL 11:cee25a834751 930 else if (end == start) {
wolfSSL 11:cee25a834751 931 /* if waiting for end or need chunk len */
wolfSSL 11:cee25a834751 932 if (state == phr_wait_end || state == phr_get_chunk_len) {
wolfSSL 11:cee25a834751 933 state = (isChunked) ? phr_get_chunk_len : phr_http_end;
wolfSSL 11:cee25a834751 934 len -= 2; start += 2; /* skip \r\n */
wolfSSL 11:cee25a834751 935 }
wolfSSL 11:cee25a834751 936 else {
wolfSSL 11:cee25a834751 937 WOLFSSL_MSG("wolfIO_HttpProcessResponse header ended early");
wolfSSL 11:cee25a834751 938 return -1;
wolfSSL 11:cee25a834751 939 }
wolfSSL 11:cee25a834751 940 }
wolfSSL 11:cee25a834751 941 else {
wolfSSL 11:cee25a834751 942 *end = 0; /* null terminate */
wolfSSL 11:cee25a834751 943 len -= (int)(end - start) + 2;
wolfSSL 11:cee25a834751 944 /* adjust len to remove the first line including the /r/n */
wolfSSL 11:cee25a834751 945
wolfSSL 11:cee25a834751 946 #ifdef WOLFIO_DEBUG
wolfSSL 11:cee25a834751 947 printf("HTTP Resp: %s\n", start);
wolfSSL 11:cee25a834751 948 #endif
wolfSSL 11:cee25a834751 949
wolfSSL 11:cee25a834751 950 switch (state) {
wolfSSL 11:cee25a834751 951 case phr_init:
wolfSSL 11:cee25a834751 952 if (XSTRNCASECMP(start, "HTTP/1", 6) == 0) {
wolfSSL 11:cee25a834751 953 start += 9;
wolfSSL 11:cee25a834751 954 if (XSTRNCASECMP(start, "200 OK", 6) != 0) {
wolfSSL 11:cee25a834751 955 WOLFSSL_MSG("wolfIO_HttpProcessResponse not OK");
wolfSSL 11:cee25a834751 956 return -1;
wolfSSL 11:cee25a834751 957 }
wolfSSL 11:cee25a834751 958 state = phr_http_start;
wolfSSL 11:cee25a834751 959 }
wolfSSL 11:cee25a834751 960 break;
wolfSSL 11:cee25a834751 961 case phr_http_start:
wolfSSL 11:cee25a834751 962 case phr_have_length:
wolfSSL 11:cee25a834751 963 case phr_have_type:
wolfSSL 11:cee25a834751 964 if (XSTRNCASECMP(start, "Content-Type:", 13) == 0) {
wolfSSL 11:cee25a834751 965 start += 13;
wolfSSL 11:cee25a834751 966 while (*start == ' ' && *start != '\0') start++;
wolfSSL 11:cee25a834751 967 if (XSTRNCASECMP(start, appStr, XSTRLEN(appStr)) != 0) {
wolfSSL 11:cee25a834751 968 WOLFSSL_MSG("wolfIO_HttpProcessResponse appstr mismatch");
wolfSSL 11:cee25a834751 969 return -1;
wolfSSL 11:cee25a834751 970 }
wolfSSL 11:cee25a834751 971 state = (state == phr_http_start) ? phr_have_type : phr_wait_end;
wolfSSL 11:cee25a834751 972 }
wolfSSL 11:cee25a834751 973 else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) {
wolfSSL 11:cee25a834751 974 start += 15;
wolfSSL 11:cee25a834751 975 while (*start == ' ' && *start != '\0') start++;
wolfSSL 11:cee25a834751 976 chunkSz = atoi(start);
wolfSSL 11:cee25a834751 977 state = (state == phr_http_start) ? phr_have_length : phr_wait_end;
wolfSSL 11:cee25a834751 978 }
wolfSSL 11:cee25a834751 979 else if (XSTRNCASECMP(start, "Transfer-Encoding:", 18) == 0) {
wolfSSL 11:cee25a834751 980 start += 18;
wolfSSL 11:cee25a834751 981 while (*start == ' ' && *start != '\0') start++;
wolfSSL 11:cee25a834751 982 if (XSTRNCASECMP(start, "chunked", 7) == 0) {
wolfSSL 11:cee25a834751 983 isChunked = 1;
wolfSSL 11:cee25a834751 984 state = (state == phr_http_start) ? phr_have_length : phr_wait_end;
wolfSSL 11:cee25a834751 985 }
wolfSSL 11:cee25a834751 986 }
wolfSSL 11:cee25a834751 987 break;
wolfSSL 11:cee25a834751 988 case phr_get_chunk_len:
wolfSSL 11:cee25a834751 989 chunkSz = (int)strtol(start, NULL, 16); /* hex format */
wolfSSL 11:cee25a834751 990 state = (chunkSz == 0) ? phr_http_end : phr_get_chunk_data;
wolfSSL 11:cee25a834751 991 break;
wolfSSL 11:cee25a834751 992 case phr_get_chunk_data:
wolfSSL 11:cee25a834751 993 /* processing for chunk data done above, since \r\n isn't required */
wolfSSL 11:cee25a834751 994 case phr_wait_end:
wolfSSL 11:cee25a834751 995 case phr_http_end:
wolfSSL 11:cee25a834751 996 /* do nothing */
wolfSSL 11:cee25a834751 997 break;
wolfSSL 11:cee25a834751 998 } /* switch (state) */
wolfSSL 11:cee25a834751 999
wolfSSL 11:cee25a834751 1000 /* skip to end plus \r\n */
wolfSSL 11:cee25a834751 1001 start = end + 2;
wolfSSL 11:cee25a834751 1002 }
wolfSSL 11:cee25a834751 1003 } while (state != phr_http_end);
wolfSSL 11:cee25a834751 1004
wolfSSL 11:cee25a834751 1005 if (!isChunked) {
wolfSSL 11:cee25a834751 1006 result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz, chunkSz,
wolfSSL 11:cee25a834751 1007 start, len, dynType, heap);
wolfSSL 11:cee25a834751 1008 }
wolfSSL 11:cee25a834751 1009
wolfSSL 11:cee25a834751 1010 if (result >= 0) {
wolfSSL 11:cee25a834751 1011 result = respBufSz;
wolfSSL 11:cee25a834751 1012 }
wolfSSL 11:cee25a834751 1013 else {
wolfSSL 11:cee25a834751 1014 WOLFSSL_ERROR(result);
wolfSSL 11:cee25a834751 1015 }
wolfSSL 11:cee25a834751 1016
wolfSSL 11:cee25a834751 1017 return result;
wolfSSL 11:cee25a834751 1018 }
wolfSSL 11:cee25a834751 1019
wolfSSL 11:cee25a834751 1020 int wolfIO_HttpBuildRequest(const char* reqType, const char* domainName,
wolfSSL 11:cee25a834751 1021 const char* path, int pathLen, int reqSz, const char* contentType,
wolfSSL 11:cee25a834751 1022 byte* buf, int bufSize)
wolfSSL 11:cee25a834751 1023 {
wolfSSL 11:cee25a834751 1024 word32 reqTypeLen, domainNameLen, reqSzStrLen, contentTypeLen, maxLen;
wolfSSL 11:cee25a834751 1025 char reqSzStr[6];
wolfSSL 11:cee25a834751 1026 char* req = (char*)buf;
wolfSSL 11:cee25a834751 1027 const char* blankStr = " ";
wolfSSL 11:cee25a834751 1028 const char* http11Str = " HTTP/1.1";
wolfSSL 11:cee25a834751 1029 const char* hostStr = "\r\nHost: ";
wolfSSL 11:cee25a834751 1030 const char* contentLenStr = "\r\nContent-Length: ";
wolfSSL 11:cee25a834751 1031 const char* contentTypeStr = "\r\nContent-Type: ";
wolfSSL 11:cee25a834751 1032 const char* doubleCrLfStr = "\r\n\r\n";
wolfSSL 11:cee25a834751 1033 word32 blankStrLen, http11StrLen, hostStrLen, contentLenStrLen,
wolfSSL 11:cee25a834751 1034 contentTypeStrLen, doubleCrLfStrLen;
wolfSSL 11:cee25a834751 1035
wolfSSL 11:cee25a834751 1036 reqTypeLen = (word32)XSTRLEN(reqType);
wolfSSL 11:cee25a834751 1037 domainNameLen = (word32)XSTRLEN(domainName);
wolfSSL 11:cee25a834751 1038 reqSzStrLen = wolfIO_Word16ToString(reqSzStr, (word16)reqSz);
wolfSSL 11:cee25a834751 1039 contentTypeLen = (word32)XSTRLEN(contentType);
wolfSSL 11:cee25a834751 1040
wolfSSL 11:cee25a834751 1041 blankStrLen = (word32)XSTRLEN(blankStr);
wolfSSL 11:cee25a834751 1042 http11StrLen = (word32)XSTRLEN(http11Str);
wolfSSL 11:cee25a834751 1043 hostStrLen = (word32)XSTRLEN(hostStr);
wolfSSL 11:cee25a834751 1044 contentLenStrLen = (word32)XSTRLEN(contentLenStr);
wolfSSL 11:cee25a834751 1045 contentTypeStrLen = (word32)XSTRLEN(contentTypeStr);
wolfSSL 11:cee25a834751 1046 doubleCrLfStrLen = (word32)XSTRLEN(doubleCrLfStr);
wolfSSL 11:cee25a834751 1047
wolfSSL 11:cee25a834751 1048 /* determine max length and check it */
wolfSSL 11:cee25a834751 1049 maxLen =
wolfSSL 11:cee25a834751 1050 reqTypeLen +
wolfSSL 11:cee25a834751 1051 blankStrLen +
wolfSSL 11:cee25a834751 1052 pathLen +
wolfSSL 11:cee25a834751 1053 http11StrLen +
wolfSSL 11:cee25a834751 1054 hostStrLen +
wolfSSL 11:cee25a834751 1055 domainNameLen +
wolfSSL 11:cee25a834751 1056 contentLenStrLen +
wolfSSL 11:cee25a834751 1057 reqSzStrLen +
wolfSSL 11:cee25a834751 1058 contentTypeStrLen +
wolfSSL 11:cee25a834751 1059 contentTypeLen +
wolfSSL 11:cee25a834751 1060 doubleCrLfStrLen +
wolfSSL 11:cee25a834751 1061 1 /* null term */;
wolfSSL 11:cee25a834751 1062 if (maxLen > (word32)bufSize)
wolfSSL 11:cee25a834751 1063 return 0;
wolfSSL 11:cee25a834751 1064
wolfSSL 11:cee25a834751 1065 XSTRNCPY((char*)buf, reqType, reqTypeLen);
wolfSSL 11:cee25a834751 1066 buf += reqTypeLen;
wolfSSL 11:cee25a834751 1067 XSTRNCPY((char*)buf, blankStr, blankStrLen+1);
wolfSSL 11:cee25a834751 1068 buf += blankStrLen;
wolfSSL 11:cee25a834751 1069 XSTRNCPY((char*)buf, path, pathLen);
wolfSSL 11:cee25a834751 1070 buf += pathLen;
wolfSSL 11:cee25a834751 1071 XSTRNCPY((char*)buf, http11Str, http11StrLen+1);
wolfSSL 11:cee25a834751 1072 buf += http11StrLen;
wolfSSL 11:cee25a834751 1073 if (domainNameLen > 0) {
wolfSSL 11:cee25a834751 1074 XSTRNCPY((char*)buf, hostStr, hostStrLen+1);
wolfSSL 11:cee25a834751 1075 buf += hostStrLen;
wolfSSL 11:cee25a834751 1076 XSTRNCPY((char*)buf, domainName, domainNameLen);
wolfSSL 11:cee25a834751 1077 buf += domainNameLen;
wolfSSL 11:cee25a834751 1078 }
wolfSSL 11:cee25a834751 1079 if (reqSz > 0 && reqSzStrLen > 0) {
wolfSSL 11:cee25a834751 1080 XSTRNCPY((char*)buf, contentLenStr, contentLenStrLen+1);
wolfSSL 11:cee25a834751 1081 buf += contentLenStrLen;
wolfSSL 11:cee25a834751 1082 XSTRNCPY((char*)buf, reqSzStr, reqSzStrLen);
wolfSSL 11:cee25a834751 1083 buf += reqSzStrLen;
wolfSSL 11:cee25a834751 1084 }
wolfSSL 11:cee25a834751 1085 if (contentTypeLen > 0) {
wolfSSL 11:cee25a834751 1086 XSTRNCPY((char*)buf, contentTypeStr, contentTypeStrLen+1);
wolfSSL 11:cee25a834751 1087 buf += contentTypeStrLen;
wolfSSL 11:cee25a834751 1088 XSTRNCPY((char*)buf, contentType, contentTypeLen);
wolfSSL 11:cee25a834751 1089 buf += contentTypeLen;
wolfSSL 11:cee25a834751 1090 }
wolfSSL 11:cee25a834751 1091 XSTRNCPY((char*)buf, doubleCrLfStr, doubleCrLfStrLen+1);
wolfSSL 11:cee25a834751 1092 buf += doubleCrLfStrLen;
wolfSSL 11:cee25a834751 1093
wolfSSL 11:cee25a834751 1094 #ifdef WOLFIO_DEBUG
wolfSSL 11:cee25a834751 1095 printf("HTTP %s: %s", reqType, req);
wolfSSL 11:cee25a834751 1096 #endif
wolfSSL 11:cee25a834751 1097
wolfSSL 11:cee25a834751 1098 /* calculate actual length based on original and new pointer */
wolfSSL 11:cee25a834751 1099 return (int)((char*)buf - req);
wolfSSL 11:cee25a834751 1100 }
wolfSSL 11:cee25a834751 1101
wolfSSL 11:cee25a834751 1102
wolfSSL 11:cee25a834751 1103 #ifdef HAVE_OCSP
wolfSSL 11:cee25a834751 1104
wolfSSL 11:cee25a834751 1105 int wolfIO_HttpBuildRequestOcsp(const char* domainName, const char* path,
wolfSSL 11:cee25a834751 1106 int ocspReqSz, byte* buf, int bufSize)
wolfSSL 11:cee25a834751 1107 {
wolfSSL 11:cee25a834751 1108 return wolfIO_HttpBuildRequest("POST", domainName, path, (int)XSTRLEN(path),
wolfSSL 11:cee25a834751 1109 ocspReqSz, "application/ocsp-request", buf, bufSize);
wolfSSL 11:cee25a834751 1110 }
wolfSSL 11:cee25a834751 1111
wolfSSL 11:cee25a834751 1112 /* return: >0 OCSP Response Size
wolfSSL 11:cee25a834751 1113 * -1 error */
wolfSSL 11:cee25a834751 1114 int wolfIO_HttpProcessResponseOcsp(int sfd, byte** respBuf,
wolfSSL 11:cee25a834751 1115 byte* httpBuf, int httpBufSz, void* heap)
wolfSSL 11:cee25a834751 1116 {
wolfSSL 11:cee25a834751 1117 return wolfIO_HttpProcessResponse(sfd, "application/ocsp-response",
wolfSSL 11:cee25a834751 1118 respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_OCSP, heap);
wolfSSL 11:cee25a834751 1119 }
wolfSSL 11:cee25a834751 1120
wolfSSL 11:cee25a834751 1121 /* in default wolfSSL callback ctx is the heap pointer */
wolfSSL 11:cee25a834751 1122 int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
wolfSSL 11:cee25a834751 1123 byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
wolfSSL 11:cee25a834751 1124 {
wolfSSL 11:cee25a834751 1125 SOCKET_T sfd = 0;
wolfSSL 11:cee25a834751 1126 word16 port;
wolfSSL 11:cee25a834751 1127 int ret = -1;
wolfSSL 11:cee25a834751 1128 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 1129 char* path;
wolfSSL 11:cee25a834751 1130 char* domainName;
wolfSSL 11:cee25a834751 1131 #else
wolfSSL 11:cee25a834751 1132 char path[MAX_URL_ITEM_SIZE];
wolfSSL 11:cee25a834751 1133 char domainName[MAX_URL_ITEM_SIZE];
wolfSSL 11:cee25a834751 1134 #endif
wolfSSL 11:cee25a834751 1135
wolfSSL 11:cee25a834751 1136 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 1137 path = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 1138 if (path == NULL)
wolfSSL 11:cee25a834751 1139 return MEMORY_E;
wolfSSL 11:cee25a834751 1140
wolfSSL 11:cee25a834751 1141 domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 1142 if (domainName == NULL) {
wolfSSL 11:cee25a834751 1143 XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 1144 return MEMORY_E;
wolfSSL 11:cee25a834751 1145 }
wolfSSL 11:cee25a834751 1146 #endif
wolfSSL 11:cee25a834751 1147
wolfSSL 11:cee25a834751 1148 if (ocspReqBuf == NULL || ocspReqSz == 0) {
wolfSSL 11:cee25a834751 1149 WOLFSSL_MSG("OCSP request is required for lookup");
wolfSSL 11:cee25a834751 1150 }
wolfSSL 11:cee25a834751 1151 else if (ocspRespBuf == NULL) {
wolfSSL 11:cee25a834751 1152 WOLFSSL_MSG("Cannot save OCSP response");
wolfSSL 11:cee25a834751 1153 }
wolfSSL 11:cee25a834751 1154 else if (wolfIO_DecodeUrl(url, urlSz, domainName, path, &port) < 0) {
wolfSSL 11:cee25a834751 1155 WOLFSSL_MSG("Unable to decode OCSP URL");
wolfSSL 11:cee25a834751 1156 }
wolfSSL 11:cee25a834751 1157 else {
wolfSSL 11:cee25a834751 1158 /* Note, the library uses the EmbedOcspRespFree() callback to
wolfSSL 11:cee25a834751 1159 * free this buffer. */
wolfSSL 11:cee25a834751 1160 int httpBufSz = HTTP_SCRATCH_BUFFER_SIZE;
wolfSSL 11:cee25a834751 1161 byte* httpBuf = (byte*)XMALLOC(httpBufSz, ctx, DYNAMIC_TYPE_OCSP);
wolfSSL 11:cee25a834751 1162
wolfSSL 11:cee25a834751 1163 if (httpBuf == NULL) {
wolfSSL 11:cee25a834751 1164 WOLFSSL_MSG("Unable to create OCSP response buffer");
wolfSSL 11:cee25a834751 1165 }
wolfSSL 11:cee25a834751 1166 else {
wolfSSL 11:cee25a834751 1167 httpBufSz = wolfIO_HttpBuildRequestOcsp(domainName, path, ocspReqSz,
wolfSSL 11:cee25a834751 1168 httpBuf, httpBufSz);
wolfSSL 11:cee25a834751 1169
wolfSSL 11:cee25a834751 1170 ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
wolfSSL 11:cee25a834751 1171 if ((ret != 0) || (sfd <= 0)) {
wolfSSL 11:cee25a834751 1172 WOLFSSL_MSG("OCSP Responder connection failed");
wolfSSL 11:cee25a834751 1173 }
wolfSSL 11:cee25a834751 1174 else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0) !=
wolfSSL 11:cee25a834751 1175 httpBufSz) {
wolfSSL 11:cee25a834751 1176 WOLFSSL_MSG("OCSP http request failed");
wolfSSL 11:cee25a834751 1177 }
wolfSSL 11:cee25a834751 1178 else if (wolfIO_Send(sfd, (char*)ocspReqBuf, ocspReqSz, 0) !=
wolfSSL 11:cee25a834751 1179 ocspReqSz) {
wolfSSL 11:cee25a834751 1180 WOLFSSL_MSG("OCSP ocsp request failed");
wolfSSL 11:cee25a834751 1181 }
wolfSSL 11:cee25a834751 1182 else {
wolfSSL 11:cee25a834751 1183 ret = wolfIO_HttpProcessResponseOcsp(sfd, ocspRespBuf, httpBuf,
wolfSSL 11:cee25a834751 1184 HTTP_SCRATCH_BUFFER_SIZE, ctx);
wolfSSL 11:cee25a834751 1185 }
wolfSSL 11:cee25a834751 1186
wolfSSL 11:cee25a834751 1187 close(sfd);
wolfSSL 11:cee25a834751 1188 XFREE(httpBuf, ctx, DYNAMIC_TYPE_OCSP);
wolfSSL 11:cee25a834751 1189 }
wolfSSL 11:cee25a834751 1190 }
wolfSSL 11:cee25a834751 1191
wolfSSL 11:cee25a834751 1192 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 1193 XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 1194 XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 1195 #endif
wolfSSL 11:cee25a834751 1196
wolfSSL 11:cee25a834751 1197 return ret;
wolfSSL 11:cee25a834751 1198 }
wolfSSL 11:cee25a834751 1199
wolfSSL 11:cee25a834751 1200 /* in default callback ctx is heap hint */
wolfSSL 11:cee25a834751 1201 void EmbedOcspRespFree(void* ctx, byte *resp)
wolfSSL 11:cee25a834751 1202 {
wolfSSL 11:cee25a834751 1203 if (resp)
wolfSSL 11:cee25a834751 1204 XFREE(resp, ctx, DYNAMIC_TYPE_OCSP);
wolfSSL 11:cee25a834751 1205
wolfSSL 11:cee25a834751 1206 (void)ctx;
wolfSSL 11:cee25a834751 1207 }
wolfSSL 11:cee25a834751 1208 #endif /* HAVE_OCSP */
wolfSSL 11:cee25a834751 1209
wolfSSL 11:cee25a834751 1210
wolfSSL 11:cee25a834751 1211 #if defined(HAVE_CRL) && defined(HAVE_CRL_IO)
wolfSSL 11:cee25a834751 1212
wolfSSL 11:cee25a834751 1213 int wolfIO_HttpBuildRequestCrl(const char* url, int urlSz,
wolfSSL 11:cee25a834751 1214 const char* domainName, byte* buf, int bufSize)
wolfSSL 11:cee25a834751 1215 {
wolfSSL 11:cee25a834751 1216 return wolfIO_HttpBuildRequest("GET", domainName, url, urlSz, 0, "",
wolfSSL 11:cee25a834751 1217 buf, bufSize);
wolfSSL 11:cee25a834751 1218 }
wolfSSL 11:cee25a834751 1219
wolfSSL 11:cee25a834751 1220 int wolfIO_HttpProcessResponseCrl(WOLFSSL_CRL* crl, int sfd, byte* httpBuf,
wolfSSL 11:cee25a834751 1221 int httpBufSz)
wolfSSL 11:cee25a834751 1222 {
wolfSSL 11:cee25a834751 1223 int result;
wolfSSL 11:cee25a834751 1224 byte *respBuf = NULL;
wolfSSL 11:cee25a834751 1225
wolfSSL 11:cee25a834751 1226 result = wolfIO_HttpProcessResponse(sfd, "application/pkix-crl",
wolfSSL 11:cee25a834751 1227 &respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_CRL, crl->heap);
wolfSSL 11:cee25a834751 1228 if (result >= 0) {
wolfSSL 11:cee25a834751 1229 result = BufferLoadCRL(crl, respBuf, result, SSL_FILETYPE_ASN1);
wolfSSL 11:cee25a834751 1230 }
wolfSSL 11:cee25a834751 1231 XFREE(respBuf, crl->heap, DYNAMIC_TYPE_CRL);
wolfSSL 11:cee25a834751 1232
wolfSSL 11:cee25a834751 1233 return result;
wolfSSL 11:cee25a834751 1234 }
wolfSSL 11:cee25a834751 1235
wolfSSL 11:cee25a834751 1236 int EmbedCrlLookup(WOLFSSL_CRL* crl, const char* url, int urlSz)
wolfSSL 11:cee25a834751 1237 {
wolfSSL 11:cee25a834751 1238 SOCKET_T sfd = 0;
wolfSSL 11:cee25a834751 1239 word16 port;
wolfSSL 11:cee25a834751 1240 int ret = -1;
wolfSSL 11:cee25a834751 1241 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 1242 char* domainName;
wolfSSL 11:cee25a834751 1243 #else
wolfSSL 11:cee25a834751 1244 char domainName[MAX_URL_ITEM_SIZE];
wolfSSL 11:cee25a834751 1245 #endif
wolfSSL 11:cee25a834751 1246
wolfSSL 11:cee25a834751 1247 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 1248 domainName = (char*)XMALLOC(MAX_URL_ITEM_SIZE, crl->heap,
wolfSSL 11:cee25a834751 1249 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 1250 if (domainName == NULL) {
wolfSSL 11:cee25a834751 1251 return MEMORY_E;
wolfSSL 11:cee25a834751 1252 }
wolfSSL 11:cee25a834751 1253 #endif
wolfSSL 11:cee25a834751 1254
wolfSSL 11:cee25a834751 1255 if (wolfIO_DecodeUrl(url, urlSz, domainName, NULL, &port) < 0) {
wolfSSL 11:cee25a834751 1256 WOLFSSL_MSG("Unable to decode CRL URL");
wolfSSL 11:cee25a834751 1257 }
wolfSSL 11:cee25a834751 1258 else {
wolfSSL 11:cee25a834751 1259 int httpBufSz = HTTP_SCRATCH_BUFFER_SIZE;
wolfSSL 11:cee25a834751 1260 byte* httpBuf = (byte*)XMALLOC(httpBufSz, crl->heap,
wolfSSL 11:cee25a834751 1261 DYNAMIC_TYPE_CRL);
wolfSSL 11:cee25a834751 1262 if (httpBuf == NULL) {
wolfSSL 11:cee25a834751 1263 WOLFSSL_MSG("Unable to create CRL response buffer");
wolfSSL 11:cee25a834751 1264 }
wolfSSL 11:cee25a834751 1265 else {
wolfSSL 11:cee25a834751 1266 httpBufSz = wolfIO_HttpBuildRequestCrl(url, urlSz, domainName,
wolfSSL 11:cee25a834751 1267 httpBuf, httpBufSz);
wolfSSL 11:cee25a834751 1268
wolfSSL 11:cee25a834751 1269 ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
wolfSSL 11:cee25a834751 1270 if ((ret != 0) || (sfd <= 0)) {
wolfSSL 11:cee25a834751 1271 WOLFSSL_MSG("CRL connection failed");
wolfSSL 11:cee25a834751 1272 }
wolfSSL 11:cee25a834751 1273 else if (wolfIO_Send(sfd, (char*)httpBuf, httpBufSz, 0)
wolfSSL 11:cee25a834751 1274 != httpBufSz) {
wolfSSL 11:cee25a834751 1275 WOLFSSL_MSG("CRL http get failed");
wolfSSL 11:cee25a834751 1276 }
wolfSSL 11:cee25a834751 1277 else {
wolfSSL 11:cee25a834751 1278 ret = wolfIO_HttpProcessResponseCrl(crl, sfd, httpBuf,
wolfSSL 11:cee25a834751 1279 HTTP_SCRATCH_BUFFER_SIZE);
wolfSSL 11:cee25a834751 1280 }
wolfSSL 11:cee25a834751 1281
wolfSSL 11:cee25a834751 1282 close(sfd);
wolfSSL 11:cee25a834751 1283 XFREE(httpBuf, crl->heap, DYNAMIC_TYPE_CRL);
wolfSSL 11:cee25a834751 1284 }
wolfSSL 11:cee25a834751 1285 }
wolfSSL 11:cee25a834751 1286
wolfSSL 11:cee25a834751 1287 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 1288 XFREE(domainName, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 1289 #endif
wolfSSL 11:cee25a834751 1290
wolfSSL 11:cee25a834751 1291 return ret;
wolfSSL 11:cee25a834751 1292 }
wolfSSL 11:cee25a834751 1293 #endif /* HAVE_CRL && HAVE_CRL_IO */
wolfSSL 11:cee25a834751 1294
wolfSSL 11:cee25a834751 1295 #endif /* HAVE_HTTP_CLIENT */
wolfSSL 11:cee25a834751 1296
wolfSSL 11:cee25a834751 1297
wolfSSL 11:cee25a834751 1298
wolfSSL 11:cee25a834751 1299 WOLFSSL_API void wolfSSL_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv)
wolfSSL 11:cee25a834751 1300 {
wolfSSL 11:cee25a834751 1301 ctx->CBIORecv = CBIORecv;
wolfSSL 11:cee25a834751 1302 }
wolfSSL 11:cee25a834751 1303
wolfSSL 11:cee25a834751 1304
wolfSSL 11:cee25a834751 1305 WOLFSSL_API void wolfSSL_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend)
wolfSSL 11:cee25a834751 1306 {
wolfSSL 11:cee25a834751 1307 ctx->CBIOSend = CBIOSend;
wolfSSL 11:cee25a834751 1308 }
wolfSSL 11:cee25a834751 1309
wolfSSL 11:cee25a834751 1310
wolfSSL 11:cee25a834751 1311 WOLFSSL_API void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
wolfSSL 11:cee25a834751 1312 {
wolfSSL 11:cee25a834751 1313 ssl->IOCB_ReadCtx = rctx;
wolfSSL 11:cee25a834751 1314 }
wolfSSL 11:cee25a834751 1315
wolfSSL 11:cee25a834751 1316
wolfSSL 11:cee25a834751 1317 WOLFSSL_API void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx)
wolfSSL 11:cee25a834751 1318 {
wolfSSL 11:cee25a834751 1319 ssl->IOCB_WriteCtx = wctx;
wolfSSL 11:cee25a834751 1320 }
wolfSSL 11:cee25a834751 1321
wolfSSL 11:cee25a834751 1322
wolfSSL 11:cee25a834751 1323 WOLFSSL_API void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl)
wolfSSL 11:cee25a834751 1324 {
wolfSSL 11:cee25a834751 1325 if (ssl)
wolfSSL 11:cee25a834751 1326 return ssl->IOCB_ReadCtx;
wolfSSL 11:cee25a834751 1327
wolfSSL 11:cee25a834751 1328 return NULL;
wolfSSL 11:cee25a834751 1329 }
wolfSSL 11:cee25a834751 1330
wolfSSL 11:cee25a834751 1331
wolfSSL 11:cee25a834751 1332 WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl)
wolfSSL 11:cee25a834751 1333 {
wolfSSL 11:cee25a834751 1334 if (ssl)
wolfSSL 11:cee25a834751 1335 return ssl->IOCB_WriteCtx;
wolfSSL 11:cee25a834751 1336
wolfSSL 11:cee25a834751 1337 return NULL;
wolfSSL 11:cee25a834751 1338 }
wolfSSL 11:cee25a834751 1339
wolfSSL 11:cee25a834751 1340
wolfSSL 11:cee25a834751 1341 WOLFSSL_API void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags)
wolfSSL 11:cee25a834751 1342 {
wolfSSL 11:cee25a834751 1343 ssl->rflags = flags;
wolfSSL 11:cee25a834751 1344 }
wolfSSL 11:cee25a834751 1345
wolfSSL 11:cee25a834751 1346
wolfSSL 11:cee25a834751 1347 WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags)
wolfSSL 11:cee25a834751 1348 {
wolfSSL 11:cee25a834751 1349 ssl->wflags = flags;
wolfSSL 11:cee25a834751 1350 }
wolfSSL 11:cee25a834751 1351
wolfSSL 11:cee25a834751 1352
wolfSSL 11:cee25a834751 1353 #ifdef WOLFSSL_DTLS
wolfSSL 11:cee25a834751 1354
wolfSSL 11:cee25a834751 1355 WOLFSSL_API void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb)
wolfSSL 11:cee25a834751 1356 {
wolfSSL 11:cee25a834751 1357 ctx->CBIOCookie = cb;
wolfSSL 11:cee25a834751 1358 }
wolfSSL 11:cee25a834751 1359
wolfSSL 11:cee25a834751 1360
wolfSSL 11:cee25a834751 1361 WOLFSSL_API void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx)
wolfSSL 11:cee25a834751 1362 {
wolfSSL 11:cee25a834751 1363 ssl->IOCB_CookieCtx = ctx;
wolfSSL 11:cee25a834751 1364 }
wolfSSL 11:cee25a834751 1365
wolfSSL 11:cee25a834751 1366
wolfSSL 11:cee25a834751 1367 WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl)
wolfSSL 11:cee25a834751 1368 {
wolfSSL 11:cee25a834751 1369 if (ssl)
wolfSSL 11:cee25a834751 1370 return ssl->IOCB_CookieCtx;
wolfSSL 11:cee25a834751 1371
wolfSSL 11:cee25a834751 1372 return NULL;
wolfSSL 11:cee25a834751 1373 }
wolfSSL 11:cee25a834751 1374
wolfSSL 11:cee25a834751 1375 #ifdef WOLFSSL_SESSION_EXPORT
wolfSSL 11:cee25a834751 1376
wolfSSL 11:cee25a834751 1377 WOLFSSL_API void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX* ctx, CallbackGetPeer cb)
wolfSSL 11:cee25a834751 1378 {
wolfSSL 11:cee25a834751 1379 ctx->CBGetPeer = cb;
wolfSSL 11:cee25a834751 1380 }
wolfSSL 11:cee25a834751 1381
wolfSSL 11:cee25a834751 1382
wolfSSL 11:cee25a834751 1383 WOLFSSL_API void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb)
wolfSSL 11:cee25a834751 1384 {
wolfSSL 11:cee25a834751 1385 ctx->CBSetPeer = cb;
wolfSSL 11:cee25a834751 1386 }
wolfSSL 11:cee25a834751 1387
wolfSSL 11:cee25a834751 1388 #endif /* WOLFSSL_SESSION_EXPORT */
wolfSSL 11:cee25a834751 1389 #endif /* WOLFSSL_DTLS */
wolfSSL 11:cee25a834751 1390
wolfSSL 11:cee25a834751 1391
wolfSSL 11:cee25a834751 1392 #ifdef HAVE_NETX
wolfSSL 11:cee25a834751 1393
wolfSSL 11:cee25a834751 1394 /* The NetX receive callback
wolfSSL 11:cee25a834751 1395 * return : bytes read, or error
wolfSSL 11:cee25a834751 1396 */
wolfSSL 11:cee25a834751 1397 int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
wolfSSL 11:cee25a834751 1398 {
wolfSSL 11:cee25a834751 1399 NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
wolfSSL 11:cee25a834751 1400 ULONG left;
wolfSSL 11:cee25a834751 1401 ULONG total;
wolfSSL 11:cee25a834751 1402 ULONG copied = 0;
wolfSSL 11:cee25a834751 1403 UINT status;
wolfSSL 11:cee25a834751 1404
wolfSSL 11:cee25a834751 1405 if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
wolfSSL 11:cee25a834751 1406 WOLFSSL_MSG("NetX Recv NULL parameters");
wolfSSL 11:cee25a834751 1407 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1408 }
wolfSSL 11:cee25a834751 1409
wolfSSL 11:cee25a834751 1410 if (nxCtx->nxPacket == NULL) {
wolfSSL 11:cee25a834751 1411 status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket,
wolfSSL 11:cee25a834751 1412 nxCtx->nxWait);
wolfSSL 11:cee25a834751 1413 if (status != NX_SUCCESS) {
wolfSSL 11:cee25a834751 1414 WOLFSSL_MSG("NetX Recv receive error");
wolfSSL 11:cee25a834751 1415 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1416 }
wolfSSL 11:cee25a834751 1417 }
wolfSSL 11:cee25a834751 1418
wolfSSL 11:cee25a834751 1419 if (nxCtx->nxPacket) {
wolfSSL 11:cee25a834751 1420 status = nx_packet_length_get(nxCtx->nxPacket, &total);
wolfSSL 11:cee25a834751 1421 if (status != NX_SUCCESS) {
wolfSSL 11:cee25a834751 1422 WOLFSSL_MSG("NetX Recv length get error");
wolfSSL 11:cee25a834751 1423 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1424 }
wolfSSL 11:cee25a834751 1425
wolfSSL 11:cee25a834751 1426 left = total - nxCtx->nxOffset;
wolfSSL 11:cee25a834751 1427 status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset,
wolfSSL 11:cee25a834751 1428 buf, sz, &copied);
wolfSSL 11:cee25a834751 1429 if (status != NX_SUCCESS) {
wolfSSL 11:cee25a834751 1430 WOLFSSL_MSG("NetX Recv data extract offset error");
wolfSSL 11:cee25a834751 1431 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1432 }
wolfSSL 11:cee25a834751 1433
wolfSSL 11:cee25a834751 1434 nxCtx->nxOffset += copied;
wolfSSL 11:cee25a834751 1435
wolfSSL 11:cee25a834751 1436 if (copied == left) {
wolfSSL 11:cee25a834751 1437 WOLFSSL_MSG("NetX Recv Drained packet");
wolfSSL 11:cee25a834751 1438 nx_packet_release(nxCtx->nxPacket);
wolfSSL 11:cee25a834751 1439 nxCtx->nxPacket = NULL;
wolfSSL 11:cee25a834751 1440 nxCtx->nxOffset = 0;
wolfSSL 11:cee25a834751 1441 }
wolfSSL 11:cee25a834751 1442 }
wolfSSL 11:cee25a834751 1443
wolfSSL 11:cee25a834751 1444 return copied;
wolfSSL 11:cee25a834751 1445 }
wolfSSL 11:cee25a834751 1446
wolfSSL 11:cee25a834751 1447
wolfSSL 11:cee25a834751 1448 /* The NetX send callback
wolfSSL 11:cee25a834751 1449 * return : bytes sent, or error
wolfSSL 11:cee25a834751 1450 */
wolfSSL 11:cee25a834751 1451 int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
wolfSSL 11:cee25a834751 1452 {
wolfSSL 11:cee25a834751 1453 NetX_Ctx* nxCtx = (NetX_Ctx*)ctx;
wolfSSL 11:cee25a834751 1454 NX_PACKET* packet;
wolfSSL 11:cee25a834751 1455 NX_PACKET_POOL* pool; /* shorthand */
wolfSSL 11:cee25a834751 1456 UINT status;
wolfSSL 11:cee25a834751 1457
wolfSSL 11:cee25a834751 1458 if (nxCtx == NULL || nxCtx->nxSocket == NULL) {
wolfSSL 11:cee25a834751 1459 WOLFSSL_MSG("NetX Send NULL parameters");
wolfSSL 11:cee25a834751 1460 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1461 }
wolfSSL 11:cee25a834751 1462
wolfSSL 11:cee25a834751 1463 pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool;
wolfSSL 11:cee25a834751 1464 status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET,
wolfSSL 11:cee25a834751 1465 nxCtx->nxWait);
wolfSSL 11:cee25a834751 1466 if (status != NX_SUCCESS) {
wolfSSL 11:cee25a834751 1467 WOLFSSL_MSG("NetX Send packet alloc error");
wolfSSL 11:cee25a834751 1468 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1469 }
wolfSSL 11:cee25a834751 1470
wolfSSL 11:cee25a834751 1471 status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait);
wolfSSL 11:cee25a834751 1472 if (status != NX_SUCCESS) {
wolfSSL 11:cee25a834751 1473 nx_packet_release(packet);
wolfSSL 11:cee25a834751 1474 WOLFSSL_MSG("NetX Send data append error");
wolfSSL 11:cee25a834751 1475 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1476 }
wolfSSL 11:cee25a834751 1477
wolfSSL 11:cee25a834751 1478 status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait);
wolfSSL 11:cee25a834751 1479 if (status != NX_SUCCESS) {
wolfSSL 11:cee25a834751 1480 nx_packet_release(packet);
wolfSSL 11:cee25a834751 1481 WOLFSSL_MSG("NetX Send socket send error");
wolfSSL 11:cee25a834751 1482 return WOLFSSL_CBIO_ERR_GENERAL;
wolfSSL 11:cee25a834751 1483 }
wolfSSL 11:cee25a834751 1484
wolfSSL 11:cee25a834751 1485 return sz;
wolfSSL 11:cee25a834751 1486 }
wolfSSL 11:cee25a834751 1487
wolfSSL 11:cee25a834751 1488
wolfSSL 11:cee25a834751 1489 /* like set_fd, but for default NetX context */
wolfSSL 11:cee25a834751 1490 void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption)
wolfSSL 11:cee25a834751 1491 {
wolfSSL 11:cee25a834751 1492 if (ssl) {
wolfSSL 11:cee25a834751 1493 ssl->nxCtx.nxSocket = nxSocket;
wolfSSL 11:cee25a834751 1494 ssl->nxCtx.nxWait = waitOption;
wolfSSL 11:cee25a834751 1495 }
wolfSSL 11:cee25a834751 1496 }
wolfSSL 11:cee25a834751 1497
wolfSSL 11:cee25a834751 1498 #endif /* HAVE_NETX */
wolfSSL 11:cee25a834751 1499
wolfSSL 11:cee25a834751 1500 #endif /* WOLFCRYPT_ONLY */
wolfSSL 11:cee25a834751 1501