OpenSSL
1.0.1c
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
crypto
pkcs7
bio_ber.c
Go to the documentation of this file.
1
/* crypto/evp/bio_ber.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/buffer.h
>
63
#include <
openssl/evp.h
>
64
65
static
int
ber_write(
BIO
*
h
,
char
*buf,
int
num
);
66
static
int
ber_read(
BIO
*
h
,
char
*buf,
int
size);
67
/*static int ber_puts(BIO *h,char *str); */
68
/*static int ber_gets(BIO *h,char *str,int size); */
69
static
long
ber_ctrl(
BIO
*
h
,
int
cmd,
long
arg1,
char
*arg2);
70
static
int
ber_new(
BIO
*
h
);
71
static
int
ber_free(
BIO
*
data
);
72
static
long
ber_callback_ctrl(
BIO
*
h
,
int
cmd,
void
*(*
fp
)());
73
#define BER_BUF_SIZE (32)
74
75
/* This is used to hold the state of the BER objects being read. */
76
typedef
struct
ber_struct
77
{
78
int
tag
;
79
int
class
;
80
long
length
;
81
int
inf
;
82
int
num_left
;
83
int
depth
;
84
}
BER_CTX
;
85
86
typedef
struct
bio_ber_struct
87
{
88
int
tag
;
89
int
class
;
90
long
length
;
91
int
inf
;
92
93
/* most of the following are used when doing non-blocking IO */
94
/* reading */
95
long
num_left
;
/* number of bytes still to read/write in block */
96
int
depth
;
/* used with indefinite encoding. */
97
int
finished
;
/* No more read data */
98
99
/* writting */
100
char
*
w_addr
;
101
int
w_offset
;
102
int
w_left
;
103
104
int
buf_len
;
105
int
buf_off
;
106
unsigned
char
buf
[
BER_BUF_SIZE
];
107
}
BIO_BER_CTX
;
108
109
static
BIO_METHOD
methods_ber=
110
{
111
BIO_TYPE_CIPHER
,
"cipher"
,
112
ber_write,
113
ber_read,
114
NULL,
/* ber_puts, */
115
NULL,
/* ber_gets, */
116
ber_ctrl,
117
ber_new,
118
ber_free,
119
ber_callback_ctrl,
120
};
121
122
BIO_METHOD
*
BIO_f_ber
(
void
)
123
{
124
return
(&methods_ber);
125
}
126
127
static
int
ber_new(
BIO
*bi)
128
{
129
BIO_BER_CTX
*ctx;
130
131
ctx=(
BIO_BER_CTX
*)
OPENSSL_malloc
(
sizeof
(
BIO_BER_CTX
));
132
if
(ctx == NULL)
return
(0);
133
134
memset((
char
*)ctx,0,
sizeof
(
BIO_BER_CTX
));
135
136
bi->
init
=0;
137
bi->
ptr
=(
char
*)ctx;
138
bi->
flags
=0;
139
return
(1);
140
}
141
142
static
int
ber_free(
BIO
*
a
)
143
{
144
BIO_BER_CTX
*
b
;
145
146
if
(a == NULL)
return
(0);
147
b=(
BIO_BER_CTX
*)a->
ptr
;
148
OPENSSL_cleanse
(a->
ptr
,
sizeof
(
BIO_BER_CTX
));
149
OPENSSL_free
(a->
ptr
);
150
a->
ptr
=NULL;
151
a->
init
=0;
152
a->
flags
=0;
153
return
(1);
154
}
155
156
int
bio_ber_get_header
(
BIO
*bio,
BIO_BER_CTX
*ctx)
157
{
158
char
buf[64];
159
int
i,j,n;
160
int
ret;
161
unsigned
char
*
p
;
162
unsigned
long
length
163
int
tag;
164
int
class
;
165
long
max
;
166
167
BIO_clear_retry_flags
(b);
168
169
/* Pack the buffer down if there is a hole at the front */
170
if
(ctx->
buf_off
!= 0)
171
{
172
p=ctx->
buf
;
173
j=ctx->
buf_off
;
174
n=ctx->
buf_len
-j;
175
for
(i=0; i<n; i++)
176
{
177
p[0]=p[j];
178
p++;
179
}
180
ctx->
buf_len
-j;
181
ctx->
buf_off
=0;
182
}
183
184
/* If there is more room, read some more data */
185
i=
BER_BUF_SIZE
-ctx->
buf_len
;
186
if
(i)
187
{
188
i=
BIO_read
(bio->
next_bio
,&(ctx->
buf
[ctx->
buf_len
]),i);
189
if
(i <= 0)
190
{
191
BIO_copy_next_retry
(b);
192
return
(i);
193
}
194
else
195
ctx->
buf_len
+=i;
196
}
197
198
max=ctx->
buf_len
;
199
p=ctx->
buf
;
200
ret=
ASN1_get_object
(&p,&
length
,&tag,&
class
,max);
201
202
if
(ret & 0x80)
203
{
204
if
((ctx->
buf_len
<
BER_BUF_SIZE
) &&
205
(
ERR_GET_REASON
(
ERR_peek_error
()) ==
ASN1_R_TOO_LONG
))
206
{
207
ERR_clear_error
();
/* clear the error */
208
BIO_set_retry_read
(b);
209
}
210
return
(-1);
211
}
212
213
/* We have no error, we have a header, so make use of it */
214
215
if
((ctx->
tag
>= 0) && (ctx->
tag
!= tag))
216
{
217
BIOerr
(
BIO_F_BIO_BER_GET_HEADER
,
BIO_R_TAG_MISMATCH
);
218
sprintf(buf,
"tag=%d, got %d"
,ctx->
tag
,tag);
219
ERR_add_error_data
(1,buf);
220
return
(-1);
221
}
222
if
(ret & 0x01)
223
if
(ret &
V_ASN1_CONSTRUCTED
)
224
}
225
226
static
int
ber_read(
BIO
*b,
char
*out,
int
outl)
227
{
228
int
ret=0,i,n;
229
BIO_BER_CTX
*ctx;
230
231
BIO_clear_retry_flags
(b);
232
233
if
(out == NULL)
return
(0);
234
ctx=(
BIO_BER_CTX
*)b->
ptr
;
235
236
if
((ctx == NULL) || (b->
next_bio
== NULL))
return
(0);
237
238
if
(ctx->
finished
)
return
(0);
239
240
again:
241
/* First see if we are half way through reading a block */
242
if
(ctx->
num_left
> 0)
243
{
244
if
(ctx->
num_left
< outl)
245
n=ctx->
num_left
;
246
else
247
n=outl;
248
i=
BIO_read
(b->
next_bio
,out,n);
249
if
(i <= 0)
250
{
251
BIO_copy_next_retry
(b);
252
return
(i);
253
}
254
ctx->
num_left
-=i;
255
outl-=i;
256
ret+=i;
257
if
(ctx->
num_left
<= 0)
258
{
259
ctx->
depth
--;
260
if
(ctx->
depth
<= 0)
261
ctx->
finished
=1;
262
}
263
if
(outl <= 0)
264
return
(ret);
265
else
266
goto
again;
267
}
268
else
/* we need to read another BER header */
269
{
270
}
271
}
272
273
static
int
ber_write(
BIO
*b,
char
*in,
int
inl)
274
{
275
int
ret=0,n,i;
276
BIO_ENC_CTX
*ctx;
277
278
ctx=(
BIO_ENC_CTX
*)b->
ptr
;
279
ret=inl;
280
281
BIO_clear_retry_flags
(b);
282
n=ctx->
buf_len
-ctx->
buf_off
;
283
while
(n > 0)
284
{
285
i=
BIO_write
(b->
next_bio
,&(ctx->
buf
[ctx->
buf_off
]),n);
286
if
(i <= 0)
287
{
288
BIO_copy_next_retry
(b);
289
return
(i);
290
}
291
ctx->
buf_off
+=i;
292
n-=i;
293
}
294
/* at this point all pending data has been written */
295
296
if
((in == NULL) || (inl <= 0))
return
(0);
297
298
ctx->
buf_off
=0;
299
while
(inl > 0)
300
{
301
n=(inl >
ENC_BLOCK_SIZE
)?
ENC_BLOCK_SIZE
:inl;
302
EVP_CipherUpdate
(&(ctx->
cipher
),
303
(
unsigned
char
*)ctx->
buf
,&ctx->
buf_len
,
304
(
unsigned
char
*)in,n);
305
inl-=n;
306
in+=n;
307
308
ctx->
buf_off
=0;
309
n=ctx->
buf_len
;
310
while
(n > 0)
311
{
312
i=
BIO_write
(b->
next_bio
,&(ctx->
buf
[ctx->
buf_off
]),n);
313
if
(i <= 0)
314
{
315
BIO_copy_next_retry
(b);
316
return
(i);
317
}
318
n-=i;
319
ctx->
buf_off
+=i;
320
}
321
ctx->
buf_len
=0;
322
ctx->
buf_off
=0;
323
}
324
BIO_copy_next_retry
(b);
325
return
(ret);
326
}
327
328
static
long
ber_ctrl(
BIO
*b,
int
cmd,
long
num
,
char
*
ptr
)
329
{
330
BIO
*dbio;
331
BIO_ENC_CTX
*ctx,*dctx;
332
long
ret=1;
333
int
i;
334
335
ctx=(
BIO_ENC_CTX
*)b->
ptr
;
336
337
switch (cmd)
338
{
339
case
BIO_CTRL_RESET
:
340
ctx->
ok
=1;
341
ctx->
finished
=0;
342
EVP_CipherInit_ex
(&(ctx->
cipher
),NULL,NULL,NULL,NULL,
343
ctx->
cipher
.berrypt);
344
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
345
break
;
346
case
BIO_CTRL_EOF
:
/* More to read */
347
if
(ctx->
cont
<= 0)
348
ret=1;
349
else
350
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
351
break
;
352
case
BIO_CTRL_WPENDING
:
353
ret=ctx->
buf_len
-ctx->
buf_off
;
354
if
(ret <= 0)
355
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
356
break
;
357
case
BIO_CTRL_PENDING
:
/* More to read in buffer */
358
ret=ctx->
buf_len
-ctx->
buf_off
;
359
if
(ret <= 0)
360
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
361
break
;
362
case
BIO_CTRL_FLUSH
:
363
/* do a final write */
364
again:
365
while
(ctx->
buf_len
!= ctx->
buf_off
)
366
{
367
i=ber_write(b,NULL,0);
368
if
(i < 0)
369
{
370
ret=i;
371
break
;
372
}
373
}
374
375
if
(!ctx->
finished
)
376
{
377
ctx->
finished
=1;
378
ctx->
buf_off
=0;
379
ret=
EVP_CipherFinal_ex
(&(ctx->
cipher
),
380
(
unsigned
char
*)ctx->
buf
,
381
&(ctx->
buf_len
));
382
ctx->
ok
=(int)ret;
383
if
(ret <= 0)
break
;
384
385
/* push out the bytes */
386
goto
again;
387
}
388
389
/* Finally flush the underlying BIO */
390
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
391
break
;
392
case
BIO_C_GET_CIPHER_STATUS
:
393
ret=(long)ctx->
ok
;
394
break
;
395
case
BIO_C_DO_STATE_MACHINE
:
396
BIO_clear_retry_flags
(b);
397
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
398
BIO_copy_next_retry
(b);
399
break
;
400
401
case
BIO_CTRL_DUP
:
402
dbio=(
BIO
*)ptr;
403
dctx=(
BIO_ENC_CTX
*)dbio->
ptr
;
404
memcpy(&(dctx->
cipher
),&(ctx->
cipher
),
sizeof
(ctx->
cipher
));
405
dbio->
init
=1;
406
break
;
407
default
:
408
ret=
BIO_ctrl
(b->
next_bio
,cmd,num,ptr);
409
break
;
410
}
411
return
(ret);
412
}
413
414
static
long
ber_callback_ctrl(
BIO
*b,
int
cmd,
void
*(*
fp
)())
415
{
416
long
ret=1;
417
418
if
(b->
next_bio
== NULL)
return
(0);
419
switch
(cmd)
420
{
421
default
:
422
ret=
BIO_callback_ctrl
(b->
next_bio
,cmd,
fp
);
423
break
;
424
}
425
return
(ret);
426
}
427
428
/*
429
void BIO_set_cipher_ctx(b,c)
430
BIO *b;
431
EVP_CIPHER_ctx *c;
432
{
433
if (b == NULL) return;
434
435
if ((b->callback != NULL) &&
436
(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
437
return;
438
439
b->init=1;
440
ctx=(BIO_ENC_CTX *)b->ptr;
441
memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
442
443
if (b->callback != NULL)
444
b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
445
}
446
*/
447
448
void
BIO_set_cipher
(
BIO
*b,
EVP_CIPHER
*c,
unsigned
char
*k,
unsigned
char
*i,
449
int
e
)
450
{
451
BIO_ENC_CTX
*ctx;
452
453
if
(b == NULL)
return
;
454
455
if
((b->
callback
!= NULL) &&
456
(b->
callback
(b,
BIO_CB_CTRL
,(
char
*)c,
BIO_CTRL_SET
,e,0L) <= 0))
457
return
;
458
459
b->
init
=1;
460
ctx=(
BIO_ENC_CTX
*)b->
ptr
;
461
EVP_CipherInit_ex
(&(ctx->
cipher
),c,NULL,k,i,
e
);
462
463
if
(b->
callback
!= NULL)
464
b->
callback
(b,
BIO_CB_CTRL
,(
char
*)c,
BIO_CTRL_SET
,e,1L);
465
}
466
Generated on Thu Jan 10 2013 09:53:38 for OpenSSL by
1.8.2