source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_buff.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 11.8 KB
Line 
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <errno.h>
12#include "bio_lcl.h"
13#include "internal/cryptlib.h"
14
15static int buffer_write(BIO *h, const char *buf, int num);
16static int buffer_read(BIO *h, char *buf, int size);
17static int buffer_puts(BIO *h, const char *str);
18static int buffer_gets(BIO *h, char *str, int size);
19static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
20static int buffer_new(BIO *h);
21static int buffer_free(BIO *data);
22static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
23#define DEFAULT_BUFFER_SIZE 4096
24
25static const BIO_METHOD methods_buffer = {
26 BIO_TYPE_BUFFER,
27 "buffer",
28 buffer_write,
29 buffer_read,
30 buffer_puts,
31 buffer_gets,
32 buffer_ctrl,
33 buffer_new,
34 buffer_free,
35 buffer_callback_ctrl,
36};
37
38const BIO_METHOD *BIO_f_buffer(void)
39{
40 return (&methods_buffer);
41}
42
43static int buffer_new(BIO *bi)
44{
45 BIO_F_BUFFER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
46
47 if (ctx == NULL)
48 return (0);
49 ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
50 ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
51 if (ctx->ibuf == NULL) {
52 OPENSSL_free(ctx);
53 return (0);
54 }
55 ctx->obuf_size = DEFAULT_BUFFER_SIZE;
56 ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
57 if (ctx->obuf == NULL) {
58 OPENSSL_free(ctx->ibuf);
59 OPENSSL_free(ctx);
60 return (0);
61 }
62
63 bi->init = 1;
64 bi->ptr = (char *)ctx;
65 bi->flags = 0;
66 return (1);
67}
68
69static int buffer_free(BIO *a)
70{
71 BIO_F_BUFFER_CTX *b;
72
73 if (a == NULL)
74 return (0);
75 b = (BIO_F_BUFFER_CTX *)a->ptr;
76 OPENSSL_free(b->ibuf);
77 OPENSSL_free(b->obuf);
78 OPENSSL_free(a->ptr);
79 a->ptr = NULL;
80 a->init = 0;
81 a->flags = 0;
82 return (1);
83}
84
85static int buffer_read(BIO *b, char *out, int outl)
86{
87 int i, num = 0;
88 BIO_F_BUFFER_CTX *ctx;
89
90 if (out == NULL)
91 return (0);
92 ctx = (BIO_F_BUFFER_CTX *)b->ptr;
93
94 if ((ctx == NULL) || (b->next_bio == NULL))
95 return (0);
96 num = 0;
97 BIO_clear_retry_flags(b);
98
99 start:
100 i = ctx->ibuf_len;
101 /* If there is stuff left over, grab it */
102 if (i != 0) {
103 if (i > outl)
104 i = outl;
105 memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
106 ctx->ibuf_off += i;
107 ctx->ibuf_len -= i;
108 num += i;
109 if (outl == i)
110 return (num);
111 outl -= i;
112 out += i;
113 }
114
115 /*
116 * We may have done a partial read. try to do more. We have nothing in
117 * the buffer. If we get an error and have read some data, just return it
118 * and let them retry to get the error again. copy direct to parent
119 * address space
120 */
121 if (outl > ctx->ibuf_size) {
122 for (;;) {
123 i = BIO_read(b->next_bio, out, outl);
124 if (i <= 0) {
125 BIO_copy_next_retry(b);
126 if (i < 0)
127 return ((num > 0) ? num : i);
128 if (i == 0)
129 return (num);
130 }
131 num += i;
132 if (outl == i)
133 return (num);
134 out += i;
135 outl -= i;
136 }
137 }
138 /* else */
139
140 /* we are going to be doing some buffering */
141 i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
142 if (i <= 0) {
143 BIO_copy_next_retry(b);
144 if (i < 0)
145 return ((num > 0) ? num : i);
146 if (i == 0)
147 return (num);
148 }
149 ctx->ibuf_off = 0;
150 ctx->ibuf_len = i;
151
152 /* Lets re-read using ourselves :-) */
153 goto start;
154}
155
156static int buffer_write(BIO *b, const char *in, int inl)
157{
158 int i, num = 0;
159 BIO_F_BUFFER_CTX *ctx;
160
161 if ((in == NULL) || (inl <= 0))
162 return (0);
163 ctx = (BIO_F_BUFFER_CTX *)b->ptr;
164 if ((ctx == NULL) || (b->next_bio == NULL))
165 return (0);
166
167 BIO_clear_retry_flags(b);
168 start:
169 i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
170 /* add to buffer and return */
171 if (i >= inl) {
172 memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
173 ctx->obuf_len += inl;
174 return (num + inl);
175 }
176 /* else */
177 /* stuff already in buffer, so add to it first, then flush */
178 if (ctx->obuf_len != 0) {
179 if (i > 0) { /* lets fill it up if we can */
180 memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
181 in += i;
182 inl -= i;
183 num += i;
184 ctx->obuf_len += i;
185 }
186 /* we now have a full buffer needing flushing */
187 for (;;) {
188 i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
189 ctx->obuf_len);
190 if (i <= 0) {
191 BIO_copy_next_retry(b);
192
193 if (i < 0)
194 return ((num > 0) ? num : i);
195 if (i == 0)
196 return (num);
197 }
198 ctx->obuf_off += i;
199 ctx->obuf_len -= i;
200 if (ctx->obuf_len == 0)
201 break;
202 }
203 }
204 /*
205 * we only get here if the buffer has been flushed and we still have
206 * stuff to write
207 */
208 ctx->obuf_off = 0;
209
210 /* we now have inl bytes to write */
211 while (inl >= ctx->obuf_size) {
212 i = BIO_write(b->next_bio, in, inl);
213 if (i <= 0) {
214 BIO_copy_next_retry(b);
215 if (i < 0)
216 return ((num > 0) ? num : i);
217 if (i == 0)
218 return (num);
219 }
220 num += i;
221 in += i;
222 inl -= i;
223 if (inl == 0)
224 return (num);
225 }
226
227 /*
228 * copy the rest into the buffer since we have only a small amount left
229 */
230 goto start;
231}
232
233static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
234{
235 BIO *dbio;
236 BIO_F_BUFFER_CTX *ctx;
237 long ret = 1;
238 char *p1, *p2;
239 int r, i, *ip;
240 int ibs, obs;
241
242 ctx = (BIO_F_BUFFER_CTX *)b->ptr;
243
244 switch (cmd) {
245 case BIO_CTRL_RESET:
246 ctx->ibuf_off = 0;
247 ctx->ibuf_len = 0;
248 ctx->obuf_off = 0;
249 ctx->obuf_len = 0;
250 if (b->next_bio == NULL)
251 return (0);
252 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
253 break;
254 case BIO_CTRL_INFO:
255 ret = (long)ctx->obuf_len;
256 break;
257 case BIO_C_GET_BUFF_NUM_LINES:
258 ret = 0;
259 p1 = ctx->ibuf;
260 for (i = 0; i < ctx->ibuf_len; i++) {
261 if (p1[ctx->ibuf_off + i] == '\n')
262 ret++;
263 }
264 break;
265 case BIO_CTRL_WPENDING:
266 ret = (long)ctx->obuf_len;
267 if (ret == 0) {
268 if (b->next_bio == NULL)
269 return (0);
270 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
271 }
272 break;
273 case BIO_CTRL_PENDING:
274 ret = (long)ctx->ibuf_len;
275 if (ret == 0) {
276 if (b->next_bio == NULL)
277 return (0);
278 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
279 }
280 break;
281 case BIO_C_SET_BUFF_READ_DATA:
282 if (num > ctx->ibuf_size) {
283 p1 = OPENSSL_malloc((int)num);
284 if (p1 == NULL)
285 goto malloc_error;
286 OPENSSL_free(ctx->ibuf);
287 ctx->ibuf = p1;
288 }
289 ctx->ibuf_off = 0;
290 ctx->ibuf_len = (int)num;
291 memcpy(ctx->ibuf, ptr, (int)num);
292 ret = 1;
293 break;
294 case BIO_C_SET_BUFF_SIZE:
295 if (ptr != NULL) {
296 ip = (int *)ptr;
297 if (*ip == 0) {
298 ibs = (int)num;
299 obs = ctx->obuf_size;
300 } else { /* if (*ip == 1) */
301
302 ibs = ctx->ibuf_size;
303 obs = (int)num;
304 }
305 } else {
306 ibs = (int)num;
307 obs = (int)num;
308 }
309 p1 = ctx->ibuf;
310 p2 = ctx->obuf;
311 if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
312 p1 = OPENSSL_malloc((int)num);
313 if (p1 == NULL)
314 goto malloc_error;
315 }
316 if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
317 p2 = OPENSSL_malloc((int)num);
318 if (p2 == NULL) {
319 if (p1 != ctx->ibuf)
320 OPENSSL_free(p1);
321 goto malloc_error;
322 }
323 }
324 if (ctx->ibuf != p1) {
325 OPENSSL_free(ctx->ibuf);
326 ctx->ibuf = p1;
327 ctx->ibuf_off = 0;
328 ctx->ibuf_len = 0;
329 ctx->ibuf_size = ibs;
330 }
331 if (ctx->obuf != p2) {
332 OPENSSL_free(ctx->obuf);
333 ctx->obuf = p2;
334 ctx->obuf_off = 0;
335 ctx->obuf_len = 0;
336 ctx->obuf_size = obs;
337 }
338 break;
339 case BIO_C_DO_STATE_MACHINE:
340 if (b->next_bio == NULL)
341 return (0);
342 BIO_clear_retry_flags(b);
343 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
344 BIO_copy_next_retry(b);
345 break;
346
347 case BIO_CTRL_FLUSH:
348 if (b->next_bio == NULL)
349 return (0);
350 if (ctx->obuf_len <= 0) {
351 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
352 break;
353 }
354
355 for (;;) {
356 BIO_clear_retry_flags(b);
357 if (ctx->obuf_len > 0) {
358 r = BIO_write(b->next_bio,
359 &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
360 BIO_copy_next_retry(b);
361 if (r <= 0)
362 return ((long)r);
363 ctx->obuf_off += r;
364 ctx->obuf_len -= r;
365 } else {
366 ctx->obuf_len = 0;
367 ctx->obuf_off = 0;
368 break;
369 }
370 }
371 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
372 break;
373 case BIO_CTRL_DUP:
374 dbio = (BIO *)ptr;
375 if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
376 !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
377 ret = 0;
378 break;
379 default:
380 if (b->next_bio == NULL)
381 return (0);
382 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
383 break;
384 }
385 return (ret);
386 malloc_error:
387 BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
388 return (0);
389}
390
391static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
392{
393 long ret = 1;
394
395 if (b->next_bio == NULL)
396 return (0);
397 switch (cmd) {
398 default:
399 ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
400 break;
401 }
402 return (ret);
403}
404
405static int buffer_gets(BIO *b, char *buf, int size)
406{
407 BIO_F_BUFFER_CTX *ctx;
408 int num = 0, i, flag;
409 char *p;
410
411 ctx = (BIO_F_BUFFER_CTX *)b->ptr;
412 size--; /* reserve space for a '\0' */
413 BIO_clear_retry_flags(b);
414
415 for (;;) {
416 if (ctx->ibuf_len > 0) {
417 p = &(ctx->ibuf[ctx->ibuf_off]);
418 flag = 0;
419 for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
420 *(buf++) = p[i];
421 if (p[i] == '\n') {
422 flag = 1;
423 i++;
424 break;
425 }
426 }
427 num += i;
428 size -= i;
429 ctx->ibuf_len -= i;
430 ctx->ibuf_off += i;
431 if (flag || size == 0) {
432 *buf = '\0';
433 return (num);
434 }
435 } else { /* read another chunk */
436
437 i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
438 if (i <= 0) {
439 BIO_copy_next_retry(b);
440 *buf = '\0';
441 if (i < 0)
442 return ((num > 0) ? num : i);
443 if (i == 0)
444 return (num);
445 }
446 ctx->ibuf_len = i;
447 ctx->ibuf_off = 0;
448 }
449 }
450}
451
452static int buffer_puts(BIO *b, const char *str)
453{
454 return (buffer_write(b, str, strlen(str)));
455}
Note: See TracBrowser for help on using the repository browser.