cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:59:36 2013 +0000
Revision:
1:b211d97b0068
Parent:
0:e979170e02e7
nothing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:e979170e02e7 1 /* io.c
ashleymills 0:e979170e02e7 2 *
ashleymills 0:e979170e02e7 3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
ashleymills 0:e979170e02e7 4 *
ashleymills 0:e979170e02e7 5 * This file is part of CyaSSL.
ashleymills 0:e979170e02e7 6 *
ashleymills 0:e979170e02e7 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:e979170e02e7 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:e979170e02e7 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:e979170e02e7 10 * (at your option) any later version.
ashleymills 0:e979170e02e7 11 *
ashleymills 0:e979170e02e7 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:e979170e02e7 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:e979170e02e7 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:e979170e02e7 15 * GNU General Public License for more details.
ashleymills 0:e979170e02e7 16 *
ashleymills 0:e979170e02e7 17 * You should have received a copy of the GNU General Public License
ashleymills 0:e979170e02e7 18 * along with this program; if not, write to the Free Software
ashleymills 0:e979170e02e7 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:e979170e02e7 20 */
ashleymills 0:e979170e02e7 21
ashleymills 0:e979170e02e7 22 #ifdef HAVE_CONFIG_H
ashleymills 0:e979170e02e7 23 #include <config.h>
ashleymills 0:e979170e02e7 24 #endif
ashleymills 0:e979170e02e7 25
ashleymills 0:e979170e02e7 26 #ifdef _WIN32_WCE
ashleymills 0:e979170e02e7 27 /* On WinCE winsock2.h must be included before windows.h for socket stuff */
ashleymills 0:e979170e02e7 28 #include <winsock2.h>
ashleymills 0:e979170e02e7 29 #endif
ashleymills 0:e979170e02e7 30
ashleymills 0:e979170e02e7 31 #include <cyassl/internal.h>
ashleymills 0:e979170e02e7 32
ashleymills 0:e979170e02e7 33 /* if user writes own I/O callbacks they can define CYASSL_USER_IO to remove
ashleymills 0:e979170e02e7 34 automatic setting of default I/O functions EmbedSend() and EmbedReceive()
ashleymills 0:e979170e02e7 35 but they'll still need SetCallback xxx() at end of file
ashleymills 0:e979170e02e7 36 */
ashleymills 0:e979170e02e7 37 #undef CYASSL_USER_IO
ashleymills 0:e979170e02e7 38 #ifndef CYASSL_USER_IO
ashleymills 0:e979170e02e7 39
ashleymills 0:e979170e02e7 40 #ifdef HAVE_LIBZ
ashleymills 0:e979170e02e7 41 #include "zlib.h"
ashleymills 0:e979170e02e7 42 #endif
ashleymills 0:e979170e02e7 43
ashleymills 0:e979170e02e7 44 #ifndef USE_WINDOWS_API
ashleymills 0:e979170e02e7 45 #ifdef CYASSL_LWIP
ashleymills 0:e979170e02e7 46 /* lwIP needs to be configured to use sockets API in this mode */
ashleymills 0:e979170e02e7 47 /* LWIP_SOCKET 1 in lwip/opt.h or in build */
ashleymills 0:e979170e02e7 48 #include "lwip/sockets.h"
ashleymills 0:e979170e02e7 49 #include <errno.h>
ashleymills 0:e979170e02e7 50 #ifndef LWIP_PROVIDE_ERRNO
ashleymills 0:e979170e02e7 51 #define LWIP_PROVIDE_ERRNO 1
ashleymills 0:e979170e02e7 52 #endif
ashleymills 0:e979170e02e7 53 #elif defined(FREESCALE_MQX)
ashleymills 0:e979170e02e7 54 #include <posix.h>
ashleymills 0:e979170e02e7 55 #include <rtcs.h>
ashleymills 0:e979170e02e7 56 #else
ashleymills 0:e979170e02e7 57 #include <sys/types.h>
ashleymills 0:e979170e02e7 58 #include <errno.h>
ashleymills 0:e979170e02e7 59 #ifndef EBSNET
ashleymills 0:e979170e02e7 60 #include <unistd.h>
ashleymills 0:e979170e02e7 61 #endif
ashleymills 0:e979170e02e7 62 #include <fcntl.h>
ashleymills 0:e979170e02e7 63 #if !(defined(DEVKITPRO) || defined(THREADX) || defined(EBSNET))
ashleymills 0:e979170e02e7 64 #include <sys/socket.h>
ashleymills 0:e979170e02e7 65 #include <arpa/inet.h>
ashleymills 0:e979170e02e7 66 #include <netinet/in.h>
ashleymills 0:e979170e02e7 67 #include <netdb.h>
ashleymills 0:e979170e02e7 68 #ifdef __PPU
ashleymills 0:e979170e02e7 69 #include <netex/errno.h>
ashleymills 0:e979170e02e7 70 #else
ashleymills 0:e979170e02e7 71 #include <sys/ioctl.h>
ashleymills 0:e979170e02e7 72 #endif
ashleymills 0:e979170e02e7 73 #endif
ashleymills 0:e979170e02e7 74 #ifdef THREADX
ashleymills 0:e979170e02e7 75 #include <socket.h>
ashleymills 0:e979170e02e7 76 #endif
ashleymills 0:e979170e02e7 77 #ifdef EBSNET
ashleymills 0:e979170e02e7 78 #include "rtipapi.h" /* errno */
ashleymills 0:e979170e02e7 79 #include "socket.h"
ashleymills 0:e979170e02e7 80 #endif
ashleymills 0:e979170e02e7 81 #endif
ashleymills 0:e979170e02e7 82 #endif /* USE_WINDOWS_API */
ashleymills 0:e979170e02e7 83
ashleymills 0:e979170e02e7 84 #ifdef __sun
ashleymills 0:e979170e02e7 85 #include <sys/filio.h>
ashleymills 0:e979170e02e7 86 #endif
ashleymills 0:e979170e02e7 87
ashleymills 0:e979170e02e7 88 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 89 /* no epipe yet */
ashleymills 0:e979170e02e7 90 #ifndef WSAEPIPE
ashleymills 0:e979170e02e7 91 #define WSAEPIPE -12345
ashleymills 0:e979170e02e7 92 #endif
ashleymills 0:e979170e02e7 93 #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
ashleymills 0:e979170e02e7 94 #define SOCKET_EAGAIN WSAETIMEDOUT
ashleymills 0:e979170e02e7 95 #define SOCKET_ECONNRESET WSAECONNRESET
ashleymills 0:e979170e02e7 96 #define SOCKET_EINTR WSAEINTR
ashleymills 0:e979170e02e7 97 #define SOCKET_EPIPE WSAEPIPE
ashleymills 0:e979170e02e7 98 #define SOCKET_ECONNREFUSED WSAENOTCONN
ashleymills 0:e979170e02e7 99 #elif defined(__PPU)
ashleymills 0:e979170e02e7 100 #define SOCKET_EWOULDBLOCK SYS_NET_EWOULDBLOCK
ashleymills 0:e979170e02e7 101 #define SOCKET_EAGAIN SYS_NET_EAGAIN
ashleymills 0:e979170e02e7 102 #define SOCKET_ECONNRESET SYS_NET_ECONNRESET
ashleymills 0:e979170e02e7 103 #define SOCKET_EINTR SYS_NET_EINTR
ashleymills 0:e979170e02e7 104 #define SOCKET_EPIPE SYS_NET_EPIPE
ashleymills 0:e979170e02e7 105 #define SOCKET_ECONNREFUSED SYS_NET_ECONNREFUSED
ashleymills 0:e979170e02e7 106 #elif defined(FREESCALE_MQX)
ashleymills 0:e979170e02e7 107 /* RTCS doesn't have an EWOULDBLOCK error */
ashleymills 0:e979170e02e7 108 #define SOCKET_EWOULDBLOCK EAGAIN
ashleymills 0:e979170e02e7 109 #define SOCKET_EAGAIN EAGAIN
ashleymills 0:e979170e02e7 110 #define SOCKET_ECONNRESET RTCSERR_TCP_CONN_RESET
ashleymills 0:e979170e02e7 111 #define SOCKET_EINTR EINTR
ashleymills 0:e979170e02e7 112 #define SOCKET_EPIPE EPIPE
ashleymills 0:e979170e02e7 113 #define SOCKET_ECONNREFUSED RTCSERR_TCP_CONN_REFUSED
ashleymills 0:e979170e02e7 114 #else
ashleymills 0:e979170e02e7 115 #define SOCKET_EWOULDBLOCK EWOULDBLOCK
ashleymills 0:e979170e02e7 116 #define SOCKET_EAGAIN EAGAIN
ashleymills 0:e979170e02e7 117 #define SOCKET_ECONNRESET ECONNRESET
ashleymills 0:e979170e02e7 118 #define SOCKET_EINTR EINTR
ashleymills 0:e979170e02e7 119 #define SOCKET_EPIPE EPIPE
ashleymills 0:e979170e02e7 120 #define SOCKET_ECONNREFUSED ECONNREFUSED
ashleymills 0:e979170e02e7 121 #endif /* USE_WINDOWS_API */
ashleymills 0:e979170e02e7 122
ashleymills 0:e979170e02e7 123 #ifdef DEVKITPRO
ashleymills 0:e979170e02e7 124 /* from network.h */
ashleymills 0:e979170e02e7 125 int net_send(int, const void*, int, unsigned int);
ashleymills 0:e979170e02e7 126 int net_recv(int, void*, int, unsigned int);
ashleymills 0:e979170e02e7 127 #define SEND_FUNCTION net_send
ashleymills 0:e979170e02e7 128 #define RECV_FUNCTION net_recv
ashleymills 0:e979170e02e7 129 #elif defined(CYASSL_LWIP)
ashleymills 0:e979170e02e7 130 #define SEND_FUNCTION lwip_send
ashleymills 0:e979170e02e7 131 #define RECV_FUNCTION lwip_recv
ashleymills 0:e979170e02e7 132 #else
ashleymills 0:e979170e02e7 133 #define SEND_FUNCTION send
ashleymills 0:e979170e02e7 134 #define RECV_FUNCTION recv
ashleymills 0:e979170e02e7 135 #endif
ashleymills 0:e979170e02e7 136
ashleymills 0:e979170e02e7 137
ashleymills 0:e979170e02e7 138 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 139 /* sizeof(struct timeval) will pass uninit bytes to setsockopt if padded */
ashleymills 0:e979170e02e7 140 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 141 #define TIMEVAL_BYTES sizeof(timeout)
ashleymills 0:e979170e02e7 142 #else
ashleymills 0:e979170e02e7 143 #define TIMEVAL_BYTES sizeof(timeout.tv_sec) + sizeof(timeout.tv_usec)
ashleymills 0:e979170e02e7 144 #endif
ashleymills 0:e979170e02e7 145 #endif
ashleymills 0:e979170e02e7 146
ashleymills 0:e979170e02e7 147
ashleymills 0:e979170e02e7 148 /* Translates return codes returned from
ashleymills 0:e979170e02e7 149 * send() and recv() if need be.
ashleymills 0:e979170e02e7 150 */
ashleymills 0:e979170e02e7 151 static INLINE int TranslateReturnCode(int old, int sd)
ashleymills 0:e979170e02e7 152 {
ashleymills 0:e979170e02e7 153 (void)sd;
ashleymills 0:e979170e02e7 154
ashleymills 0:e979170e02e7 155 #ifdef FREESCALE_MQX
ashleymills 0:e979170e02e7 156 if (old == 0) {
ashleymills 0:e979170e02e7 157 errno = SOCKET_EWOULDBLOCK;
ashleymills 0:e979170e02e7 158 return -1; /* convert to BSD style wouldblock as error */
ashleymills 0:e979170e02e7 159 }
ashleymills 0:e979170e02e7 160
ashleymills 0:e979170e02e7 161 if (old < 0) {
ashleymills 0:e979170e02e7 162 errno = RTCS_geterror(sd);
ashleymills 0:e979170e02e7 163 if (errno == RTCSERR_TCP_CONN_CLOSING)
ashleymills 0:e979170e02e7 164 return 0; /* convert to BSD style closing */
ashleymills 0:e979170e02e7 165 }
ashleymills 0:e979170e02e7 166 #endif
ashleymills 0:e979170e02e7 167
ashleymills 0:e979170e02e7 168 return old;
ashleymills 0:e979170e02e7 169 }
ashleymills 0:e979170e02e7 170
ashleymills 0:e979170e02e7 171 static INLINE int LastError(void)
ashleymills 0:e979170e02e7 172 {
ashleymills 0:e979170e02e7 173 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 174 return WSAGetLastError();
ashleymills 0:e979170e02e7 175 #elif defined(EBSNET)
ashleymills 0:e979170e02e7 176 return xn_getlasterror();
ashleymills 0:e979170e02e7 177 #else
ashleymills 0:e979170e02e7 178 return errno;
ashleymills 0:e979170e02e7 179 #endif
ashleymills 0:e979170e02e7 180 }
ashleymills 0:e979170e02e7 181
ashleymills 0:e979170e02e7 182 /* The receive embedded callback
ashleymills 0:e979170e02e7 183 * return : nb bytes read, or error
ashleymills 0:e979170e02e7 184 */
ashleymills 0:e979170e02e7 185 int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx)
ashleymills 0:e979170e02e7 186 {
ashleymills 0:e979170e02e7 187 int recvd;
ashleymills 0:e979170e02e7 188 int err;
ashleymills 0:e979170e02e7 189 int sd = *(int*)ctx;
ashleymills 0:e979170e02e7 190
ashleymills 0:e979170e02e7 191 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 192 {
ashleymills 0:e979170e02e7 193 int dtls_timeout = CyaSSL_dtls_get_current_timeout(ssl);
ashleymills 0:e979170e02e7 194 if (CyaSSL_dtls(ssl)
ashleymills 0:e979170e02e7 195 && !CyaSSL_get_using_nonblock(ssl)
ashleymills 0:e979170e02e7 196 && dtls_timeout != 0) {
ashleymills 0:e979170e02e7 197 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 198 DWORD timeout = dtls_timeout * 1000;
ashleymills 0:e979170e02e7 199 #else
ashleymills 0:e979170e02e7 200 struct timeval timeout = {dtls_timeout, 0};
ashleymills 0:e979170e02e7 201 #endif
ashleymills 0:e979170e02e7 202 setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO,
ashleymills 0:e979170e02e7 203 (char*)&timeout, TIMEVAL_BYTES);
ashleymills 0:e979170e02e7 204 }
ashleymills 0:e979170e02e7 205 }
ashleymills 0:e979170e02e7 206 #endif
ashleymills 0:e979170e02e7 207
ashleymills 0:e979170e02e7 208 recvd = (int)RECV_FUNCTION(sd, buf, sz, ssl->rflags);
ashleymills 0:e979170e02e7 209
ashleymills 0:e979170e02e7 210 recvd = TranslateReturnCode(recvd, sd);
ashleymills 0:e979170e02e7 211
ashleymills 0:e979170e02e7 212 if (recvd < 0) {
ashleymills 0:e979170e02e7 213 err = LastError();
ashleymills 0:e979170e02e7 214 CYASSL_MSG("Embed Receive error");
ashleymills 0:e979170e02e7 215
ashleymills 0:e979170e02e7 216 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
ashleymills 0:e979170e02e7 217 if (!CyaSSL_dtls(ssl) || CyaSSL_get_using_nonblock(ssl)) {
ashleymills 0:e979170e02e7 218 CYASSL_MSG(" Would block");
ashleymills 0:e979170e02e7 219 return IO_ERR_WANT_READ;
ashleymills 0:e979170e02e7 220 }
ashleymills 0:e979170e02e7 221 else {
ashleymills 0:e979170e02e7 222 CYASSL_MSG(" Socket timeout");
ashleymills 0:e979170e02e7 223 return IO_ERR_TIMEOUT;
ashleymills 0:e979170e02e7 224 }
ashleymills 0:e979170e02e7 225 }
ashleymills 0:e979170e02e7 226 else if (err == SOCKET_ECONNRESET) {
ashleymills 0:e979170e02e7 227 CYASSL_MSG(" Connection reset");
ashleymills 0:e979170e02e7 228 return IO_ERR_CONN_RST;
ashleymills 0:e979170e02e7 229 }
ashleymills 0:e979170e02e7 230 else if (err == SOCKET_EINTR) {
ashleymills 0:e979170e02e7 231 CYASSL_MSG(" Socket interrupted");
ashleymills 0:e979170e02e7 232 return IO_ERR_ISR;
ashleymills 0:e979170e02e7 233 }
ashleymills 0:e979170e02e7 234 else if (err == SOCKET_ECONNREFUSED) {
ashleymills 0:e979170e02e7 235 CYASSL_MSG(" Connection refused");
ashleymills 0:e979170e02e7 236 return IO_ERR_WANT_READ;
ashleymills 0:e979170e02e7 237 }
ashleymills 0:e979170e02e7 238 else {
ashleymills 0:e979170e02e7 239 CYASSL_MSG(" General error");
ashleymills 0:e979170e02e7 240 return IO_ERR_GENERAL;
ashleymills 0:e979170e02e7 241 }
ashleymills 0:e979170e02e7 242 }
ashleymills 0:e979170e02e7 243 else if (recvd == 0) {
ashleymills 0:e979170e02e7 244 CYASSL_MSG("Embed receive connection closed");
ashleymills 0:e979170e02e7 245 return IO_ERR_CONN_CLOSE;
ashleymills 0:e979170e02e7 246 }
ashleymills 0:e979170e02e7 247
ashleymills 0:e979170e02e7 248 return recvd;
ashleymills 0:e979170e02e7 249 }
ashleymills 0:e979170e02e7 250
ashleymills 0:e979170e02e7 251 /* The send embedded callback
ashleymills 0:e979170e02e7 252 * return : nb bytes sent, or error
ashleymills 0:e979170e02e7 253 */
ashleymills 0:e979170e02e7 254 int EmbedSend(CYASSL* ssl, char *buf, int sz, void *ctx)
ashleymills 0:e979170e02e7 255 {
ashleymills 0:e979170e02e7 256 int sd = *(int*)ctx;
ashleymills 0:e979170e02e7 257 int sent;
ashleymills 0:e979170e02e7 258 int len = sz;
ashleymills 0:e979170e02e7 259 int err;
ashleymills 0:e979170e02e7 260
ashleymills 0:e979170e02e7 261 sent = (int)SEND_FUNCTION(sd, &buf[sz - len], len, ssl->wflags);
ashleymills 0:e979170e02e7 262
ashleymills 0:e979170e02e7 263 if (sent < 0) {
ashleymills 0:e979170e02e7 264 err = LastError();
ashleymills 0:e979170e02e7 265 CYASSL_MSG("Embed Send error");
ashleymills 0:e979170e02e7 266
ashleymills 0:e979170e02e7 267 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
ashleymills 0:e979170e02e7 268 CYASSL_MSG(" Would Block");
ashleymills 0:e979170e02e7 269 return IO_ERR_WANT_WRITE;
ashleymills 0:e979170e02e7 270 }
ashleymills 0:e979170e02e7 271 else if (err == SOCKET_ECONNRESET) {
ashleymills 0:e979170e02e7 272 CYASSL_MSG(" Connection reset");
ashleymills 0:e979170e02e7 273 return IO_ERR_CONN_RST;
ashleymills 0:e979170e02e7 274 }
ashleymills 0:e979170e02e7 275 else if (err == SOCKET_EINTR) {
ashleymills 0:e979170e02e7 276 CYASSL_MSG(" Socket interrupted");
ashleymills 0:e979170e02e7 277 return IO_ERR_ISR;
ashleymills 0:e979170e02e7 278 }
ashleymills 0:e979170e02e7 279 else if (err == SOCKET_EPIPE) {
ashleymills 0:e979170e02e7 280 CYASSL_MSG(" Socket EPIPE");
ashleymills 0:e979170e02e7 281 return IO_ERR_CONN_CLOSE;
ashleymills 0:e979170e02e7 282 }
ashleymills 0:e979170e02e7 283 else {
ashleymills 0:e979170e02e7 284 CYASSL_MSG(" General error");
ashleymills 0:e979170e02e7 285 return IO_ERR_GENERAL;
ashleymills 0:e979170e02e7 286 }
ashleymills 0:e979170e02e7 287 }
ashleymills 0:e979170e02e7 288
ashleymills 0:e979170e02e7 289 return sent;
ashleymills 0:e979170e02e7 290 }
ashleymills 0:e979170e02e7 291
ashleymills 0:e979170e02e7 292
ashleymills 0:e979170e02e7 293 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 294
ashleymills 0:e979170e02e7 295 #include <cyassl/ctaocrypt/sha.h>
ashleymills 0:e979170e02e7 296
ashleymills 0:e979170e02e7 297 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 298 #define XSOCKLENT int
ashleymills 0:e979170e02e7 299 #else
ashleymills 0:e979170e02e7 300 #define XSOCKLENT socklen_t
ashleymills 0:e979170e02e7 301 #endif
ashleymills 0:e979170e02e7 302
ashleymills 0:e979170e02e7 303 #define SENDTO_FUNCTION sendto
ashleymills 0:e979170e02e7 304 #define RECVFROM_FUNCTION recvfrom
ashleymills 0:e979170e02e7 305
ashleymills 0:e979170e02e7 306
ashleymills 0:e979170e02e7 307 /* The receive embedded callback
ashleymills 0:e979170e02e7 308 * return : nb bytes read, or error
ashleymills 0:e979170e02e7 309 */
ashleymills 0:e979170e02e7 310 int EmbedReceiveFrom(CYASSL *ssl, char *buf, int sz, void *ctx)
ashleymills 0:e979170e02e7 311 {
ashleymills 0:e979170e02e7 312 CYASSL_DTLS_CTX* dtlsCtx = (CYASSL_DTLS_CTX*)ctx;
ashleymills 0:e979170e02e7 313 int recvd;
ashleymills 0:e979170e02e7 314 int err;
ashleymills 0:e979170e02e7 315 int sd = dtlsCtx->fd;
ashleymills 0:e979170e02e7 316 int dtls_timeout = CyaSSL_dtls_get_current_timeout(ssl);
ashleymills 0:e979170e02e7 317 struct sockaddr_in peer;
ashleymills 0:e979170e02e7 318 XSOCKLENT peerSz = sizeof(peer);
ashleymills 0:e979170e02e7 319
ashleymills 0:e979170e02e7 320 CYASSL_ENTER("EmbedReceiveFrom()");
ashleymills 0:e979170e02e7 321 if (!CyaSSL_get_using_nonblock(ssl) && dtls_timeout != 0) {
ashleymills 0:e979170e02e7 322 #ifdef USE_WINDOWS_API
ashleymills 0:e979170e02e7 323 DWORD timeout = dtls_timeout * 1000;
ashleymills 0:e979170e02e7 324 #else
ashleymills 0:e979170e02e7 325 struct timeval timeout = { dtls_timeout, 0 };
ashleymills 0:e979170e02e7 326 #endif
ashleymills 0:e979170e02e7 327 setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO,
ashleymills 0:e979170e02e7 328 (char*)&timeout, TIMEVAL_BYTES);
ashleymills 0:e979170e02e7 329 }
ashleymills 0:e979170e02e7 330
ashleymills 0:e979170e02e7 331 recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
ashleymills 0:e979170e02e7 332 (struct sockaddr*)&peer, &peerSz);
ashleymills 0:e979170e02e7 333
ashleymills 0:e979170e02e7 334 recvd = TranslateReturnCode(recvd, sd);
ashleymills 0:e979170e02e7 335
ashleymills 0:e979170e02e7 336 if (recvd < 0) {
ashleymills 0:e979170e02e7 337 err = LastError();
ashleymills 0:e979170e02e7 338 CYASSL_MSG("Embed Receive From error");
ashleymills 0:e979170e02e7 339
ashleymills 0:e979170e02e7 340 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
ashleymills 0:e979170e02e7 341 if (CyaSSL_get_using_nonblock(ssl)) {
ashleymills 0:e979170e02e7 342 CYASSL_MSG(" Would block");
ashleymills 0:e979170e02e7 343 return IO_ERR_WANT_READ;
ashleymills 0:e979170e02e7 344 }
ashleymills 0:e979170e02e7 345 else {
ashleymills 0:e979170e02e7 346 CYASSL_MSG(" Socket timeout");
ashleymills 0:e979170e02e7 347 return IO_ERR_TIMEOUT;
ashleymills 0:e979170e02e7 348 }
ashleymills 0:e979170e02e7 349 }
ashleymills 0:e979170e02e7 350 else if (err == SOCKET_ECONNRESET) {
ashleymills 0:e979170e02e7 351 CYASSL_MSG(" Connection reset");
ashleymills 0:e979170e02e7 352 return IO_ERR_CONN_RST;
ashleymills 0:e979170e02e7 353 }
ashleymills 0:e979170e02e7 354 else if (err == SOCKET_EINTR) {
ashleymills 0:e979170e02e7 355 CYASSL_MSG(" Socket interrupted");
ashleymills 0:e979170e02e7 356 return IO_ERR_ISR;
ashleymills 0:e979170e02e7 357 }
ashleymills 0:e979170e02e7 358 else if (err == SOCKET_ECONNREFUSED) {
ashleymills 0:e979170e02e7 359 CYASSL_MSG(" Connection refused");
ashleymills 0:e979170e02e7 360 return IO_ERR_WANT_READ;
ashleymills 0:e979170e02e7 361 }
ashleymills 0:e979170e02e7 362 else {
ashleymills 0:e979170e02e7 363 CYASSL_MSG(" General error");
ashleymills 0:e979170e02e7 364 return IO_ERR_GENERAL;
ashleymills 0:e979170e02e7 365 }
ashleymills 0:e979170e02e7 366 }
ashleymills 0:e979170e02e7 367 else {
ashleymills 0:e979170e02e7 368 if (dtlsCtx != NULL
ashleymills 0:e979170e02e7 369 && dtlsCtx->peer.sz > 0
ashleymills 0:e979170e02e7 370 && peerSz != (XSOCKLENT)dtlsCtx->peer.sz
ashleymills 0:e979170e02e7 371 && memcmp(&peer, dtlsCtx->peer.sa, peerSz) != 0) {
ashleymills 0:e979170e02e7 372 CYASSL_MSG(" Ignored packet from invalid peer");
ashleymills 0:e979170e02e7 373 return IO_ERR_WANT_READ;
ashleymills 0:e979170e02e7 374 }
ashleymills 0:e979170e02e7 375 }
ashleymills 0:e979170e02e7 376
ashleymills 0:e979170e02e7 377 return recvd;
ashleymills 0:e979170e02e7 378 }
ashleymills 0:e979170e02e7 379
ashleymills 0:e979170e02e7 380
ashleymills 0:e979170e02e7 381 /* The send embedded callback
ashleymills 0:e979170e02e7 382 * return : nb bytes sent, or error
ashleymills 0:e979170e02e7 383 */
ashleymills 0:e979170e02e7 384 int EmbedSendTo(CYASSL* ssl, char *buf, int sz, void *ctx)
ashleymills 0:e979170e02e7 385 {
ashleymills 0:e979170e02e7 386 CYASSL_DTLS_CTX* dtlsCtx = (CYASSL_DTLS_CTX*)ctx;
ashleymills 0:e979170e02e7 387 int sd = dtlsCtx->fd;
ashleymills 0:e979170e02e7 388 int sent;
ashleymills 0:e979170e02e7 389 int len = sz;
ashleymills 0:e979170e02e7 390 int err;
ashleymills 0:e979170e02e7 391
ashleymills 0:e979170e02e7 392 CYASSL_ENTER("EmbedSendTo()");
ashleymills 0:e979170e02e7 393 sent = (int)SENDTO_FUNCTION(sd, &buf[sz - len], len, ssl->wflags,
ashleymills 0:e979170e02e7 394 dtlsCtx->peer.sa, dtlsCtx->peer.sz);
ashleymills 0:e979170e02e7 395 if (sent < 0) {
ashleymills 0:e979170e02e7 396 err = LastError();
ashleymills 0:e979170e02e7 397 CYASSL_MSG("Embed Send To error");
ashleymills 0:e979170e02e7 398
ashleymills 0:e979170e02e7 399 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
ashleymills 0:e979170e02e7 400 CYASSL_MSG(" Would Block");
ashleymills 0:e979170e02e7 401 return IO_ERR_WANT_WRITE;
ashleymills 0:e979170e02e7 402 }
ashleymills 0:e979170e02e7 403 else if (err == SOCKET_ECONNRESET) {
ashleymills 0:e979170e02e7 404 CYASSL_MSG(" Connection reset");
ashleymills 0:e979170e02e7 405 return IO_ERR_CONN_RST;
ashleymills 0:e979170e02e7 406 }
ashleymills 0:e979170e02e7 407 else if (err == SOCKET_EINTR) {
ashleymills 0:e979170e02e7 408 CYASSL_MSG(" Socket interrupted");
ashleymills 0:e979170e02e7 409 return IO_ERR_ISR;
ashleymills 0:e979170e02e7 410 }
ashleymills 0:e979170e02e7 411 else if (err == SOCKET_EPIPE) {
ashleymills 0:e979170e02e7 412 CYASSL_MSG(" Socket EPIPE");
ashleymills 0:e979170e02e7 413 return IO_ERR_CONN_CLOSE;
ashleymills 0:e979170e02e7 414 }
ashleymills 0:e979170e02e7 415 else {
ashleymills 0:e979170e02e7 416 CYASSL_MSG(" General error");
ashleymills 0:e979170e02e7 417 return IO_ERR_GENERAL;
ashleymills 0:e979170e02e7 418 }
ashleymills 0:e979170e02e7 419 }
ashleymills 0:e979170e02e7 420
ashleymills 0:e979170e02e7 421 return sent;
ashleymills 0:e979170e02e7 422 }
ashleymills 0:e979170e02e7 423
ashleymills 0:e979170e02e7 424
ashleymills 0:e979170e02e7 425 /* The DTLS Generate Cookie callback
ashleymills 0:e979170e02e7 426 * return : number of bytes copied into buf, or error
ashleymills 0:e979170e02e7 427 */
ashleymills 0:e979170e02e7 428 int EmbedGenerateCookie(byte *buf, int sz, void *ctx)
ashleymills 0:e979170e02e7 429 {
ashleymills 0:e979170e02e7 430 CYASSL* ssl = (CYASSL*)ctx;
ashleymills 0:e979170e02e7 431 int sd = ssl->wfd;
ashleymills 0:e979170e02e7 432 struct sockaddr_in peer;
ashleymills 0:e979170e02e7 433 XSOCKLENT peerSz = sizeof(peer);
ashleymills 0:e979170e02e7 434 byte cookieSrc[sizeof(struct in_addr) + sizeof(int)];
ashleymills 0:e979170e02e7 435 int cookieSrcSz = 0;
ashleymills 0:e979170e02e7 436 Sha sha;
ashleymills 0:e979170e02e7 437
ashleymills 0:e979170e02e7 438 getpeername(sd, (struct sockaddr*)&peer, &peerSz);
ashleymills 0:e979170e02e7 439
ashleymills 0:e979170e02e7 440 if (peer.sin_family == AF_INET) {
ashleymills 0:e979170e02e7 441 struct sockaddr_in *s = (struct sockaddr_in*)&peer;
ashleymills 0:e979170e02e7 442
ashleymills 0:e979170e02e7 443 cookieSrcSz = sizeof(struct in_addr) + sizeof(s->sin_port);
ashleymills 0:e979170e02e7 444 XMEMCPY(cookieSrc, &s->sin_port, sizeof(s->sin_port));
ashleymills 0:e979170e02e7 445 XMEMCPY(cookieSrc + sizeof(s->sin_port),
ashleymills 0:e979170e02e7 446 &s->sin_addr, sizeof(struct in_addr));
ashleymills 0:e979170e02e7 447 }
ashleymills 0:e979170e02e7 448
ashleymills 0:e979170e02e7 449 InitSha(&sha);
ashleymills 0:e979170e02e7 450 ShaUpdate(&sha, cookieSrc, cookieSrcSz);
ashleymills 0:e979170e02e7 451
ashleymills 0:e979170e02e7 452 if (sz < SHA_DIGEST_SIZE) {
ashleymills 0:e979170e02e7 453 byte digest[SHA_DIGEST_SIZE];
ashleymills 0:e979170e02e7 454 ShaFinal(&sha, digest);
ashleymills 0:e979170e02e7 455 XMEMCPY(buf, digest, sz);
ashleymills 0:e979170e02e7 456 return sz;
ashleymills 0:e979170e02e7 457 }
ashleymills 0:e979170e02e7 458
ashleymills 0:e979170e02e7 459 ShaFinal(&sha, buf);
ashleymills 0:e979170e02e7 460
ashleymills 0:e979170e02e7 461 return SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 462 }
ashleymills 0:e979170e02e7 463
ashleymills 0:e979170e02e7 464 #endif /* CYASSL_DTLS */
ashleymills 0:e979170e02e7 465
ashleymills 0:e979170e02e7 466 #ifdef HAVE_OCSP
ashleymills 0:e979170e02e7 467
ashleymills 0:e979170e02e7 468 #ifdef TEST_IPV6
ashleymills 0:e979170e02e7 469 typedef struct sockaddr_in6 SOCKADDR_IN_T;
ashleymills 0:e979170e02e7 470 #define AF_INET_V AF_INET6
ashleymills 0:e979170e02e7 471 #else
ashleymills 0:e979170e02e7 472 typedef struct sockaddr_in SOCKADDR_IN_T;
ashleymills 0:e979170e02e7 473 #define AF_INET_V AF_INET
ashleymills 0:e979170e02e7 474 #endif
ashleymills 0:e979170e02e7 475
ashleymills 0:e979170e02e7 476
ashleymills 0:e979170e02e7 477 static INLINE int tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
ashleymills 0:e979170e02e7 478 {
ashleymills 0:e979170e02e7 479 SOCKADDR_IN_T addr;
ashleymills 0:e979170e02e7 480 const char* host = ip;
ashleymills 0:e979170e02e7 481
ashleymills 0:e979170e02e7 482 /* peer could be in human readable form */
ashleymills 0:e979170e02e7 483 if (ip != INADDR_ANY && isalpha(ip[0])) {
ashleymills 0:e979170e02e7 484 struct hostent* entry = gethostbyname(ip);
ashleymills 0:e979170e02e7 485
ashleymills 0:e979170e02e7 486 if (entry) {
ashleymills 0:e979170e02e7 487 struct sockaddr_in tmp;
ashleymills 0:e979170e02e7 488 XMEMSET(&tmp, 0, sizeof(struct sockaddr_in));
ashleymills 0:e979170e02e7 489 XMEMCPY(&tmp.sin_addr.s_addr, entry->h_addr_list[0],
ashleymills 0:e979170e02e7 490 entry->h_length);
ashleymills 0:e979170e02e7 491 host = inet_ntoa(tmp.sin_addr);
ashleymills 0:e979170e02e7 492 }
ashleymills 0:e979170e02e7 493 else {
ashleymills 0:e979170e02e7 494 CYASSL_MSG("no addr entry for OCSP responder");
ashleymills 0:e979170e02e7 495 return -1;
ashleymills 0:e979170e02e7 496 }
ashleymills 0:e979170e02e7 497 }
ashleymills 0:e979170e02e7 498
ashleymills 0:e979170e02e7 499 *sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
ashleymills 0:e979170e02e7 500 XMEMSET(&addr, 0, sizeof(SOCKADDR_IN_T));
ashleymills 0:e979170e02e7 501
ashleymills 0:e979170e02e7 502 addr.sin_family = AF_INET_V;
ashleymills 0:e979170e02e7 503 addr.sin_port = htons(port);
ashleymills 0:e979170e02e7 504 if (host == INADDR_ANY)
ashleymills 0:e979170e02e7 505 addr.sin_addr.s_addr = INADDR_ANY;
ashleymills 0:e979170e02e7 506 else
ashleymills 0:e979170e02e7 507 addr.sin_addr.s_addr = inet_addr(host);
ashleymills 0:e979170e02e7 508
ashleymills 0:e979170e02e7 509 if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) {
ashleymills 0:e979170e02e7 510 CYASSL_MSG("OCSP responder tcp connect failed");
ashleymills 0:e979170e02e7 511 return -1;
ashleymills 0:e979170e02e7 512 }
ashleymills 0:e979170e02e7 513
ashleymills 0:e979170e02e7 514 return 0;
ashleymills 0:e979170e02e7 515 }
ashleymills 0:e979170e02e7 516
ashleymills 0:e979170e02e7 517
ashleymills 0:e979170e02e7 518 static int build_http_request(const char* domainName, const char* path,
ashleymills 0:e979170e02e7 519 int ocspReqSz, byte* buf, int bufSize)
ashleymills 0:e979170e02e7 520 {
ashleymills 0:e979170e02e7 521 return snprintf((char*)buf, bufSize,
ashleymills 0:e979170e02e7 522 "POST %s HTTP/1.1\r\n"
ashleymills 0:e979170e02e7 523 "Host: %s\r\n"
ashleymills 0:e979170e02e7 524 "Content-Length: %d\r\n"
ashleymills 0:e979170e02e7 525 "Content-Type: application/ocsp-request\r\n"
ashleymills 0:e979170e02e7 526 "\r\n",
ashleymills 0:e979170e02e7 527 path, domainName, ocspReqSz);
ashleymills 0:e979170e02e7 528 }
ashleymills 0:e979170e02e7 529
ashleymills 0:e979170e02e7 530
ashleymills 0:e979170e02e7 531 static int decode_http_response(byte* httpBuf, int httpBufSz, byte** dst)
ashleymills 0:e979170e02e7 532 {
ashleymills 0:e979170e02e7 533 int idx = 0;
ashleymills 0:e979170e02e7 534 int stop = 0;
ashleymills 0:e979170e02e7 535 int len = 0;
ashleymills 0:e979170e02e7 536 byte* contentType = NULL;
ashleymills 0:e979170e02e7 537 byte* contentLength = NULL;
ashleymills 0:e979170e02e7 538 char* buf = (char*)httpBuf; /* kludge so I'm not constantly casting */
ashleymills 0:e979170e02e7 539
ashleymills 0:e979170e02e7 540 if (XSTRNCASECMP(buf, "HTTP/1", 6) != 0)
ashleymills 0:e979170e02e7 541 return 0;
ashleymills 0:e979170e02e7 542
ashleymills 0:e979170e02e7 543 idx = 9; /* sets to the first byte after "HTTP/1.X ", which should be the
ashleymills 0:e979170e02e7 544 * HTTP result code */
ashleymills 0:e979170e02e7 545
ashleymills 0:e979170e02e7 546 if (XSTRNCASECMP(&buf[idx], "200 OK", 6) != 0)
ashleymills 0:e979170e02e7 547 return 0;
ashleymills 0:e979170e02e7 548
ashleymills 0:e979170e02e7 549 idx += 8;
ashleymills 0:e979170e02e7 550
ashleymills 0:e979170e02e7 551 while (idx < httpBufSz && !stop) {
ashleymills 0:e979170e02e7 552 if (buf[idx] == '\r' && buf[idx+1] == '\n') {
ashleymills 0:e979170e02e7 553 stop = 1;
ashleymills 0:e979170e02e7 554 idx += 2;
ashleymills 0:e979170e02e7 555 }
ashleymills 0:e979170e02e7 556 else {
ashleymills 0:e979170e02e7 557 if (contentType == NULL &&
ashleymills 0:e979170e02e7 558 XSTRNCASECMP(&buf[idx], "Content-Type:", 13) == 0) {
ashleymills 0:e979170e02e7 559 idx += 13;
ashleymills 0:e979170e02e7 560 if (buf[idx] == ' ') idx++;
ashleymills 0:e979170e02e7 561 if (XSTRNCASECMP(&buf[idx],
ashleymills 0:e979170e02e7 562 "application/ocsp-response", 25) != 0) {
ashleymills 0:e979170e02e7 563 return 0;
ashleymills 0:e979170e02e7 564 }
ashleymills 0:e979170e02e7 565 idx += 27;
ashleymills 0:e979170e02e7 566 }
ashleymills 0:e979170e02e7 567 else if (contentLength == NULL &&
ashleymills 0:e979170e02e7 568 XSTRNCASECMP(&buf[idx], "Content-Length:", 15) == 0) {
ashleymills 0:e979170e02e7 569 idx += 15;
ashleymills 0:e979170e02e7 570 if (buf[idx] == ' ') idx++;
ashleymills 0:e979170e02e7 571 while (buf[idx] >= '0' && buf[idx] <= '9' && idx < httpBufSz) {
ashleymills 0:e979170e02e7 572 len = (len * 10) + (buf[idx] - '0');
ashleymills 0:e979170e02e7 573 idx++;
ashleymills 0:e979170e02e7 574 }
ashleymills 0:e979170e02e7 575 idx += 2; /* skip the crlf */
ashleymills 0:e979170e02e7 576 }
ashleymills 0:e979170e02e7 577 else {
ashleymills 0:e979170e02e7 578 /* Advance idx past the next \r\n */
ashleymills 0:e979170e02e7 579 char* end = XSTRSTR(&buf[idx], "\r\n");
ashleymills 0:e979170e02e7 580 idx = (int)(end - buf + 2);
ashleymills 0:e979170e02e7 581 stop = 1;
ashleymills 0:e979170e02e7 582 }
ashleymills 0:e979170e02e7 583 }
ashleymills 0:e979170e02e7 584 }
ashleymills 0:e979170e02e7 585
ashleymills 0:e979170e02e7 586 if (len > 0) {
ashleymills 0:e979170e02e7 587 *dst = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 588 XMEMCPY(*dst, httpBuf + idx, len);
ashleymills 0:e979170e02e7 589 }
ashleymills 0:e979170e02e7 590
ashleymills 0:e979170e02e7 591 return len;
ashleymills 0:e979170e02e7 592 }
ashleymills 0:e979170e02e7 593
ashleymills 0:e979170e02e7 594
ashleymills 0:e979170e02e7 595 static int decode_url(const char* url, int urlSz,
ashleymills 0:e979170e02e7 596 char* outName, char* outPath, int* outPort)
ashleymills 0:e979170e02e7 597 {
ashleymills 0:e979170e02e7 598 if (outName != NULL && outPath != NULL && outPort != NULL)
ashleymills 0:e979170e02e7 599 {
ashleymills 0:e979170e02e7 600 if (url == NULL || urlSz == 0)
ashleymills 0:e979170e02e7 601 {
ashleymills 0:e979170e02e7 602 *outName = 0;
ashleymills 0:e979170e02e7 603 *outPath = 0;
ashleymills 0:e979170e02e7 604 *outPort = 0;
ashleymills 0:e979170e02e7 605 }
ashleymills 0:e979170e02e7 606 else
ashleymills 0:e979170e02e7 607 {
ashleymills 0:e979170e02e7 608 int i, cur;
ashleymills 0:e979170e02e7 609
ashleymills 0:e979170e02e7 610 /* need to break the url down into scheme, address, and port */
ashleymills 0:e979170e02e7 611 /* "http://example.com:8080/" */
ashleymills 0:e979170e02e7 612 if (XSTRNCMP(url, "http://", 7) == 0) {
ashleymills 0:e979170e02e7 613 cur = 7;
ashleymills 0:e979170e02e7 614 } else cur = 0;
ashleymills 0:e979170e02e7 615
ashleymills 0:e979170e02e7 616 i = 0;
ashleymills 0:e979170e02e7 617 while (url[cur] != 0 && url[cur] != ':' && url[cur] != '/') {
ashleymills 0:e979170e02e7 618 outName[i++] = url[cur++];
ashleymills 0:e979170e02e7 619 }
ashleymills 0:e979170e02e7 620 outName[i] = 0;
ashleymills 0:e979170e02e7 621 /* Need to pick out the path after the domain name */
ashleymills 0:e979170e02e7 622
ashleymills 0:e979170e02e7 623 if (cur < urlSz && url[cur] == ':') {
ashleymills 0:e979170e02e7 624 char port[6];
ashleymills 0:e979170e02e7 625 int j;
ashleymills 0:e979170e02e7 626 i = 0;
ashleymills 0:e979170e02e7 627 cur++;
ashleymills 0:e979170e02e7 628 while (cur < urlSz && url[cur] != 0 && url[cur] != '/' &&
ashleymills 0:e979170e02e7 629 i < 6) {
ashleymills 0:e979170e02e7 630 port[i++] = url[cur++];
ashleymills 0:e979170e02e7 631 }
ashleymills 0:e979170e02e7 632
ashleymills 0:e979170e02e7 633 *outPort = 0;
ashleymills 0:e979170e02e7 634 for (j = 0; j < i; j++) {
ashleymills 0:e979170e02e7 635 if (port[j] < '0' || port[j] > '9') return -1;
ashleymills 0:e979170e02e7 636 *outPort = (*outPort * 10) + (port[j] - '0');
ashleymills 0:e979170e02e7 637 }
ashleymills 0:e979170e02e7 638 }
ashleymills 0:e979170e02e7 639 else
ashleymills 0:e979170e02e7 640 *outPort = 80;
ashleymills 0:e979170e02e7 641
ashleymills 0:e979170e02e7 642 if (cur < urlSz && url[cur] == '/') {
ashleymills 0:e979170e02e7 643 i = 0;
ashleymills 0:e979170e02e7 644 while (cur < urlSz && url[cur] != 0 && i < 80) {
ashleymills 0:e979170e02e7 645 outPath[i++] = url[cur++];
ashleymills 0:e979170e02e7 646 }
ashleymills 0:e979170e02e7 647 outPath[i] = 0;
ashleymills 0:e979170e02e7 648 }
ashleymills 0:e979170e02e7 649 else {
ashleymills 0:e979170e02e7 650 outPath[0] = '/';
ashleymills 0:e979170e02e7 651 outPath[1] = 0;
ashleymills 0:e979170e02e7 652 }
ashleymills 0:e979170e02e7 653 }
ashleymills 0:e979170e02e7 654 }
ashleymills 0:e979170e02e7 655
ashleymills 0:e979170e02e7 656 return 0;
ashleymills 0:e979170e02e7 657 }
ashleymills 0:e979170e02e7 658
ashleymills 0:e979170e02e7 659
ashleymills 0:e979170e02e7 660 #define SCRATCH_BUFFER_SIZE 2048
ashleymills 0:e979170e02e7 661
ashleymills 0:e979170e02e7 662 int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
ashleymills 0:e979170e02e7 663 byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
ashleymills 0:e979170e02e7 664 {
ashleymills 0:e979170e02e7 665 char domainName[80], path[80];
ashleymills 0:e979170e02e7 666 int port, httpBufSz, sfd;
ashleymills 0:e979170e02e7 667 int ocspRespSz = 0;
ashleymills 0:e979170e02e7 668 byte* httpBuf = NULL;
ashleymills 0:e979170e02e7 669
ashleymills 0:e979170e02e7 670 (void)ctx;
ashleymills 0:e979170e02e7 671
ashleymills 0:e979170e02e7 672 if (ocspReqBuf == NULL || ocspReqSz == 0) {
ashleymills 0:e979170e02e7 673 CYASSL_MSG("OCSP request is required for lookup");
ashleymills 0:e979170e02e7 674 return -1;
ashleymills 0:e979170e02e7 675 }
ashleymills 0:e979170e02e7 676
ashleymills 0:e979170e02e7 677 if (ocspRespBuf == NULL) {
ashleymills 0:e979170e02e7 678 CYASSL_MSG("Cannot save OCSP response");
ashleymills 0:e979170e02e7 679 return -1;
ashleymills 0:e979170e02e7 680 }
ashleymills 0:e979170e02e7 681
ashleymills 0:e979170e02e7 682 if (decode_url(url, urlSz, domainName, path, &port) < 0) {
ashleymills 0:e979170e02e7 683 CYASSL_MSG("Unable to decode OCSP URL");
ashleymills 0:e979170e02e7 684 return -1;
ashleymills 0:e979170e02e7 685 }
ashleymills 0:e979170e02e7 686
ashleymills 0:e979170e02e7 687 httpBufSz = SCRATCH_BUFFER_SIZE;
ashleymills 0:e979170e02e7 688 httpBuf = (byte*)XMALLOC(httpBufSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 689
ashleymills 0:e979170e02e7 690 if (httpBuf == NULL) {
ashleymills 0:e979170e02e7 691 CYASSL_MSG("Unable to create OCSP response buffer");
ashleymills 0:e979170e02e7 692 return -1;
ashleymills 0:e979170e02e7 693 }
ashleymills 0:e979170e02e7 694 *ocspRespBuf = httpBuf;
ashleymills 0:e979170e02e7 695
ashleymills 0:e979170e02e7 696 httpBufSz = build_http_request(domainName, path, ocspReqSz,
ashleymills 0:e979170e02e7 697 httpBuf, httpBufSz);
ashleymills 0:e979170e02e7 698
ashleymills 0:e979170e02e7 699 if ((tcp_connect(&sfd, domainName, port) == 0) && (sfd > 0)) {
ashleymills 0:e979170e02e7 700 int written;
ashleymills 0:e979170e02e7 701 written = (int)write(sfd, httpBuf, httpBufSz);
ashleymills 0:e979170e02e7 702 if (written == httpBufSz) {
ashleymills 0:e979170e02e7 703 written = (int)write(sfd, ocspReqBuf, ocspReqSz);
ashleymills 0:e979170e02e7 704 if (written == ocspReqSz) {
ashleymills 0:e979170e02e7 705 httpBufSz = (int)read(sfd, httpBuf, SCRATCH_BUFFER_SIZE);
ashleymills 0:e979170e02e7 706 if (httpBufSz > 0) {
ashleymills 0:e979170e02e7 707 ocspRespSz = decode_http_response(httpBuf, httpBufSz,
ashleymills 0:e979170e02e7 708 ocspRespBuf);
ashleymills 0:e979170e02e7 709 }
ashleymills 0:e979170e02e7 710 }
ashleymills 0:e979170e02e7 711 }
ashleymills 0:e979170e02e7 712 close(sfd);
ashleymills 0:e979170e02e7 713 if (ocspRespSz == 0) {
ashleymills 0:e979170e02e7 714 CYASSL_MSG("OCSP response was not OK, no OCSP response");
ashleymills 0:e979170e02e7 715 return -1;
ashleymills 0:e979170e02e7 716 }
ashleymills 0:e979170e02e7 717 } else {
ashleymills 0:e979170e02e7 718 CYASSL_MSG("OCSP Responder connection failed");
ashleymills 0:e979170e02e7 719 return -1;
ashleymills 0:e979170e02e7 720 }
ashleymills 0:e979170e02e7 721
ashleymills 0:e979170e02e7 722 return ocspRespSz;
ashleymills 0:e979170e02e7 723 }
ashleymills 0:e979170e02e7 724
ashleymills 0:e979170e02e7 725
ashleymills 0:e979170e02e7 726 void EmbedOcspRespFree(void* ctx, byte *resp)
ashleymills 0:e979170e02e7 727 {
ashleymills 0:e979170e02e7 728 (void)ctx;
ashleymills 0:e979170e02e7 729
ashleymills 0:e979170e02e7 730 if (resp)
ashleymills 0:e979170e02e7 731 XFREE(resp, NULL, DYNAMIC_TYPE_IN_BUFFER);
ashleymills 0:e979170e02e7 732 }
ashleymills 0:e979170e02e7 733
ashleymills 0:e979170e02e7 734
ashleymills 0:e979170e02e7 735 #endif
ashleymills 0:e979170e02e7 736
ashleymills 0:e979170e02e7 737 #endif /* CYASSL_USER_IO */
ashleymills 0:e979170e02e7 738
ashleymills 0:e979170e02e7 739 CYASSL_API void CyaSSL_SetIORecv(CYASSL_CTX *ctx, CallbackIORecv CBIORecv)
ashleymills 0:e979170e02e7 740 {
ashleymills 0:e979170e02e7 741 ctx->CBIORecv = CBIORecv;
ashleymills 0:e979170e02e7 742 }
ashleymills 0:e979170e02e7 743
ashleymills 0:e979170e02e7 744
ashleymills 0:e979170e02e7 745 CYASSL_API void CyaSSL_SetIOSend(CYASSL_CTX *ctx, CallbackIOSend CBIOSend)
ashleymills 0:e979170e02e7 746 {
ashleymills 0:e979170e02e7 747 ctx->CBIOSend = CBIOSend;
ashleymills 0:e979170e02e7 748 }
ashleymills 0:e979170e02e7 749
ashleymills 0:e979170e02e7 750
ashleymills 0:e979170e02e7 751 CYASSL_API void CyaSSL_SetIOReadCtx(CYASSL* ssl, void *rctx)
ashleymills 0:e979170e02e7 752 {
ashleymills 0:e979170e02e7 753 ssl->IOCB_ReadCtx = rctx;
ashleymills 0:e979170e02e7 754 }
ashleymills 0:e979170e02e7 755
ashleymills 0:e979170e02e7 756
ashleymills 0:e979170e02e7 757 CYASSL_API void CyaSSL_SetIOWriteCtx(CYASSL* ssl, void *wctx)
ashleymills 0:e979170e02e7 758 {
ashleymills 0:e979170e02e7 759 ssl->IOCB_WriteCtx = wctx;
ashleymills 0:e979170e02e7 760 }
ashleymills 0:e979170e02e7 761
ashleymills 0:e979170e02e7 762
ashleymills 0:e979170e02e7 763 CYASSL_API void CyaSSL_SetIOReadFlags(CYASSL* ssl, int flags)
ashleymills 0:e979170e02e7 764 {
ashleymills 0:e979170e02e7 765 ssl->rflags = flags;
ashleymills 0:e979170e02e7 766 }
ashleymills 0:e979170e02e7 767
ashleymills 0:e979170e02e7 768
ashleymills 0:e979170e02e7 769 CYASSL_API void CyaSSL_SetIOWriteFlags(CYASSL* ssl, int flags)
ashleymills 0:e979170e02e7 770 {
ashleymills 0:e979170e02e7 771 ssl->wflags = flags;
ashleymills 0:e979170e02e7 772 }
ashleymills 0:e979170e02e7 773
ashleymills 0:e979170e02e7 774 #ifdef HAVE_OCSP
ashleymills 0:e979170e02e7 775
ashleymills 0:e979170e02e7 776 CYASSL_API void CyaSSL_SetIOOcsp(CYASSL_CTX* ctx, CallbackIOOcsp cb)
ashleymills 0:e979170e02e7 777 {
ashleymills 0:e979170e02e7 778 ctx->ocsp.CBIOOcsp = cb;
ashleymills 0:e979170e02e7 779 }
ashleymills 0:e979170e02e7 780
ashleymills 0:e979170e02e7 781 CYASSL_API void CyaSSL_SetIOOcspRespFree(CYASSL_CTX* ctx,
ashleymills 0:e979170e02e7 782 CallbackIOOcspRespFree cb)
ashleymills 0:e979170e02e7 783 {
ashleymills 0:e979170e02e7 784 ctx->ocsp.CBIOOcspRespFree = cb;
ashleymills 0:e979170e02e7 785 }
ashleymills 0:e979170e02e7 786
ashleymills 0:e979170e02e7 787 CYASSL_API void CyaSSL_SetIOOcspCtx(CYASSL_CTX* ctx, void *octx)
ashleymills 0:e979170e02e7 788 {
ashleymills 0:e979170e02e7 789 ctx->ocsp.IOCB_OcspCtx = octx;
ashleymills 0:e979170e02e7 790 }
ashleymills 0:e979170e02e7 791
ashleymills 0:e979170e02e7 792 #endif