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

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

Committer:
wolfSSL
Date:
Fri Jun 05 00:11:07 2020 +0000
Revision:
17:a5f916481144
Parent:
16:8e0d178b1d1e
wolfSSL 4.4.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 16:8e0d178b1d1e 1 /* bio.c
wolfSSL 16:8e0d178b1d1e 2 *
wolfSSL 16:8e0d178b1d1e 3 * Copyright (C) 2006-2020 wolfSSL Inc.
wolfSSL 16:8e0d178b1d1e 4 *
wolfSSL 16:8e0d178b1d1e 5 * This file is part of wolfSSL.
wolfSSL 16:8e0d178b1d1e 6 *
wolfSSL 16:8e0d178b1d1e 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 16:8e0d178b1d1e 8 * it under the terms of the GNU General Public License as published by
wolfSSL 16:8e0d178b1d1e 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 16:8e0d178b1d1e 10 * (at your option) any later version.
wolfSSL 16:8e0d178b1d1e 11 *
wolfSSL 16:8e0d178b1d1e 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 16:8e0d178b1d1e 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 16:8e0d178b1d1e 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 16:8e0d178b1d1e 15 * GNU General Public License for more details.
wolfSSL 16:8e0d178b1d1e 16 *
wolfSSL 16:8e0d178b1d1e 17 * You should have received a copy of the GNU General Public License
wolfSSL 16:8e0d178b1d1e 18 * along with this program; if not, write to the Free Software
wolfSSL 16:8e0d178b1d1e 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 16:8e0d178b1d1e 20 */
wolfSSL 16:8e0d178b1d1e 21
wolfSSL 16:8e0d178b1d1e 22 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 16:8e0d178b1d1e 23
wolfSSL 16:8e0d178b1d1e 24 #if !defined(WOLFSSL_BIO_INCLUDED)
wolfSSL 16:8e0d178b1d1e 25 #ifndef WOLFSSL_IGNORE_FILE_WARN
wolfSSL 16:8e0d178b1d1e 26 #warning bio.c does not need to be compiled separately from ssl.c
wolfSSL 16:8e0d178b1d1e 27 #endif
wolfSSL 16:8e0d178b1d1e 28 #else
wolfSSL 16:8e0d178b1d1e 29
wolfSSL 16:8e0d178b1d1e 30
wolfSSL 16:8e0d178b1d1e 31 /* Helper function to decode a base64 input
wolfSSL 16:8e0d178b1d1e 32 *
wolfSSL 16:8e0d178b1d1e 33 * returns size of resulting buffer on success
wolfSSL 16:8e0d178b1d1e 34 */
wolfSSL 16:8e0d178b1d1e 35 static int wolfSSL_BIO_BASE64_read(WOLFSSL_BIO* bio, void* buf, int len)
wolfSSL 16:8e0d178b1d1e 36 {
wolfSSL 16:8e0d178b1d1e 37 word32 frmtSz = len;
wolfSSL 16:8e0d178b1d1e 38
wolfSSL 16:8e0d178b1d1e 39 WOLFSSL_ENTER("wolfSSL_BIO_BASE64_read");
wolfSSL 16:8e0d178b1d1e 40
wolfSSL 16:8e0d178b1d1e 41 if (Base64_Decode((const byte*)buf, (word32)len, (byte*)buf, &frmtSz) !=0) {
wolfSSL 16:8e0d178b1d1e 42 WOLFSSL_MSG("Err doing base64 decode");
wolfSSL 16:8e0d178b1d1e 43 return SSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 44 }
wolfSSL 16:8e0d178b1d1e 45
wolfSSL 16:8e0d178b1d1e 46 (void)bio;
wolfSSL 16:8e0d178b1d1e 47 return (int)frmtSz;
wolfSSL 16:8e0d178b1d1e 48 }
wolfSSL 16:8e0d178b1d1e 49
wolfSSL 16:8e0d178b1d1e 50
wolfSSL 16:8e0d178b1d1e 51 /* Helper function to read from WOLFSSL_BIO_BIO type
wolfSSL 16:8e0d178b1d1e 52 *
wolfSSL 16:8e0d178b1d1e 53 * returns amount in bytes read on success
wolfSSL 16:8e0d178b1d1e 54 */
wolfSSL 16:8e0d178b1d1e 55 static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
wolfSSL 16:8e0d178b1d1e 56 {
wolfSSL 16:8e0d178b1d1e 57 int sz;
wolfSSL 16:8e0d178b1d1e 58 char* pt;
wolfSSL 16:8e0d178b1d1e 59
wolfSSL 16:8e0d178b1d1e 60 sz = wolfSSL_BIO_nread(bio, &pt, len);
wolfSSL 16:8e0d178b1d1e 61
wolfSSL 16:8e0d178b1d1e 62 if (sz > 0) {
wolfSSL 16:8e0d178b1d1e 63 XMEMCPY(buf, pt, sz);
wolfSSL 16:8e0d178b1d1e 64 }
wolfSSL 16:8e0d178b1d1e 65
wolfSSL 16:8e0d178b1d1e 66 return sz;
wolfSSL 16:8e0d178b1d1e 67 }
wolfSSL 16:8e0d178b1d1e 68
wolfSSL 16:8e0d178b1d1e 69
wolfSSL 16:8e0d178b1d1e 70 /* Handles reading from a memory type BIO and advancing the state.
wolfSSL 16:8e0d178b1d1e 71 *
wolfSSL 16:8e0d178b1d1e 72 * bio WOLFSSL_BIO to read from
wolfSSL 16:8e0d178b1d1e 73 * buf buffer to put data from bio in
wolfSSL 16:8e0d178b1d1e 74 * len amount of data to be read
wolfSSL 16:8e0d178b1d1e 75 *
wolfSSL 16:8e0d178b1d1e 76 * returns size read on success
wolfSSL 16:8e0d178b1d1e 77 */
wolfSSL 16:8e0d178b1d1e 78 static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len)
wolfSSL 16:8e0d178b1d1e 79 {
wolfSSL 16:8e0d178b1d1e 80 int sz;
wolfSSL 16:8e0d178b1d1e 81 WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_read");
wolfSSL 16:8e0d178b1d1e 82
wolfSSL 16:8e0d178b1d1e 83 sz = wolfSSL_BIO_pending(bio);
wolfSSL 16:8e0d178b1d1e 84 if (sz > 0) {
wolfSSL 16:8e0d178b1d1e 85 const unsigned char* pt = NULL;
wolfSSL 16:8e0d178b1d1e 86 int memSz;
wolfSSL 16:8e0d178b1d1e 87
wolfSSL 16:8e0d178b1d1e 88 if (sz > len) {
wolfSSL 16:8e0d178b1d1e 89 sz = len;
wolfSSL 16:8e0d178b1d1e 90 }
wolfSSL 16:8e0d178b1d1e 91 memSz = wolfSSL_BIO_get_mem_data(bio, (void*)&pt);
wolfSSL 16:8e0d178b1d1e 92 if (memSz >= sz && pt != NULL) {
wolfSSL 16:8e0d178b1d1e 93 byte* tmp;
wolfSSL 16:8e0d178b1d1e 94
wolfSSL 16:8e0d178b1d1e 95 XMEMCPY(buf, (void*)pt, sz);
wolfSSL 16:8e0d178b1d1e 96 if (memSz - sz > 0) {
wolfSSL 16:8e0d178b1d1e 97 tmp = (byte*)XMALLOC(memSz-sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 98 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 99 WOLFSSL_MSG("Memory error");
wolfSSL 16:8e0d178b1d1e 100 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 101 }
wolfSSL 16:8e0d178b1d1e 102 XMEMCPY(tmp, (void*)(pt + sz), memSz - sz);
wolfSSL 16:8e0d178b1d1e 103
wolfSSL 16:8e0d178b1d1e 104 /* reset internal bio->mem */
wolfSSL 16:8e0d178b1d1e 105 XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 106 bio->ptr = tmp;
wolfSSL 16:8e0d178b1d1e 107 bio->num = memSz-sz;
wolfSSL 16:8e0d178b1d1e 108 if (bio->mem_buf != NULL) {
wolfSSL 16:8e0d178b1d1e 109 bio->mem_buf->data = (char*)bio->ptr;
wolfSSL 16:8e0d178b1d1e 110 bio->mem_buf->length = bio->num;
wolfSSL 16:8e0d178b1d1e 111 }
wolfSSL 16:8e0d178b1d1e 112 }
wolfSSL 16:8e0d178b1d1e 113 bio->wrSz -= sz;
wolfSSL 16:8e0d178b1d1e 114 }
wolfSSL 16:8e0d178b1d1e 115 else {
wolfSSL 16:8e0d178b1d1e 116 WOLFSSL_MSG("Issue with getting bio mem pointer");
wolfSSL 16:8e0d178b1d1e 117 return 0;
wolfSSL 16:8e0d178b1d1e 118 }
wolfSSL 16:8e0d178b1d1e 119 }
wolfSSL 16:8e0d178b1d1e 120 else {
wolfSSL 16:8e0d178b1d1e 121 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 122 }
wolfSSL 16:8e0d178b1d1e 123
wolfSSL 16:8e0d178b1d1e 124 return sz;
wolfSSL 16:8e0d178b1d1e 125 }
wolfSSL 16:8e0d178b1d1e 126
wolfSSL 16:8e0d178b1d1e 127 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 128 /* Helper function to read from WOLFSSL_BIO_SSL type
wolfSSL 16:8e0d178b1d1e 129 *
wolfSSL 16:8e0d178b1d1e 130 * returns the number of bytes read on success
wolfSSL 16:8e0d178b1d1e 131 */
wolfSSL 16:8e0d178b1d1e 132 static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf,
wolfSSL 16:8e0d178b1d1e 133 int len, WOLFSSL_BIO* front)
wolfSSL 16:8e0d178b1d1e 134 {
wolfSSL 16:8e0d178b1d1e 135 int ret;
wolfSSL 16:8e0d178b1d1e 136
wolfSSL 16:8e0d178b1d1e 137 WOLFSSL_ENTER("wolfSSL_BIO_SSL_read");
wolfSSL 16:8e0d178b1d1e 138
wolfSSL 16:8e0d178b1d1e 139 /* already got eof, again is error */
wolfSSL 16:8e0d178b1d1e 140 if ((front == NULL) || front->eof)
wolfSSL 16:8e0d178b1d1e 141 return WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 142
wolfSSL 16:8e0d178b1d1e 143 bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */
wolfSSL 16:8e0d178b1d1e 144 ret = wolfSSL_read((WOLFSSL*)bio->ptr, buf, len);
wolfSSL 16:8e0d178b1d1e 145 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 146 front->eof = 1;
wolfSSL 16:8e0d178b1d1e 147 else if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 148 int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
wolfSSL 16:8e0d178b1d1e 149 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) {
wolfSSL 16:8e0d178b1d1e 150 front->eof = 1;
wolfSSL 16:8e0d178b1d1e 151 }
wolfSSL 16:8e0d178b1d1e 152 else {
wolfSSL 16:8e0d178b1d1e 153 bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */
wolfSSL 16:8e0d178b1d1e 154 }
wolfSSL 16:8e0d178b1d1e 155 }
wolfSSL 16:8e0d178b1d1e 156
wolfSSL 16:8e0d178b1d1e 157 return ret;
wolfSSL 16:8e0d178b1d1e 158 }
wolfSSL 16:8e0d178b1d1e 159
wolfSSL 16:8e0d178b1d1e 160 static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz)
wolfSSL 16:8e0d178b1d1e 161 {
wolfSSL 16:8e0d178b1d1e 162 int ret = sz;
wolfSSL 16:8e0d178b1d1e 163
wolfSSL 16:8e0d178b1d1e 164 if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == NID_hmac) {
wolfSSL 16:8e0d178b1d1e 165 if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf,
wolfSSL 16:8e0d178b1d1e 166 sz) != WOLFSSL_SUCCESS)
wolfSSL 16:8e0d178b1d1e 167 {
wolfSSL 16:8e0d178b1d1e 168 ret = WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 169 }
wolfSSL 16:8e0d178b1d1e 170 }
wolfSSL 16:8e0d178b1d1e 171 else {
wolfSSL 16:8e0d178b1d1e 172 if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf, ret)
wolfSSL 16:8e0d178b1d1e 173 != WOLFSSL_SUCCESS) {
wolfSSL 16:8e0d178b1d1e 174 ret = WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 175 }
wolfSSL 16:8e0d178b1d1e 176 }
wolfSSL 16:8e0d178b1d1e 177 return ret;
wolfSSL 16:8e0d178b1d1e 178 }
wolfSSL 16:8e0d178b1d1e 179 #endif /* WOLFCRYPT_ONLY */
wolfSSL 16:8e0d178b1d1e 180
wolfSSL 16:8e0d178b1d1e 181
wolfSSL 16:8e0d178b1d1e 182 /* Used to read data from a WOLFSSL_BIO structure
wolfSSL 16:8e0d178b1d1e 183 *
wolfSSL 16:8e0d178b1d1e 184 * bio structure to read data from
wolfSSL 16:8e0d178b1d1e 185 * buf buffer to hold the result
wolfSSL 16:8e0d178b1d1e 186 * len length of buf buffer
wolfSSL 16:8e0d178b1d1e 187 *
wolfSSL 16:8e0d178b1d1e 188 * returns the number of bytes read on success
wolfSSL 16:8e0d178b1d1e 189 */
wolfSSL 16:8e0d178b1d1e 190 int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
wolfSSL 16:8e0d178b1d1e 191 {
wolfSSL 16:8e0d178b1d1e 192 int ret = 0;
wolfSSL 16:8e0d178b1d1e 193 WOLFSSL_BIO* front = bio;
wolfSSL 16:8e0d178b1d1e 194 int sz = 0;
wolfSSL 16:8e0d178b1d1e 195
wolfSSL 16:8e0d178b1d1e 196 WOLFSSL_ENTER("wolfSSL_BIO_read");
wolfSSL 16:8e0d178b1d1e 197
wolfSSL 16:8e0d178b1d1e 198 /* info cb, abort if user returns <= 0*/
wolfSSL 16:8e0d178b1d1e 199 if (front != NULL && front->infoCb != NULL) {
wolfSSL 16:8e0d178b1d1e 200 ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_READ, (const char*)buf,
wolfSSL 16:8e0d178b1d1e 201 len, 0, 1);
wolfSSL 16:8e0d178b1d1e 202 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 203 return ret;
wolfSSL 16:8e0d178b1d1e 204 }
wolfSSL 16:8e0d178b1d1e 205 }
wolfSSL 16:8e0d178b1d1e 206
wolfSSL 16:8e0d178b1d1e 207 /* start at end of list and work backwards */
wolfSSL 16:8e0d178b1d1e 208 while ((bio != NULL) && (bio->next != NULL)) {
wolfSSL 16:8e0d178b1d1e 209 bio = bio->next;
wolfSSL 16:8e0d178b1d1e 210 }
wolfSSL 16:8e0d178b1d1e 211
wolfSSL 16:8e0d178b1d1e 212 while (bio != NULL && ret >= 0) {
wolfSSL 16:8e0d178b1d1e 213 /* check for custom read */
wolfSSL 16:8e0d178b1d1e 214 if (bio->method && bio->method->readCb) {
wolfSSL 16:8e0d178b1d1e 215 ret = bio->method->readCb(bio, (char*)buf, len);
wolfSSL 16:8e0d178b1d1e 216 }
wolfSSL 16:8e0d178b1d1e 217
wolfSSL 16:8e0d178b1d1e 218 /* formatting data */
wolfSSL 16:8e0d178b1d1e 219 if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0 && sz > 0) {
wolfSSL 16:8e0d178b1d1e 220 ret = wolfSSL_BIO_BASE64_read(bio, buf, sz);
wolfSSL 16:8e0d178b1d1e 221 }
wolfSSL 16:8e0d178b1d1e 222
wolfSSL 16:8e0d178b1d1e 223 /* write BIOs */
wolfSSL 16:8e0d178b1d1e 224 if (bio && bio->type == WOLFSSL_BIO_BIO) {
wolfSSL 16:8e0d178b1d1e 225 ret = wolfSSL_BIO_BIO_read(bio, buf, len);
wolfSSL 16:8e0d178b1d1e 226 }
wolfSSL 16:8e0d178b1d1e 227
wolfSSL 16:8e0d178b1d1e 228 if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
wolfSSL 16:8e0d178b1d1e 229 ret = wolfSSL_BIO_MEMORY_read(bio, buf, len);
wolfSSL 16:8e0d178b1d1e 230 }
wolfSSL 16:8e0d178b1d1e 231
wolfSSL 16:8e0d178b1d1e 232 #ifndef NO_FILESYSTEM
wolfSSL 16:8e0d178b1d1e 233 if (bio && bio->type == WOLFSSL_BIO_FILE) {
wolfSSL 16:8e0d178b1d1e 234 ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr);
wolfSSL 16:8e0d178b1d1e 235 }
wolfSSL 16:8e0d178b1d1e 236 #endif
wolfSSL 16:8e0d178b1d1e 237
wolfSSL 16:8e0d178b1d1e 238 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 239 if (bio && bio->type == WOLFSSL_BIO_SSL) {
wolfSSL 16:8e0d178b1d1e 240 ret = wolfSSL_BIO_SSL_read(bio, buf, len, front);
wolfSSL 16:8e0d178b1d1e 241 }
wolfSSL 16:8e0d178b1d1e 242
wolfSSL 16:8e0d178b1d1e 243 /* data passing through BIO MD wrapper */
wolfSSL 16:8e0d178b1d1e 244 if (bio && bio->type == WOLFSSL_BIO_MD && ret > 0) {
wolfSSL 16:8e0d178b1d1e 245 ret = wolfSSL_BIO_MD_read(bio, buf, ret);
wolfSSL 16:8e0d178b1d1e 246 }
wolfSSL 16:8e0d178b1d1e 247 #endif
wolfSSL 16:8e0d178b1d1e 248
wolfSSL 16:8e0d178b1d1e 249 /* case where front of list is done */
wolfSSL 16:8e0d178b1d1e 250 if (bio == front) {
wolfSSL 16:8e0d178b1d1e 251 break; /* at front of list so be done */
wolfSSL 16:8e0d178b1d1e 252 }
wolfSSL 16:8e0d178b1d1e 253
wolfSSL 16:8e0d178b1d1e 254 if (ret > 0) {
wolfSSL 16:8e0d178b1d1e 255 sz = ret; /* adjust size for formatting */
wolfSSL 16:8e0d178b1d1e 256 }
wolfSSL 16:8e0d178b1d1e 257
wolfSSL 16:8e0d178b1d1e 258 /* previous WOLFSSL_BIO in list working towards head of list */
wolfSSL 16:8e0d178b1d1e 259 bio = bio->prev;
wolfSSL 16:8e0d178b1d1e 260 }
wolfSSL 16:8e0d178b1d1e 261
wolfSSL 16:8e0d178b1d1e 262 /* info cb, user can override return value */
wolfSSL 16:8e0d178b1d1e 263 if (front != NULL && front->infoCb != NULL) {
wolfSSL 16:8e0d178b1d1e 264 ret = (int)front->infoCb(front,
wolfSSL 16:8e0d178b1d1e 265 WOLFSSL_BIO_CB_READ | WOLFSSL_BIO_CB_RETURN,
wolfSSL 16:8e0d178b1d1e 266 (const char*)buf, len, 0, ret);
wolfSSL 16:8e0d178b1d1e 267 }
wolfSSL 16:8e0d178b1d1e 268
wolfSSL 16:8e0d178b1d1e 269 return ret;
wolfSSL 16:8e0d178b1d1e 270 }
wolfSSL 16:8e0d178b1d1e 271
wolfSSL 16:8e0d178b1d1e 272
wolfSSL 16:8e0d178b1d1e 273 /* Converts data into base64 output
wolfSSL 16:8e0d178b1d1e 274 *
wolfSSL 16:8e0d178b1d1e 275 * returns the resulting buffer size on success.
wolfSSL 16:8e0d178b1d1e 276 */
wolfSSL 16:8e0d178b1d1e 277 static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
wolfSSL 16:8e0d178b1d1e 278 word32 inLen, byte* out, word32* outLen)
wolfSSL 16:8e0d178b1d1e 279 {
wolfSSL 16:8e0d178b1d1e 280 byte* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 281 int ret = 0;
wolfSSL 16:8e0d178b1d1e 282
wolfSSL 16:8e0d178b1d1e 283 WOLFSSL_ENTER("wolfSSL_BIO_BASE64_write");
wolfSSL 16:8e0d178b1d1e 284
wolfSSL 16:8e0d178b1d1e 285 if (bio == NULL || data == NULL || out == NULL || outLen == NULL) {
wolfSSL 16:8e0d178b1d1e 286 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 287 }
wolfSSL 16:8e0d178b1d1e 288
wolfSSL 16:8e0d178b1d1e 289 #if defined(WOLFSSL_BASE64_ENCODE)
wolfSSL 16:8e0d178b1d1e 290 tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 291 if (tmp == NULL) {
wolfSSL 16:8e0d178b1d1e 292 return WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 293 }
wolfSSL 16:8e0d178b1d1e 294
wolfSSL 16:8e0d178b1d1e 295 if ((bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) ==
wolfSSL 16:8e0d178b1d1e 296 WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
wolfSSL 16:8e0d178b1d1e 297 if (Base64_Encode_NoNl((const byte*)data, inLen,
wolfSSL 16:8e0d178b1d1e 298 tmp, outLen) < 0) {
wolfSSL 16:8e0d178b1d1e 299 ret = WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 300 }
wolfSSL 16:8e0d178b1d1e 301 }
wolfSSL 16:8e0d178b1d1e 302 else {
wolfSSL 16:8e0d178b1d1e 303 if (Base64_Encode((const byte*)data, inLen,
wolfSSL 16:8e0d178b1d1e 304 tmp, outLen) < 0) {
wolfSSL 16:8e0d178b1d1e 305 ret = WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 306 }
wolfSSL 16:8e0d178b1d1e 307 }
wolfSSL 16:8e0d178b1d1e 308
wolfSSL 16:8e0d178b1d1e 309 if (ret != WOLFSSL_FATAL_ERROR) {
wolfSSL 16:8e0d178b1d1e 310 ret = (int) inLen;
wolfSSL 16:8e0d178b1d1e 311 XMEMCPY(out, tmp, *outLen);
wolfSSL 16:8e0d178b1d1e 312
wolfSSL 16:8e0d178b1d1e 313 }
wolfSSL 16:8e0d178b1d1e 314 XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 315 #else
wolfSSL 16:8e0d178b1d1e 316 (void)bio;
wolfSSL 16:8e0d178b1d1e 317 (void)data;
wolfSSL 16:8e0d178b1d1e 318 (void)inLen;
wolfSSL 16:8e0d178b1d1e 319 (void)out;
wolfSSL 16:8e0d178b1d1e 320 (void)outLen;
wolfSSL 16:8e0d178b1d1e 321 (void)tmp;
wolfSSL 16:8e0d178b1d1e 322 WOLFSSL_MSG("BASE64 encoding not compiled in");
wolfSSL 16:8e0d178b1d1e 323 #endif
wolfSSL 16:8e0d178b1d1e 324 return ret;
wolfSSL 16:8e0d178b1d1e 325 }
wolfSSL 16:8e0d178b1d1e 326
wolfSSL 16:8e0d178b1d1e 327
wolfSSL 16:8e0d178b1d1e 328 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 329 /* Helper function for writing to a WOLFSSL_BIO_SSL type
wolfSSL 16:8e0d178b1d1e 330 *
wolfSSL 16:8e0d178b1d1e 331 * returns the amount written in bytes on success
wolfSSL 16:8e0d178b1d1e 332 */
wolfSSL 16:8e0d178b1d1e 333 static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data,
wolfSSL 16:8e0d178b1d1e 334 int len, WOLFSSL_BIO* front)
wolfSSL 16:8e0d178b1d1e 335 {
wolfSSL 16:8e0d178b1d1e 336 int ret;
wolfSSL 16:8e0d178b1d1e 337
wolfSSL 16:8e0d178b1d1e 338 WOLFSSL_ENTER("wolfSSL_BIO_SSL_write");
wolfSSL 16:8e0d178b1d1e 339
wolfSSL 16:8e0d178b1d1e 340 if (bio->ptr == NULL) {
wolfSSL 16:8e0d178b1d1e 341 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 342 }
wolfSSL 16:8e0d178b1d1e 343
wolfSSL 16:8e0d178b1d1e 344 bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */
wolfSSL 16:8e0d178b1d1e 345 ret = wolfSSL_write((WOLFSSL*)bio->ptr, data, len);
wolfSSL 16:8e0d178b1d1e 346 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 347 front->eof = 1;
wolfSSL 16:8e0d178b1d1e 348 else if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 349 int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
wolfSSL 16:8e0d178b1d1e 350 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) {
wolfSSL 16:8e0d178b1d1e 351 front->eof = 1;
wolfSSL 16:8e0d178b1d1e 352 }
wolfSSL 16:8e0d178b1d1e 353 else {
wolfSSL 16:8e0d178b1d1e 354 bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */
wolfSSL 16:8e0d178b1d1e 355 }
wolfSSL 16:8e0d178b1d1e 356 }
wolfSSL 16:8e0d178b1d1e 357 return ret;
wolfSSL 16:8e0d178b1d1e 358 }
wolfSSL 16:8e0d178b1d1e 359 #endif /* WOLFCRYPT_ONLY */
wolfSSL 16:8e0d178b1d1e 360
wolfSSL 16:8e0d178b1d1e 361
wolfSSL 16:8e0d178b1d1e 362 /* Writes to a WOLFSSL_BIO_BIO type.
wolfSSL 16:8e0d178b1d1e 363 *
wolfSSL 16:8e0d178b1d1e 364 * returns the amount written on success
wolfSSL 16:8e0d178b1d1e 365 */
wolfSSL 16:8e0d178b1d1e 366 static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
wolfSSL 16:8e0d178b1d1e 367 int len)
wolfSSL 16:8e0d178b1d1e 368 {
wolfSSL 16:8e0d178b1d1e 369 int sz;
wolfSSL 16:8e0d178b1d1e 370 char* buf;
wolfSSL 16:8e0d178b1d1e 371
wolfSSL 16:8e0d178b1d1e 372 WOLFSSL_ENTER("wolfSSL_BIO_BIO_write");
wolfSSL 16:8e0d178b1d1e 373
wolfSSL 16:8e0d178b1d1e 374 /* adding in sanity checks for static analysis tools */
wolfSSL 16:8e0d178b1d1e 375 if (bio == NULL || data == NULL) {
wolfSSL 16:8e0d178b1d1e 376 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 377 }
wolfSSL 16:8e0d178b1d1e 378
wolfSSL 16:8e0d178b1d1e 379 sz = wolfSSL_BIO_nwrite(bio, &buf, len);
wolfSSL 16:8e0d178b1d1e 380
wolfSSL 16:8e0d178b1d1e 381 /* test space for write */
wolfSSL 16:8e0d178b1d1e 382 if (sz <= 0) {
wolfSSL 16:8e0d178b1d1e 383 WOLFSSL_MSG("No room left to write");
wolfSSL 16:8e0d178b1d1e 384 return sz;
wolfSSL 16:8e0d178b1d1e 385 }
wolfSSL 16:8e0d178b1d1e 386
wolfSSL 16:8e0d178b1d1e 387 XMEMCPY(buf, data, sz);
wolfSSL 16:8e0d178b1d1e 388
wolfSSL 16:8e0d178b1d1e 389 return sz;
wolfSSL 16:8e0d178b1d1e 390 }
wolfSSL 16:8e0d178b1d1e 391
wolfSSL 16:8e0d178b1d1e 392
wolfSSL 16:8e0d178b1d1e 393 /* for complete compatibility a bio memory write allocs its own memory
wolfSSL 16:8e0d178b1d1e 394 * until the application runs out ....
wolfSSL 16:8e0d178b1d1e 395 *
wolfSSL 16:8e0d178b1d1e 396 * bio structure to hold incoming data
wolfSSL 16:8e0d178b1d1e 397 * data buffer holding the data to be written
wolfSSL 16:8e0d178b1d1e 398 * len length of data buffer
wolfSSL 16:8e0d178b1d1e 399 *
wolfSSL 16:8e0d178b1d1e 400 * returns the amount of data written on success and WOLFSSL_FAILURE or
wolfSSL 16:8e0d178b1d1e 401 * WOLFSSL_BIO_ERROR for failure cases.
wolfSSL 16:8e0d178b1d1e 402 */
wolfSSL 16:8e0d178b1d1e 403 static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
wolfSSL 16:8e0d178b1d1e 404 int len)
wolfSSL 16:8e0d178b1d1e 405 {
wolfSSL 16:8e0d178b1d1e 406 int sz;
wolfSSL 16:8e0d178b1d1e 407 const unsigned char* buf;
wolfSSL 16:8e0d178b1d1e 408
wolfSSL 16:8e0d178b1d1e 409 WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write");
wolfSSL 16:8e0d178b1d1e 410
wolfSSL 16:8e0d178b1d1e 411 if (bio == NULL || data == NULL) {
wolfSSL 16:8e0d178b1d1e 412 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 413 }
wolfSSL 16:8e0d178b1d1e 414
wolfSSL 16:8e0d178b1d1e 415 sz = wolfSSL_BIO_pending(bio);
wolfSSL 16:8e0d178b1d1e 416 if (sz < 0) {
wolfSSL 16:8e0d178b1d1e 417 WOLFSSL_MSG("Error getting memory data");
wolfSSL 16:8e0d178b1d1e 418 return sz;
wolfSSL 16:8e0d178b1d1e 419 }
wolfSSL 16:8e0d178b1d1e 420
wolfSSL 16:8e0d178b1d1e 421 if (bio->ptr == NULL) {
wolfSSL 16:8e0d178b1d1e 422 bio->ptr = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 423 if (bio->ptr == NULL) {
wolfSSL 16:8e0d178b1d1e 424 WOLFSSL_MSG("Error on malloc");
wolfSSL 16:8e0d178b1d1e 425 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 426 }
wolfSSL 16:8e0d178b1d1e 427 bio->num = len;
wolfSSL 16:8e0d178b1d1e 428 if (bio->mem_buf != NULL) {
wolfSSL 16:8e0d178b1d1e 429 bio->mem_buf->data = (char*)bio->ptr;
wolfSSL 16:8e0d178b1d1e 430 bio->mem_buf->length = bio->num;
wolfSSL 16:8e0d178b1d1e 431 }
wolfSSL 16:8e0d178b1d1e 432 }
wolfSSL 16:8e0d178b1d1e 433
wolfSSL 16:8e0d178b1d1e 434 /* check if will fit in current buffer size */
wolfSSL 16:8e0d178b1d1e 435 if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) {
wolfSSL 16:8e0d178b1d1e 436 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 437 }
wolfSSL 16:8e0d178b1d1e 438 if (bio->num < sz + len) {
wolfSSL 16:8e0d178b1d1e 439 bio->ptr = (byte*)XREALLOC(bio->ptr, sz + len, bio->heap,
wolfSSL 16:8e0d178b1d1e 440 DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 441 if (bio->ptr == NULL) {
wolfSSL 16:8e0d178b1d1e 442 WOLFSSL_MSG("Error on realloc");
wolfSSL 16:8e0d178b1d1e 443 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 444 }
wolfSSL 16:8e0d178b1d1e 445 bio->num = sz + len;
wolfSSL 16:8e0d178b1d1e 446 if (bio->mem_buf != NULL) {
wolfSSL 16:8e0d178b1d1e 447 bio->mem_buf->data = (char*)bio->ptr;
wolfSSL 16:8e0d178b1d1e 448 bio->mem_buf->length = bio->num;
wolfSSL 16:8e0d178b1d1e 449 }
wolfSSL 16:8e0d178b1d1e 450 }
wolfSSL 16:8e0d178b1d1e 451
wolfSSL 16:8e0d178b1d1e 452 XMEMCPY((byte*)bio->ptr + sz, data, len);
wolfSSL 16:8e0d178b1d1e 453 bio->wrSz += len;
wolfSSL 16:8e0d178b1d1e 454
wolfSSL 16:8e0d178b1d1e 455 return len;
wolfSSL 16:8e0d178b1d1e 456 }
wolfSSL 16:8e0d178b1d1e 457
wolfSSL 16:8e0d178b1d1e 458
wolfSSL 16:8e0d178b1d1e 459 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 460 /* Helper function for writing to a WOLFSSL_BIO_MD type
wolfSSL 16:8e0d178b1d1e 461 *
wolfSSL 16:8e0d178b1d1e 462 * returns the amount written in bytes on success (0)
wolfSSL 16:8e0d178b1d1e 463 */
wolfSSL 16:8e0d178b1d1e 464 static int wolfSSL_BIO_MD_write(WOLFSSL_BIO* bio, const void* data, int len)
wolfSSL 16:8e0d178b1d1e 465 {
wolfSSL 16:8e0d178b1d1e 466 int ret = 0;
wolfSSL 16:8e0d178b1d1e 467
wolfSSL 16:8e0d178b1d1e 468 if (bio == NULL || data == NULL) {
wolfSSL 16:8e0d178b1d1e 469 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 470 }
wolfSSL 16:8e0d178b1d1e 471
wolfSSL 16:8e0d178b1d1e 472 if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == NID_hmac) {
wolfSSL 16:8e0d178b1d1e 473 if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data,
wolfSSL 16:8e0d178b1d1e 474 len) != WOLFSSL_SUCCESS) {
wolfSSL 16:8e0d178b1d1e 475 ret = WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 476 }
wolfSSL 16:8e0d178b1d1e 477 }
wolfSSL 16:8e0d178b1d1e 478 else {
wolfSSL 16:8e0d178b1d1e 479 if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data, len)
wolfSSL 16:8e0d178b1d1e 480 != WOLFSSL_SUCCESS) {
wolfSSL 16:8e0d178b1d1e 481 ret = WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 482 }
wolfSSL 16:8e0d178b1d1e 483 }
wolfSSL 16:8e0d178b1d1e 484 return ret;
wolfSSL 16:8e0d178b1d1e 485 }
wolfSSL 16:8e0d178b1d1e 486 #endif /* WOLFCRYPT_ONLY */
wolfSSL 16:8e0d178b1d1e 487
wolfSSL 16:8e0d178b1d1e 488
wolfSSL 16:8e0d178b1d1e 489 /* Writes data to a WOLFSSL_BIO structure
wolfSSL 16:8e0d178b1d1e 490 *
wolfSSL 16:8e0d178b1d1e 491 * bio structure to write to
wolfSSL 16:8e0d178b1d1e 492 * data holds the data to be written
wolfSSL 16:8e0d178b1d1e 493 * len length of data buffer
wolfSSL 16:8e0d178b1d1e 494 *
wolfSSL 16:8e0d178b1d1e 495 * returns the amount written in bytes on success
wolfSSL 16:8e0d178b1d1e 496 */
wolfSSL 16:8e0d178b1d1e 497 int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
wolfSSL 16:8e0d178b1d1e 498 {
wolfSSL 16:8e0d178b1d1e 499 int ret = 0;
wolfSSL 16:8e0d178b1d1e 500 int retB64 = 0;
wolfSSL 16:8e0d178b1d1e 501 WOLFSSL_BIO* front = bio;
wolfSSL 16:8e0d178b1d1e 502 void* frmt = NULL;
wolfSSL 16:8e0d178b1d1e 503 word32 frmtSz = 0;
wolfSSL 16:8e0d178b1d1e 504
wolfSSL 16:8e0d178b1d1e 505 WOLFSSL_ENTER("wolfSSL_BIO_write");
wolfSSL 16:8e0d178b1d1e 506
wolfSSL 16:8e0d178b1d1e 507 /* info cb, abort if user returns <= 0*/
wolfSSL 16:8e0d178b1d1e 508 if (front != NULL && front->infoCb != NULL) {
wolfSSL 16:8e0d178b1d1e 509 ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_WRITE,
wolfSSL 16:8e0d178b1d1e 510 (const char*)data, len, 0, 1);
wolfSSL 16:8e0d178b1d1e 511 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 512 return ret;
wolfSSL 16:8e0d178b1d1e 513 }
wolfSSL 16:8e0d178b1d1e 514 }
wolfSSL 16:8e0d178b1d1e 515
wolfSSL 16:8e0d178b1d1e 516 while (bio != NULL && ret >= 0) {
wolfSSL 16:8e0d178b1d1e 517 /* check for custom write */
wolfSSL 16:8e0d178b1d1e 518 if (bio->method && bio->method->writeCb) {
wolfSSL 16:8e0d178b1d1e 519 ret = bio->method->writeCb(bio, (const char*)data, len);
wolfSSL 16:8e0d178b1d1e 520 }
wolfSSL 16:8e0d178b1d1e 521
wolfSSL 16:8e0d178b1d1e 522 /* check for formatting */
wolfSSL 16:8e0d178b1d1e 523 if (bio->type == WOLFSSL_BIO_BASE64) {
wolfSSL 16:8e0d178b1d1e 524 #if defined(WOLFSSL_BASE64_ENCODE)
wolfSSL 16:8e0d178b1d1e 525 word32 sz = 0;
wolfSSL 16:8e0d178b1d1e 526
wolfSSL 16:8e0d178b1d1e 527 if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
wolfSSL 16:8e0d178b1d1e 528 if (Base64_Encode_NoNl((const byte*)data, len, NULL,
wolfSSL 16:8e0d178b1d1e 529 &sz) != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 530 WOLFSSL_MSG("Error with base 64 get length");
wolfSSL 16:8e0d178b1d1e 531 ret = SSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 532 }
wolfSSL 16:8e0d178b1d1e 533 }
wolfSSL 16:8e0d178b1d1e 534 else {
wolfSSL 16:8e0d178b1d1e 535 if (Base64_Encode((const byte*)data, len, NULL, &sz) !=
wolfSSL 16:8e0d178b1d1e 536 LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 537 WOLFSSL_MSG("Error with base 64 get length");
wolfSSL 16:8e0d178b1d1e 538 ret = SSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 539 }
wolfSSL 16:8e0d178b1d1e 540 }
wolfSSL 16:8e0d178b1d1e 541
wolfSSL 16:8e0d178b1d1e 542 if (frmt == NULL && sz > 0 && ret != SSL_FATAL_ERROR) {
wolfSSL 16:8e0d178b1d1e 543 frmt = (void*)XMALLOC(sz, front->heap,
wolfSSL 16:8e0d178b1d1e 544 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 545 if (frmt == NULL) {
wolfSSL 16:8e0d178b1d1e 546 WOLFSSL_MSG("Memory error");
wolfSSL 16:8e0d178b1d1e 547 ret = SSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 548 }
wolfSSL 16:8e0d178b1d1e 549 frmtSz = sz;
wolfSSL 16:8e0d178b1d1e 550 }
wolfSSL 16:8e0d178b1d1e 551 else if (sz > frmtSz) {
wolfSSL 16:8e0d178b1d1e 552 frmt = (void*)XREALLOC(frmt, sz, front->heap,
wolfSSL 16:8e0d178b1d1e 553 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 554 if (frmt == NULL) {
wolfSSL 16:8e0d178b1d1e 555 WOLFSSL_MSG("Memory error");
wolfSSL 16:8e0d178b1d1e 556 ret = SSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 557 }
wolfSSL 16:8e0d178b1d1e 558 /* since frmt already existed then data should point to knew
wolfSSL 16:8e0d178b1d1e 559 formatted buffer */
wolfSSL 16:8e0d178b1d1e 560 data = frmt;
wolfSSL 16:8e0d178b1d1e 561 len = frmtSz;
wolfSSL 16:8e0d178b1d1e 562 frmtSz = sz;
wolfSSL 16:8e0d178b1d1e 563 }
wolfSSL 16:8e0d178b1d1e 564 #endif /* defined(WOLFSSL_BASE64_ENCODE) */
wolfSSL 16:8e0d178b1d1e 565
wolfSSL 16:8e0d178b1d1e 566 if (ret >= 0) {
wolfSSL 16:8e0d178b1d1e 567 /* change so that data is formatted buffer */
wolfSSL 16:8e0d178b1d1e 568 retB64 = wolfSSL_BIO_BASE64_write(bio, data, (word32)len,
wolfSSL 16:8e0d178b1d1e 569 (byte*)frmt, &frmtSz);
wolfSSL 16:8e0d178b1d1e 570 data = frmt;
wolfSSL 16:8e0d178b1d1e 571 len = frmtSz;
wolfSSL 16:8e0d178b1d1e 572 }
wolfSSL 16:8e0d178b1d1e 573 }
wolfSSL 16:8e0d178b1d1e 574
wolfSSL 16:8e0d178b1d1e 575 /* write bios */
wolfSSL 16:8e0d178b1d1e 576 if (bio && bio->type == WOLFSSL_BIO_BIO) {
wolfSSL 16:8e0d178b1d1e 577 ret = wolfSSL_BIO_BIO_write(bio, data, len);
wolfSSL 16:8e0d178b1d1e 578 }
wolfSSL 16:8e0d178b1d1e 579
wolfSSL 16:8e0d178b1d1e 580 if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
wolfSSL 16:8e0d178b1d1e 581 ret = wolfSSL_BIO_MEMORY_write(bio, data, len);
wolfSSL 16:8e0d178b1d1e 582 }
wolfSSL 16:8e0d178b1d1e 583
wolfSSL 16:8e0d178b1d1e 584 #ifndef NO_FILESYSTEM
wolfSSL 16:8e0d178b1d1e 585 if (bio && bio->type == WOLFSSL_BIO_FILE) {
wolfSSL 16:8e0d178b1d1e 586 ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr);
wolfSSL 16:8e0d178b1d1e 587 }
wolfSSL 16:8e0d178b1d1e 588 #endif
wolfSSL 16:8e0d178b1d1e 589
wolfSSL 16:8e0d178b1d1e 590 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 591 if (bio && bio->type == WOLFSSL_BIO_SSL) {
wolfSSL 16:8e0d178b1d1e 592 /* already got eof, again is error */
wolfSSL 16:8e0d178b1d1e 593 if (front->eof) {
wolfSSL 16:8e0d178b1d1e 594 ret = SSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 595 }
wolfSSL 16:8e0d178b1d1e 596 else {
wolfSSL 16:8e0d178b1d1e 597 ret = wolfSSL_BIO_SSL_write(bio, data, len, front);
wolfSSL 16:8e0d178b1d1e 598 }
wolfSSL 16:8e0d178b1d1e 599 }
wolfSSL 16:8e0d178b1d1e 600
wolfSSL 16:8e0d178b1d1e 601 if (bio && bio->type == WOLFSSL_BIO_MD) {
wolfSSL 16:8e0d178b1d1e 602 if (bio->next != NULL) { /* data passing through MD BIO */
wolfSSL 16:8e0d178b1d1e 603 ret = wolfSSL_BIO_MD_write(bio, data, len);
wolfSSL 16:8e0d178b1d1e 604 }
wolfSSL 16:8e0d178b1d1e 605 }
wolfSSL 16:8e0d178b1d1e 606 #endif /* WOLFCRYPT_ONLY */
wolfSSL 16:8e0d178b1d1e 607
wolfSSL 16:8e0d178b1d1e 608 /* advance to the next bio in list */
wolfSSL 16:8e0d178b1d1e 609 bio = bio->next;
wolfSSL 16:8e0d178b1d1e 610 }
wolfSSL 16:8e0d178b1d1e 611
wolfSSL 16:8e0d178b1d1e 612 if (frmt != NULL) {
wolfSSL 16:8e0d178b1d1e 613 XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 614 }
wolfSSL 16:8e0d178b1d1e 615
wolfSSL 16:8e0d178b1d1e 616 /* info cb, user can override return value */
wolfSSL 16:8e0d178b1d1e 617 if (front != NULL && front->infoCb != NULL) {
wolfSSL 16:8e0d178b1d1e 618 ret = (int)front->infoCb(front,
wolfSSL 16:8e0d178b1d1e 619 WOLFSSL_BIO_CB_WRITE | WOLFSSL_BIO_CB_RETURN,
wolfSSL 16:8e0d178b1d1e 620 (const char*)data, 0, 0, ret);
wolfSSL 16:8e0d178b1d1e 621 }
wolfSSL 16:8e0d178b1d1e 622
wolfSSL 16:8e0d178b1d1e 623 if (retB64 != 0)
wolfSSL 16:8e0d178b1d1e 624 return retB64;
wolfSSL 16:8e0d178b1d1e 625 else
wolfSSL 16:8e0d178b1d1e 626 return ret;
wolfSSL 16:8e0d178b1d1e 627 }
wolfSSL 16:8e0d178b1d1e 628
wolfSSL 16:8e0d178b1d1e 629
wolfSSL 16:8e0d178b1d1e 630 /* Wrapper for other BIO type functions, expected to grow as OpenSSL compatibility
wolfSSL 16:8e0d178b1d1e 631 * layer grows.
wolfSSL 16:8e0d178b1d1e 632 *
wolfSSL 16:8e0d178b1d1e 633 * return info. specific to the cmd that is passed in.
wolfSSL 16:8e0d178b1d1e 634 */
wolfSSL 16:8e0d178b1d1e 635 #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
wolfSSL 16:8e0d178b1d1e 636 long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
wolfSSL 16:8e0d178b1d1e 637 {
wolfSSL 16:8e0d178b1d1e 638 long ret;
wolfSSL 16:8e0d178b1d1e 639
wolfSSL 16:8e0d178b1d1e 640 (void)larg; /* not currently used */
wolfSSL 16:8e0d178b1d1e 641
wolfSSL 16:8e0d178b1d1e 642 WOLFSSL_ENTER("wolfSSL_BIO_ctrl");
wolfSSL 16:8e0d178b1d1e 643
wolfSSL 16:8e0d178b1d1e 644 if (bio && bio->method && bio->method->ctrlCb) {
wolfSSL 16:8e0d178b1d1e 645 return bio->method->ctrlCb(bio, cmd, larg, parg);
wolfSSL 16:8e0d178b1d1e 646 }
wolfSSL 16:8e0d178b1d1e 647
wolfSSL 16:8e0d178b1d1e 648 switch(cmd) {
wolfSSL 16:8e0d178b1d1e 649 case BIO_CTRL_PENDING:
wolfSSL 16:8e0d178b1d1e 650 case BIO_CTRL_WPENDING:
wolfSSL 16:8e0d178b1d1e 651 ret = (long)wolfSSL_BIO_ctrl_pending(bio);
wolfSSL 16:8e0d178b1d1e 652 break;
wolfSSL 16:8e0d178b1d1e 653 case BIO_CTRL_INFO:
wolfSSL 16:8e0d178b1d1e 654 ret = (long)wolfSSL_BIO_get_mem_data(bio, parg);
wolfSSL 16:8e0d178b1d1e 655 break;
wolfSSL 16:8e0d178b1d1e 656 case BIO_CTRL_FLUSH:
wolfSSL 16:8e0d178b1d1e 657 ret = (long)wolfSSL_BIO_flush(bio);
wolfSSL 16:8e0d178b1d1e 658 break;
wolfSSL 16:8e0d178b1d1e 659 case BIO_CTRL_RESET:
wolfSSL 16:8e0d178b1d1e 660 ret = (long)wolfSSL_BIO_reset(bio);
wolfSSL 16:8e0d178b1d1e 661 break;
wolfSSL 16:8e0d178b1d1e 662 default:
wolfSSL 16:8e0d178b1d1e 663 WOLFSSL_MSG("CMD not yet implemented");
wolfSSL 16:8e0d178b1d1e 664 ret = WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 665 break;
wolfSSL 16:8e0d178b1d1e 666 }
wolfSSL 16:8e0d178b1d1e 667 return ret;
wolfSSL 16:8e0d178b1d1e 668 }
wolfSSL 16:8e0d178b1d1e 669 #endif
wolfSSL 16:8e0d178b1d1e 670
wolfSSL 16:8e0d178b1d1e 671
wolfSSL 16:8e0d178b1d1e 672 /* helper function for wolfSSL_BIO_gets
wolfSSL 16:8e0d178b1d1e 673 * size till a newline is hit
wolfSSL 16:8e0d178b1d1e 674 * returns the number of bytes including the new line character
wolfSSL 16:8e0d178b1d1e 675 */
wolfSSL 16:8e0d178b1d1e 676 static int wolfSSL_getLineLength(char* in, int inSz)
wolfSSL 16:8e0d178b1d1e 677 {
wolfSSL 16:8e0d178b1d1e 678 int i;
wolfSSL 16:8e0d178b1d1e 679
wolfSSL 16:8e0d178b1d1e 680 for (i = 0; i < inSz; i++) {
wolfSSL 16:8e0d178b1d1e 681 if (in[i] == '\n') {
wolfSSL 16:8e0d178b1d1e 682 return i + 1; /* includes new line character */
wolfSSL 16:8e0d178b1d1e 683 }
wolfSSL 16:8e0d178b1d1e 684 }
wolfSSL 16:8e0d178b1d1e 685
wolfSSL 16:8e0d178b1d1e 686 return inSz; /* rest of buffer is all one line */
wolfSSL 16:8e0d178b1d1e 687 }
wolfSSL 16:8e0d178b1d1e 688
wolfSSL 16:8e0d178b1d1e 689
wolfSSL 16:8e0d178b1d1e 690 /* Gets the next line from bio. Goes until a new line character or end of
wolfSSL 16:8e0d178b1d1e 691 * buffer is reached.
wolfSSL 16:8e0d178b1d1e 692 *
wolfSSL 16:8e0d178b1d1e 693 * bio the structure to read a new line from
wolfSSL 16:8e0d178b1d1e 694 * buf buffer to hold the result
wolfSSL 16:8e0d178b1d1e 695 * sz the size of "buf" buffer
wolfSSL 16:8e0d178b1d1e 696 *
wolfSSL 16:8e0d178b1d1e 697 * returns the size of the result placed in buf on success and a 0 or negative
wolfSSL 16:8e0d178b1d1e 698 * value in an error case.
wolfSSL 16:8e0d178b1d1e 699 */
wolfSSL 16:8e0d178b1d1e 700 int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
wolfSSL 16:8e0d178b1d1e 701 {
wolfSSL 16:8e0d178b1d1e 702 int ret = WOLFSSL_BIO_UNSET;
wolfSSL 16:8e0d178b1d1e 703
wolfSSL 16:8e0d178b1d1e 704 WOLFSSL_ENTER("wolfSSL_BIO_gets");
wolfSSL 16:8e0d178b1d1e 705
wolfSSL 16:8e0d178b1d1e 706 if (bio == NULL || buf == NULL) {
wolfSSL 16:8e0d178b1d1e 707 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 708 }
wolfSSL 16:8e0d178b1d1e 709
wolfSSL 16:8e0d178b1d1e 710 /* not enough space for character plus terminator */
wolfSSL 16:8e0d178b1d1e 711 if (sz <= 1) {
wolfSSL 16:8e0d178b1d1e 712 return 0;
wolfSSL 16:8e0d178b1d1e 713 }
wolfSSL 16:8e0d178b1d1e 714
wolfSSL 16:8e0d178b1d1e 715 /* info cb, abort if user returns <= 0*/
wolfSSL 16:8e0d178b1d1e 716 if (bio->infoCb != NULL) {
wolfSSL 16:8e0d178b1d1e 717 ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_GETS, buf, sz, 0, 1);
wolfSSL 16:8e0d178b1d1e 718 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 719 return ret;
wolfSSL 16:8e0d178b1d1e 720 }
wolfSSL 16:8e0d178b1d1e 721 }
wolfSSL 16:8e0d178b1d1e 722
wolfSSL 16:8e0d178b1d1e 723 /* check if is custom method */
wolfSSL 16:8e0d178b1d1e 724 if (bio->method && bio->method->getsCb) {
wolfSSL 16:8e0d178b1d1e 725 return bio->method->getsCb(bio, buf, sz);
wolfSSL 16:8e0d178b1d1e 726 }
wolfSSL 16:8e0d178b1d1e 727
wolfSSL 16:8e0d178b1d1e 728 switch (bio->type) {
wolfSSL 16:8e0d178b1d1e 729 #ifndef NO_FILESYSTEM
wolfSSL 16:8e0d178b1d1e 730 case WOLFSSL_BIO_FILE:
wolfSSL 16:8e0d178b1d1e 731 if (((XFILE)bio->ptr) == XBADFILE) {
wolfSSL 16:8e0d178b1d1e 732 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 733 }
wolfSSL 16:8e0d178b1d1e 734
wolfSSL 16:8e0d178b1d1e 735 #if defined(MICRIUM) || defined(LSR_FS) || defined(EBSNET)
wolfSSL 16:8e0d178b1d1e 736 WOLFSSL_MSG("XFGETS not ported for this system yet");
wolfSSL 16:8e0d178b1d1e 737 ret = XFGETS(buf, sz, (XFILE)bio->ptr);
wolfSSL 16:8e0d178b1d1e 738 #else
wolfSSL 16:8e0d178b1d1e 739 if (XFGETS(buf, sz, (XFILE)bio->ptr) != NULL) {
wolfSSL 16:8e0d178b1d1e 740 ret = (int)XSTRLEN(buf);
wolfSSL 16:8e0d178b1d1e 741 }
wolfSSL 16:8e0d178b1d1e 742 else {
wolfSSL 16:8e0d178b1d1e 743 ret = WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 744 }
wolfSSL 16:8e0d178b1d1e 745 #endif
wolfSSL 16:8e0d178b1d1e 746 break;
wolfSSL 16:8e0d178b1d1e 747 #endif /* NO_FILESYSTEM */
wolfSSL 16:8e0d178b1d1e 748 case WOLFSSL_BIO_MEMORY:
wolfSSL 16:8e0d178b1d1e 749 {
wolfSSL 16:8e0d178b1d1e 750 const byte* c;
wolfSSL 16:8e0d178b1d1e 751 int cSz;
wolfSSL 16:8e0d178b1d1e 752 cSz = wolfSSL_BIO_pending(bio);
wolfSSL 16:8e0d178b1d1e 753 if (cSz == 0) {
wolfSSL 16:8e0d178b1d1e 754 ret = 0; /* Nothing to read */
wolfSSL 16:8e0d178b1d1e 755 buf[0] = '\0';
wolfSSL 16:8e0d178b1d1e 756 break;
wolfSSL 16:8e0d178b1d1e 757 }
wolfSSL 16:8e0d178b1d1e 758
wolfSSL 16:8e0d178b1d1e 759 if (wolfSSL_BIO_get_mem_data(bio, (void*)&c) <= 0) {
wolfSSL 16:8e0d178b1d1e 760 ret = WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 761 break;
wolfSSL 16:8e0d178b1d1e 762 }
wolfSSL 16:8e0d178b1d1e 763
wolfSSL 16:8e0d178b1d1e 764 cSz = wolfSSL_getLineLength((char*)c, cSz);
wolfSSL 16:8e0d178b1d1e 765 /* check case where line was bigger then buffer and buffer
wolfSSL 16:8e0d178b1d1e 766 * needs end terminator */
wolfSSL 16:8e0d178b1d1e 767 if (cSz >= sz) {
wolfSSL 16:8e0d178b1d1e 768 cSz = sz - 1;
wolfSSL 16:8e0d178b1d1e 769 buf[cSz] = '\0';
wolfSSL 16:8e0d178b1d1e 770 }
wolfSSL 16:8e0d178b1d1e 771 else {
wolfSSL 16:8e0d178b1d1e 772 /* not minus 1 here because placing terminator after
wolfSSL 16:8e0d178b1d1e 773 msg and have checked that sz is large enough */
wolfSSL 16:8e0d178b1d1e 774 buf[cSz] = '\0';
wolfSSL 16:8e0d178b1d1e 775 }
wolfSSL 16:8e0d178b1d1e 776
wolfSSL 16:8e0d178b1d1e 777 ret = wolfSSL_BIO_MEMORY_read(bio, (void*)buf, cSz);
wolfSSL 16:8e0d178b1d1e 778 /* ret is read after the switch statement */
wolfSSL 16:8e0d178b1d1e 779 break;
wolfSSL 16:8e0d178b1d1e 780 }
wolfSSL 16:8e0d178b1d1e 781 case WOLFSSL_BIO_BIO:
wolfSSL 16:8e0d178b1d1e 782 {
wolfSSL 16:8e0d178b1d1e 783 char* c;
wolfSSL 16:8e0d178b1d1e 784 int cSz;
wolfSSL 16:8e0d178b1d1e 785 cSz = wolfSSL_BIO_nread0(bio, &c);
wolfSSL 16:8e0d178b1d1e 786 if (cSz == 0) {
wolfSSL 16:8e0d178b1d1e 787 ret = 0; /* Nothing to read */
wolfSSL 16:8e0d178b1d1e 788 buf[0] = '\0';
wolfSSL 16:8e0d178b1d1e 789 break;
wolfSSL 16:8e0d178b1d1e 790 }
wolfSSL 16:8e0d178b1d1e 791
wolfSSL 16:8e0d178b1d1e 792 cSz = wolfSSL_getLineLength(c, cSz);
wolfSSL 16:8e0d178b1d1e 793 /* check case where line was bigger then buffer and buffer
wolfSSL 16:8e0d178b1d1e 794 * needs end terminator */
wolfSSL 16:8e0d178b1d1e 795 if (cSz >= sz) {
wolfSSL 16:8e0d178b1d1e 796 cSz = sz - 1;
wolfSSL 16:8e0d178b1d1e 797 buf[cSz] = '\0';
wolfSSL 16:8e0d178b1d1e 798 }
wolfSSL 16:8e0d178b1d1e 799 else {
wolfSSL 16:8e0d178b1d1e 800 /* not minus 1 here because placing terminator after
wolfSSL 16:8e0d178b1d1e 801 msg and have checked that sz is large enough */
wolfSSL 16:8e0d178b1d1e 802 buf[cSz] = '\0';
wolfSSL 16:8e0d178b1d1e 803 }
wolfSSL 16:8e0d178b1d1e 804
wolfSSL 16:8e0d178b1d1e 805 ret = wolfSSL_BIO_nread(bio, &c, cSz);
wolfSSL 16:8e0d178b1d1e 806 if (ret > 0 && ret < sz) {
wolfSSL 16:8e0d178b1d1e 807 XMEMCPY(buf, c, ret);
wolfSSL 16:8e0d178b1d1e 808 }
wolfSSL 16:8e0d178b1d1e 809 break;
wolfSSL 16:8e0d178b1d1e 810 }
wolfSSL 16:8e0d178b1d1e 811
wolfSSL 16:8e0d178b1d1e 812 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 813 /* call final on hash */
wolfSSL 16:8e0d178b1d1e 814 case WOLFSSL_BIO_MD:
wolfSSL 16:8e0d178b1d1e 815 if (wolfSSL_EVP_MD_CTX_size((WOLFSSL_EVP_MD_CTX*)bio->ptr) > sz) {
wolfSSL 16:8e0d178b1d1e 816 WOLFSSL_MSG("Output buffer was too small for digest");
wolfSSL 16:8e0d178b1d1e 817 ret = WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 818 }
wolfSSL 16:8e0d178b1d1e 819 else {
wolfSSL 16:8e0d178b1d1e 820 unsigned int szOut = 0;
wolfSSL 16:8e0d178b1d1e 821 ret = wolfSSL_EVP_DigestFinal((WOLFSSL_EVP_MD_CTX*)bio->ptr,
wolfSSL 16:8e0d178b1d1e 822 (unsigned char*)buf, &szOut);
wolfSSL 16:8e0d178b1d1e 823 if (ret == WOLFSSL_SUCCESS) {
wolfSSL 16:8e0d178b1d1e 824 ret = szOut;
wolfSSL 16:8e0d178b1d1e 825 }
wolfSSL 16:8e0d178b1d1e 826 }
wolfSSL 16:8e0d178b1d1e 827 break;
wolfSSL 16:8e0d178b1d1e 828 #endif /* WOLFCRYPT_ONLY */
wolfSSL 16:8e0d178b1d1e 829
wolfSSL 16:8e0d178b1d1e 830 default:
wolfSSL 16:8e0d178b1d1e 831 WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets");
wolfSSL 16:8e0d178b1d1e 832 }
wolfSSL 16:8e0d178b1d1e 833
wolfSSL 16:8e0d178b1d1e 834 /* info cb, user can override return value */
wolfSSL 16:8e0d178b1d1e 835 if (bio->infoCb != NULL) {
wolfSSL 16:8e0d178b1d1e 836 ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_GETS | WOLFSSL_BIO_CB_RETURN,
wolfSSL 16:8e0d178b1d1e 837 buf, sz, 0, ret);
wolfSSL 16:8e0d178b1d1e 838 }
wolfSSL 16:8e0d178b1d1e 839
wolfSSL 16:8e0d178b1d1e 840 return ret;
wolfSSL 16:8e0d178b1d1e 841 }
wolfSSL 16:8e0d178b1d1e 842
wolfSSL 16:8e0d178b1d1e 843
wolfSSL 16:8e0d178b1d1e 844 /* Writes a null terminated string to bio.
wolfSSL 16:8e0d178b1d1e 845 *
wolfSSL 16:8e0d178b1d1e 846 * bio the structure to write to
wolfSSL 16:8e0d178b1d1e 847 * buf buffer to holding input string
wolfSSL 16:8e0d178b1d1e 848 *
wolfSSL 16:8e0d178b1d1e 849 * returns the size of the result placed in bio on success and a 0 or negative
wolfSSL 16:8e0d178b1d1e 850 * value in an error case. -2 is returned if the implementation is not
wolfSSL 16:8e0d178b1d1e 851 * supported for the BIO type.
wolfSSL 16:8e0d178b1d1e 852 */
wolfSSL 16:8e0d178b1d1e 853 int wolfSSL_BIO_puts(WOLFSSL_BIO* bio, const char* buf)
wolfSSL 16:8e0d178b1d1e 854 {
wolfSSL 16:8e0d178b1d1e 855 int sz;
wolfSSL 16:8e0d178b1d1e 856
wolfSSL 16:8e0d178b1d1e 857 if (bio == NULL || buf == NULL) {
wolfSSL 16:8e0d178b1d1e 858 return WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 859 }
wolfSSL 16:8e0d178b1d1e 860
wolfSSL 16:8e0d178b1d1e 861 /* check if is custom method */
wolfSSL 16:8e0d178b1d1e 862 if (bio->method && bio->method->putsCb) {
wolfSSL 16:8e0d178b1d1e 863 return bio->method->putsCb(bio, buf);
wolfSSL 16:8e0d178b1d1e 864 }
wolfSSL 16:8e0d178b1d1e 865
wolfSSL 16:8e0d178b1d1e 866 sz = (int)XSTRLEN(buf);
wolfSSL 16:8e0d178b1d1e 867 if (sz <= 0) {
wolfSSL 16:8e0d178b1d1e 868 return WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 869 }
wolfSSL 16:8e0d178b1d1e 870
wolfSSL 16:8e0d178b1d1e 871 return wolfSSL_BIO_write(bio, buf, sz);
wolfSSL 16:8e0d178b1d1e 872 }
wolfSSL 16:8e0d178b1d1e 873
wolfSSL 16:8e0d178b1d1e 874
wolfSSL 16:8e0d178b1d1e 875 /* searches through bio list for a BIO of type "type"
wolfSSL 16:8e0d178b1d1e 876 * returns NULL on failure to find a given type */
wolfSSL 16:8e0d178b1d1e 877 WOLFSSL_BIO* wolfSSL_BIO_find_type(WOLFSSL_BIO* bio, int type)
wolfSSL 16:8e0d178b1d1e 878 {
wolfSSL 16:8e0d178b1d1e 879 WOLFSSL_BIO* local = NULL;
wolfSSL 16:8e0d178b1d1e 880 WOLFSSL_BIO* current;
wolfSSL 16:8e0d178b1d1e 881
wolfSSL 16:8e0d178b1d1e 882 WOLFSSL_ENTER("wolfSSL_BIO_find_type");
wolfSSL 16:8e0d178b1d1e 883
wolfSSL 16:8e0d178b1d1e 884 if (bio == NULL) {
wolfSSL 16:8e0d178b1d1e 885 return local;
wolfSSL 16:8e0d178b1d1e 886 }
wolfSSL 16:8e0d178b1d1e 887
wolfSSL 16:8e0d178b1d1e 888 current = bio;
wolfSSL 16:8e0d178b1d1e 889 while (current != NULL) {
wolfSSL 16:8e0d178b1d1e 890 if (current->type == type) {
wolfSSL 16:8e0d178b1d1e 891 WOLFSSL_MSG("Found matching WOLFSSL_BIO type");
wolfSSL 16:8e0d178b1d1e 892 local = current;
wolfSSL 16:8e0d178b1d1e 893 break;
wolfSSL 16:8e0d178b1d1e 894 }
wolfSSL 16:8e0d178b1d1e 895 current = current->next;
wolfSSL 16:8e0d178b1d1e 896 }
wolfSSL 16:8e0d178b1d1e 897
wolfSSL 16:8e0d178b1d1e 898 return local;
wolfSSL 16:8e0d178b1d1e 899 }
wolfSSL 16:8e0d178b1d1e 900
wolfSSL 16:8e0d178b1d1e 901
wolfSSL 16:8e0d178b1d1e 902 /* returns a pointer to the next WOLFSSL_BIO in the chain on success.
wolfSSL 16:8e0d178b1d1e 903 * If a failure case then NULL is returned */
wolfSSL 16:8e0d178b1d1e 904 WOLFSSL_BIO* wolfSSL_BIO_next(WOLFSSL_BIO* bio)
wolfSSL 16:8e0d178b1d1e 905 {
wolfSSL 16:8e0d178b1d1e 906 WOLFSSL_ENTER("wolfSSL_BIO_next");
wolfSSL 16:8e0d178b1d1e 907
wolfSSL 16:8e0d178b1d1e 908 if (bio == NULL) {
wolfSSL 16:8e0d178b1d1e 909 WOLFSSL_MSG("Bad argument passed in");
wolfSSL 16:8e0d178b1d1e 910 return NULL;
wolfSSL 16:8e0d178b1d1e 911 }
wolfSSL 16:8e0d178b1d1e 912
wolfSSL 16:8e0d178b1d1e 913 return bio->next;
wolfSSL 16:8e0d178b1d1e 914 }
wolfSSL 16:8e0d178b1d1e 915
wolfSSL 16:8e0d178b1d1e 916 /* BIO_wpending returns the number of bytes pending to be written. */
wolfSSL 16:8e0d178b1d1e 917 size_t wolfSSL_BIO_wpending(const WOLFSSL_BIO *bio)
wolfSSL 16:8e0d178b1d1e 918 {
wolfSSL 16:8e0d178b1d1e 919 WOLFSSL_ENTER("BIO_wpending");
wolfSSL 16:8e0d178b1d1e 920
wolfSSL 16:8e0d178b1d1e 921 if (bio == NULL)
wolfSSL 16:8e0d178b1d1e 922 return 0;
wolfSSL 16:8e0d178b1d1e 923
wolfSSL 16:8e0d178b1d1e 924 if (bio->type == WOLFSSL_BIO_MEMORY) {
wolfSSL 16:8e0d178b1d1e 925 return bio->wrSz;
wolfSSL 16:8e0d178b1d1e 926 }
wolfSSL 16:8e0d178b1d1e 927
wolfSSL 16:8e0d178b1d1e 928 /* type BIO_BIO then check paired buffer */
wolfSSL 16:8e0d178b1d1e 929 if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
wolfSSL 16:8e0d178b1d1e 930 WOLFSSL_BIO* pair = bio->pair;
wolfSSL 16:8e0d178b1d1e 931 return pair->wrIdx;
wolfSSL 16:8e0d178b1d1e 932 }
wolfSSL 16:8e0d178b1d1e 933
wolfSSL 16:8e0d178b1d1e 934 return 0;
wolfSSL 16:8e0d178b1d1e 935 }
wolfSSL 16:8e0d178b1d1e 936
wolfSSL 16:8e0d178b1d1e 937 /* Return the number of pending bytes in read and write buffers */
wolfSSL 16:8e0d178b1d1e 938 size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
wolfSSL 16:8e0d178b1d1e 939 {
wolfSSL 16:8e0d178b1d1e 940 WOLFSSL_ENTER("wolfSSL_BIO_ctrl_pending");
wolfSSL 16:8e0d178b1d1e 941 if (bio == NULL) {
wolfSSL 16:8e0d178b1d1e 942 return 0;
wolfSSL 16:8e0d178b1d1e 943 }
wolfSSL 16:8e0d178b1d1e 944
wolfSSL 16:8e0d178b1d1e 945 if (bio->type == WOLFSSL_BIO_MD) {
wolfSSL 16:8e0d178b1d1e 946 /* MD is a wrapper only get next bio */
wolfSSL 16:8e0d178b1d1e 947 while (bio->next != NULL) {
wolfSSL 16:8e0d178b1d1e 948 bio = bio->next;
wolfSSL 16:8e0d178b1d1e 949 if (bio->type != WOLFSSL_BIO_MD) {
wolfSSL 16:8e0d178b1d1e 950 break;
wolfSSL 16:8e0d178b1d1e 951 }
wolfSSL 16:8e0d178b1d1e 952 }
wolfSSL 16:8e0d178b1d1e 953 }
wolfSSL 16:8e0d178b1d1e 954
wolfSSL 16:8e0d178b1d1e 955 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 956 if (bio->type == WOLFSSL_BIO_SSL && bio->ptr != NULL) {
wolfSSL 16:8e0d178b1d1e 957 return (long)wolfSSL_pending((WOLFSSL*)bio->ptr);
wolfSSL 16:8e0d178b1d1e 958 }
wolfSSL 16:8e0d178b1d1e 959 #endif
wolfSSL 16:8e0d178b1d1e 960
wolfSSL 16:8e0d178b1d1e 961 if (bio->type == WOLFSSL_BIO_MEMORY) {
wolfSSL 16:8e0d178b1d1e 962 return bio->wrSz;
wolfSSL 16:8e0d178b1d1e 963 }
wolfSSL 16:8e0d178b1d1e 964
wolfSSL 16:8e0d178b1d1e 965 /* type BIO_BIO then check paired buffer */
wolfSSL 16:8e0d178b1d1e 966 if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
wolfSSL 16:8e0d178b1d1e 967 WOLFSSL_BIO* pair = bio->pair;
wolfSSL 16:8e0d178b1d1e 968 if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) {
wolfSSL 16:8e0d178b1d1e 969 /* in wrap around state where beginning of buffer is being
wolfSSL 16:8e0d178b1d1e 970 * overwritten */
wolfSSL 16:8e0d178b1d1e 971 return pair->wrSz - pair->rdIdx + pair->wrIdx;
wolfSSL 16:8e0d178b1d1e 972 }
wolfSSL 16:8e0d178b1d1e 973 else {
wolfSSL 16:8e0d178b1d1e 974 /* simple case where has not wrapped around */
wolfSSL 16:8e0d178b1d1e 975 return pair->wrIdx - pair->rdIdx;
wolfSSL 16:8e0d178b1d1e 976 }
wolfSSL 16:8e0d178b1d1e 977 }
wolfSSL 16:8e0d178b1d1e 978 return 0;
wolfSSL 16:8e0d178b1d1e 979 }
wolfSSL 16:8e0d178b1d1e 980
wolfSSL 16:8e0d178b1d1e 981
wolfSSL 16:8e0d178b1d1e 982 long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr)
wolfSSL 16:8e0d178b1d1e 983 {
wolfSSL 16:8e0d178b1d1e 984 WOLFSSL_BIO* front = bio;
wolfSSL 16:8e0d178b1d1e 985 long ret = WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 986
wolfSSL 16:8e0d178b1d1e 987 WOLFSSL_ENTER("wolfSSL_BIO_get_mem_ptr");
wolfSSL 16:8e0d178b1d1e 988
wolfSSL 16:8e0d178b1d1e 989 if (bio == NULL || ptr == NULL) {
wolfSSL 16:8e0d178b1d1e 990 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 991 }
wolfSSL 16:8e0d178b1d1e 992
wolfSSL 16:8e0d178b1d1e 993 /* start at end and work backwards to find a memory BIO in the BIO chain */
wolfSSL 16:8e0d178b1d1e 994 while ((bio != NULL) && (bio->next != NULL)) {
wolfSSL 16:8e0d178b1d1e 995 bio = bio->next;
wolfSSL 16:8e0d178b1d1e 996 }
wolfSSL 16:8e0d178b1d1e 997
wolfSSL 16:8e0d178b1d1e 998 while (bio != NULL) {
wolfSSL 16:8e0d178b1d1e 999
wolfSSL 16:8e0d178b1d1e 1000 if (bio->type == WOLFSSL_BIO_MEMORY) {
wolfSSL 16:8e0d178b1d1e 1001 *ptr = bio->mem_buf;
wolfSSL 16:8e0d178b1d1e 1002 ret = WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1003 }
wolfSSL 16:8e0d178b1d1e 1004
wolfSSL 16:8e0d178b1d1e 1005 if (bio == front) {
wolfSSL 16:8e0d178b1d1e 1006 break;
wolfSSL 16:8e0d178b1d1e 1007 }
wolfSSL 16:8e0d178b1d1e 1008 bio = bio->prev;
wolfSSL 16:8e0d178b1d1e 1009 }
wolfSSL 16:8e0d178b1d1e 1010
wolfSSL 16:8e0d178b1d1e 1011 return ret;
wolfSSL 16:8e0d178b1d1e 1012 }
wolfSSL 16:8e0d178b1d1e 1013
wolfSSL 16:8e0d178b1d1e 1014 WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg)
wolfSSL 16:8e0d178b1d1e 1015 {
wolfSSL 16:8e0d178b1d1e 1016 (void) bp;
wolfSSL 16:8e0d178b1d1e 1017 (void) cmd;
wolfSSL 16:8e0d178b1d1e 1018 (void) larg;
wolfSSL 16:8e0d178b1d1e 1019 (void) iarg;
wolfSSL 16:8e0d178b1d1e 1020 WOLFSSL_STUB("BIO_int_ctrl");
wolfSSL 16:8e0d178b1d1e 1021 return 0;
wolfSSL 16:8e0d178b1d1e 1022 }
wolfSSL 16:8e0d178b1d1e 1023
wolfSSL 16:8e0d178b1d1e 1024
wolfSSL 16:8e0d178b1d1e 1025 int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size)
wolfSSL 16:8e0d178b1d1e 1026 {
wolfSSL 16:8e0d178b1d1e 1027 WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size");
wolfSSL 16:8e0d178b1d1e 1028
wolfSSL 16:8e0d178b1d1e 1029 if (bio == NULL || bio->type != WOLFSSL_BIO_BIO || size < 0) {
wolfSSL 16:8e0d178b1d1e 1030 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1031 }
wolfSSL 16:8e0d178b1d1e 1032
wolfSSL 16:8e0d178b1d1e 1033 /* if already in pair then do not change size */
wolfSSL 16:8e0d178b1d1e 1034 if (bio->pair != NULL) {
wolfSSL 16:8e0d178b1d1e 1035 WOLFSSL_MSG("WOLFSSL_BIO is paired, free from pair before changing");
wolfSSL 16:8e0d178b1d1e 1036 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1037 }
wolfSSL 16:8e0d178b1d1e 1038
wolfSSL 16:8e0d178b1d1e 1039 bio->wrSz = (int)size;
wolfSSL 16:8e0d178b1d1e 1040 if (bio->wrSz < 0) {
wolfSSL 16:8e0d178b1d1e 1041 WOLFSSL_MSG("Unexpected negative size value");
wolfSSL 16:8e0d178b1d1e 1042 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1043 }
wolfSSL 16:8e0d178b1d1e 1044
wolfSSL 16:8e0d178b1d1e 1045 if (bio->ptr != NULL) {
wolfSSL 16:8e0d178b1d1e 1046 XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 1047 }
wolfSSL 16:8e0d178b1d1e 1048
wolfSSL 16:8e0d178b1d1e 1049 bio->ptr = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 1050 if (bio->ptr == NULL) {
wolfSSL 16:8e0d178b1d1e 1051 WOLFSSL_MSG("Memory allocation error");
wolfSSL 16:8e0d178b1d1e 1052 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1053 }
wolfSSL 16:8e0d178b1d1e 1054 bio->num = bio->wrSz;
wolfSSL 16:8e0d178b1d1e 1055 bio->wrIdx = 0;
wolfSSL 16:8e0d178b1d1e 1056 bio->rdIdx = 0;
wolfSSL 16:8e0d178b1d1e 1057 if (bio->mem_buf != NULL) {
wolfSSL 16:8e0d178b1d1e 1058 bio->mem_buf->data = (char*)bio->ptr;
wolfSSL 16:8e0d178b1d1e 1059 bio->mem_buf->length = bio->num;
wolfSSL 16:8e0d178b1d1e 1060 }
wolfSSL 16:8e0d178b1d1e 1061
wolfSSL 16:8e0d178b1d1e 1062 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1063 }
wolfSSL 16:8e0d178b1d1e 1064
wolfSSL 16:8e0d178b1d1e 1065
wolfSSL 16:8e0d178b1d1e 1066 /* Joins two BIO_BIO types. The write of b1 goes to the read of b2 and vice
wolfSSL 16:8e0d178b1d1e 1067 * versa. Creating something similar to a two way pipe.
wolfSSL 16:8e0d178b1d1e 1068 * Reading and writing between the two BIOs is not thread safe, they are
wolfSSL 16:8e0d178b1d1e 1069 * expected to be used by the same thread. */
wolfSSL 16:8e0d178b1d1e 1070 int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2)
wolfSSL 16:8e0d178b1d1e 1071 {
wolfSSL 16:8e0d178b1d1e 1072 WOLFSSL_ENTER("wolfSSL_BIO_make_bio_pair");
wolfSSL 16:8e0d178b1d1e 1073
wolfSSL 16:8e0d178b1d1e 1074 if (b1 == NULL || b2 == NULL) {
wolfSSL 16:8e0d178b1d1e 1075 WOLFSSL_LEAVE("wolfSSL_BIO_make_bio_pair", BAD_FUNC_ARG);
wolfSSL 16:8e0d178b1d1e 1076 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1077 }
wolfSSL 16:8e0d178b1d1e 1078
wolfSSL 16:8e0d178b1d1e 1079 /* both are expected to be of type BIO and not already paired */
wolfSSL 16:8e0d178b1d1e 1080 if (b1->type != WOLFSSL_BIO_BIO || b2->type != WOLFSSL_BIO_BIO ||
wolfSSL 16:8e0d178b1d1e 1081 b1->pair != NULL || b2->pair != NULL) {
wolfSSL 16:8e0d178b1d1e 1082 WOLFSSL_MSG("Expected type BIO and not already paired");
wolfSSL 16:8e0d178b1d1e 1083 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1084 }
wolfSSL 16:8e0d178b1d1e 1085
wolfSSL 16:8e0d178b1d1e 1086 /* set default write size if not already set */
wolfSSL 16:8e0d178b1d1e 1087 if (b1->ptr == NULL && wolfSSL_BIO_set_write_buf_size(b1,
wolfSSL 16:8e0d178b1d1e 1088 WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
wolfSSL 16:8e0d178b1d1e 1089 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1090 }
wolfSSL 16:8e0d178b1d1e 1091
wolfSSL 16:8e0d178b1d1e 1092 if (b2->ptr == NULL && wolfSSL_BIO_set_write_buf_size(b2,
wolfSSL 16:8e0d178b1d1e 1093 WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
wolfSSL 16:8e0d178b1d1e 1094 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1095 }
wolfSSL 16:8e0d178b1d1e 1096
wolfSSL 16:8e0d178b1d1e 1097 b1->pair = b2;
wolfSSL 16:8e0d178b1d1e 1098 b2->pair = b1;
wolfSSL 16:8e0d178b1d1e 1099
wolfSSL 16:8e0d178b1d1e 1100 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1101 }
wolfSSL 16:8e0d178b1d1e 1102
wolfSSL 16:8e0d178b1d1e 1103
wolfSSL 16:8e0d178b1d1e 1104 int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b)
wolfSSL 16:8e0d178b1d1e 1105 {
wolfSSL 16:8e0d178b1d1e 1106 WOLFSSL_ENTER("wolfSSL_BIO_ctrl_reset_read_request");
wolfSSL 16:8e0d178b1d1e 1107
wolfSSL 16:8e0d178b1d1e 1108 if (b == NULL || b->type == WOLFSSL_BIO_MEMORY) {
wolfSSL 16:8e0d178b1d1e 1109 return SSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1110 }
wolfSSL 16:8e0d178b1d1e 1111
wolfSSL 16:8e0d178b1d1e 1112 b->readRq = 0;
wolfSSL 16:8e0d178b1d1e 1113
wolfSSL 16:8e0d178b1d1e 1114 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1115 }
wolfSSL 16:8e0d178b1d1e 1116
wolfSSL 16:8e0d178b1d1e 1117
wolfSSL 16:8e0d178b1d1e 1118 /* Does not advance read index pointer */
wolfSSL 16:8e0d178b1d1e 1119 int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
wolfSSL 16:8e0d178b1d1e 1120 {
wolfSSL 16:8e0d178b1d1e 1121 WOLFSSL_ENTER("wolfSSL_BIO_nread0");
wolfSSL 16:8e0d178b1d1e 1122
wolfSSL 16:8e0d178b1d1e 1123 if (bio == NULL || buf == NULL) {
wolfSSL 16:8e0d178b1d1e 1124 WOLFSSL_MSG("NULL argument passed in");
wolfSSL 16:8e0d178b1d1e 1125 return 0;
wolfSSL 16:8e0d178b1d1e 1126 }
wolfSSL 16:8e0d178b1d1e 1127
wolfSSL 16:8e0d178b1d1e 1128 /* if paired read from pair */
wolfSSL 16:8e0d178b1d1e 1129 if (bio->pair != NULL) {
wolfSSL 16:8e0d178b1d1e 1130 WOLFSSL_BIO* pair = bio->pair;
wolfSSL 16:8e0d178b1d1e 1131
wolfSSL 16:8e0d178b1d1e 1132 /* case where have wrapped around write buffer */
wolfSSL 16:8e0d178b1d1e 1133 *buf = (char*)pair->ptr + pair->rdIdx;
wolfSSL 16:8e0d178b1d1e 1134 if (pair->wrIdx > 0 && pair->rdIdx >= pair->wrIdx) {
wolfSSL 16:8e0d178b1d1e 1135 return pair->wrSz - pair->rdIdx;
wolfSSL 16:8e0d178b1d1e 1136 }
wolfSSL 16:8e0d178b1d1e 1137 else {
wolfSSL 16:8e0d178b1d1e 1138 return pair->wrIdx - pair->rdIdx;
wolfSSL 16:8e0d178b1d1e 1139 }
wolfSSL 16:8e0d178b1d1e 1140 }
wolfSSL 16:8e0d178b1d1e 1141
wolfSSL 16:8e0d178b1d1e 1142 return 0;
wolfSSL 16:8e0d178b1d1e 1143 }
wolfSSL 16:8e0d178b1d1e 1144
wolfSSL 16:8e0d178b1d1e 1145
wolfSSL 16:8e0d178b1d1e 1146 /* similar to wolfSSL_BIO_nread0 but advances the read index */
wolfSSL 16:8e0d178b1d1e 1147 int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
wolfSSL 16:8e0d178b1d1e 1148 {
wolfSSL 16:8e0d178b1d1e 1149 int sz = WOLFSSL_BIO_UNSET;
wolfSSL 16:8e0d178b1d1e 1150
wolfSSL 16:8e0d178b1d1e 1151 WOLFSSL_ENTER("wolfSSL_BIO_nread");
wolfSSL 16:8e0d178b1d1e 1152
wolfSSL 16:8e0d178b1d1e 1153 if (bio == NULL || buf == NULL) {
wolfSSL 16:8e0d178b1d1e 1154 WOLFSSL_MSG("NULL argument passed in");
wolfSSL 16:8e0d178b1d1e 1155 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1156 }
wolfSSL 16:8e0d178b1d1e 1157
wolfSSL 16:8e0d178b1d1e 1158 if (bio->type == WOLFSSL_BIO_MEMORY) {
wolfSSL 16:8e0d178b1d1e 1159 return SSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1160 }
wolfSSL 16:8e0d178b1d1e 1161
wolfSSL 16:8e0d178b1d1e 1162 if (bio->pair != NULL) {
wolfSSL 16:8e0d178b1d1e 1163 /* special case if asking to read 0 bytes */
wolfSSL 16:8e0d178b1d1e 1164 if (num == 0) {
wolfSSL 16:8e0d178b1d1e 1165 *buf = (char*)bio->pair->ptr + bio->pair->rdIdx;
wolfSSL 16:8e0d178b1d1e 1166 return 0;
wolfSSL 16:8e0d178b1d1e 1167 }
wolfSSL 16:8e0d178b1d1e 1168
wolfSSL 16:8e0d178b1d1e 1169 /* get amount able to read and set buffer pointer */
wolfSSL 16:8e0d178b1d1e 1170 sz = wolfSSL_BIO_nread0(bio, buf);
wolfSSL 16:8e0d178b1d1e 1171 if (sz == 0) {
wolfSSL 16:8e0d178b1d1e 1172 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 1173 }
wolfSSL 16:8e0d178b1d1e 1174
wolfSSL 16:8e0d178b1d1e 1175 if (num < sz) {
wolfSSL 16:8e0d178b1d1e 1176 sz = num;
wolfSSL 16:8e0d178b1d1e 1177 }
wolfSSL 16:8e0d178b1d1e 1178 bio->pair->rdIdx += sz;
wolfSSL 16:8e0d178b1d1e 1179
wolfSSL 16:8e0d178b1d1e 1180 /* check if have read to the end of the buffer and need to reset */
wolfSSL 16:8e0d178b1d1e 1181 if (bio->pair->rdIdx == bio->pair->wrSz) {
wolfSSL 16:8e0d178b1d1e 1182 bio->pair->rdIdx = 0;
wolfSSL 16:8e0d178b1d1e 1183 if (bio->pair->wrIdx == bio->pair->wrSz) {
wolfSSL 16:8e0d178b1d1e 1184 bio->pair->wrIdx = 0;
wolfSSL 16:8e0d178b1d1e 1185 }
wolfSSL 16:8e0d178b1d1e 1186 }
wolfSSL 16:8e0d178b1d1e 1187
wolfSSL 16:8e0d178b1d1e 1188 /* check if read up to write index, if so then reset index */
wolfSSL 16:8e0d178b1d1e 1189 if (bio->pair->rdIdx == bio->pair->wrIdx) {
wolfSSL 16:8e0d178b1d1e 1190 bio->pair->rdIdx = 0;
wolfSSL 16:8e0d178b1d1e 1191 bio->pair->wrIdx = 0;
wolfSSL 16:8e0d178b1d1e 1192 }
wolfSSL 16:8e0d178b1d1e 1193 }
wolfSSL 16:8e0d178b1d1e 1194
wolfSSL 16:8e0d178b1d1e 1195 return sz;
wolfSSL 16:8e0d178b1d1e 1196 }
wolfSSL 16:8e0d178b1d1e 1197
wolfSSL 16:8e0d178b1d1e 1198
wolfSSL 16:8e0d178b1d1e 1199 int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
wolfSSL 16:8e0d178b1d1e 1200 {
wolfSSL 16:8e0d178b1d1e 1201 int sz = WOLFSSL_BIO_UNSET;
wolfSSL 16:8e0d178b1d1e 1202
wolfSSL 16:8e0d178b1d1e 1203 WOLFSSL_ENTER("wolfSSL_BIO_nwrite");
wolfSSL 16:8e0d178b1d1e 1204
wolfSSL 16:8e0d178b1d1e 1205 if (bio == NULL || buf == NULL) {
wolfSSL 16:8e0d178b1d1e 1206 WOLFSSL_MSG("NULL argument passed in");
wolfSSL 16:8e0d178b1d1e 1207 return 0;
wolfSSL 16:8e0d178b1d1e 1208 }
wolfSSL 16:8e0d178b1d1e 1209
wolfSSL 16:8e0d178b1d1e 1210 if (bio->type != WOLFSSL_BIO_BIO) {
wolfSSL 16:8e0d178b1d1e 1211 return SSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1212 }
wolfSSL 16:8e0d178b1d1e 1213
wolfSSL 16:8e0d178b1d1e 1214 if (bio->pair != NULL) {
wolfSSL 16:8e0d178b1d1e 1215 if (num == 0) {
wolfSSL 16:8e0d178b1d1e 1216 *buf = (char*)bio->ptr + bio->wrIdx;
wolfSSL 16:8e0d178b1d1e 1217 return 0;
wolfSSL 16:8e0d178b1d1e 1218 }
wolfSSL 16:8e0d178b1d1e 1219
wolfSSL 16:8e0d178b1d1e 1220 if (bio->wrIdx < bio->rdIdx) {
wolfSSL 16:8e0d178b1d1e 1221 /* if wrapped around only write up to read index. In this case
wolfSSL 16:8e0d178b1d1e 1222 * rdIdx is always greater then wrIdx so sz will not be negative. */
wolfSSL 16:8e0d178b1d1e 1223 sz = bio->rdIdx - bio->wrIdx;
wolfSSL 16:8e0d178b1d1e 1224 }
wolfSSL 16:8e0d178b1d1e 1225 else if (bio->rdIdx > 0 && bio->wrIdx == bio->rdIdx) {
wolfSSL 16:8e0d178b1d1e 1226 return WOLFSSL_BIO_ERROR; /* no more room to write */
wolfSSL 16:8e0d178b1d1e 1227 }
wolfSSL 16:8e0d178b1d1e 1228 else {
wolfSSL 16:8e0d178b1d1e 1229 /* write index is past read index so write to end of buffer */
wolfSSL 16:8e0d178b1d1e 1230 sz = bio->wrSz - bio->wrIdx;
wolfSSL 16:8e0d178b1d1e 1231
wolfSSL 16:8e0d178b1d1e 1232 if (sz <= 0) {
wolfSSL 16:8e0d178b1d1e 1233 /* either an error has occurred with write index or it is at the
wolfSSL 16:8e0d178b1d1e 1234 * end of the write buffer. */
wolfSSL 16:8e0d178b1d1e 1235 if (bio->rdIdx == 0) {
wolfSSL 16:8e0d178b1d1e 1236 /* no more room, nothing has been read */
wolfSSL 16:8e0d178b1d1e 1237 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 1238 }
wolfSSL 16:8e0d178b1d1e 1239
wolfSSL 16:8e0d178b1d1e 1240 bio->wrIdx = 0;
wolfSSL 16:8e0d178b1d1e 1241
wolfSSL 16:8e0d178b1d1e 1242 /* check case where read index is not at 0 */
wolfSSL 16:8e0d178b1d1e 1243 if (bio->rdIdx > 0) {
wolfSSL 16:8e0d178b1d1e 1244 sz = bio->rdIdx; /* can write up to the read index */
wolfSSL 16:8e0d178b1d1e 1245 }
wolfSSL 16:8e0d178b1d1e 1246 else {
wolfSSL 16:8e0d178b1d1e 1247 sz = bio->wrSz; /* no restriction other then buffer size */
wolfSSL 16:8e0d178b1d1e 1248 }
wolfSSL 16:8e0d178b1d1e 1249 }
wolfSSL 16:8e0d178b1d1e 1250 }
wolfSSL 16:8e0d178b1d1e 1251
wolfSSL 16:8e0d178b1d1e 1252 if (num < sz) {
wolfSSL 16:8e0d178b1d1e 1253 sz = num;
wolfSSL 16:8e0d178b1d1e 1254 }
wolfSSL 16:8e0d178b1d1e 1255 *buf = (char*)bio->ptr + bio->wrIdx;
wolfSSL 16:8e0d178b1d1e 1256 bio->wrIdx += sz;
wolfSSL 16:8e0d178b1d1e 1257
wolfSSL 16:8e0d178b1d1e 1258 /* if at the end of the buffer and space for wrap around then set
wolfSSL 16:8e0d178b1d1e 1259 * write index back to 0 */
wolfSSL 16:8e0d178b1d1e 1260 if (bio->wrIdx == bio->wrSz && bio->rdIdx > 0) {
wolfSSL 16:8e0d178b1d1e 1261 bio->wrIdx = 0;
wolfSSL 16:8e0d178b1d1e 1262 }
wolfSSL 16:8e0d178b1d1e 1263 }
wolfSSL 16:8e0d178b1d1e 1264
wolfSSL 16:8e0d178b1d1e 1265 return sz;
wolfSSL 16:8e0d178b1d1e 1266 }
wolfSSL 16:8e0d178b1d1e 1267
wolfSSL 16:8e0d178b1d1e 1268
wolfSSL 16:8e0d178b1d1e 1269 /* Reset BIO to initial state */
wolfSSL 16:8e0d178b1d1e 1270 int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
wolfSSL 16:8e0d178b1d1e 1271 {
wolfSSL 16:8e0d178b1d1e 1272 WOLFSSL_ENTER("wolfSSL_BIO_reset");
wolfSSL 16:8e0d178b1d1e 1273
wolfSSL 16:8e0d178b1d1e 1274 if (bio == NULL) {
wolfSSL 16:8e0d178b1d1e 1275 WOLFSSL_MSG("NULL argument passed in");
wolfSSL 16:8e0d178b1d1e 1276 /* -1 is consistent failure even for FILE type */
wolfSSL 16:8e0d178b1d1e 1277 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 1278 }
wolfSSL 16:8e0d178b1d1e 1279
wolfSSL 16:8e0d178b1d1e 1280 switch (bio->type) {
wolfSSL 16:8e0d178b1d1e 1281 #ifndef NO_FILESYSTEM
wolfSSL 16:8e0d178b1d1e 1282 case WOLFSSL_BIO_FILE:
wolfSSL 16:8e0d178b1d1e 1283 XREWIND((XFILE)bio->ptr);
wolfSSL 16:8e0d178b1d1e 1284 return 0;
wolfSSL 16:8e0d178b1d1e 1285 #endif
wolfSSL 16:8e0d178b1d1e 1286
wolfSSL 16:8e0d178b1d1e 1287 case WOLFSSL_BIO_BIO:
wolfSSL 16:8e0d178b1d1e 1288 bio->rdIdx = 0;
wolfSSL 16:8e0d178b1d1e 1289 bio->wrIdx = 0;
wolfSSL 16:8e0d178b1d1e 1290 return 0;
wolfSSL 16:8e0d178b1d1e 1291
wolfSSL 16:8e0d178b1d1e 1292 case WOLFSSL_BIO_MEMORY:
wolfSSL 16:8e0d178b1d1e 1293 bio->rdIdx = 0;
wolfSSL 16:8e0d178b1d1e 1294 bio->wrIdx = 0;
wolfSSL 16:8e0d178b1d1e 1295 bio->wrSz = 0;
wolfSSL 16:8e0d178b1d1e 1296 XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 1297 bio->ptr = NULL;
wolfSSL 16:8e0d178b1d1e 1298 bio->num = 0;
wolfSSL 16:8e0d178b1d1e 1299 if (bio->mem_buf != NULL) {
wolfSSL 16:8e0d178b1d1e 1300 bio->mem_buf->data = (char*)bio->ptr;
wolfSSL 16:8e0d178b1d1e 1301 bio->mem_buf->length = bio->num;
wolfSSL 16:8e0d178b1d1e 1302 }
wolfSSL 16:8e0d178b1d1e 1303 return 0;
wolfSSL 16:8e0d178b1d1e 1304
wolfSSL 16:8e0d178b1d1e 1305 #ifndef WOLFCRYPT_ONLY
wolfSSL 16:8e0d178b1d1e 1306 case WOLFSSL_BIO_MD:
wolfSSL 16:8e0d178b1d1e 1307 if (bio->ptr != NULL) {
wolfSSL 16:8e0d178b1d1e 1308 const WOLFSSL_EVP_MD* md =
wolfSSL 16:8e0d178b1d1e 1309 wolfSSL_EVP_MD_CTX_md((WOLFSSL_EVP_MD_CTX*)bio->ptr);
wolfSSL 16:8e0d178b1d1e 1310 wolfSSL_EVP_MD_CTX_init((WOLFSSL_EVP_MD_CTX*)bio->ptr);
wolfSSL 16:8e0d178b1d1e 1311 wolfSSL_EVP_DigestInit((WOLFSSL_EVP_MD_CTX*)bio->ptr, md);
wolfSSL 16:8e0d178b1d1e 1312 }
wolfSSL 16:8e0d178b1d1e 1313 return 0;
wolfSSL 16:8e0d178b1d1e 1314 #endif /* WOLFCRYPT_ONLY */
wolfSSL 16:8e0d178b1d1e 1315
wolfSSL 16:8e0d178b1d1e 1316 default:
wolfSSL 16:8e0d178b1d1e 1317 WOLFSSL_MSG("Unknown BIO type needs added to reset function");
wolfSSL 16:8e0d178b1d1e 1318 }
wolfSSL 16:8e0d178b1d1e 1319
wolfSSL 16:8e0d178b1d1e 1320 return WOLFSSL_BIO_ERROR;
wolfSSL 16:8e0d178b1d1e 1321 }
wolfSSL 16:8e0d178b1d1e 1322
wolfSSL 16:8e0d178b1d1e 1323 #ifndef NO_FILESYSTEM
wolfSSL 16:8e0d178b1d1e 1324 long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c)
wolfSSL 16:8e0d178b1d1e 1325 {
wolfSSL 16:8e0d178b1d1e 1326 WOLFSSL_ENTER("wolfSSL_BIO_set_fp");
wolfSSL 16:8e0d178b1d1e 1327
wolfSSL 16:8e0d178b1d1e 1328 if (bio == NULL || fp == XBADFILE) {
wolfSSL 16:8e0d178b1d1e 1329 WOLFSSL_LEAVE("wolfSSL_BIO_set_fp", BAD_FUNC_ARG);
wolfSSL 16:8e0d178b1d1e 1330 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1331 }
wolfSSL 16:8e0d178b1d1e 1332
wolfSSL 16:8e0d178b1d1e 1333 if (bio->type != WOLFSSL_BIO_FILE) {
wolfSSL 16:8e0d178b1d1e 1334 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1335 }
wolfSSL 16:8e0d178b1d1e 1336
wolfSSL 16:8e0d178b1d1e 1337 bio->shutdown = (byte)c;
wolfSSL 16:8e0d178b1d1e 1338 bio->ptr = (XFILE)fp;
wolfSSL 16:8e0d178b1d1e 1339
wolfSSL 16:8e0d178b1d1e 1340 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1341 }
wolfSSL 16:8e0d178b1d1e 1342
wolfSSL 16:8e0d178b1d1e 1343
wolfSSL 16:8e0d178b1d1e 1344 long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp)
wolfSSL 16:8e0d178b1d1e 1345 {
wolfSSL 16:8e0d178b1d1e 1346 WOLFSSL_ENTER("wolfSSL_BIO_get_fp");
wolfSSL 16:8e0d178b1d1e 1347
wolfSSL 16:8e0d178b1d1e 1348 if (bio == NULL || fp == XBADFILE) {
wolfSSL 16:8e0d178b1d1e 1349 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1350 }
wolfSSL 16:8e0d178b1d1e 1351
wolfSSL 16:8e0d178b1d1e 1352 if (bio->type != WOLFSSL_BIO_FILE) {
wolfSSL 16:8e0d178b1d1e 1353 return SSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1354 }
wolfSSL 16:8e0d178b1d1e 1355
wolfSSL 16:8e0d178b1d1e 1356 *fp = (XFILE)bio->ptr;
wolfSSL 16:8e0d178b1d1e 1357
wolfSSL 16:8e0d178b1d1e 1358 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1359 }
wolfSSL 16:8e0d178b1d1e 1360
wolfSSL 16:8e0d178b1d1e 1361 /* overwrites file */
wolfSSL 16:8e0d178b1d1e 1362 int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name)
wolfSSL 16:8e0d178b1d1e 1363 {
wolfSSL 16:8e0d178b1d1e 1364 WOLFSSL_ENTER("wolfSSL_BIO_write_filename");
wolfSSL 16:8e0d178b1d1e 1365
wolfSSL 16:8e0d178b1d1e 1366 if (bio == NULL || name == NULL) {
wolfSSL 16:8e0d178b1d1e 1367 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1368 }
wolfSSL 16:8e0d178b1d1e 1369
wolfSSL 16:8e0d178b1d1e 1370 if (bio->type == WOLFSSL_BIO_FILE) {
wolfSSL 16:8e0d178b1d1e 1371 if (((XFILE)bio->ptr) != XBADFILE && bio->shutdown == BIO_CLOSE) {
wolfSSL 16:8e0d178b1d1e 1372 XFCLOSE((XFILE)bio->ptr);
wolfSSL 16:8e0d178b1d1e 1373 }
wolfSSL 16:8e0d178b1d1e 1374
wolfSSL 16:8e0d178b1d1e 1375 bio->ptr = XFOPEN(name, "w");
wolfSSL 16:8e0d178b1d1e 1376 if (((XFILE)bio->ptr) == XBADFILE) {
wolfSSL 16:8e0d178b1d1e 1377 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1378 }
wolfSSL 16:8e0d178b1d1e 1379 bio->shutdown = BIO_CLOSE;
wolfSSL 16:8e0d178b1d1e 1380
wolfSSL 16:8e0d178b1d1e 1381 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1382 }
wolfSSL 16:8e0d178b1d1e 1383
wolfSSL 16:8e0d178b1d1e 1384 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1385 }
wolfSSL 16:8e0d178b1d1e 1386
wolfSSL 16:8e0d178b1d1e 1387
wolfSSL 16:8e0d178b1d1e 1388 int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs)
wolfSSL 16:8e0d178b1d1e 1389 {
wolfSSL 16:8e0d178b1d1e 1390 WOLFSSL_ENTER("wolfSSL_BIO_seek");
wolfSSL 16:8e0d178b1d1e 1391
wolfSSL 16:8e0d178b1d1e 1392 if (bio == NULL) {
wolfSSL 16:8e0d178b1d1e 1393 return -1;
wolfSSL 16:8e0d178b1d1e 1394 }
wolfSSL 16:8e0d178b1d1e 1395
wolfSSL 16:8e0d178b1d1e 1396 /* offset ofs from beginning of file */
wolfSSL 16:8e0d178b1d1e 1397 if (bio->type == WOLFSSL_BIO_FILE &&
wolfSSL 16:8e0d178b1d1e 1398 XFSEEK((XFILE)bio->ptr, ofs, SEEK_SET) < 0) {
wolfSSL 16:8e0d178b1d1e 1399 return -1;
wolfSSL 16:8e0d178b1d1e 1400 }
wolfSSL 16:8e0d178b1d1e 1401
wolfSSL 16:8e0d178b1d1e 1402 return 0;
wolfSSL 16:8e0d178b1d1e 1403 }
wolfSSL 16:8e0d178b1d1e 1404 #endif /* NO_FILESYSTEM */
wolfSSL 16:8e0d178b1d1e 1405
wolfSSL 16:8e0d178b1d1e 1406
wolfSSL 16:8e0d178b1d1e 1407 long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v)
wolfSSL 16:8e0d178b1d1e 1408 {
wolfSSL 16:8e0d178b1d1e 1409 WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return");
wolfSSL 16:8e0d178b1d1e 1410
wolfSSL 16:8e0d178b1d1e 1411 if (bio != NULL) {
wolfSSL 16:8e0d178b1d1e 1412 bio->eof = v;
wolfSSL 16:8e0d178b1d1e 1413 }
wolfSSL 16:8e0d178b1d1e 1414
wolfSSL 16:8e0d178b1d1e 1415 return 0;
wolfSSL 16:8e0d178b1d1e 1416 }
wolfSSL 16:8e0d178b1d1e 1417
wolfSSL 16:8e0d178b1d1e 1418 int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio)
wolfSSL 16:8e0d178b1d1e 1419 {
wolfSSL 16:8e0d178b1d1e 1420 int len;
wolfSSL 16:8e0d178b1d1e 1421 #ifndef NO_FILESYSTEM
wolfSSL 16:8e0d178b1d1e 1422 long memSz = 0, curr = 0;
wolfSSL 16:8e0d178b1d1e 1423 XFILE file;
wolfSSL 16:8e0d178b1d1e 1424 #endif
wolfSSL 16:8e0d178b1d1e 1425
wolfSSL 16:8e0d178b1d1e 1426 WOLFSSL_ENTER("wolfSSL_BIO_get_len");
wolfSSL 16:8e0d178b1d1e 1427
wolfSSL 16:8e0d178b1d1e 1428 if ((len = wolfSSL_BIO_pending(bio)) > 0) {
wolfSSL 16:8e0d178b1d1e 1429 }
wolfSSL 16:8e0d178b1d1e 1430 #ifndef NO_FILESYSTEM
wolfSSL 16:8e0d178b1d1e 1431 else if (bio->type == WOLFSSL_BIO_FILE) {
wolfSSL 16:8e0d178b1d1e 1432 if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
wolfSSL 16:8e0d178b1d1e 1433 len = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1434 if (len == 0) {
wolfSSL 16:8e0d178b1d1e 1435 curr = XFTELL(file);
wolfSSL 16:8e0d178b1d1e 1436 if (curr < 0) {
wolfSSL 16:8e0d178b1d1e 1437 len = WOLFSSL_BAD_FILE;
wolfSSL 16:8e0d178b1d1e 1438 }
wolfSSL 16:8e0d178b1d1e 1439 if (XFSEEK(file, 0, XSEEK_END) != 0)
wolfSSL 16:8e0d178b1d1e 1440 len = WOLFSSL_BAD_FILE;
wolfSSL 16:8e0d178b1d1e 1441 }
wolfSSL 16:8e0d178b1d1e 1442 if (len == 0) {
wolfSSL 16:8e0d178b1d1e 1443 memSz = XFTELL(file);
wolfSSL 16:8e0d178b1d1e 1444 if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0)
wolfSSL 16:8e0d178b1d1e 1445 len = WOLFSSL_BAD_FILE;
wolfSSL 16:8e0d178b1d1e 1446 }
wolfSSL 16:8e0d178b1d1e 1447 if (len == 0) {
wolfSSL 16:8e0d178b1d1e 1448 memSz -= curr;
wolfSSL 16:8e0d178b1d1e 1449 len = (int)memSz;
wolfSSL 16:8e0d178b1d1e 1450 if (XFSEEK(file, curr, SEEK_SET) != 0)
wolfSSL 16:8e0d178b1d1e 1451 len = WOLFSSL_BAD_FILE;
wolfSSL 16:8e0d178b1d1e 1452 }
wolfSSL 16:8e0d178b1d1e 1453 }
wolfSSL 16:8e0d178b1d1e 1454 #endif
wolfSSL 16:8e0d178b1d1e 1455 return len;
wolfSSL 16:8e0d178b1d1e 1456 }
wolfSSL 16:8e0d178b1d1e 1457
wolfSSL 16:8e0d178b1d1e 1458
wolfSSL 16:8e0d178b1d1e 1459 void wolfSSL_BIO_set_callback(WOLFSSL_BIO *bio, wolf_bio_info_cb callback_func)
wolfSSL 16:8e0d178b1d1e 1460 {
wolfSSL 16:8e0d178b1d1e 1461 WOLFSSL_ENTER("wolfSSL_BIO_set_callback");
wolfSSL 16:8e0d178b1d1e 1462
wolfSSL 16:8e0d178b1d1e 1463 if (bio != NULL) {
wolfSSL 16:8e0d178b1d1e 1464 bio->infoCb = callback_func;
wolfSSL 16:8e0d178b1d1e 1465 }
wolfSSL 16:8e0d178b1d1e 1466 }
wolfSSL 16:8e0d178b1d1e 1467
wolfSSL 16:8e0d178b1d1e 1468
wolfSSL 16:8e0d178b1d1e 1469 wolf_bio_info_cb wolfSSL_BIO_get_callback(WOLFSSL_BIO *bio)
wolfSSL 16:8e0d178b1d1e 1470 {
wolfSSL 16:8e0d178b1d1e 1471 WOLFSSL_ENTER("wolfSSL_BIO_get_callback");
wolfSSL 16:8e0d178b1d1e 1472
wolfSSL 16:8e0d178b1d1e 1473 if (bio != NULL) {
wolfSSL 16:8e0d178b1d1e 1474 return bio->infoCb;
wolfSSL 16:8e0d178b1d1e 1475 }
wolfSSL 16:8e0d178b1d1e 1476
wolfSSL 16:8e0d178b1d1e 1477 return NULL;
wolfSSL 16:8e0d178b1d1e 1478 }
wolfSSL 16:8e0d178b1d1e 1479
wolfSSL 16:8e0d178b1d1e 1480
wolfSSL 16:8e0d178b1d1e 1481 void wolfSSL_BIO_set_callback_arg(WOLFSSL_BIO *bio, char *arg)
wolfSSL 16:8e0d178b1d1e 1482 {
wolfSSL 16:8e0d178b1d1e 1483 WOLFSSL_ENTER("wolfSSL_BIO_set_callback_arg");
wolfSSL 16:8e0d178b1d1e 1484
wolfSSL 16:8e0d178b1d1e 1485 if (bio != NULL) {
wolfSSL 16:8e0d178b1d1e 1486 bio->infoArg = arg;
wolfSSL 16:8e0d178b1d1e 1487 }
wolfSSL 16:8e0d178b1d1e 1488 }
wolfSSL 16:8e0d178b1d1e 1489
wolfSSL 16:8e0d178b1d1e 1490
wolfSSL 16:8e0d178b1d1e 1491 char* wolfSSL_BIO_get_callback_arg(const WOLFSSL_BIO *bio)
wolfSSL 16:8e0d178b1d1e 1492 {
wolfSSL 16:8e0d178b1d1e 1493 WOLFSSL_ENTER("wolfSSL_BIO_get_callback_arg");
wolfSSL 16:8e0d178b1d1e 1494
wolfSSL 16:8e0d178b1d1e 1495 if (bio != NULL) {
wolfSSL 16:8e0d178b1d1e 1496 return bio->infoArg;
wolfSSL 16:8e0d178b1d1e 1497 }
wolfSSL 16:8e0d178b1d1e 1498
wolfSSL 16:8e0d178b1d1e 1499 return NULL;
wolfSSL 16:8e0d178b1d1e 1500 }
wolfSSL 16:8e0d178b1d1e 1501
wolfSSL 16:8e0d178b1d1e 1502
wolfSSL 16:8e0d178b1d1e 1503 /* store a user pointer in the WOLFSSL_BIO structure */
wolfSSL 16:8e0d178b1d1e 1504 void wolfSSL_BIO_set_data(WOLFSSL_BIO* bio, void *ptr)
wolfSSL 16:8e0d178b1d1e 1505 {
wolfSSL 16:8e0d178b1d1e 1506 WOLFSSL_ENTER("wolfSSL_BIO_set_data");
wolfSSL 16:8e0d178b1d1e 1507
wolfSSL 16:8e0d178b1d1e 1508 if (bio != NULL) {
wolfSSL 16:8e0d178b1d1e 1509 bio->usrCtx = ptr;
wolfSSL 16:8e0d178b1d1e 1510 }
wolfSSL 16:8e0d178b1d1e 1511 }
wolfSSL 16:8e0d178b1d1e 1512
wolfSSL 16:8e0d178b1d1e 1513
wolfSSL 16:8e0d178b1d1e 1514 void* wolfSSL_BIO_get_data(WOLFSSL_BIO* bio)
wolfSSL 16:8e0d178b1d1e 1515 {
wolfSSL 16:8e0d178b1d1e 1516 WOLFSSL_ENTER("wolfSSL_BIO_get_data");
wolfSSL 16:8e0d178b1d1e 1517
wolfSSL 16:8e0d178b1d1e 1518 if (bio != NULL)
wolfSSL 16:8e0d178b1d1e 1519 return bio->usrCtx;
wolfSSL 16:8e0d178b1d1e 1520
wolfSSL 16:8e0d178b1d1e 1521 WOLFSSL_MSG("WOLFSSL_BIO was null");
wolfSSL 16:8e0d178b1d1e 1522 return NULL;
wolfSSL 16:8e0d178b1d1e 1523 }
wolfSSL 16:8e0d178b1d1e 1524
wolfSSL 16:8e0d178b1d1e 1525 /* If flag is 0 then blocking is set, if 1 then non blocking.
wolfSSL 16:8e0d178b1d1e 1526 * Always returns 1
wolfSSL 16:8e0d178b1d1e 1527 */
wolfSSL 16:8e0d178b1d1e 1528 long wolfSSL_BIO_set_nbio(WOLFSSL_BIO* bio, long on)
wolfSSL 16:8e0d178b1d1e 1529 {
wolfSSL 16:8e0d178b1d1e 1530 #ifndef WOLFSSL_DTLS
wolfSSL 16:8e0d178b1d1e 1531 (void)on;
wolfSSL 16:8e0d178b1d1e 1532 #endif
wolfSSL 16:8e0d178b1d1e 1533 WOLFSSL_ENTER("wolfSSL_BIO_set_nbio");
wolfSSL 16:8e0d178b1d1e 1534
wolfSSL 16:8e0d178b1d1e 1535 switch (bio->type) {
wolfSSL 16:8e0d178b1d1e 1536 case WOLFSSL_BIO_SOCKET:
wolfSSL 16:8e0d178b1d1e 1537 #ifdef XFCNTL
wolfSSL 16:8e0d178b1d1e 1538 {
wolfSSL 16:8e0d178b1d1e 1539 int flag = XFCNTL(bio->num, F_GETFL, 0);
wolfSSL 16:8e0d178b1d1e 1540 if (on)
wolfSSL 16:8e0d178b1d1e 1541 XFCNTL(bio->num, F_SETFL, flag | O_NONBLOCK);
wolfSSL 16:8e0d178b1d1e 1542 else
wolfSSL 16:8e0d178b1d1e 1543 XFCNTL(bio->num, F_SETFL, flag & ~O_NONBLOCK);
wolfSSL 16:8e0d178b1d1e 1544 }
wolfSSL 16:8e0d178b1d1e 1545 #endif
wolfSSL 16:8e0d178b1d1e 1546 break;
wolfSSL 16:8e0d178b1d1e 1547 case WOLFSSL_BIO_SSL:
wolfSSL 16:8e0d178b1d1e 1548 #ifdef WOLFSSL_DTLS
wolfSSL 16:8e0d178b1d1e 1549 wolfSSL_dtls_set_using_nonblock((WOLFSSL*)bio->ptr, (int)on);
wolfSSL 16:8e0d178b1d1e 1550 #endif
wolfSSL 16:8e0d178b1d1e 1551 break;
wolfSSL 16:8e0d178b1d1e 1552
wolfSSL 16:8e0d178b1d1e 1553 default:
wolfSSL 16:8e0d178b1d1e 1554 WOLFSSL_MSG("Unsupported bio type for non blocking");
wolfSSL 16:8e0d178b1d1e 1555 break;
wolfSSL 16:8e0d178b1d1e 1556 }
wolfSSL 16:8e0d178b1d1e 1557
wolfSSL 16:8e0d178b1d1e 1558 return 1;
wolfSSL 16:8e0d178b1d1e 1559 }
wolfSSL 16:8e0d178b1d1e 1560
wolfSSL 16:8e0d178b1d1e 1561
wolfSSL 16:8e0d178b1d1e 1562
wolfSSL 16:8e0d178b1d1e 1563 /* creates a new custom WOLFSSL_BIO_METHOD */
wolfSSL 16:8e0d178b1d1e 1564 WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int type, const char *name)
wolfSSL 16:8e0d178b1d1e 1565 {
wolfSSL 16:8e0d178b1d1e 1566 WOLFSSL_BIO_METHOD* meth;
wolfSSL 16:8e0d178b1d1e 1567
wolfSSL 16:8e0d178b1d1e 1568 WOLFSSL_ENTER("wolfSSL_BIO_meth_new");
wolfSSL 16:8e0d178b1d1e 1569
wolfSSL 16:8e0d178b1d1e 1570 meth = (WOLFSSL_BIO_METHOD*)XMALLOC(sizeof(WOLFSSL_BIO_METHOD), NULL,
wolfSSL 16:8e0d178b1d1e 1571 DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 1572 if (meth == NULL) {
wolfSSL 16:8e0d178b1d1e 1573 WOLFSSL_MSG("Error allocating memory for WOLFSSL_BIO_METHOD");
wolfSSL 16:8e0d178b1d1e 1574 return NULL;
wolfSSL 16:8e0d178b1d1e 1575 }
wolfSSL 16:8e0d178b1d1e 1576 XMEMSET(meth, 0, sizeof(WOLFSSL_BIO_METHOD));
wolfSSL 16:8e0d178b1d1e 1577 meth->type = (byte)type;
wolfSSL 16:8e0d178b1d1e 1578 XSTRNCPY(meth->name, name, MAX_BIO_METHOD_NAME - 1);
wolfSSL 16:8e0d178b1d1e 1579
wolfSSL 16:8e0d178b1d1e 1580 return meth;
wolfSSL 16:8e0d178b1d1e 1581 }
wolfSSL 16:8e0d178b1d1e 1582
wolfSSL 16:8e0d178b1d1e 1583
wolfSSL 16:8e0d178b1d1e 1584 void wolfSSL_BIO_meth_free(WOLFSSL_BIO_METHOD *biom)
wolfSSL 16:8e0d178b1d1e 1585 {
wolfSSL 16:8e0d178b1d1e 1586 WOLFSSL_ENTER("wolfSSL_BIO_meth_free");
wolfSSL 16:8e0d178b1d1e 1587 if (biom) {
wolfSSL 16:8e0d178b1d1e 1588 XFREE(biom, NULL, DYNAMIC_TYPE_OPENSSL);
wolfSSL 16:8e0d178b1d1e 1589 }
wolfSSL 16:8e0d178b1d1e 1590 }
wolfSSL 16:8e0d178b1d1e 1591
wolfSSL 16:8e0d178b1d1e 1592
wolfSSL 16:8e0d178b1d1e 1593 int wolfSSL_BIO_meth_set_write(WOLFSSL_BIO_METHOD *biom,
wolfSSL 16:8e0d178b1d1e 1594 wolfSSL_BIO_meth_write_cb biom_write)
wolfSSL 16:8e0d178b1d1e 1595 {
wolfSSL 16:8e0d178b1d1e 1596 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_write");
wolfSSL 16:8e0d178b1d1e 1597 if (biom) {
wolfSSL 16:8e0d178b1d1e 1598 biom->writeCb = biom_write;
wolfSSL 16:8e0d178b1d1e 1599 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1600 }
wolfSSL 16:8e0d178b1d1e 1601 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1602 }
wolfSSL 16:8e0d178b1d1e 1603
wolfSSL 16:8e0d178b1d1e 1604
wolfSSL 16:8e0d178b1d1e 1605 int wolfSSL_BIO_meth_set_read(WOLFSSL_BIO_METHOD *biom,
wolfSSL 16:8e0d178b1d1e 1606 wolfSSL_BIO_meth_read_cb biom_read)
wolfSSL 16:8e0d178b1d1e 1607 {
wolfSSL 16:8e0d178b1d1e 1608 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_read");
wolfSSL 16:8e0d178b1d1e 1609 if (biom) {
wolfSSL 16:8e0d178b1d1e 1610 biom->readCb = biom_read;
wolfSSL 16:8e0d178b1d1e 1611 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1612 }
wolfSSL 16:8e0d178b1d1e 1613 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1614 }
wolfSSL 16:8e0d178b1d1e 1615
wolfSSL 16:8e0d178b1d1e 1616
wolfSSL 16:8e0d178b1d1e 1617 int wolfSSL_BIO_meth_set_puts(WOLFSSL_BIO_METHOD *biom,
wolfSSL 16:8e0d178b1d1e 1618 wolfSSL_BIO_meth_puts_cb biom_puts)
wolfSSL 16:8e0d178b1d1e 1619 {
wolfSSL 16:8e0d178b1d1e 1620 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_puts");
wolfSSL 16:8e0d178b1d1e 1621 if (biom) {
wolfSSL 16:8e0d178b1d1e 1622 biom->putsCb = biom_puts;
wolfSSL 16:8e0d178b1d1e 1623 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1624 }
wolfSSL 16:8e0d178b1d1e 1625 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1626 }
wolfSSL 16:8e0d178b1d1e 1627
wolfSSL 16:8e0d178b1d1e 1628
wolfSSL 16:8e0d178b1d1e 1629 int wolfSSL_BIO_meth_set_gets(WOLFSSL_BIO_METHOD *biom,
wolfSSL 16:8e0d178b1d1e 1630 wolfSSL_BIO_meth_gets_cb biom_gets)
wolfSSL 16:8e0d178b1d1e 1631 {
wolfSSL 16:8e0d178b1d1e 1632 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_gets");
wolfSSL 16:8e0d178b1d1e 1633 if (biom) {
wolfSSL 16:8e0d178b1d1e 1634 biom->getsCb = biom_gets;
wolfSSL 16:8e0d178b1d1e 1635 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1636 }
wolfSSL 16:8e0d178b1d1e 1637 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1638 }
wolfSSL 16:8e0d178b1d1e 1639
wolfSSL 16:8e0d178b1d1e 1640
wolfSSL 16:8e0d178b1d1e 1641 int wolfSSL_BIO_meth_set_ctrl(WOLFSSL_BIO_METHOD *biom,
wolfSSL 16:8e0d178b1d1e 1642 wolfSSL_BIO_meth_ctrl_get_cb biom_ctrl)
wolfSSL 16:8e0d178b1d1e 1643 {
wolfSSL 16:8e0d178b1d1e 1644 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_ctrl");
wolfSSL 16:8e0d178b1d1e 1645 if (biom) {
wolfSSL 16:8e0d178b1d1e 1646 biom->ctrlCb = biom_ctrl;
wolfSSL 16:8e0d178b1d1e 1647 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1648 }
wolfSSL 16:8e0d178b1d1e 1649 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1650 }
wolfSSL 16:8e0d178b1d1e 1651
wolfSSL 16:8e0d178b1d1e 1652
wolfSSL 16:8e0d178b1d1e 1653 int wolfSSL_BIO_meth_set_create(WOLFSSL_BIO_METHOD *biom,
wolfSSL 16:8e0d178b1d1e 1654 wolfSSL_BIO_meth_create_cb biom_create)
wolfSSL 16:8e0d178b1d1e 1655 {
wolfSSL 16:8e0d178b1d1e 1656 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_create");
wolfSSL 16:8e0d178b1d1e 1657 if (biom) {
wolfSSL 16:8e0d178b1d1e 1658 biom->createCb = biom_create;
wolfSSL 16:8e0d178b1d1e 1659 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1660 }
wolfSSL 16:8e0d178b1d1e 1661 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1662 }
wolfSSL 16:8e0d178b1d1e 1663
wolfSSL 16:8e0d178b1d1e 1664
wolfSSL 16:8e0d178b1d1e 1665 int wolfSSL_BIO_meth_set_destroy(WOLFSSL_BIO_METHOD *biom,
wolfSSL 16:8e0d178b1d1e 1666 wolfSSL_BIO_meth_destroy_cb biom_destroy)
wolfSSL 16:8e0d178b1d1e 1667 {
wolfSSL 16:8e0d178b1d1e 1668 WOLFSSL_STUB("wolfSSL_BIO_meth_set_destroy");
wolfSSL 16:8e0d178b1d1e 1669 if (biom) {
wolfSSL 16:8e0d178b1d1e 1670 biom->freeCb = biom_destroy;
wolfSSL 16:8e0d178b1d1e 1671 return WOLFSSL_SUCCESS;
wolfSSL 16:8e0d178b1d1e 1672 }
wolfSSL 16:8e0d178b1d1e 1673 return WOLFSSL_FAILURE;
wolfSSL 16:8e0d178b1d1e 1674 }
wolfSSL 16:8e0d178b1d1e 1675
wolfSSL 16:8e0d178b1d1e 1676
wolfSSL 16:8e0d178b1d1e 1677 /* this compatibility function can be used for multiple BIO types */
wolfSSL 16:8e0d178b1d1e 1678 int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
wolfSSL 16:8e0d178b1d1e 1679 {
wolfSSL 16:8e0d178b1d1e 1680 WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
wolfSSL 16:8e0d178b1d1e 1681
wolfSSL 16:8e0d178b1d1e 1682 if (bio == NULL)
wolfSSL 16:8e0d178b1d1e 1683 return WOLFSSL_FATAL_ERROR;
wolfSSL 16:8e0d178b1d1e 1684
wolfSSL 16:8e0d178b1d1e 1685 if (p) {
wolfSSL 16:8e0d178b1d1e 1686 *(byte**)p = (byte*)bio->ptr;
wolfSSL 16:8e0d178b1d1e 1687 }
wolfSSL 16:8e0d178b1d1e 1688
wolfSSL 16:8e0d178b1d1e 1689 return bio->num;
wolfSSL 16:8e0d178b1d1e 1690 }
wolfSSL 16:8e0d178b1d1e 1691
wolfSSL 16:8e0d178b1d1e 1692 int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
wolfSSL 16:8e0d178b1d1e 1693 {
wolfSSL 16:8e0d178b1d1e 1694 return (int)wolfSSL_BIO_ctrl_pending(bio);
wolfSSL 16:8e0d178b1d1e 1695 }
wolfSSL 16:8e0d178b1d1e 1696
wolfSSL 16:8e0d178b1d1e 1697
wolfSSL 16:8e0d178b1d1e 1698 int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
wolfSSL 16:8e0d178b1d1e 1699 {
wolfSSL 16:8e0d178b1d1e 1700 /* for wolfSSL no flushing needed */
wolfSSL 16:8e0d178b1d1e 1701 WOLFSSL_ENTER("BIO_flush");
wolfSSL 16:8e0d178b1d1e 1702 (void)bio;
wolfSSL 16:8e0d178b1d1e 1703 return 1;
wolfSSL 16:8e0d178b1d1e 1704 }
wolfSSL 16:8e0d178b1d1e 1705 #endif /* WOLFSSL_BIO_INCLUDED */
wolfSSL 16:8e0d178b1d1e 1706