CyaSSL 3.0.0

Dependents:   HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more

Committer:
wolfSSL
Date:
Wed Dec 03 05:24:18 2014 +0000
Revision:
3:64d4f7cb83d5
Parent:
0:1239e9b70ca2
added IGNORE_KEY_EXTENSIONS

Who changed what in which revision?

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