94
/* return the tag - LBER_DEFAULT returned means trouble */
96
ber_get_tag( BerElement *ber )
89
/* Return tag, with *bv = rest of element (starting at length octets) */
91
ber_tag_and_rest( const BerElement *ber, struct berval *bv )
102
97
assert( ber != NULL );
103
98
assert( LBER_VALID( ber ) );
105
if ( ber_pvt_ber_remaining( ber ) < 1 ) {
109
if ( ber->ber_ptr == ber->ber_buf ) {
110
tag = *(unsigned char *)ber->ber_ptr;
100
ptr = (unsigned char *) ber->ber_ptr;
101
rest = (unsigned char *) ber->ber_end - ptr;
107
if ( (char *) ptr == ber->ber_buf ) {
116
112
if ( (tag & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK ) {
120
for ( i = 1; i < sizeof(ber_tag_t); i++ ) {
121
if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 ) {
126
tag |= 0x00ffUL & (ber_tag_t) xbyte;
121
tag |= *ptr++ & 0xffU;
128
if ( ! (xbyte & LBER_MORE_TAG_MASK) ) {
124
if ( ! (tag & LBER_MORE_TAG_MASK) ) {
134
if ( i == sizeof(ber_tag_t) ) {
142
ber_skip_tag( BerElement *ber, ber_len_t *len )
127
} while ( tag <= (ber_tag_t)-1 / 256 );
130
/* Error or unsupported tag size */
135
bv->bv_val = (char *) ptr;
139
/* Return the tag - LBER_DEFAULT returned means trouble */
141
ber_get_tag( BerElement *ber )
144
ber_tag_t tag = ber_tag_and_rest( ber, &bv );
146
ber->ber_ptr = bv.bv_val;
150
/* Return next element's tag and point *bv at its contents in-place */
152
ber_peek_element( const BerElement *ber, struct berval *bv )
146
ber_len_t i, noctets;
147
unsigned char netlen[sizeof(ber_len_t)];
149
assert( ber != NULL );
150
assert( len != NULL );
151
assert( LBER_VALID( ber ) );
159
assert( bv != NULL );
154
162
* Any ber element looks like this: tag length contents.
155
* Assuming everything's ok, we return the tag byte (we
156
* can assume a single byte), and return the length in len.
163
* Assuming everything's ok, we return the tag, and point
164
* bv at the contents.
159
167
* 1) definite lengths
160
168
* 2) primitive encodings used whenever possible
166
174
* First, we read the tag.
176
tag = ber_tag_and_rest( ber, bv );
169
if ( (tag = ber_get_tag( ber )) == LBER_DEFAULT ) {
179
ptr = (unsigned char *) bv->bv_val;
180
if ( tag == LBER_DEFAULT || rest == 0 ) {
174
* Next, read the length. The first byte contains the length of
175
* the length. If bit 8 is set, the length is the long form,
176
* otherwise it's the short form. We don't allow a length that's
177
* greater than what we can hold in a ber_len_t.
185
* Next, read the length. The first octet determines the length
186
* of the length. If bit 8 is 0, the length is the short form,
187
* otherwise if the octet != 0x80 it's the long form, otherwise
188
* the ber element has the unsupported indefinite-length format.
189
* Lengths that do not fit in a ber_len_t are not accepted.
180
if ( ber_read( ber, (char *) &lc, 1 ) != 1 ) {
185
noctets = (lc & 0x7fU);
187
if ( noctets > sizeof(ber_len_t) ) {
191
if( (unsigned) ber_read( ber, (char *) netlen, noctets ) != noctets ) {
195
for( i = 0; i < noctets; i++ ) {
197
if ( len - 1U > sizeof(ber_len_t) - 1U || rest < len ) {
198
/* Indefinite-length/too long length/not enough data */
204
for( len = *ptr++ & 0xffU; --i; len |= *ptr++ & 0xffU ) {
204
209
/* BER element should have enough data left */
205
if( *len > (ber_len_t) ber_pvt_ber_remaining( ber ) ) {
208
ber->ber_tag = *(unsigned char *)ber->ber_ptr;
216
bv->bv_val = (char *) ptr;
220
/* Move past next element, point *bv at it in-place, and return its tag.
221
* The caller may \0-terminate *bv, as next octet is saved in ber->ber_tag.
222
* Similar to ber_get_stringbv(ber, bv, LBER_BV_NOTERM) except on error.
225
ber_skip_element( BerElement *ber, struct berval *bv )
227
ber_tag_t tag = ber_peek_element( ber, bv );
229
if ( tag != LBER_DEFAULT ) {
230
ber->ber_ptr = bv->bv_val + bv->bv_len;
231
ber->ber_tag = *(unsigned char *) ber->ber_ptr;
219
* This implementation assumes ber_skip_tag() only
220
* modifies ber_ptr field of the BerElement.
228
tag = ber_skip_tag( ber, len );
243
ber_tag_t tag = ber_peek_element( ber, &bv );
250
ber_skip_tag( BerElement *ber, ber_len_t *lenp )
253
ber_tag_t tag = ber_peek_element( ber, &bv );
255
ber->ber_ptr = bv.bv_val;
256
ber->ber_tag = *(unsigned char *) ber->ber_ptr;
241
unsigned char buf[sizeof(ber_int_t)];
243
assert( ber != NULL );
244
271
assert( num != NULL );
245
assert( LBER_VALID( ber ) );
248
* The tag and length have already been stripped off. We should
249
* be sitting right before len bytes of 2's complement integer,
250
* ready to be read straight into an int. We may have to sign
251
* extend after we read it in.
254
if ( len > sizeof(ber_int_t) ) {
258
/* read into the low-order bytes of our buffer */
259
if ( (ber_len_t) ber_read( ber, (char *) buf, len ) != len ) {
273
tag = ber_skip_element( ber, &bv );
275
if ( tag == LBER_DEFAULT || len > sizeof(ber_int_t) ) {
279
/* parse two's complement integer */
264
/* sign extend if necessary */
281
unsigned char *buf = (unsigned char *) bv.bv_val;
266
ber_int_t netnum = 0x80 & buf[0] ? -1 : 0;
283
ber_int_t netnum = buf[0] & 0xff;
286
netnum = (netnum ^ 0x80) - 0x80;
268
288
/* shift in the bytes */
269
for( i=0 ; i<len; i++ ) {
289
for( i = 1; i < len; i++ ) {
270
290
netnum = (netnum << 8 ) | buf[i];
354
344
* stack use to the absolute minimum.
356
346
typedef struct bgbvr {
347
const enum bgbvc choice;
348
const int alloc; /* choice == BvOff ? 0 : LBER_ALLOC */
349
ber_len_t siz; /* input array element size, output count */
350
ber_len_t off; /* BvOff offset to the struct berval */
370
ber_get_stringbvl( bgbvr *b, ber_len_t *rlen )
355
ber_get_stringbvl( BerElement *ber, bgbvr *b )
359
ber_len_t tot_size = 0, siz = b->siz;
375
360
char *last, *orig;
376
361
struct berval bv, *bvp = NULL;
378
/* For rewinding, just like ber_peek_tag() */
379
orig = b->ber->ber_ptr;
380
tag = b->ber->ber_tag;
382
if ( ber_first_element( b->ber, &len, &last ) != LBER_DEFAULT ) {
383
for ( ; b->ber->ber_ptr < last; i++ ) {
384
if (ber_skip_tag( b->ber, &len ) == LBER_DEFAULT) break;
385
b->ber->ber_ptr += len;
386
b->ber->ber_tag = *(unsigned char *)b->ber->ber_ptr;
363
char **ca; /* ChArray */
364
BerVarray ba; /* BvArray */
365
struct berval **bv; /* BvVec */
366
char *bo; /* BvOff */
369
tag = ber_skip_tag( ber, &bv.bv_len );
371
if ( tag != LBER_DEFAULT ) {
374
last = orig + bv.bv_len;
376
for ( ; ber->ber_ptr < last; i++, tot_size += siz ) {
377
if ( ber_skip_element( ber, &bv ) == LBER_DEFAULT )
380
if ( ber->ber_ptr != last ) {
386
ber->ber_tag = *(unsigned char *) orig;
390
if ( rlen ) *rlen = i;
399
/* Allocate the result vector */
394
/* Allocate and NULL-terminate the result vector */
395
b->result = ber_memalloc_x( tot_size + siz, ber->ber_memctx );
396
if ( b->result == NULL ) {
400
399
switch (b->choice) {
402
*b->res.c = ber_memalloc_x( (n+1)*sizeof( char * ),
404
if ( *b->res.c == NULL ) return LBER_DEFAULT;
405
(*b->res.c)[n] = NULL;
408
*b->res.ba = ber_memalloc_x( (n+1)*sizeof( struct berval ),
410
if ( *b->res.ba == NULL ) return LBER_DEFAULT;
411
(*b->res.ba)[n].bv_val = NULL;
406
res.ba[i].bv_val = NULL;
414
*b->res.bv = ber_memalloc_x( (n+1)*sizeof( struct berval *),
416
if ( *b->res.bv == NULL ) return LBER_DEFAULT;
417
(*b->res.bv)[n] = NULL;
420
*b->res.ba = ber_memalloc_x( (n+1) * b->siz, b->ber->ber_memctx );
421
if ( *b->res.ba == NULL ) return LBER_DEFAULT;
422
((struct berval *)((char *)(*b->res.ba) + n*b->siz +
423
b->off))->bv_val = NULL;
413
res.bo = (char *) b->result + b->off;
414
((struct berval *) (res.bo + tot_size))->bv_val = NULL;
426
b->ber->ber_ptr = orig;
427
b->ber->ber_tag = tag;
428
ber_skip_tag( b->ber, &len );
432
tag = ber_next_element( b->ber, &len, last );
433
if ( ber_get_stringbv( b->ber, &bv, b->alloc ) == LBER_DEFAULT ) {
421
tag = ber_get_stringbv( ber, &bv, b->alloc );
422
if ( tag == LBER_DEFAULT ) {
437
426
/* store my result */
438
427
switch (b->choice) {
440
(*b->res.c)[n] = bv.bv_val;
429
res.ca[n] = bv.bv_val;
443
(*b->res.ba)[n] = bv;
446
bvp = ber_memalloc_x( sizeof( struct berval ), b->ber->ber_memctx);
435
bvp = ber_memalloc_x( sizeof( struct berval ),
448
LBER_FREE(bv.bv_val);
438
ber_memfree_x( bv.bv_val, ber->ber_memctx );
451
(*b->res.bv)[n] = bvp;
455
*(BerVarray)((char *)(*b->res.ba)+n*b->siz+b->off) = bv;
445
*(struct berval *)(res.bo + tot_size) = bv;
462
if (b->alloc || b->choice == BvVec) {
463
for (--n; n>=0; n--) {
453
if (b->choice != BvOff) { /* BvOff does not have b->alloc set */
464
455
switch(b->choice) {
466
LBER_FREE((*b->res.c)[n]);
457
ber_memfree_x(res.ca[n], ber->ber_memctx);
469
LBER_FREE((*b->res.ba)[n].bv_val);
460
ber_memfree_x(res.ba[n].bv_val, ber->ber_memctx);
472
LBER_FREE((*b->res.bv)[n]->bv_val);
473
LBER_FREE((*b->res.bv)[n]);
463
ber_memfree_x(res.bv[n]->bv_val, ber->ber_memctx);
464
ber_memfree_x(res.bv[n], ber->ber_memctx);
480
LBER_FREE(*b->res.c);
471
ber_memfree_x(b->result, ber->ber_memctx);
482
473
return LBER_DEFAULT;
633
590
ber_len_t *blen )
637
594
unsigned char unusedbits;
639
assert( ber != NULL );
640
596
assert( buf != NULL );
641
597
assert( blen != NULL );
643
assert( LBER_VALID( ber ) );
645
if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
651
*buf = (char *) ber_memalloc_x( datalen, ber->ber_memctx );
599
if ( (tag = ber_skip_element( ber, &data )) == LBER_DEFAULT ) {
603
if ( --data.bv_len > (ber_len_t)-1 / 8 ) {
606
unusedbits = *(unsigned char *) data.bv_val++;
607
if ( unusedbits > 7 ) {
611
*buf = (char *) ber_memalloc_x( data.bv_len, ber->ber_memctx );
652
612
if ( *buf == NULL ) {
653
613
return LBER_DEFAULT;
656
if ( ber_read( ber, (char *)&unusedbits, 1 ) != 1 ) {
662
if ( (ber_len_t) ber_read( ber, *buf, datalen ) != datalen ) {
667
ber->ber_tag = *(unsigned char *)ber->ber_ptr;
669
*blen = datalen * 8 - unusedbits;
615
memcpy( *buf, data.bv_val, data.bv_len );
617
*blen = data.bv_len * 8 - unusedbits;
674
626
ber_get_null( BerElement *ber )
679
assert( ber != NULL );
680
assert( LBER_VALID( ber ) );
682
if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
689
ber->ber_tag = *(unsigned char *)ber->ber_ptr;
629
ber_tag_t tag = ber_skip_tag( ber, &len );
631
return( len == 0 ? tag : LBER_DEFAULT );
888
811
case 'v': /* sequence of strings */
890
bgbvr cookie = { ChArray };
892
cookie.res.c = va_arg( ap, char *** );
893
cookie.alloc = LBER_BV_ALLOC;
894
rc = ber_get_stringbvl( &cookie, NULL );
814
ChArray, LBER_BV_ALLOC, sizeof( char * )
816
rc = ber_get_stringbvl( ber, &cookie );
817
*(va_arg( ap, char *** )) = cookie.result;
898
821
case 'V': /* sequence of strings + lengths */
900
bgbvr cookie = { BvVec };
902
cookie.res.bv = va_arg( ap, struct berval *** );
903
cookie.alloc = LBER_BV_ALLOC;
904
rc = ber_get_stringbvl( &cookie, NULL );
824
BvVec, LBER_BV_ALLOC, sizeof( struct berval * )
826
rc = ber_get_stringbvl( ber, &cookie );
827
*(va_arg( ap, struct berval *** )) = cookie.result;
908
831
case 'W': /* bvarray */
910
bgbvr cookie = { BvArray };
912
cookie.res.ba = va_arg( ap, struct berval ** );
913
cookie.alloc = LBER_BV_ALLOC;
914
rc = ber_get_stringbvl( &cookie, NULL );
834
BvArray, LBER_BV_ALLOC, sizeof( struct berval )
836
rc = ber_get_stringbvl( ber, &cookie );
837
*(va_arg( ap, struct berval ** )) = cookie.result;
918
841
case 'x': /* skip the next element - whatever it is */
919
if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
922
ber->ber_tag = *(unsigned char *)ber->ber_ptr;
842
rc = ber_skip_element( ber, &data );
925
845
case '{': /* begin sequence */
926
846
case '[': /* begin set */
927
if ( *(fmt + 1) != 'v' && *(fmt + 1) != 'V'
928
&& *(fmt + 1) != 'W' && *(fmt + 1) != 'M' )
848
case 'v': case 'V': case 'W': case 'M':
929
851
rc = ber_skip_tag( ber, &len );
932
856
case '}': /* end sequence */
966
891
case 'a': /* octet string - allocate storage as needed */
968
893
ss = va_arg( ap, char ** );
894
ber_memfree_x( *ss, ber->ber_memctx );
975
898
case 'b': /* boolean */
976
899
case 'e': /* enumerated */
978
(void) va_arg( ap, int * );
900
case 'i': /* integer */
901
(void) va_arg( ap, ber_int_t * );
981
904
case 'l': /* length of next item */
982
(void) va_arg( ap, ber_len_t * );
905
*(va_arg( ap, ber_len_t * )) = 0;
908
case 'm': /* berval in-place */
909
bval = va_arg( ap, struct berval * );
913
case 'M': /* BVoff array in-place */
914
bvp = va_arg( ap, struct berval ** );
915
ber_memfree_x( *bvp, ber->ber_memctx );
917
*(va_arg( ap, ber_len_t * )) = 0;
918
(void) va_arg( ap, ber_len_t );
985
921
case 'o': /* octet string in a supplied berval */
986
922
bval = va_arg( ap, struct berval * );
987
if ( bval->bv_val != NULL ) {
988
LBER_FREE( bval->bv_val );
923
ber_memfree_x( bval->bv_val, ber->ber_memctx );
994
927
case 'O': /* octet string - allocate & include length */
995
928
bvp = va_arg( ap, struct berval ** );
929
ber_bvfree_x( *bvp, ber->ber_memctx );
1002
933
case 's': /* octet string - in a buffer */
1003
934
(void) va_arg( ap, char * );
1004
(void) va_arg( ap, ber_len_t * );
935
*(va_arg( ap, ber_len_t * )) = 0;
1007
938
case 't': /* tag of next item */
1012
943
case 'B': /* bit string - allocate storage as needed */
1013
944
ss = va_arg( ap, char ** );
945
ber_memfree_x( *ss, ber->ber_memctx );
1018
947
*(va_arg( ap, ber_len_t * )) = 0; /* for length, in bits */
1021
case 'm': /* berval in-place */
1022
case 'M': /* BVoff array in-place */
1023
case 'n': /* null */
1024
950
case 'v': /* sequence of strings */
951
sss = va_arg( ap, char *** );
952
ber_memvfree_x( (void **) *sss, ber->ber_memctx );
1025
956
case 'V': /* sequence of strings + lengths */
957
bvpp = va_arg( ap, struct berval *** );
958
ber_bvecfree_x( *bvpp, ber->ber_memctx );
1026
962
case 'W': /* BerVarray */
963
bvp = va_arg( ap, struct berval ** );
964
ber_bvarray_free_x( *bvp, ber->ber_memctx );
1027
969
case 'x': /* skip the next element - whatever it is */
1028
970
case '{': /* begin sequence */
1029
971
case '[': /* begin set */