2 * Copyright (C) 1997-2005 by Objective Systems, Inc.
4 * This software is furnished under an open source license and may be
5 * used and copied only in accordance with the terms of this license.
6 * The text of the license may generally be found in the root
7 * directory of this installation in the COPYING file. It
8 * can also be viewed online at the following URL:
10 * http://www.obj-sys.com/open/license.html
12 * Any redistributions of this file including modified versions must
13 * maintain this copyright notice.
15 *****************************************************************************/
18 #include "asterisk/lock.h"
22 static int decode16BitConstrainedString
23 (OOCTXT* pctxt, Asn116BitCharString* pString, Asn116BitCharSet* pCharSet);
25 static int decodeOctets
26 (OOCTXT* pctxt, ASN1OCTET* pbuffer, ASN1UINT bufsiz, ASN1UINT nbits);
28 static int getComponentLength (OOCTXT* pctxt, ASN1UINT itemBits);
30 int decodeBits (OOCTXT* pctxt, ASN1UINT* pvalue, ASN1UINT nbits)
39 /* If the number of bits is less than the current bit offset, mask */
40 /* off the required number of bits and return.. */
42 if (nbits < (unsigned)pctxt->buffer.bitOffset) {
43 /* Check if buffer contains number of bits requested */
45 if (pctxt->buffer.byteIndex >= pctxt->buffer.size)
46 return LOG_ASN1ERR (pctxt, ASN_E_ENDOFBUF);
48 pctxt->buffer.bitOffset -= nbits;
50 *pvalue = ((pctxt->buffer.data[pctxt->buffer.byteIndex]) >>
51 pctxt->buffer.bitOffset) & ((1 << nbits) - 1);
56 /* Otherwise, we first need to mask off the remaining bits in the */
57 /* current byte, followed by a loop to extract bits from full bytes, */
58 /* followed by logic to mask of remaining bits from the start of */
59 /* of the last byte.. */
62 /* Check if buffer contains number of bits requested */
64 int nbytes = (((nbits - pctxt->buffer.bitOffset) + 7) / 8);
66 if ((pctxt->buffer.byteIndex + nbytes) >= pctxt->buffer.size) {
67 return LOG_ASN1ERR (pctxt, ASN_E_ENDOFBUF);
70 /* first read current byte remaining bits */
71 mask = ((1 << pctxt->buffer.bitOffset) - 1);
73 *pvalue = (pctxt->buffer.data[pctxt->buffer.byteIndex]) & mask;
75 nbits -= pctxt->buffer.bitOffset;
76 pctxt->buffer.bitOffset = 8;
77 pctxt->buffer.byteIndex++;
79 /* second read bytes from next byteIndex */
81 *pvalue = (*pvalue << 8) |
82 (pctxt->buffer.data[pctxt->buffer.byteIndex]);
83 pctxt->buffer.byteIndex++;
87 /* third read bits & set bitoffset of the byteIndex */
89 pctxt->buffer.bitOffset = 8 - nbits;
90 *pvalue = (*pvalue << nbits) |
91 ((pctxt->buffer.data[pctxt->buffer.byteIndex]) >>
92 pctxt->buffer.bitOffset);
100 (OOCTXT* pctxt, ASN1UINT* numbits_p, ASN1OCTET* buffer, ASN1UINT bufsiz)
103 int lstat, octidx = 0, stat;
104 Asn1SizeCnst* pSizeList = pctxt->pSizeConstraint;
107 for (*numbits_p = 0;;) {
108 lstat = decodeLength (pctxt, &bitcnt);
109 if (lstat < 0) return LOG_ASN1ERR (pctxt, lstat);
112 *numbits_p += bitcnt;
114 stat = bitAndOctetStringAlignmentTest
115 (pSizeList, bitcnt, TRUE, &doAlign);
116 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
119 stat = decodeByteAlign (pctxt);
120 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
123 stat = decodeOctets (pctxt, &buffer[octidx], bufsiz - octidx, bitcnt);
124 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
127 if (lstat == ASN_OK_FRAG) {
128 octidx += (bitcnt / 8);
137 (OOCTXT* pctxt, ASN1BMPString* pvalue, Asn116BitCharSet* permCharSet)
139 Asn116BitCharSet charSet;
142 /* Set character set */
144 init16BitCharSet (&charSet, BMP_FIRST, BMP_LAST, BMP_ABITS, BMP_UBITS);
147 set16BitCharSet (pctxt, &charSet, permCharSet);
150 /* Decode constrained string */
152 stat = decode16BitConstrainedString (pctxt, pvalue, &charSet);
153 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
158 int decodeByteAlign (OOCTXT* pctxt)
160 if (pctxt->buffer.bitOffset != 8) {
161 pctxt->buffer.byteIndex++;
162 pctxt->buffer.bitOffset = 8;
167 int decodeConstrainedStringEx
168 (OOCTXT* pctxt, const char** string, const char* charSet,
169 ASN1UINT abits, ASN1UINT ubits, ASN1UINT canSetBits)
174 ASN1UINT i, idx, len, nbits = abits;
176 /* note: need to save size constraint for use in alignCharStr */
177 /* because it will be cleared in decodeLength from the context.. */
178 Asn1SizeCnst* psize = pctxt->pSizeConstraint;
182 stat = decodeLength (pctxt, &len);
183 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
187 if (alignCharStr (pctxt, len, nbits, psize)) {
188 stat = decodeByteAlign (pctxt);
189 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
194 tmpstr = (char*) ASN1MALLOC (pctxt, len+1);
196 if (nbits >= canSetBits && canSetBits > 4) {
197 for (i = 0; i < len; i++) {
198 if ((stat = decodeBits (pctxt, &idx, nbits)) == ASN_OK) {
199 tmpstr[i] = (char) idx;
204 else if (0 != charSet) {
205 ASN1UINT nchars = strlen (charSet);
206 for (i = 0; i < len; i++) {
207 if ((stat = decodeBits (pctxt, &idx, nbits)) == ASN_OK) {
209 tmpstr[i] = charSet[idx];
211 else return LOG_ASN1ERR (pctxt, ASN_E_CONSVIO);
216 else stat = ASN_E_INVPARAM;
218 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
220 tmpstr[i] = '\0'; /* add null-terminator */
223 return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);
230 int decodeConsInteger
231 (OOCTXT* pctxt, ASN1INT* pvalue, ASN1INT lower, ASN1INT upper)
233 ASN1UINT range_value = upper - lower;
234 ASN1UINT adjusted_value;
237 if (range_value != ASN1UINT_MAX) { range_value += 1; }
240 return ASN_E_RANGERR;
241 else if (lower != upper) {
242 stat = decodeConsWholeNumber (pctxt, &adjusted_value, range_value);
243 if (stat == ASN_OK) {
244 *pvalue = adjusted_value + lower;
246 if (*pvalue < lower || *pvalue > upper)
247 stat = ASN_E_CONSVIO;
258 (OOCTXT* pctxt, ASN1UINT8* pvalue, ASN1UINT lower, ASN1UINT upper)
260 ASN1UINT range_value, value;
261 ASN1UINT adjusted_value;
264 /* Check for special case: if lower is 0 and upper is ASN1UINT_MAX, */
265 /* set range to ASN1UINT_MAX; otherwise to upper - lower + 1 */
267 range_value = (lower == 0 && upper == ASN1UINT_MAX) ?
268 ASN1UINT_MAX : upper - lower + 1;
270 if (lower != upper) {
271 ASN1UINT range_bitcnt = 0;
273 /* If range is <= 255, bit-field case (10.5.7a) */
275 if (range_value <= 255) {
276 range_bitcnt = getUIntBitCount (range_value - 1);
279 /* If range is exactly 256, one-octet case (10.5.7b) */
281 else if (range_value == 256) {
282 stat = decodeByteAlign (pctxt);
283 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
287 stat = decodeBits (pctxt, &adjusted_value, range_bitcnt);
288 if (stat == ASN_OK) {
289 value = adjusted_value + lower;
291 if (value < lower || value > upper)
292 stat = ASN_E_CONSVIO;
294 *pvalue = (ASN1OCTET)value;
297 else *pvalue = (ASN1OCTET)lower;
303 (OOCTXT* pctxt, ASN1USINT* pvalue, ASN1UINT lower, ASN1UINT upper)
305 ASN1UINT range_value, value;
306 ASN1UINT adjusted_value;
309 /* Check for special case: if lower is 0 and upper is ASN1UINT_MAX, */
310 /* set range to ASN1UINT_MAX; otherwise to upper - lower + 1 */
312 range_value = (lower == 0 && upper == ASN1UINT_MAX) ?
313 ASN1UINT_MAX : upper - lower + 1;
315 if (lower != upper) {
316 stat = decodeConsWholeNumber (pctxt, &adjusted_value, range_value);
317 if (stat == ASN_OK) {
318 value = adjusted_value + lower;
320 /* Verify value is within given range (ED, 1/15/2002) */
321 if (value < lower || value > upper)
322 stat = ASN_E_CONSVIO;
323 *pvalue = (ASN1USINT) value;
326 else *pvalue = (ASN1USINT) lower;
331 int decodeConsUnsigned
332 (OOCTXT* pctxt, ASN1UINT* pvalue, ASN1UINT lower, ASN1UINT upper)
334 ASN1UINT range_value;
335 ASN1UINT adjusted_value;
338 /* Check for special case: if lower is 0 and upper is ASN1UINT_MAX, */
339 /* set range to ASN1UINT_MAX; otherwise to upper - lower + 1 */
341 range_value = (lower == 0 && upper == ASN1UINT_MAX) ?
342 ASN1UINT_MAX : upper - lower + 1;
344 if (lower != upper) {
345 stat = decodeConsWholeNumber (pctxt, &adjusted_value, range_value);
346 if (stat == ASN_OK) {
347 *pvalue = adjusted_value + lower;
348 if (*pvalue < lower || *pvalue > upper)
349 stat = ASN_E_CONSVIO;
352 else *pvalue = lower;
357 int decodeConsWholeNumber
358 (OOCTXT* pctxt, ASN1UINT* padjusted_value, ASN1UINT range_value)
360 ASN1UINT nocts, range_bitcnt;
363 /* If unaligned, decode non-negative binary integer in the minimum */
364 /* number of bits necessary to represent the range (10.5.6) */
367 range_bitcnt = getUIntBitCount (range_value - 1);
370 /* If aligned, encoding depended on range value (10.5.7) */
374 /* If range is <= 255, bit-field case (10.5.7a) */
376 if (range_value <= 255) {
377 range_bitcnt = getUIntBitCount (range_value - 1);
380 /* If range is exactly 256, one-octet case (10.5.7b) */
382 else if (range_value == 256) {
383 stat = decodeByteAlign (pctxt);
384 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
389 /* If range > 256 and <= 64k (65535), two-octet case (10.5.7c) */
391 else if (range_value <= 65536) {
392 stat = decodeByteAlign (pctxt);
393 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
398 /* If range > 64k, indefinite-length case (10.5.7d) */
401 stat = decodeBits (pctxt, &nocts, 2);
402 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
404 stat = decodeByteAlign (pctxt);
405 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
407 range_bitcnt = (nocts + 1) * 8;
411 return decodeBits (pctxt, padjusted_value, range_bitcnt);
414 int decodeDynBitString (OOCTXT* pctxt, ASN1DynBitStr* pBitStr)
418 int nbits, stat = ASN_OK;
420 /* If "fast copy" option is not set (ASN1FATSCOPY) or if constructed,
421 * copy the bit string value into a dynamic memory buffer;
422 * otherwise, store the pointer to the value in the decode
423 * buffer in the data pointer argument. */
425 if (pctxt->flags & ASN1FASTCOPY) {
426 /* check is it possible to do optimized decoding */
429 ASN1UINT byteIndex = pctxt->buffer.byteIndex; /* save byte index */
430 ASN1USINT bitOffset = pctxt->buffer.bitOffset; /* save bit offset */
432 stat = decodeByteAlign (pctxt);
433 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
435 stat = DECODEBIT (pctxt, &bit); /* read first bit of length determinant */
436 if (bit == 1 && stat == ASN_OK)
437 stat = DECODEBIT (pctxt, &bit); /* read second bit */
439 pctxt->buffer.byteIndex = byteIndex; /* restore byte index */
440 pctxt->buffer.bitOffset = bitOffset; /* restore bit offset */
442 /* if either first or second bit != 0 - not fragmented */
444 if (bit == 0 && stat == ASN_OK) {
447 stat = decodeLength (pctxt, &bitcnt);
448 if (stat != 0) return LOG_ASN1ERR (pctxt, stat);
450 pBitStr->numbits = bitcnt;
452 pBitStr->data = ASN1BUFPTR (pctxt);
454 stat = moveBitCursor (pctxt, bitcnt);
455 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
464 nbits = getComponentLength (pctxt, 1);
466 if (nbits < 0) return LOG_ASN1ERR (pctxt, nbits);
467 else if (nbits == 0) {
468 pBitStr->numbits = 0;
472 nocts = (nbits + 7) / 8;
474 /* Allocate memory for the target string */
477 ptmp = (ASN1OCTET*) ASN1MALLOC (pctxt, nocts);
478 if (0 == ptmp) return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);
480 /* Call static bit string decode function */
482 stat = decodeBitString (pctxt, &pBitStr->numbits, ptmp, nocts);
484 pBitStr->data = ptmp;
489 int decodeDynOctetString (OOCTXT* pctxt, ASN1DynOctStr* pOctStr)
494 /* If "fast copy" option is not set (ASN1FASTCOPY) or if constructed,
495 * copy the octet string value into a dynamic memory buffer;
496 * otherwise, store the pointer to the value in the decode
497 * buffer in the data pointer argument. */
499 if (pctxt->flags & ASN1FASTCOPY) {
500 /* check if it is possible to do optimized decoding */
503 ASN1UINT byteIndex = pctxt->buffer.byteIndex; /* save byte index */
504 ASN1USINT bitOffset = pctxt->buffer.bitOffset; /* save bit offset */
506 stat = decodeByteAlign (pctxt);
507 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
509 stat = DECODEBIT (pctxt, &bit); /* read first bit of length determinant */
510 if (bit == 1 && stat == ASN_OK)
511 stat = DECODEBIT (pctxt, &bit); /* read second bit */
513 pctxt->buffer.byteIndex = byteIndex; /* restore byte index */
514 pctxt->buffer.bitOffset = bitOffset; /* restore bit offset */
516 /* if either first or second bit != 0 - not fragmented */
518 if (bit == 0 && stat == ASN_OK) {
521 stat = decodeLength (pctxt, &octcnt);
522 if (stat != 0) return LOG_ASN1ERR (pctxt, stat);
524 pOctStr->numocts = octcnt;
526 pOctStr->data = ASN1BUFPTR (pctxt);
528 stat = moveBitCursor (pctxt, octcnt * 8);
529 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
538 nocts = getComponentLength (pctxt, 8);
540 if (nocts < 0) return LOG_ASN1ERR (pctxt, nocts);
541 else if (nocts == 0) {
542 pOctStr->numocts = 0;
546 /* Allocate memory for the target string */
549 ptmp = (ASN1OCTET*) ASN1MALLOC (pctxt, nocts);
550 if (0 == ptmp) return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);
553 /* Call static octet string decode function */
555 stat = decodeOctetString (pctxt, &pOctStr->numocts, ptmp, nocts);
557 pOctStr->data = ptmp;
562 int decodeLength (OOCTXT* pctxt, ASN1UINT* pvalue)
565 ASN1UINT lower, upper;
566 ASN1BOOL bitValue, extbit;
569 /* If size constraint is present and extendable, decode extension */
572 if (isExtendableSize(pctxt->pSizeConstraint)) {
573 stat = DECODEBIT (pctxt, &extbit);
574 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
578 /* Now use the value of the extension bit to select the proper */
579 /* size constraint range specification.. */
581 pSize = getSizeConstraint (pctxt, extbit);
583 lower = (pSize) ? pSize->lower : 0;
584 upper = (pSize) ? pSize->upper : ASN1UINT_MAX;
586 /* Reset the size constraint in the context block structure */
588 pctxt->pSizeConstraint = 0;
590 /* If upper limit is less than 64k, constrained case */
593 if (lower == upper) {
598 stat = decodeConsWholeNumber (pctxt, pvalue, (upper - lower + 1));
600 if (stat == ASN_OK) *pvalue += lower;
603 /* unconstrained case OR constrained with upper bound >= 64K*/
605 stat = decodeByteAlign (pctxt);
606 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
608 stat = DECODEBIT (pctxt, &bitValue);
609 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
612 stat = decodeBits (pctxt, pvalue, 7); /* 10.9.3.6 */
613 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
616 stat = DECODEBIT (pctxt, &bitValue);
617 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
620 stat = decodeBits (pctxt, pvalue, 14); /* 10.9.3.7 */
621 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
626 stat = decodeBits (pctxt, &multiplier, 6);
627 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
629 *pvalue = 16384 * multiplier;
639 int decodeObjectIdentifier (OOCTXT* pctxt, ASN1OBJID* pvalue)
646 /* Decode unconstrained length */
648 if ((stat = decodeLength (pctxt, &len)) < 0) {
649 return LOG_ASN1ERR (pctxt, stat);
652 /* Copy contents to a byte-aligned local buffer */
655 while (len > 0 && stat == ASN_OK) {
656 if (j < ASN_K_MAXSUBIDS) {
658 /* Parse a subidentifier out of the contents field */
660 pvalue->subid[j] = 0;
662 if ((stat = decodeBits (pctxt, &b, 8)) == ASN_OK) {
663 pvalue->subid[j] = (pvalue->subid[j] * 128) + (b & 0x7F);
666 } while (b & 0x80 && stat == ASN_OK);
668 /* Handle the first subidentifier special case: the first two */
669 /* sub-id's are encoded into one using the formula (x * 40) + y */
672 subid = pvalue->subid[0];
673 pvalue->subid[0] = ((subid / 40) >= 2) ? 2 : subid / 40;
674 pvalue->subid[1] = (pvalue->subid[0] == 2) ?
675 subid - 80 : subid % 40;
681 stat = ASN_E_INVOBJID;
685 if (stat == ASN_OK && len != 0) stat = ASN_E_INVLEN;
690 static int decodeOctets
691 (OOCTXT* pctxt, ASN1OCTET* pbuffer, ASN1UINT bufsiz, ASN1UINT nbits)
693 ASN1UINT nbytes = (nbits + 7) / 8 ;
695 ASN1UINT rshift = pctxt->buffer.bitOffset;
696 ASN1UINT lshift = 8 - rshift;
697 ASN1UINT nbitsInLastOctet;
701 /* Check to make sure buffer contains number of bits requested */
703 if ((pctxt->buffer.byteIndex + nbytes) > pctxt->buffer.size) {
704 return LOG_ASN1ERR (pctxt, ASN_E_ENDOFBUF);
707 /* Check to make sure buffer is big enough to hold requested */
708 /* number of bits.. */
710 if (nbytes > bufsiz) {
711 return LOG_ASN1ERR (pctxt, ASN_E_STROVFLW);
714 /* If on a byte boundary, can do a direct memcpy to target buffer */
716 if (pctxt->buffer.bitOffset == 8) {
717 memcpy (pbuffer, &pctxt->buffer.data[pctxt->buffer.byteIndex], nbytes);
718 stat = moveBitCursor (pctxt, nbits);
719 if (stat != ASN_OK) return stat;
720 i = nbytes - 1; nbits %= 8;
725 /* Transfer lower bits from stream octet to upper bits of */
728 pbuffer[i] = pctxt->buffer.data[pctxt->buffer.byteIndex++]
731 /* Transfer upper bits from next stream octet to lower bits */
734 pbuffer[i++] |= pctxt->buffer.data[pctxt->buffer.byteIndex]
740 /* Copy last partial byte */
742 if (nbits >= rshift) {
744 pctxt->buffer.data[pctxt->buffer.byteIndex++] << lshift;
746 nbitsInLastOctet = nbits - rshift;
748 if (nbitsInLastOctet > 0) {
750 pctxt->buffer.data[pctxt->buffer.byteIndex] >> rshift;
753 pctxt->buffer.bitOffset = 8 - nbitsInLastOctet;
755 else if (nbits > 0) { /* nbits < rshift */
757 pctxt->buffer.data[pctxt->buffer.byteIndex] << lshift;
758 pctxt->buffer.bitOffset = rshift - nbits;
762 /* Mask unused bits off of last byte */
766 for (j = 0; j < nbits; j++) {
776 int decodeOctetString
777 (OOCTXT* pctxt, ASN1UINT* numocts_p, ASN1OCTET* buffer, ASN1UINT bufsiz)
780 int lstat, octidx = 0, stat;
781 Asn1SizeCnst* pSizeList = pctxt->pSizeConstraint;
783 for (*numocts_p = 0;;) {
784 lstat = decodeLength (pctxt, &octcnt);
785 if (lstat < 0) return LOG_ASN1ERR (pctxt, lstat);
788 *numocts_p += octcnt;
793 stat = bitAndOctetStringAlignmentTest
794 (pSizeList, octcnt, FALSE, &doAlign);
795 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
798 stat = decodeByteAlign (pctxt);
799 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
803 stat = decodeOctets (pctxt, &buffer[octidx],
804 bufsiz - octidx, (octcnt * 8));
806 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
809 if (lstat == ASN_OK_FRAG) {
819 (OOCTXT* pctxt, const ASN1OCTET** object_p2, ASN1UINT* numocts_p)
821 ASN1DynOctStr octStr;
824 stat = decodeDynOctetString (pctxt, &octStr);
825 if (stat == ASN_OK) {
826 *numocts_p = octStr.numocts;
827 *object_p2 = octStr.data;
833 int decodeSemiConsInteger (OOCTXT* pctxt, ASN1INT* pvalue, ASN1INT lower)
840 stat = decodeLength (pctxt, &nbytes);
841 if (stat < 0) return LOG_ASN1ERR (pctxt, stat);
847 stat = decodeByteAlign (pctxt);
848 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
850 /* Decode first byte into a signed byte value and assign to integer. */
851 /* This should handle sign extension.. */
853 stat = decodeOctets (pctxt, (ASN1OCTET*)&b, 1, 8);
854 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
859 /* Decode remaining bytes and add to result */
862 stat = decodeOctets (pctxt, (ASN1OCTET*)&ub, 1, 8);
863 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
865 *pvalue = (*pvalue * 256) + ub;
869 else { /* nbytes == 0 */
872 if (lower > ASN1INT_MIN)
878 int decodeSemiConsUnsigned (OOCTXT* pctxt, ASN1UINT* pvalue, ASN1UINT lower)
883 stat = decodeLength (pctxt, &nbytes);
884 if (stat < 0) return LOG_ASN1ERR (pctxt, stat);
888 stat = decodeByteAlign (pctxt);
889 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
891 stat = decodeBits (pctxt, pvalue, nbytes * 8);
900 int decodeSmallNonNegWholeNumber (OOCTXT* pctxt, ASN1UINT* pvalue)
906 if ((ret = DECODEBIT (pctxt, &bitValue)) != ASN_OK)
910 return decodeBits (pctxt, pvalue, 6); /* 10.6.1 */
913 if ((ret = decodeLength (pctxt, &len)) < 0)
916 if ((ret = decodeByteAlign (pctxt)) != ASN_OK)
919 return decodeBits (pctxt, pvalue, len*8);
923 int decodeVarWidthCharString (OOCTXT* pctxt, const char** pvalue)
929 /* note: need to save size constraint for use in alignCharStr */
930 /* because it will be cleared in decodeLength from the context.. */
931 Asn1SizeCnst* psize = pctxt->pSizeConstraint;
935 stat = decodeLength (pctxt, &len);
936 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
940 if (alignCharStr (pctxt, len, 8, psize)) {
941 stat = decodeByteAlign (pctxt);
942 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
947 tmpstr = (ASN1OCTET*) ASN1MALLOC (pctxt, len + 1);
949 if ((stat = decodeOctets (pctxt, tmpstr, len, len * 8)) != ASN_OK)
950 return LOG_ASN1ERR (pctxt, stat);
952 tmpstr[len] = '\0'; /* add null-terminator */
955 return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);
957 *pvalue = (char*)tmpstr;
962 static int decode16BitConstrainedString
963 (OOCTXT* pctxt, Asn116BitCharString* pString, Asn116BitCharSet* pCharSet)
965 ASN1UINT i, idx, nbits = pCharSet->alignedBits;
970 stat = decodeLength (pctxt, &pString->nchars);
971 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
975 stat = decodeByteAlign (pctxt);
976 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
980 pString->data = (ASN116BITCHAR*)
981 ASN1MALLOC (pctxt, pString->nchars*sizeof(ASN116BITCHAR));
984 for (i = 0; i < pString->nchars; i++) {
985 stat = decodeBits (pctxt, &idx, nbits);
986 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
988 pString->data[i] = (pCharSet->charSet.data == 0) ?
989 idx + pCharSet->firstChar : pCharSet->charSet.data[idx];
993 return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);
998 static int getComponentLength (OOCTXT* pctxt, ASN1UINT itemBits)
1001 ASN1UINT len, totalLen = 0;
1004 stat = initSubContext (&lctxt, pctxt);
1005 if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
1007 stat = setPERBufferUsingCtxt (&lctxt, pctxt);
1008 if (stat != ASN_OK) {
1009 freeContext (&lctxt);
1010 return LOG_ASN1ERR (pctxt, stat);
1012 lctxt.pSizeConstraint = pctxt->pSizeConstraint;
1015 stat = decodeLength (&lctxt, &len);
1017 freeContext (&lctxt);
1018 return LOG_ASN1ERR (pctxt, stat);
1023 if (stat == ASN_OK_FRAG) {
1024 stat = moveBitCursor (&lctxt, len * itemBits);
1025 if (stat != ASN_OK) {
1026 freeContext (&lctxt);
1027 return LOG_ASN1ERR (pctxt, stat);
1033 freeContext (&lctxt);
1038 int moveBitCursor (OOCTXT* pctxt, int bitOffset)
1041 (pctxt->buffer.byteIndex * 8) + (8 - pctxt->buffer.bitOffset);
1043 currBitOffset += bitOffset;
1045 pctxt->buffer.byteIndex = (currBitOffset / 8);
1046 pctxt->buffer.bitOffset = 8 - (currBitOffset % 8);
1048 if (pctxt->buffer.byteIndex > pctxt->buffer.size) {
1049 return (ASN_E_ENDOFBUF);