wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Tue May 02 08:44:47 2017 +0000
Revision:
7:481bce714567
wolfSSL3.10.2

Who changed what in which revision?

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