OpenSSL
1.0.1c
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
crypto
bio
bf_buff.c
Go to the documentation of this file.
1
/* crypto/bio/bf_buff.c */
2
/* Copyright (C) 1995-1998 Eric Young (
[email protected]
)
3
* All rights reserved.
4
*
5
* This package is an SSL implementation written
6
* by Eric Young (
[email protected]
).
7
* The implementation was written so as to conform with Netscapes SSL.
8
*
9
* This library is free for commercial and non-commercial use as long as
10
* the following conditions are aheared to. The following conditions
11
* apply to all code found in this distribution, be it the RC4, RSA,
12
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
13
* included with this distribution is covered by the same copyright terms
14
* except that the holder is Tim Hudson (
[email protected]
).
15
*
16
* Copyright remains Eric Young's, and as such any Copyright notices in
17
* the code are not to be removed.
18
* If this package is used in a product, Eric Young should be given attribution
19
* as the author of the parts of the library used.
20
* This can be in the form of a textual message at program startup or
21
* in documentation (online or textual) provided with the package.
22
*
23
* Redistribution and use in source and binary forms, with or without
24
* modification, are permitted provided that the following conditions
25
* are met:
26
* 1. Redistributions of source code must retain the copyright
27
* notice, this list of conditions and the following disclaimer.
28
* 2. Redistributions in binary form must reproduce the above copyright
29
* notice, this list of conditions and the following disclaimer in the
30
* documentation and/or other materials provided with the distribution.
31
* 3. All advertising materials mentioning features or use of this software
32
* must display the following acknowledgement:
33
* "This product includes cryptographic software written by
34
* Eric Young (
[email protected]
)"
35
* The word 'cryptographic' can be left out if the rouines from the library
36
* being used are not cryptographic related :-).
37
* 4. If you include any Windows specific code (or a derivative thereof) from
38
* the apps directory (application code) you must include an acknowledgement:
39
* "This product includes software written by Tim Hudson (
[email protected]
)"
40
*
41
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
* SUCH DAMAGE.
52
*
53
* The licence and distribution terms for any publically available version or
54
* derivative of this code cannot be changed. i.e. this code cannot simply be
55
* copied and put under another distribution licence
56
* [including the GNU Public Licence.]
57
*/
58
59
#include <stdio.h>
60
#include <errno.h>
61
#include "
cryptlib.h
"
62
#include <
openssl/bio.h
>
63
64
static
int
buffer_write(
BIO
*
h
,
const
char
*buf,
int
num
);
65
static
int
buffer_read(
BIO
*
h
,
char
*buf,
int
size);
66
static
int
buffer_puts(
BIO
*
h
,
const
char
*str);
67
static
int
buffer_gets(
BIO
*
h
,
char
*str,
int
size);
68
static
long
buffer_ctrl(
BIO
*
h
,
int
cmd,
long
arg1,
void
*arg2);
69
static
int
buffer_new(
BIO
*
h
);
70
static
int
buffer_free(
BIO
*
data
);
71
static
long
buffer_callback_ctrl(
BIO
*
h
,
int
cmd,
bio_info_cb
*
fp
);
72
#define DEFAULT_BUFFER_SIZE 4096
73
74
static
BIO_METHOD
methods_buffer=
75
{
76
BIO_TYPE_BUFFER
,
77
"buffer"
,
78
buffer_write,
79
buffer_read,
80
buffer_puts,
81
buffer_gets,
82
buffer_ctrl,
83
buffer_new,
84
buffer_free,
85
buffer_callback_ctrl,
86
};
87
88
BIO_METHOD
*
BIO_f_buffer
(
void
)
89
{
90
return
(&methods_buffer);
91
}
92
93
static
int
buffer_new(
BIO
*bi)
94
{
95
BIO_F_BUFFER_CTX
*ctx;
96
97
ctx=(
BIO_F_BUFFER_CTX
*)
OPENSSL_malloc
(
sizeof
(
BIO_F_BUFFER_CTX
));
98
if
(ctx == NULL)
return
(0);
99
ctx->
ibuf
=(
char
*)
OPENSSL_malloc
(
DEFAULT_BUFFER_SIZE
);
100
if
(ctx->
ibuf
== NULL) {
OPENSSL_free
(ctx);
return
(0); }
101
ctx->
obuf
=(
char
*)
OPENSSL_malloc
(
DEFAULT_BUFFER_SIZE
);
102
if
(ctx->
obuf
== NULL) {
OPENSSL_free
(ctx->
ibuf
);
OPENSSL_free
(ctx);
return
(0); }
103
ctx->
ibuf_size
=
DEFAULT_BUFFER_SIZE
;
104
ctx->
obuf_size
=
DEFAULT_BUFFER_SIZE
;
105
ctx->
ibuf_len
=0;
106
ctx->
ibuf_off
=0;
107
ctx->
obuf_len
=0;
108
ctx->
obuf_off
=0;
109
110
bi->
init
=1;
111
bi->
ptr
=(
char
*)ctx;
112
bi->
flags
=0;
113
return
(1);
114
}
115
116
static
int
buffer_free(
BIO
*
a
)
117
{
118
BIO_F_BUFFER_CTX
*
b
;
119
120
if
(a == NULL)
return
(0);
121
b=(
BIO_F_BUFFER_CTX
*)a->
ptr
;
122
if
(b->
ibuf
!= NULL)
OPENSSL_free
(b->
ibuf
);
123
if
(b->
obuf
!= NULL)
OPENSSL_free
(b->
obuf
);
124
OPENSSL_free
(a->
ptr
);
125
a->
ptr
=NULL;
126
a->
init
=0;
127
a->
flags
=0;
128
return
(1);
129
}
130
131
static
int
buffer_read(
BIO
*b,
char
*out,
int
outl)
132
{
133
int
i,
num
=0;
134
BIO_F_BUFFER_CTX
*ctx;
135
136
if
(out == NULL)
return
(0);
137
ctx=(
BIO_F_BUFFER_CTX
*)b->
ptr
;
138
139
if
((ctx == NULL) || (b->
next_bio
== NULL))
return
(0);
140
num=0;
141
BIO_clear_retry_flags
(b);
142
143
start:
144
i=ctx->
ibuf_len
;
145
/* If there is stuff left over, grab it */
146
if
(i != 0)
147
{
148
if
(i > outl) i=outl;
149
memcpy(out,&(ctx->
ibuf
[ctx->
ibuf_off
]),i);
150
ctx->
ibuf_off
+=i;
151
ctx->
ibuf_len
-=i;
152
num+=i;
153
if
(outl == i)
return
(num);
154
outl-=i;
155
out+=i;
156
}
157
158
/* We may have done a partial read. try to do more.
159
* We have nothing in the buffer.
160
* If we get an error and have read some data, just return it
161
* and let them retry to get the error again.
162
* copy direct to parent address space */
163
if
(outl > ctx->
ibuf_size
)
164
{
165
for
(;;)
166
{
167
i=
BIO_read
(b->
next_bio
,out,outl);
168
if
(i <= 0)
169
{
170
BIO_copy_next_retry
(b);
171
if
(i < 0)
return
((num > 0)?num:i);
172
if
(i == 0)
return
(num);
173
}
174
num+=i;
175
if
(outl == i)
return
(num);
176
out+=i;
177
outl-=i;
178
}
179
}
180
/* else */
181
182
/* we are going to be doing some buffering */
183
i=
BIO_read
(b->
next_bio
,ctx->
ibuf
,ctx->
ibuf_size
);
184
if
(i <= 0)
185
{
186
BIO_copy_next_retry
(b);
187
if
(i < 0)
return
((num > 0)?num:i);
188
if
(i == 0)
return
(num);
189
}
190
ctx->
ibuf_off
=0;
191
ctx->
ibuf_len
=i;
192
193
/* Lets re-read using ourselves :-) */
194
goto
start;
195
}
196
197
static
int
buffer_write(
BIO
*b,
const
char
*in,
int
inl)
198
{
199
int
i,num=0;
200
BIO_F_BUFFER_CTX
*ctx;
201
202
if
((in == NULL) || (inl <= 0))
return
(0);
203
ctx=(
BIO_F_BUFFER_CTX
*)b->
ptr
;
204
if
((ctx == NULL) || (b->
next_bio
== NULL))
return
(0);
205
206
BIO_clear_retry_flags
(b);
207
start:
208
i=ctx->
obuf_size
-(ctx->
obuf_len
+ctx->
obuf_off
);
209
/* add to buffer and return */
210
if
(i >= inl)
211
{
212
memcpy(&(ctx->
obuf
[ctx->
obuf_off
+ctx->
obuf_len
]),in,inl);
213
ctx->
obuf_len
+=inl;
214
return
(num+inl);
215
}
216
/* else */
217
/* stuff already in buffer, so add to it first, then flush */
218
if
(ctx->
obuf_len
!= 0)
219
{
220
if
(i > 0)
/* lets fill it up if we can */
221
{
222
memcpy(&(ctx->
obuf
[ctx->
obuf_off
+ctx->
obuf_len
]),in,i);
223
in+=i;
224
inl-=i;
225
num+=i;
226
ctx->
obuf_len
+=i;
227
}
228
/* we now have a full buffer needing flushing */
229
for
(;;)
230
{
231
i=
BIO_write
(b->
next_bio
,&(ctx->
obuf
[ctx->
obuf_off
]),
232
ctx->
obuf_len
);
233
if
(i <= 0)
234
{
235
BIO_copy_next_retry
(b);
236
237
if
(i < 0)
return
((num > 0)?num:i);
238
if
(i == 0)
return
(num);
239
}
240
ctx->
obuf_off
+=i;
241
ctx->
obuf_len
-=i;
242
if
(ctx->
obuf_len
== 0)
break
;
243
}
244
}
245
/* we only get here if the buffer has been flushed and we
246
* still have stuff to write */
247
ctx->
obuf_off
=0;
248
249
/* we now have inl bytes to write */
250
while
(inl >= ctx->
obuf_size
)
251
{
252
i=
BIO_write
(b->
next_bio
,in,inl);
253
if
(i <= 0)
254
{
255
BIO_copy_next_retry
(b);
256
if
(i < 0)
return
((num > 0)?num:i);
257
if
(i == 0)
return
(num);
258
}
259
num+=i;
260
in+=i;
261
inl-=i;
262
if
(inl == 0)
return
(num);
263
}
264
265
/* copy the rest into the buffer since we have only a small
266
* amount left */
267
goto
start;
268
}
269
270
static
long
buffer_ctrl(
BIO
*b,
int
cmd,
long
num,
void
*
ptr
)
271
{
272
BIO
*dbio;
273
BIO_F_BUFFER_CTX
*ctx;
274
long
ret=1;
275
char
*p1,*p2;
276
int
r,i,*ip;
277
int
ibs,obs;
278
279
ctx=(
BIO_F_BUFFER_CTX
*)b->
ptr
;
280
281
switch (cmd)
282
{
283
case
BIO_CTRL_RESET
:
284
ctx->
ibuf_off
=0;
285
ctx->
ibuf_len
=0;
286
ctx->
obuf_off
=0;
287
ctx->
obuf_len
=0;
288
if
(b->
next_bio
== NULL)
return
(0);
289
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
290
break
;
291
case
BIO_CTRL_INFO
:
292
ret=(long)ctx->
obuf_len
;
293
break
;
294
case
BIO_C_GET_BUFF_NUM_LINES
:
295
ret=0;
296
p1=ctx->
ibuf
;
297
for (i=0; i<ctx->
ibuf_len
; i++)
298
{
299
if
(p1[ctx->
ibuf_off
+ i] ==
'\n'
) ret++;
300
}
301
break
;
302
case
BIO_CTRL_WPENDING
:
303
ret=(long)ctx->
obuf_len
;
304
if
(ret == 0)
305
{
306
if
(b->
next_bio
== NULL)
return
(0);
307
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
308
}
309
break
;
310
case
BIO_CTRL_PENDING
:
311
ret=(long)ctx->
ibuf_len
;
312
if
(ret == 0)
313
{
314
if
(b->
next_bio
== NULL)
return
(0);
315
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
316
}
317
break
;
318
case
BIO_C_SET_BUFF_READ_DATA
:
319
if
(num > ctx->
ibuf_size
)
320
{
321
p1=
OPENSSL_malloc
((
int
)num);
322
if
(p1 == NULL)
goto
malloc_error;
323
if
(ctx->
ibuf
!= NULL)
OPENSSL_free
(ctx->
ibuf
);
324
ctx->
ibuf
=p1;
325
}
326
ctx->
ibuf_off
=0;
327
ctx->
ibuf_len
=(int)num;
328
memcpy(ctx->
ibuf
,ptr,(
int
)num);
329
ret=1;
330
break
;
331
case
BIO_C_SET_BUFF_SIZE
:
332
if
(ptr != NULL)
333
{
334
ip=(
int
*)ptr;
335
if
(*ip == 0)
336
{
337
ibs=(int)num;
338
obs=ctx->
obuf_size
;
339
}
340
else
/* if (*ip == 1) */
341
{
342
ibs=ctx->
ibuf_size
;
343
obs=(int)num;
344
}
345
}
346
else
347
{
348
ibs=(int)num;
349
obs=(int)num;
350
}
351
p1=ctx->
ibuf
;
352
p2=ctx->
obuf
;
353
if
((ibs >
DEFAULT_BUFFER_SIZE
) && (ibs != ctx->
ibuf_size
))
354
{
355
p1=(
char
*)
OPENSSL_malloc
((
int
)
num
);
356
if
(p1 == NULL)
goto
malloc_error;
357
}
358
if
((obs >
DEFAULT_BUFFER_SIZE
) && (obs != ctx->
obuf_size
))
359
{
360
p2=(
char
*)
OPENSSL_malloc
((
int
)
num
);
361
if
(p2 == NULL)
362
{
363
if
(p1 != ctx->
ibuf
)
OPENSSL_free
(p1);
364
goto
malloc_error;
365
}
366
}
367
if
(ctx->
ibuf
!= p1)
368
{
369
OPENSSL_free
(ctx->
ibuf
);
370
ctx->
ibuf
=p1;
371
ctx->
ibuf_off
=0;
372
ctx->
ibuf_len
=0;
373
ctx->
ibuf_size
=ibs;
374
}
375
if
(ctx->
obuf
!= p2)
376
{
377
OPENSSL_free
(ctx->
obuf
);
378
ctx->
obuf
=p2;
379
ctx->
obuf_off
=0;
380
ctx->
obuf_len
=0;
381
ctx->
obuf_size
=obs;
382
}
383
break
;
384
case
BIO_C_DO_STATE_MACHINE
:
385
if
(b->
next_bio
== NULL)
return
(0);
386
BIO_clear_retry_flags
(b);
387
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
388
BIO_copy_next_retry
(b);
389
break
;
390
391
case
BIO_CTRL_FLUSH
:
392
if
(b->
next_bio
== NULL)
return
(0);
393
if
(ctx->
obuf_len
<= 0)
394
{
395
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
396
break
;
397
}
398
399
for
(;;)
400
{
401
BIO_clear_retry_flags
(b);
402
if
(ctx->
obuf_len
> 0)
403
{
404
r=
BIO_write
(b->
next_bio
,
405
&(ctx->
obuf
[ctx->
obuf_off
]),
406
ctx->
obuf_len
);
407
#if 0
408
fprintf(stderr,
"FLUSH [%3d] %3d -> %3d\n"
,ctx->
obuf_off
,ctx->
obuf_len
,r);
409
#endif
410
BIO_copy_next_retry
(b);
411
if
(r <= 0)
return
((
long
)r);
412
ctx->
obuf_off
+=r;
413
ctx->
obuf_len
-=r;
414
}
415
else
416
{
417
ctx->
obuf_len
=0;
418
ctx->
obuf_off
=0;
419
ret=1;
420
break
;
421
}
422
}
423
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
424
break
;
425
case
BIO_CTRL_DUP
:
426
dbio=(
BIO
*)ptr;
427
if
( !
BIO_set_read_buffer_size
(dbio,ctx->
ibuf_size
) ||
428
!
BIO_set_write_buffer_size
(dbio,ctx->
obuf_size
))
429
ret=0;
430
break
;
431
default
:
432
if
(b->
next_bio
== NULL)
return
(0);
433
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
434
break
;
435
}
436
return
(ret);
437
malloc_error:
438
BIOerr
(
BIO_F_BUFFER_CTRL
,
ERR_R_MALLOC_FAILURE
);
439
return
(0);
440
}
441
442
static
long
buffer_callback_ctrl(
BIO
*b,
int
cmd,
bio_info_cb
*
fp
)
443
{
444
long
ret=1;
445
446
if
(b->
next_bio
== NULL)
return
(0);
447
switch
(cmd)
448
{
449
default
:
450
ret=
BIO_callback_ctrl
(b->
next_bio
,cmd,fp);
451
break
;
452
}
453
return
(ret);
454
}
455
456
static
int
buffer_gets(
BIO
*b,
char
*buf,
int
size)
457
{
458
BIO_F_BUFFER_CTX
*ctx;
459
int
num=0,i,flag;
460
char
*
p
;
461
462
ctx=(
BIO_F_BUFFER_CTX
*)b->
ptr
;
463
size--;
/* reserve space for a '\0' */
464
BIO_clear_retry_flags
(b);
465
466
for
(;;)
467
{
468
if
(ctx->
ibuf_len
> 0)
469
{
470
p= &(ctx->
ibuf
[ctx->
ibuf_off
]);
471
flag=0;
472
for
(i=0; (i<ctx->
ibuf_len
) && (i<size); i++)
473
{
474
*(buf++)=p[i];
475
if
(p[i] ==
'\n'
)
476
{
477
flag=1;
478
i++;
479
break
;
480
}
481
}
482
num+=i;
483
size-=i;
484
ctx->
ibuf_len
-=i;
485
ctx->
ibuf_off
+=i;
486
if
(flag || size == 0)
487
{
488
*buf=
'\0'
;
489
return
(num);
490
}
491
}
492
else
/* read another chunk */
493
{
494
i=
BIO_read
(b->
next_bio
,ctx->
ibuf
,ctx->
ibuf_size
);
495
if
(i <= 0)
496
{
497
BIO_copy_next_retry
(b);
498
*buf=
'\0'
;
499
if
(i < 0)
return
((num > 0)?num:i);
500
if
(i == 0)
return
(num);
501
}
502
ctx->
ibuf_len
=i;
503
ctx->
ibuf_off
=0;
504
}
505
}
506
}
507
508
static
int
buffer_puts(
BIO
*b,
const
char
*str)
509
{
510
return
(buffer_write(b,str,strlen(str)));
511
}
512
Generated on Thu Jan 10 2013 09:53:34 for OpenSSL by
1.8.2