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

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

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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