A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

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