SSL/TLS Library

Dependents:  

CyaSSL is SSL/TLS library for embedded systems.

wolfssl.com

Committer:
wolfSSL
Date:
Sun Apr 20 12:40:57 2014 +0000
Revision:
0:9d17e4342598
CyaSSL SSL/TLS Library 2.9.4;

Who changed what in which revision?

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