fork of cyassl-lib

Dependents:   TLS_cyassl TLS_cyassl

Committer:
feb11
Date:
Mon Sep 16 09:53:35 2013 +0000
Revision:
4:f377303c41be
Parent:
1:c0ce1562443a
changed settings

Who changed what in which revision?

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