2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
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
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
, int free_all
);
24 static int mem_buf_sync(BIO
*h
);
26 static const BIO_METHOD mem_method
= {
39 static const BIO_METHOD secmem_method
= {
41 "secure memory buffer",
52 /* BIO memory stores buffer and read pointer */
53 typedef struct bio_buf_mem_st
{
54 struct buf_mem_st
*buf
; /* allocated buffer */
55 struct buf_mem_st
*readp
; /* read pointer */
59 * bio->num is used to hold the value to return on 'empty', if it is 0,
60 * should_retry is not set
63 const BIO_METHOD
*BIO_s_mem(void)
68 const BIO_METHOD
*BIO_s_secmem(void)
70 return(&secmem_method
);
73 BIO
*BIO_new_mem_buf(const void *buf
, int len
)
81 BIOerr(BIO_F_BIO_NEW_MEM_BUF
, BIO_R_NULL_PARAMETER
);
84 sz
= (len
< 0) ? strlen(buf
) : (size_t)len
;
85 if ((ret
= BIO_new(BIO_s_mem())) == NULL
)
87 bb
= (BIO_BUF_MEM
*)ret
->ptr
;
89 /* Cast away const and trust in the MEM_RDONLY flag. */
90 b
->data
= (void *)buf
;
93 *bb
->readp
= *bb
->buf
;
94 ret
->flags
|= BIO_FLAGS_MEM_RDONLY
;
95 /* Since this is static data retrying won't help */
100 static int mem_init(BIO
*bi
, unsigned long flags
)
102 BIO_BUF_MEM
*bb
= OPENSSL_zalloc(sizeof(*bb
));
106 if ((bb
->buf
= BUF_MEM_new_ex(flags
)) == NULL
) {
110 if ((bb
->readp
= OPENSSL_zalloc(sizeof(*bb
->readp
))) == NULL
) {
111 BUF_MEM_free(bb
->buf
);
115 *bb
->readp
= *bb
->buf
;
119 bi
->ptr
= (char *)bb
;
123 static int mem_new(BIO
*bi
)
125 return (mem_init(bi
, 0L));
128 static int secmem_new(BIO
*bi
)
130 return (mem_init(bi
, BUF_MEM_FLAG_SECURE
));
133 static int mem_free(BIO
*a
)
135 return (mem_buf_free(a
, 1));
138 static int mem_buf_free(BIO
*a
, int free_all
)
143 if ((a
->init
) && (a
->ptr
!= NULL
)) {
145 BIO_BUF_MEM
*bb
= (BIO_BUF_MEM
*)a
->ptr
;
149 if (a
->flags
& BIO_FLAGS_MEM_RDONLY
)
153 OPENSSL_free(bb
->readp
);
164 * Reallocate memory buffer if read pointer differs
166 static int mem_buf_sync(BIO
*b
)
168 if (b
!= NULL
&& b
->init
!= 0 && b
->ptr
!= NULL
) {
169 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
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
;
180 static int mem_read(BIO
*b
, char *out
, int outl
)
183 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
184 BUF_MEM
*bm
= bbm
->readp
;
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
);
192 } else if (bm
->length
== 0) {
195 BIO_set_retry_read(b
);
200 static int mem_write(BIO
*b
, const char *in
, int inl
)
204 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
207 BIOerr(BIO_F_MEM_WRITE
, BIO_R_NULL_PARAMETER
);
210 if (b
->flags
& BIO_FLAGS_MEM_RDONLY
) {
211 BIOerr(BIO_F_MEM_WRITE
, BIO_R_WRITE_TO_READ_ONLY_BIO
);
214 BIO_clear_retry_flags(b
);
215 blen
= bbm
->readp
->length
;
217 if (BUF_MEM_grow_clean(bbm
->buf
, blen
+ inl
) == 0)
219 memcpy(bbm
->buf
->data
+ blen
, in
, inl
);
220 *bbm
->readp
= *bbm
->buf
;
226 static long mem_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
230 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)b
->ptr
;
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
;
241 memset(bm
->data
, 0, bm
->max
);
244 *bbm
->readp
= *bbm
->buf
;
249 ret
= (long)(bm
->length
== 0);
251 case BIO_C_SET_BUF_MEM_EOF_RETURN
:
256 ret
= (long)bm
->length
;
259 *pptr
= (char *)&(bm
->data
[0]);
262 case BIO_C_SET_BUF_MEM
:
264 b
->shutdown
= (int)num
;
266 *bbm
->readp
= *bbm
->buf
;
269 case BIO_C_GET_BUF_MEM_PTR
:
277 case BIO_CTRL_GET_CLOSE
:
278 ret
= (long)b
->shutdown
;
280 case BIO_CTRL_SET_CLOSE
:
281 b
->shutdown
= (int)num
;
283 case BIO_CTRL_WPENDING
:
286 case BIO_CTRL_PENDING
:
288 ret
= (long)bm
->length
;
303 static int mem_gets(BIO
*bp
, char *buf
, int size
)
308 BIO_BUF_MEM
*bbm
= (BIO_BUF_MEM
*)bp
->ptr
;
309 BUF_MEM
*bm
= bbm
->readp
;
311 BIO_clear_retry_flags(bp
);
320 for (i
= 0; i
< j
; i
++) {
328 * i is now the max num of bytes to copy, either j or up to
329 * and including the first newline
332 i
= mem_read(bp
, buf
, i
);
339 static int mem_puts(BIO
*bp
, const char *str
)
344 ret
= mem_write(bp
, str
, n
);
345 /* memory semantics is that it will always work */