source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_mem.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: 8.0 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 mem_write(BIO *h, const char *buf, int num);
16static int mem_read(BIO *h, char *buf, int size);
17static int mem_puts(BIO *h, const char *str);
18static int mem_gets(BIO *h, char *str, int size);
19static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
20static int mem_new(BIO *h);
21static int secmem_new(BIO *h);
22static int mem_free(BIO *data);
23static int mem_buf_free(BIO *data, int free_all);
24static int mem_buf_sync(BIO *h);
25
26static const BIO_METHOD mem_method = {
27 BIO_TYPE_MEM,
28 "memory buffer",
29 mem_write,
30 mem_read,
31 mem_puts,
32 mem_gets,
33 mem_ctrl,
34 mem_new,
35 mem_free,
36 NULL,
37};
38
39static const BIO_METHOD secmem_method = {
40 BIO_TYPE_MEM,
41 "secure memory buffer",
42 mem_write,
43 mem_read,
44 mem_puts,
45 mem_gets,
46 mem_ctrl,
47 secmem_new,
48 mem_free,
49 NULL,
50};
51
52/* BIO memory stores buffer and read pointer */
53typedef struct bio_buf_mem_st {
54 struct buf_mem_st *buf; /* allocated buffer */
55 struct buf_mem_st *readp; /* read pointer */
56} BIO_BUF_MEM;
57
58/*
59 * bio->num is used to hold the value to return on 'empty', if it is 0,
60 * should_retry is not set
61 */
62
63const BIO_METHOD *BIO_s_mem(void)
64{
65 return (&mem_method);
66}
67
68const BIO_METHOD *BIO_s_secmem(void)
69{
70 return(&secmem_method);
71}
72
73BIO *BIO_new_mem_buf(const void *buf, int len)
74{
75 BIO *ret;
76 BUF_MEM *b;
77 BIO_BUF_MEM *bb;
78 size_t sz;
79
80 if (buf == NULL) {
81 BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
82 return NULL;
83 }
84 sz = (len < 0) ? strlen(buf) : (size_t)len;
85 if ((ret = BIO_new(BIO_s_mem())) == NULL)
86 return NULL;
87 bb = (BIO_BUF_MEM *)ret->ptr;
88 b = bb->buf;
89 /* Cast away const and trust in the MEM_RDONLY flag. */
90 b->data = (void *)buf;
91 b->length = sz;
92 b->max = sz;
93 *bb->readp = *bb->buf;
94 ret->flags |= BIO_FLAGS_MEM_RDONLY;
95 /* Since this is static data retrying won't help */
96 ret->num = 0;
97 return ret;
98}
99
100static int mem_init(BIO *bi, unsigned long flags)
101{
102 BIO_BUF_MEM *bb = OPENSSL_zalloc(sizeof(*bb));
103
104 if (bb == NULL)
105 return 0;
106 if ((bb->buf = BUF_MEM_new_ex(flags)) == NULL) {
107 OPENSSL_free(bb);
108 return 0;
109 }
110 if ((bb->readp = OPENSSL_zalloc(sizeof(*bb->readp))) == NULL) {
111 BUF_MEM_free(bb->buf);
112 OPENSSL_free(bb);
113 return 0;
114 }
115 *bb->readp = *bb->buf;
116 bi->shutdown = 1;
117 bi->init = 1;
118 bi->num = -1;
119 bi->ptr = (char *)bb;
120 return 1;
121}
122
123static int mem_new(BIO *bi)
124{
125 return (mem_init(bi, 0L));
126}
127
128static int secmem_new(BIO *bi)
129{
130 return (mem_init(bi, BUF_MEM_FLAG_SECURE));
131}
132
133static int mem_free(BIO *a)
134{
135 return (mem_buf_free(a, 1));
136}
137
138static int mem_buf_free(BIO *a, int free_all)
139{
140 if (a == NULL)
141 return (0);
142 if (a->shutdown) {
143 if ((a->init) && (a->ptr != NULL)) {
144 BUF_MEM *b;
145 BIO_BUF_MEM *bb = (BIO_BUF_MEM *)a->ptr;
146
147 if (bb != NULL) {
148 b = bb->buf;
149 if (a->flags & BIO_FLAGS_MEM_RDONLY)
150 b->data = NULL;
151 BUF_MEM_free(b);
152 if (free_all) {
153 OPENSSL_free(bb->readp);
154 OPENSSL_free(bb);
155 }
156 }
157 a->ptr = NULL;
158 }
159 }
160 return (1);
161}
162
163/*
164 * Reallocate memory buffer if read pointer differs
165 */
166static int mem_buf_sync(BIO *b)
167{
168 if (b != NULL && b->init != 0 && b->ptr != NULL) {
169 BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
170
171 if (bbm->readp->data != bbm->buf->data) {
172 memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
173 bbm->buf->length = bbm->readp->length;
174 bbm->readp->data = bbm->buf->data;
175 }
176 }
177 return (0);
178}
179
180static int mem_read(BIO *b, char *out, int outl)
181{
182 int ret = -1;
183 BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
184 BUF_MEM *bm = bbm->readp;
185
186 BIO_clear_retry_flags(b);
187 ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
188 if ((out != NULL) && (ret > 0)) {
189 memcpy(out, bm->data, ret);
190 bm->length -= ret;
191 bm->data += ret;
192 } else if (bm->length == 0) {
193 ret = b->num;
194 if (ret != 0)
195 BIO_set_retry_read(b);
196 }
197 return (ret);
198}
199
200static int mem_write(BIO *b, const char *in, int inl)
201{
202 int ret = -1;
203 int blen;
204 BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
205
206 if (in == NULL) {
207 BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
208 goto end;
209 }
210 if (b->flags & BIO_FLAGS_MEM_RDONLY) {
211 BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
212 goto end;
213 }
214 BIO_clear_retry_flags(b);
215 blen = bbm->readp->length;
216 mem_buf_sync(b);
217 if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
218 goto end;
219 memcpy(bbm->buf->data + blen, in, inl);
220 *bbm->readp = *bbm->buf;
221 ret = inl;
222 end:
223 return (ret);
224}
225
226static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
227{
228 long ret = 1;
229 char **pptr;
230 BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
231 BUF_MEM *bm;
232
233 switch (cmd) {
234 case BIO_CTRL_RESET:
235 bm = bbm->buf;
236 if (bm->data != NULL) {
237 /* For read only case reset to the start again */
238 if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) {
239 bm->length = bm->max;
240 } else {
241 memset(bm->data, 0, bm->max);
242 bm->length = 0;
243 }
244 *bbm->readp = *bbm->buf;
245 }
246 break;
247 case BIO_CTRL_EOF:
248 bm = bbm->readp;
249 ret = (long)(bm->length == 0);
250 break;
251 case BIO_C_SET_BUF_MEM_EOF_RETURN:
252 b->num = (int)num;
253 break;
254 case BIO_CTRL_INFO:
255 bm = bbm->readp;
256 ret = (long)bm->length;
257 if (ptr != NULL) {
258 pptr = (char **)ptr;
259 *pptr = (char *)&(bm->data[0]);
260 }
261 break;
262 case BIO_C_SET_BUF_MEM:
263 mem_buf_free(b, 0);
264 b->shutdown = (int)num;
265 bbm->buf = ptr;
266 *bbm->readp = *bbm->buf;
267 b->ptr = bbm;
268 break;
269 case BIO_C_GET_BUF_MEM_PTR:
270 if (ptr != NULL) {
271 mem_buf_sync(b);
272 bm = bbm->readp;
273 pptr = (char **)ptr;
274 *pptr = (char *)bm;
275 }
276 break;
277 case BIO_CTRL_GET_CLOSE:
278 ret = (long)b->shutdown;
279 break;
280 case BIO_CTRL_SET_CLOSE:
281 b->shutdown = (int)num;
282 break;
283 case BIO_CTRL_WPENDING:
284 ret = 0L;
285 break;
286 case BIO_CTRL_PENDING:
287 bm = bbm->readp;
288 ret = (long)bm->length;
289 break;
290 case BIO_CTRL_DUP:
291 case BIO_CTRL_FLUSH:
292 ret = 1;
293 break;
294 case BIO_CTRL_PUSH:
295 case BIO_CTRL_POP:
296 default:
297 ret = 0;
298 break;
299 }
300 return (ret);
301}
302
303static int mem_gets(BIO *bp, char *buf, int size)
304{
305 int i, j;
306 int ret = -1;
307 char *p;
308 BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
309 BUF_MEM *bm = bbm->readp;
310
311 BIO_clear_retry_flags(bp);
312 j = bm->length;
313 if ((size - 1) < j)
314 j = size - 1;
315 if (j <= 0) {
316 *buf = '\0';
317 return 0;
318 }
319 p = bm->data;
320 for (i = 0; i < j; i++) {
321 if (p[i] == '\n') {
322 i++;
323 break;
324 }
325 }
326
327 /*
328 * i is now the max num of bytes to copy, either j or up to
329 * and including the first newline
330 */
331
332 i = mem_read(bp, buf, i);
333 if (i > 0)
334 buf[i] = '\0';
335 ret = i;
336 return (ret);
337}
338
339static int mem_puts(BIO *bp, const char *str)
340{
341 int n, ret;
342
343 n = strlen(str);
344 ret = mem_write(bp, str, n);
345 /* memory semantics is that it will always work */
346 return (ret);
347}
Note: See TracBrowser for help on using the repository browser.