2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
12 #include "bio_local.h"
13 #include "internal/cryptlib.h"
15 static int mem_write(BIO
*h
, const char *buf
, int num
);
16 static int mem_read(BIO
*h
, char *buf
, int size
);
17 static int mem_puts(BIO
*h
, const char *str
);
18 static int mem_gets(BIO
*h
, char *str
, int size
);
19 static long mem_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
20 static int mem_new(BIO
*h
);
21 static int secmem_new(BIO
*h
);
22 static int mem_free(BIO
*data
);
23 static int mem_buf_free(BIO
*data
);
24 static int mem_buf_sync(BIO
*h
);
26 static const BIO_METHOD mem_method
= {
29 /* TODO: Convert to new style write function */
32 /* TODO: Convert to new style read function */
40 NULL
, /* mem_callback_ctrl */
43 static const BIO_METHOD secmem_method
= {
45 "secure memory buffer",
46 /* TODO: Convert to new style write function */
49 /* TODO: Convert to new style read function */
57 NULL
, /* mem_callback_ctrl */
61 * BIO memory stores buffer and read pointer
62 * however the roles are different for read only BIOs.
63 * In that case the readp just stores the original state
64 * to be used for reset.
66 typedef struct bio_buf_mem_st
{
67 struct buf_mem_st
*buf
; /* allocated buffer */
68 struct buf_mem_st
*readp
; /* read pointer */
72 * bio->num is used to hold the value to return on 'empty', if it is 0,
73 * should_retry is not set
76 const BIO_METHOD
*BIO_s_mem(void)
81 const BIO_METHOD
*BIO_s_secmem(void)
83 return(&secmem_method
);
86 BIO
*BIO_new_mem_buf(const void *buf
, int len
)
94 BIOerr(BIO_F_BIO_NEW_MEM_BUF
, BIO_R_NULL_PARAMETER
);
97 sz
= (len
< 0) ? strlen(buf
) : (size_t)len
;
98 if ((ret
= BIO_new(BIO_s_mem())) == NULL
)
100 bb
= (BIO_BUF_MEM
*)ret
->ptr
;
102 /* Cast away const and trust in the MEM_RDONLY flag. */
103 b
->data
= (void *)buf
;
106 *bb
->readp
= *bb
->buf
;
107 ret
->flags
|= BIO_FLAGS_MEM_RDONLY
;
108 /* Since this is static data retrying won't help */
113 static int mem_init(BIO
*bi
, unsigned long flags
)
115 BIO_BUF_MEM
*bb
= OPENSSL_zalloc(sizeof(*bb
));
119 if ((bb
->buf
= BUF_MEM_new_ex(flags
)) == NULL
) {
123 if ((bb
->readp
= OPENSSL_zalloc(sizeof(*bb
->readp
))) == NULL
) {
124 BUF_MEM_free(bb
->buf
);
128 *bb
->readp
= *bb
->buf
;
132 bi
->ptr
= (char *)bb
;
136 static int mem_new(BIO
*bi
)
138 return mem_init(bi
, 0L);
141 static int secmem_new(BIO
*bi
)
143 return mem_init(bi
, BUF_MEM_FLAG_SECURE
);
146 static int mem_free(BIO
*a
)
153 bb
= (BIO_BUF_MEM
*)a
->ptr
;
154 if (!mem_buf_free(a
))
156 OPENSSL_free(bb
->readp
);
161 static int mem_buf_free(BIO
*a
)
166 if (a
->shutdown
&& a
->init
&& a
->ptr
!= NULL
) {
167 BIO_BUF_MEM
*bb
= (BIO_BUF_MEM
*)a
->ptr
;
168 BUF_MEM
*b
= bb
->buf
;
170 if (a
->flags
& BIO_FLAGS_MEM_RDONLY
)
178 * Reallocate memory buffer if read pointer differs
181 static int mem_buf_sync(BIO
*b
)
183 if (b
!= NULL
&& b
->init
!= 0 && b
->ptr
!= NULL
) {
184 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
186 if (bbm
->readp
->data
!= bbm
->buf
->data
) {
187 memmove(bbm
->buf
->data
, bbm
->readp
->data
, bbm
->readp
->length
);
188 bbm
->buf
->length
= bbm
->readp
->length
;
189 bbm
->readp
->data
= bbm
->buf
->data
;
195 static int mem_read(BIO
*b
, char *out
, int outl
)
198 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
199 BUF_MEM
*bm
= bbm
->readp
;
201 if (b
->flags
& BIO_FLAGS_MEM_RDONLY
)
203 BIO_clear_retry_flags(b
);
204 ret
= (outl
>= 0 && (size_t)outl
> bm
->length
) ? (int)bm
->length
: outl
;
205 if ((out
!= NULL
) && (ret
> 0)) {
206 memcpy(out
, bm
->data
, ret
);
210 } else if (bm
->length
== 0) {
213 BIO_set_retry_read(b
);
218 static int mem_write(BIO
*b
, const char *in
, int inl
)
222 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
225 BIOerr(BIO_F_MEM_WRITE
, BIO_R_NULL_PARAMETER
);
228 if (b
->flags
& BIO_FLAGS_MEM_RDONLY
) {
229 BIOerr(BIO_F_MEM_WRITE
, BIO_R_WRITE_TO_READ_ONLY_BIO
);
232 BIO_clear_retry_flags(b
);
235 blen
= bbm
->readp
->length
;
237 if (BUF_MEM_grow_clean(bbm
->buf
, blen
+ inl
) == 0)
239 memcpy(bbm
->buf
->data
+ blen
, in
, inl
);
240 *bbm
->readp
= *bbm
->buf
;
246 static long mem_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
250 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
251 BUF_MEM
*bm
, *bo
; /* bio_mem, bio_other */
254 if (b
->flags
& BIO_FLAGS_MEM_RDONLY
) {
261 off
= bm
->data
- bo
->data
;
267 if (bm
->data
!= NULL
) {
268 if (!(b
->flags
& BIO_FLAGS_MEM_RDONLY
)) {
269 if (!(b
->flags
& BIO_FLAGS_NONCLEAR_RST
)) {
270 memset(bm
->data
, 0, bm
->max
);
273 *bbm
->readp
= *bbm
->buf
;
275 /* For read only case just reset to the start again */
276 *bbm
->buf
= *bbm
->readp
;
280 case BIO_C_FILE_SEEK
:
281 if (num
< 0 || num
> off
+ remain
)
282 return -1; /* Can't see outside of the current buffer */
284 bm
->data
= bo
->data
+ num
;
285 bm
->length
= bo
->length
- num
;
286 bm
->max
= bo
->max
- num
;
289 case BIO_C_FILE_TELL
:
293 ret
= (long)(bm
->length
== 0);
295 case BIO_C_SET_BUF_MEM_EOF_RETURN
:
299 ret
= (long)bm
->length
;
302 *pptr
= (char *)&(bm
->data
[0]);
305 case BIO_C_SET_BUF_MEM
:
307 b
->shutdown
= (int)num
;
309 *bbm
->readp
= *bbm
->buf
;
311 case BIO_C_GET_BUF_MEM_PTR
:
313 if (!(b
->flags
& BIO_FLAGS_MEM_RDONLY
))
320 case BIO_CTRL_GET_CLOSE
:
321 ret
= (long)b
->shutdown
;
323 case BIO_CTRL_SET_CLOSE
:
324 b
->shutdown
= (int)num
;
326 case BIO_CTRL_WPENDING
:
329 case BIO_CTRL_PENDING
:
330 ret
= (long)bm
->length
;
345 static int mem_gets(BIO
*bp
, char *buf
, int size
)
350 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)bp
->ptr
;
351 BUF_MEM
*bm
= bbm
->readp
;
353 if (bp
->flags
& BIO_FLAGS_MEM_RDONLY
)
355 BIO_clear_retry_flags(bp
);
364 for (i
= 0; i
< j
; i
++) {
372 * i is now the max num of bytes to copy, either j or up to
373 * and including the first newline
376 i
= mem_read(bp
, buf
, i
);
383 static int mem_puts(BIO
*bp
, const char *str
)
388 ret
= mem_write(bp
, str
, n
);
389 /* memory semantics is that it will always work */