wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
src/bio.c@12:1a06964c2adb, 2017-08-22 (annotated)
- Committer:
- wolfSSL
- Date:
- Tue Aug 22 10:47:28 2017 +0000
- Revision:
- 12:1a06964c2adb
wolfSSL 3.12.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 12:1a06964c2adb | 1 | /* bio.c |
wolfSSL | 12:1a06964c2adb | 2 | * |
wolfSSL | 12:1a06964c2adb | 3 | * Copyright (C) 2006-2016 wolfSSL Inc. |
wolfSSL | 12:1a06964c2adb | 4 | * |
wolfSSL | 12:1a06964c2adb | 5 | * This file is part of wolfSSL. |
wolfSSL | 12:1a06964c2adb | 6 | * |
wolfSSL | 12:1a06964c2adb | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 12:1a06964c2adb | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 12:1a06964c2adb | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 12:1a06964c2adb | 10 | * (at your option) any later version. |
wolfSSL | 12:1a06964c2adb | 11 | * |
wolfSSL | 12:1a06964c2adb | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 12:1a06964c2adb | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 12:1a06964c2adb | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 12:1a06964c2adb | 15 | * GNU General Public License for more details. |
wolfSSL | 12:1a06964c2adb | 16 | * |
wolfSSL | 12:1a06964c2adb | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 12:1a06964c2adb | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 12:1a06964c2adb | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 12:1a06964c2adb | 20 | */ |
wolfSSL | 12:1a06964c2adb | 21 | |
wolfSSL | 12:1a06964c2adb | 22 | #if !defined(WOLFSSL_BIO_INCLUDED) |
wolfSSL | 12:1a06964c2adb | 23 | #warning bio.c does not need to be compiled seperatly from ssl.c |
wolfSSL | 12:1a06964c2adb | 24 | #else |
wolfSSL | 12:1a06964c2adb | 25 | |
wolfSSL | 12:1a06964c2adb | 26 | /*** TBD ***/ |
wolfSSL | 12:1a06964c2adb | 27 | WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg) |
wolfSSL | 12:1a06964c2adb | 28 | { |
wolfSSL | 12:1a06964c2adb | 29 | (void)bio; |
wolfSSL | 12:1a06964c2adb | 30 | (void)cmd; |
wolfSSL | 12:1a06964c2adb | 31 | (void)larg; |
wolfSSL | 12:1a06964c2adb | 32 | (void)parg; |
wolfSSL | 12:1a06964c2adb | 33 | |
wolfSSL | 12:1a06964c2adb | 34 | WOLFSSL_ENTER("BIO_ctrl"); |
wolfSSL | 12:1a06964c2adb | 35 | return 1; |
wolfSSL | 12:1a06964c2adb | 36 | } |
wolfSSL | 12:1a06964c2adb | 37 | |
wolfSSL | 12:1a06964c2adb | 38 | |
wolfSSL | 12:1a06964c2adb | 39 | /* Return the number of pending bytes in read and write buffers */ |
wolfSSL | 12:1a06964c2adb | 40 | size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) |
wolfSSL | 12:1a06964c2adb | 41 | { |
wolfSSL | 12:1a06964c2adb | 42 | WOLFSSL_ENTER("BIO_ctrl_pending"); |
wolfSSL | 12:1a06964c2adb | 43 | if (bio == NULL) { |
wolfSSL | 12:1a06964c2adb | 44 | return 0; |
wolfSSL | 12:1a06964c2adb | 45 | } |
wolfSSL | 12:1a06964c2adb | 46 | |
wolfSSL | 12:1a06964c2adb | 47 | if (bio->ssl != NULL) { |
wolfSSL | 12:1a06964c2adb | 48 | return (long)wolfSSL_pending(bio->ssl); |
wolfSSL | 12:1a06964c2adb | 49 | } |
wolfSSL | 12:1a06964c2adb | 50 | |
wolfSSL | 12:1a06964c2adb | 51 | if (bio->type == BIO_MEMORY) { |
wolfSSL | 12:1a06964c2adb | 52 | return bio->memLen; |
wolfSSL | 12:1a06964c2adb | 53 | } |
wolfSSL | 12:1a06964c2adb | 54 | |
wolfSSL | 12:1a06964c2adb | 55 | /* type BIO_BIO then check paired buffer */ |
wolfSSL | 12:1a06964c2adb | 56 | if (bio->type == BIO_BIO && bio->pair != NULL) { |
wolfSSL | 12:1a06964c2adb | 57 | WOLFSSL_BIO* pair = bio->pair; |
wolfSSL | 12:1a06964c2adb | 58 | if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) { |
wolfSSL | 12:1a06964c2adb | 59 | /* in wrap around state where begining of buffer is being |
wolfSSL | 12:1a06964c2adb | 60 | * overwritten */ |
wolfSSL | 12:1a06964c2adb | 61 | return pair->wrSz - pair->rdIdx + pair->wrIdx; |
wolfSSL | 12:1a06964c2adb | 62 | } |
wolfSSL | 12:1a06964c2adb | 63 | else { |
wolfSSL | 12:1a06964c2adb | 64 | /* simple case where has not wrapped around */ |
wolfSSL | 12:1a06964c2adb | 65 | return pair->wrIdx - pair->rdIdx; |
wolfSSL | 12:1a06964c2adb | 66 | } |
wolfSSL | 12:1a06964c2adb | 67 | } |
wolfSSL | 12:1a06964c2adb | 68 | |
wolfSSL | 12:1a06964c2adb | 69 | return 0; |
wolfSSL | 12:1a06964c2adb | 70 | } |
wolfSSL | 12:1a06964c2adb | 71 | |
wolfSSL | 12:1a06964c2adb | 72 | |
wolfSSL | 12:1a06964c2adb | 73 | long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr) |
wolfSSL | 12:1a06964c2adb | 74 | { |
wolfSSL | 12:1a06964c2adb | 75 | WOLFSSL_ENTER("BIO_get_mem_ptr"); |
wolfSSL | 12:1a06964c2adb | 76 | |
wolfSSL | 12:1a06964c2adb | 77 | if (bio == NULL || ptr == NULL) { |
wolfSSL | 12:1a06964c2adb | 78 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 79 | } |
wolfSSL | 12:1a06964c2adb | 80 | |
wolfSSL | 12:1a06964c2adb | 81 | *ptr = (WOLFSSL_BUF_MEM*)(bio->mem); |
wolfSSL | 12:1a06964c2adb | 82 | return SSL_SUCCESS; |
wolfSSL | 12:1a06964c2adb | 83 | } |
wolfSSL | 12:1a06964c2adb | 84 | |
wolfSSL | 12:1a06964c2adb | 85 | /*** TBD ***/ |
wolfSSL | 12:1a06964c2adb | 86 | WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg) |
wolfSSL | 12:1a06964c2adb | 87 | { |
wolfSSL | 12:1a06964c2adb | 88 | (void) bp; |
wolfSSL | 12:1a06964c2adb | 89 | (void) cmd; |
wolfSSL | 12:1a06964c2adb | 90 | (void) larg; |
wolfSSL | 12:1a06964c2adb | 91 | (void) iarg; |
wolfSSL | 12:1a06964c2adb | 92 | WOLFSSL_ENTER("BIO_int_ctrl"); |
wolfSSL | 12:1a06964c2adb | 93 | return 0; |
wolfSSL | 12:1a06964c2adb | 94 | } |
wolfSSL | 12:1a06964c2adb | 95 | |
wolfSSL | 12:1a06964c2adb | 96 | |
wolfSSL | 12:1a06964c2adb | 97 | int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) |
wolfSSL | 12:1a06964c2adb | 98 | { |
wolfSSL | 12:1a06964c2adb | 99 | WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size"); |
wolfSSL | 12:1a06964c2adb | 100 | |
wolfSSL | 12:1a06964c2adb | 101 | if (bio == NULL || bio->type != BIO_BIO || size < 0) { |
wolfSSL | 12:1a06964c2adb | 102 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 103 | } |
wolfSSL | 12:1a06964c2adb | 104 | |
wolfSSL | 12:1a06964c2adb | 105 | /* if already in pair then do not change size */ |
wolfSSL | 12:1a06964c2adb | 106 | if (bio->pair != NULL) { |
wolfSSL | 12:1a06964c2adb | 107 | WOLFSSL_MSG("WOLFSSL_BIO is paired, free from pair before changing"); |
wolfSSL | 12:1a06964c2adb | 108 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 109 | } |
wolfSSL | 12:1a06964c2adb | 110 | |
wolfSSL | 12:1a06964c2adb | 111 | bio->wrSz = (int)size; |
wolfSSL | 12:1a06964c2adb | 112 | if (bio->wrSz < 0) { |
wolfSSL | 12:1a06964c2adb | 113 | WOLFSSL_MSG("Unexpected negative size value"); |
wolfSSL | 12:1a06964c2adb | 114 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 115 | } |
wolfSSL | 12:1a06964c2adb | 116 | |
wolfSSL | 12:1a06964c2adb | 117 | if (bio->mem != NULL) { |
wolfSSL | 12:1a06964c2adb | 118 | XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL); |
wolfSSL | 12:1a06964c2adb | 119 | } |
wolfSSL | 12:1a06964c2adb | 120 | |
wolfSSL | 12:1a06964c2adb | 121 | bio->mem = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL); |
wolfSSL | 12:1a06964c2adb | 122 | if (bio->mem == NULL) { |
wolfSSL | 12:1a06964c2adb | 123 | WOLFSSL_MSG("Memory allocation error"); |
wolfSSL | 12:1a06964c2adb | 124 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 125 | } |
wolfSSL | 12:1a06964c2adb | 126 | bio->wrIdx = 0; |
wolfSSL | 12:1a06964c2adb | 127 | bio->rdIdx = 0; |
wolfSSL | 12:1a06964c2adb | 128 | |
wolfSSL | 12:1a06964c2adb | 129 | return SSL_SUCCESS; |
wolfSSL | 12:1a06964c2adb | 130 | } |
wolfSSL | 12:1a06964c2adb | 131 | |
wolfSSL | 12:1a06964c2adb | 132 | |
wolfSSL | 12:1a06964c2adb | 133 | /* Joins two BIO_BIO types. The write of b1 goes to the read of b2 and vise |
wolfSSL | 12:1a06964c2adb | 134 | * versa. Creating something similar to a two way pipe. |
wolfSSL | 12:1a06964c2adb | 135 | * Reading and writing between the two BIOs is not thread safe, they are |
wolfSSL | 12:1a06964c2adb | 136 | * expected to be used by the same thread. */ |
wolfSSL | 12:1a06964c2adb | 137 | int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2) |
wolfSSL | 12:1a06964c2adb | 138 | { |
wolfSSL | 12:1a06964c2adb | 139 | WOLFSSL_ENTER("wolfSSL_BIO_make_bio_pair"); |
wolfSSL | 12:1a06964c2adb | 140 | |
wolfSSL | 12:1a06964c2adb | 141 | if (b1 == NULL || b2 == NULL) { |
wolfSSL | 12:1a06964c2adb | 142 | WOLFSSL_LEAVE("wolfSSL_BIO_make_bio_pair", BAD_FUNC_ARG); |
wolfSSL | 12:1a06964c2adb | 143 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 144 | } |
wolfSSL | 12:1a06964c2adb | 145 | |
wolfSSL | 12:1a06964c2adb | 146 | /* both are expected to be of type BIO and not already paired */ |
wolfSSL | 12:1a06964c2adb | 147 | if (b1->type != BIO_BIO || b2->type != BIO_BIO || |
wolfSSL | 12:1a06964c2adb | 148 | b1->pair != NULL || b2->pair != NULL) { |
wolfSSL | 12:1a06964c2adb | 149 | WOLFSSL_MSG("Expected type BIO and not already paired"); |
wolfSSL | 12:1a06964c2adb | 150 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 151 | } |
wolfSSL | 12:1a06964c2adb | 152 | |
wolfSSL | 12:1a06964c2adb | 153 | /* set default write size if not already set */ |
wolfSSL | 12:1a06964c2adb | 154 | if (b1->mem == NULL && wolfSSL_BIO_set_write_buf_size(b1, |
wolfSSL | 12:1a06964c2adb | 155 | WOLFSSL_BIO_SIZE) != SSL_SUCCESS) { |
wolfSSL | 12:1a06964c2adb | 156 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 157 | } |
wolfSSL | 12:1a06964c2adb | 158 | |
wolfSSL | 12:1a06964c2adb | 159 | if (b2->mem == NULL && wolfSSL_BIO_set_write_buf_size(b2, |
wolfSSL | 12:1a06964c2adb | 160 | WOLFSSL_BIO_SIZE) != SSL_SUCCESS) { |
wolfSSL | 12:1a06964c2adb | 161 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 162 | } |
wolfSSL | 12:1a06964c2adb | 163 | |
wolfSSL | 12:1a06964c2adb | 164 | b1->pair = b2; |
wolfSSL | 12:1a06964c2adb | 165 | b2->pair = b1; |
wolfSSL | 12:1a06964c2adb | 166 | |
wolfSSL | 12:1a06964c2adb | 167 | return SSL_SUCCESS; |
wolfSSL | 12:1a06964c2adb | 168 | } |
wolfSSL | 12:1a06964c2adb | 169 | |
wolfSSL | 12:1a06964c2adb | 170 | |
wolfSSL | 12:1a06964c2adb | 171 | int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b) |
wolfSSL | 12:1a06964c2adb | 172 | { |
wolfSSL | 12:1a06964c2adb | 173 | WOLFSSL_ENTER("wolfSSL_BIO_ctrl_reset_read_request"); |
wolfSSL | 12:1a06964c2adb | 174 | |
wolfSSL | 12:1a06964c2adb | 175 | if (b == NULL) { |
wolfSSL | 12:1a06964c2adb | 176 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 177 | } |
wolfSSL | 12:1a06964c2adb | 178 | |
wolfSSL | 12:1a06964c2adb | 179 | b->readRq = 0; |
wolfSSL | 12:1a06964c2adb | 180 | |
wolfSSL | 12:1a06964c2adb | 181 | return SSL_SUCCESS; |
wolfSSL | 12:1a06964c2adb | 182 | } |
wolfSSL | 12:1a06964c2adb | 183 | |
wolfSSL | 12:1a06964c2adb | 184 | |
wolfSSL | 12:1a06964c2adb | 185 | /* Does not advance read index pointer */ |
wolfSSL | 12:1a06964c2adb | 186 | int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf) |
wolfSSL | 12:1a06964c2adb | 187 | { |
wolfSSL | 12:1a06964c2adb | 188 | WOLFSSL_ENTER("wolfSSL_BIO_nread0"); |
wolfSSL | 12:1a06964c2adb | 189 | |
wolfSSL | 12:1a06964c2adb | 190 | if (bio == NULL || buf == NULL) { |
wolfSSL | 12:1a06964c2adb | 191 | WOLFSSL_MSG("NULL argument passed in"); |
wolfSSL | 12:1a06964c2adb | 192 | return 0; |
wolfSSL | 12:1a06964c2adb | 193 | } |
wolfSSL | 12:1a06964c2adb | 194 | |
wolfSSL | 12:1a06964c2adb | 195 | /* if paired read from pair */ |
wolfSSL | 12:1a06964c2adb | 196 | if (bio->pair != NULL) { |
wolfSSL | 12:1a06964c2adb | 197 | WOLFSSL_BIO* pair = bio->pair; |
wolfSSL | 12:1a06964c2adb | 198 | |
wolfSSL | 12:1a06964c2adb | 199 | /* case where have wrapped around write buffer */ |
wolfSSL | 12:1a06964c2adb | 200 | *buf = (char*)pair->mem + pair->rdIdx; |
wolfSSL | 12:1a06964c2adb | 201 | if (pair->wrIdx > 0 && pair->rdIdx >= pair->wrIdx) { |
wolfSSL | 12:1a06964c2adb | 202 | return pair->wrSz - pair->rdIdx; |
wolfSSL | 12:1a06964c2adb | 203 | } |
wolfSSL | 12:1a06964c2adb | 204 | else { |
wolfSSL | 12:1a06964c2adb | 205 | return pair->wrIdx - pair->rdIdx; |
wolfSSL | 12:1a06964c2adb | 206 | } |
wolfSSL | 12:1a06964c2adb | 207 | } |
wolfSSL | 12:1a06964c2adb | 208 | |
wolfSSL | 12:1a06964c2adb | 209 | return 0; |
wolfSSL | 12:1a06964c2adb | 210 | } |
wolfSSL | 12:1a06964c2adb | 211 | |
wolfSSL | 12:1a06964c2adb | 212 | |
wolfSSL | 12:1a06964c2adb | 213 | /* similar to wolfSSL_BIO_nread0 but advances the read index */ |
wolfSSL | 12:1a06964c2adb | 214 | int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num) |
wolfSSL | 12:1a06964c2adb | 215 | { |
wolfSSL | 12:1a06964c2adb | 216 | int sz = WOLFSSL_BIO_UNSET; |
wolfSSL | 12:1a06964c2adb | 217 | |
wolfSSL | 12:1a06964c2adb | 218 | WOLFSSL_ENTER("wolfSSL_BIO_nread"); |
wolfSSL | 12:1a06964c2adb | 219 | |
wolfSSL | 12:1a06964c2adb | 220 | if (bio == NULL || buf == NULL) { |
wolfSSL | 12:1a06964c2adb | 221 | WOLFSSL_MSG("NULL argument passed in"); |
wolfSSL | 12:1a06964c2adb | 222 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 223 | } |
wolfSSL | 12:1a06964c2adb | 224 | |
wolfSSL | 12:1a06964c2adb | 225 | if (bio->pair != NULL) { |
wolfSSL | 12:1a06964c2adb | 226 | /* special case if asking to read 0 bytes */ |
wolfSSL | 12:1a06964c2adb | 227 | if (num == 0) { |
wolfSSL | 12:1a06964c2adb | 228 | *buf = (char*)bio->pair->mem + bio->pair->rdIdx; |
wolfSSL | 12:1a06964c2adb | 229 | return 0; |
wolfSSL | 12:1a06964c2adb | 230 | } |
wolfSSL | 12:1a06964c2adb | 231 | |
wolfSSL | 12:1a06964c2adb | 232 | /* get amount able to read and set buffer pointer */ |
wolfSSL | 12:1a06964c2adb | 233 | sz = wolfSSL_BIO_nread0(bio, buf); |
wolfSSL | 12:1a06964c2adb | 234 | if (sz == 0) { |
wolfSSL | 12:1a06964c2adb | 235 | return WOLFSSL_BIO_ERROR; |
wolfSSL | 12:1a06964c2adb | 236 | } |
wolfSSL | 12:1a06964c2adb | 237 | |
wolfSSL | 12:1a06964c2adb | 238 | if (num < sz) { |
wolfSSL | 12:1a06964c2adb | 239 | sz = num; |
wolfSSL | 12:1a06964c2adb | 240 | } |
wolfSSL | 12:1a06964c2adb | 241 | bio->pair->rdIdx += sz; |
wolfSSL | 12:1a06964c2adb | 242 | |
wolfSSL | 12:1a06964c2adb | 243 | /* check if have read to the end of the buffer and need to reset */ |
wolfSSL | 12:1a06964c2adb | 244 | if (bio->pair->rdIdx == bio->pair->wrSz) { |
wolfSSL | 12:1a06964c2adb | 245 | bio->pair->rdIdx = 0; |
wolfSSL | 12:1a06964c2adb | 246 | if (bio->pair->wrIdx == bio->pair->wrSz) { |
wolfSSL | 12:1a06964c2adb | 247 | bio->pair->wrIdx = 0; |
wolfSSL | 12:1a06964c2adb | 248 | } |
wolfSSL | 12:1a06964c2adb | 249 | } |
wolfSSL | 12:1a06964c2adb | 250 | |
wolfSSL | 12:1a06964c2adb | 251 | /* check if read up to write index, if so then reset indexs */ |
wolfSSL | 12:1a06964c2adb | 252 | if (bio->pair->rdIdx == bio->pair->wrIdx) { |
wolfSSL | 12:1a06964c2adb | 253 | bio->pair->rdIdx = 0; |
wolfSSL | 12:1a06964c2adb | 254 | bio->pair->wrIdx = 0; |
wolfSSL | 12:1a06964c2adb | 255 | } |
wolfSSL | 12:1a06964c2adb | 256 | } |
wolfSSL | 12:1a06964c2adb | 257 | |
wolfSSL | 12:1a06964c2adb | 258 | return sz; |
wolfSSL | 12:1a06964c2adb | 259 | } |
wolfSSL | 12:1a06964c2adb | 260 | |
wolfSSL | 12:1a06964c2adb | 261 | |
wolfSSL | 12:1a06964c2adb | 262 | int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num) |
wolfSSL | 12:1a06964c2adb | 263 | { |
wolfSSL | 12:1a06964c2adb | 264 | int sz = WOLFSSL_BIO_UNSET; |
wolfSSL | 12:1a06964c2adb | 265 | |
wolfSSL | 12:1a06964c2adb | 266 | WOLFSSL_ENTER("wolfSSL_BIO_nwrite"); |
wolfSSL | 12:1a06964c2adb | 267 | |
wolfSSL | 12:1a06964c2adb | 268 | if (bio == NULL || buf == NULL) { |
wolfSSL | 12:1a06964c2adb | 269 | WOLFSSL_MSG("NULL argument passed in"); |
wolfSSL | 12:1a06964c2adb | 270 | return 0; |
wolfSSL | 12:1a06964c2adb | 271 | } |
wolfSSL | 12:1a06964c2adb | 272 | |
wolfSSL | 12:1a06964c2adb | 273 | if (bio->pair != NULL) { |
wolfSSL | 12:1a06964c2adb | 274 | if (num == 0) { |
wolfSSL | 12:1a06964c2adb | 275 | *buf = (char*)bio->mem + bio->wrIdx; |
wolfSSL | 12:1a06964c2adb | 276 | return 0; |
wolfSSL | 12:1a06964c2adb | 277 | } |
wolfSSL | 12:1a06964c2adb | 278 | |
wolfSSL | 12:1a06964c2adb | 279 | if (bio->wrIdx < bio->rdIdx) { |
wolfSSL | 12:1a06964c2adb | 280 | /* if wrapped around only write up to read index. In this case |
wolfSSL | 12:1a06964c2adb | 281 | * rdIdx is always greater then wrIdx so sz will not be negative. */ |
wolfSSL | 12:1a06964c2adb | 282 | sz = bio->rdIdx - bio->wrIdx; |
wolfSSL | 12:1a06964c2adb | 283 | } |
wolfSSL | 12:1a06964c2adb | 284 | else if (bio->rdIdx > 0 && bio->wrIdx == bio->rdIdx) { |
wolfSSL | 12:1a06964c2adb | 285 | return WOLFSSL_BIO_ERROR; /* no more room to write */ |
wolfSSL | 12:1a06964c2adb | 286 | } |
wolfSSL | 12:1a06964c2adb | 287 | else { |
wolfSSL | 12:1a06964c2adb | 288 | /* write index is past read index so write to end of buffer */ |
wolfSSL | 12:1a06964c2adb | 289 | sz = bio->wrSz - bio->wrIdx; |
wolfSSL | 12:1a06964c2adb | 290 | |
wolfSSL | 12:1a06964c2adb | 291 | if (sz <= 0) { |
wolfSSL | 12:1a06964c2adb | 292 | /* either an error has occured with write index or it is at the |
wolfSSL | 12:1a06964c2adb | 293 | * end of the write buffer. */ |
wolfSSL | 12:1a06964c2adb | 294 | if (bio->rdIdx == 0) { |
wolfSSL | 12:1a06964c2adb | 295 | /* no more room, nothing has been read */ |
wolfSSL | 12:1a06964c2adb | 296 | return WOLFSSL_BIO_ERROR; |
wolfSSL | 12:1a06964c2adb | 297 | } |
wolfSSL | 12:1a06964c2adb | 298 | |
wolfSSL | 12:1a06964c2adb | 299 | bio->wrIdx = 0; |
wolfSSL | 12:1a06964c2adb | 300 | |
wolfSSL | 12:1a06964c2adb | 301 | /* check case where read index is not at 0 */ |
wolfSSL | 12:1a06964c2adb | 302 | if (bio->rdIdx > 0) { |
wolfSSL | 12:1a06964c2adb | 303 | sz = bio->rdIdx; /* can write up to the read index */ |
wolfSSL | 12:1a06964c2adb | 304 | } |
wolfSSL | 12:1a06964c2adb | 305 | else { |
wolfSSL | 12:1a06964c2adb | 306 | sz = bio->wrSz; /* no restriction other then buffer size */ |
wolfSSL | 12:1a06964c2adb | 307 | } |
wolfSSL | 12:1a06964c2adb | 308 | } |
wolfSSL | 12:1a06964c2adb | 309 | } |
wolfSSL | 12:1a06964c2adb | 310 | |
wolfSSL | 12:1a06964c2adb | 311 | if (num < sz) { |
wolfSSL | 12:1a06964c2adb | 312 | sz = num; |
wolfSSL | 12:1a06964c2adb | 313 | } |
wolfSSL | 12:1a06964c2adb | 314 | *buf = (char*)bio->mem + bio->wrIdx; |
wolfSSL | 12:1a06964c2adb | 315 | bio->wrIdx += sz; |
wolfSSL | 12:1a06964c2adb | 316 | |
wolfSSL | 12:1a06964c2adb | 317 | /* if at the end of the buffer and space for wrap around then set |
wolfSSL | 12:1a06964c2adb | 318 | * write index back to 0 */ |
wolfSSL | 12:1a06964c2adb | 319 | if (bio->wrIdx == bio->wrSz && bio->rdIdx > 0) { |
wolfSSL | 12:1a06964c2adb | 320 | bio->wrIdx = 0; |
wolfSSL | 12:1a06964c2adb | 321 | } |
wolfSSL | 12:1a06964c2adb | 322 | } |
wolfSSL | 12:1a06964c2adb | 323 | |
wolfSSL | 12:1a06964c2adb | 324 | return sz; |
wolfSSL | 12:1a06964c2adb | 325 | } |
wolfSSL | 12:1a06964c2adb | 326 | |
wolfSSL | 12:1a06964c2adb | 327 | |
wolfSSL | 12:1a06964c2adb | 328 | /* Reset BIO to initial state */ |
wolfSSL | 12:1a06964c2adb | 329 | int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) |
wolfSSL | 12:1a06964c2adb | 330 | { |
wolfSSL | 12:1a06964c2adb | 331 | WOLFSSL_ENTER("wolfSSL_BIO_reset"); |
wolfSSL | 12:1a06964c2adb | 332 | |
wolfSSL | 12:1a06964c2adb | 333 | if (bio == NULL) { |
wolfSSL | 12:1a06964c2adb | 334 | WOLFSSL_MSG("NULL argument passed in"); |
wolfSSL | 12:1a06964c2adb | 335 | /* -1 is consistent failure even for FILE type */ |
wolfSSL | 12:1a06964c2adb | 336 | return WOLFSSL_BIO_ERROR; |
wolfSSL | 12:1a06964c2adb | 337 | } |
wolfSSL | 12:1a06964c2adb | 338 | |
wolfSSL | 12:1a06964c2adb | 339 | switch (bio->type) { |
wolfSSL | 12:1a06964c2adb | 340 | #ifndef NO_FILESYSTEM |
wolfSSL | 12:1a06964c2adb | 341 | case BIO_FILE: |
wolfSSL | 12:1a06964c2adb | 342 | XREWIND(bio->file); |
wolfSSL | 12:1a06964c2adb | 343 | return 0; |
wolfSSL | 12:1a06964c2adb | 344 | #endif |
wolfSSL | 12:1a06964c2adb | 345 | |
wolfSSL | 12:1a06964c2adb | 346 | case BIO_BIO: |
wolfSSL | 12:1a06964c2adb | 347 | bio->rdIdx = 0; |
wolfSSL | 12:1a06964c2adb | 348 | bio->wrIdx = 0; |
wolfSSL | 12:1a06964c2adb | 349 | return 0; |
wolfSSL | 12:1a06964c2adb | 350 | |
wolfSSL | 12:1a06964c2adb | 351 | default: |
wolfSSL | 12:1a06964c2adb | 352 | WOLFSSL_MSG("Unknown BIO type needs added to reset function"); |
wolfSSL | 12:1a06964c2adb | 353 | } |
wolfSSL | 12:1a06964c2adb | 354 | |
wolfSSL | 12:1a06964c2adb | 355 | return WOLFSSL_BIO_ERROR; |
wolfSSL | 12:1a06964c2adb | 356 | } |
wolfSSL | 12:1a06964c2adb | 357 | |
wolfSSL | 12:1a06964c2adb | 358 | #ifndef NO_FILESYSTEM |
wolfSSL | 12:1a06964c2adb | 359 | long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c) |
wolfSSL | 12:1a06964c2adb | 360 | { |
wolfSSL | 12:1a06964c2adb | 361 | WOLFSSL_ENTER("wolfSSL_BIO_set_fp"); |
wolfSSL | 12:1a06964c2adb | 362 | |
wolfSSL | 12:1a06964c2adb | 363 | if (bio == NULL || fp == NULL) { |
wolfSSL | 12:1a06964c2adb | 364 | WOLFSSL_LEAVE("wolfSSL_BIO_set_fp", BAD_FUNC_ARG); |
wolfSSL | 12:1a06964c2adb | 365 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 366 | } |
wolfSSL | 12:1a06964c2adb | 367 | |
wolfSSL | 12:1a06964c2adb | 368 | if (bio->type != BIO_FILE) { |
wolfSSL | 12:1a06964c2adb | 369 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 370 | } |
wolfSSL | 12:1a06964c2adb | 371 | |
wolfSSL | 12:1a06964c2adb | 372 | bio->close = (byte)c; |
wolfSSL | 12:1a06964c2adb | 373 | bio->file = fp; |
wolfSSL | 12:1a06964c2adb | 374 | |
wolfSSL | 12:1a06964c2adb | 375 | return SSL_SUCCESS; |
wolfSSL | 12:1a06964c2adb | 376 | } |
wolfSSL | 12:1a06964c2adb | 377 | |
wolfSSL | 12:1a06964c2adb | 378 | |
wolfSSL | 12:1a06964c2adb | 379 | long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp) |
wolfSSL | 12:1a06964c2adb | 380 | { |
wolfSSL | 12:1a06964c2adb | 381 | WOLFSSL_ENTER("wolfSSL_BIO_get_fp"); |
wolfSSL | 12:1a06964c2adb | 382 | |
wolfSSL | 12:1a06964c2adb | 383 | if (bio == NULL || fp == NULL) { |
wolfSSL | 12:1a06964c2adb | 384 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 385 | } |
wolfSSL | 12:1a06964c2adb | 386 | |
wolfSSL | 12:1a06964c2adb | 387 | if (bio->type != BIO_FILE) { |
wolfSSL | 12:1a06964c2adb | 388 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 389 | } |
wolfSSL | 12:1a06964c2adb | 390 | |
wolfSSL | 12:1a06964c2adb | 391 | *fp = bio->file; |
wolfSSL | 12:1a06964c2adb | 392 | |
wolfSSL | 12:1a06964c2adb | 393 | return SSL_SUCCESS; |
wolfSSL | 12:1a06964c2adb | 394 | } |
wolfSSL | 12:1a06964c2adb | 395 | |
wolfSSL | 12:1a06964c2adb | 396 | /* overwrites file */ |
wolfSSL | 12:1a06964c2adb | 397 | int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name) |
wolfSSL | 12:1a06964c2adb | 398 | { |
wolfSSL | 12:1a06964c2adb | 399 | WOLFSSL_ENTER("wolfSSL_BIO_write_filename"); |
wolfSSL | 12:1a06964c2adb | 400 | |
wolfSSL | 12:1a06964c2adb | 401 | if (bio == NULL || name == NULL) { |
wolfSSL | 12:1a06964c2adb | 402 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 403 | } |
wolfSSL | 12:1a06964c2adb | 404 | |
wolfSSL | 12:1a06964c2adb | 405 | if (bio->type == BIO_FILE) { |
wolfSSL | 12:1a06964c2adb | 406 | if (bio->file != NULL && bio->close == BIO_CLOSE) { |
wolfSSL | 12:1a06964c2adb | 407 | XFCLOSE(bio->file); |
wolfSSL | 12:1a06964c2adb | 408 | } |
wolfSSL | 12:1a06964c2adb | 409 | |
wolfSSL | 12:1a06964c2adb | 410 | bio->file = XFOPEN(name, "w"); |
wolfSSL | 12:1a06964c2adb | 411 | if (bio->file == NULL) { |
wolfSSL | 12:1a06964c2adb | 412 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 413 | } |
wolfSSL | 12:1a06964c2adb | 414 | bio->close = BIO_CLOSE; |
wolfSSL | 12:1a06964c2adb | 415 | |
wolfSSL | 12:1a06964c2adb | 416 | return SSL_SUCCESS; |
wolfSSL | 12:1a06964c2adb | 417 | } |
wolfSSL | 12:1a06964c2adb | 418 | |
wolfSSL | 12:1a06964c2adb | 419 | return SSL_FAILURE; |
wolfSSL | 12:1a06964c2adb | 420 | } |
wolfSSL | 12:1a06964c2adb | 421 | |
wolfSSL | 12:1a06964c2adb | 422 | |
wolfSSL | 12:1a06964c2adb | 423 | int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs) |
wolfSSL | 12:1a06964c2adb | 424 | { |
wolfSSL | 12:1a06964c2adb | 425 | WOLFSSL_ENTER("wolfSSL_BIO_seek"); |
wolfSSL | 12:1a06964c2adb | 426 | |
wolfSSL | 12:1a06964c2adb | 427 | if (bio == NULL) { |
wolfSSL | 12:1a06964c2adb | 428 | return -1; |
wolfSSL | 12:1a06964c2adb | 429 | } |
wolfSSL | 12:1a06964c2adb | 430 | |
wolfSSL | 12:1a06964c2adb | 431 | /* offset ofs from begining of file */ |
wolfSSL | 12:1a06964c2adb | 432 | if (bio->type == BIO_FILE && XFSEEK(bio->file, ofs, SEEK_SET) < 0) { |
wolfSSL | 12:1a06964c2adb | 433 | return -1; |
wolfSSL | 12:1a06964c2adb | 434 | } |
wolfSSL | 12:1a06964c2adb | 435 | |
wolfSSL | 12:1a06964c2adb | 436 | return 0; |
wolfSSL | 12:1a06964c2adb | 437 | } |
wolfSSL | 12:1a06964c2adb | 438 | #endif /* NO_FILESYSTEM */ |
wolfSSL | 12:1a06964c2adb | 439 | |
wolfSSL | 12:1a06964c2adb | 440 | |
wolfSSL | 12:1a06964c2adb | 441 | long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) |
wolfSSL | 12:1a06964c2adb | 442 | { |
wolfSSL | 12:1a06964c2adb | 443 | WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return"); |
wolfSSL | 12:1a06964c2adb | 444 | |
wolfSSL | 12:1a06964c2adb | 445 | if (bio != NULL) { |
wolfSSL | 12:1a06964c2adb | 446 | bio->eof = v; |
wolfSSL | 12:1a06964c2adb | 447 | } |
wolfSSL | 12:1a06964c2adb | 448 | |
wolfSSL | 12:1a06964c2adb | 449 | return 0; |
wolfSSL | 12:1a06964c2adb | 450 | } |
wolfSSL | 12:1a06964c2adb | 451 | #endif /* WOLFSSL_BIO_INCLUDED */ |
wolfSSL | 12:1a06964c2adb | 452 | |
wolfSSL | 12:1a06964c2adb | 453 |