Nut/OS  4.10.3
API Reference
asn1.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 1998-2007 by egnite Software GmbH
00003  * Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00022  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00025  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00026  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00028  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * For additional information see http://www.ethernut.de/
00032  */
00033 
00034 #include <sys/types.h>
00035 
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <memdebug.h>
00039 
00040 #include <pro/asn1.h>
00041 
00042 /*
00043  * Abstract Syntax Notation One, ASN.1 as defined in ISO/IS 8824 and 
00044  * ISO/IS 8825. This implements a subset of the above international 
00045  * standards that is sufficient for SNMP.
00046  */
00047 
00058 static CONST uint8_t *AsnLenParse(CONST uint8_t * data, uint32_t * length)
00059 {
00060     uint8_t lengthbyte = *data++;
00061 
00062     if (lengthbyte & ASN_LONG_LEN) {
00063         /* Long length. */
00064         lengthbyte &= ~ASN_LONG_LEN;
00065         if (lengthbyte == 0 || lengthbyte > sizeof(long)) {
00066             return NULL;
00067         }
00068         *length = 0;
00069         while (lengthbyte--) {
00070             *length <<= 8;
00071             *length |= *data++;
00072         }
00073     } else {
00074         /* Short length. */
00075         *length = lengthbyte;
00076     }
00077     return data;
00078 }
00079 
00093 static uint8_t *AsnLenBuild(uint8_t * data, size_t * datalength, size_t length)
00094 {
00095     if (length < 0x80) {
00096         /* Check for buffer overflow. */
00097         if (*datalength < 1) {
00098             return NULL;
00099         }
00100         *datalength -= 1;
00101         *data++ = (uint8_t) length;
00102     } else if (length <= 0xFF) {
00103         /* Check for buffer overflow. */
00104         if (*datalength < 2) {
00105             return NULL;
00106         }
00107         *datalength -= 2;
00108         *data++ = (uint8_t) (0x01 | ASN_LONG_LEN);
00109         *data++ = (uint8_t) length;
00110     } else {
00111         /* Check for buffer overflow. */
00112         if (*datalength < 3) {
00113             return NULL;
00114         }
00115         *datalength -= 3;
00116         *data++ = (uint8_t) (0x02 | ASN_LONG_LEN);
00117         *data++ = (uint8_t) (((unsigned) length >> 8) & 0xFF);
00118         *data++ = (uint8_t) (length & 0xFF);
00119     }
00120     return data;
00121 }
00122 
00136 CONST uint8_t *AsnHeaderParse(CONST uint8_t * data, size_t * datalength, uint8_t * type)
00137 {
00138     size_t header_len;
00139     uint32_t asn_length;
00140     CONST uint8_t *bufp = data;
00141 
00142     if (*datalength <= 0) {
00143         return NULL;
00144     }
00145 
00146     /*
00147      * The first byte of the header is the type. This only
00148      * works on data types < 30, i.e. no extension octets.
00149      */
00150     *type = *bufp;
00151     if ((*type & ASN_EXTENSION_ID) == ASN_EXTENSION_ID) {
00152         return NULL;
00153     }
00154 
00155     /*
00156      * Interpret the length (short or long) of this object.
00157      */
00158     if ((bufp = AsnLenParse(bufp + 1, &asn_length)) == NULL) {
00159         return NULL;
00160     }
00161 
00162     header_len = bufp - data;
00163     /* Data length exceeds packet size. */
00164     if (header_len + asn_length > *datalength) {
00165         return NULL;
00166     }
00167     *datalength = (int) asn_length;
00168 
00169     return bufp;
00170 }
00171 
00189 uint8_t *AsnHeaderBuild(uint8_t * data, size_t * datalength, uint8_t type, size_t length)
00190 {
00191     if (*datalength < 1) {
00192         return NULL;
00193     }
00194     *data++ = type;
00195     (*datalength)--;
00196 
00197     return AsnLenBuild(data, datalength, length);
00198 }
00199 
00215 CONST uint8_t *AsnSequenceParse(CONST uint8_t * data, size_t * datalength, uint8_t type)
00216 {
00217     uint8_t t;
00218 
00219     if ((data = AsnHeaderParse(data, datalength, &t)) != NULL) {
00220         if (t != type) {
00221             data = NULL;
00222         }
00223     }
00224     return data;
00225 }
00226 
00244 uint8_t *AsnSequenceBuild(uint8_t * data, size_t * datalength, uint8_t type, size_t length)
00245 {
00246     if (*datalength < 4) {
00247         /* Not enough space in output packet. */
00248         return NULL;
00249     }
00250 
00251     *datalength -= 4;
00252     *data++ = type;
00253     *data++ = (uint8_t) (0x02 | ASN_LONG_LEN);
00254     *data++ = (uint8_t) (((unsigned) length >> 8) & 0xFF);
00255     *data++ = (uint8_t) length;
00256 
00257     return data;
00258 }
00259 
00277 CONST uint8_t *AsnIntegerParse(CONST uint8_t * data, size_t * datalength, uint8_t * type, long *intp)
00278 {
00279     CONST uint8_t *bufp = data;
00280     uint32_t asn_length;
00281 
00282     /* Get the type. */
00283     *type = *bufp++;
00284     /* Parse the length. */
00285     if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
00286         return NULL;
00287     }
00288     /* Check for overflow. */
00289     if (asn_length > sizeof(long) || asn_length + (bufp - data) > *datalength) {
00290         return NULL;
00291     }
00292     /* Update the number of valid bytes. */
00293     *datalength -= asn_length + (bufp - data);
00294     /* Determine sign. */
00295     if (*bufp & 0x80) {
00296         *intp = -1;
00297     } else {
00298         *intp = 0;
00299     }
00300     /* Retrieve the value. */
00301     while (asn_length--) {
00302         *intp <<= 8;
00303         *intp |= *bufp++;
00304     }
00305     return bufp;
00306 }
00307 
00323 uint8_t *AsnIntegerBuild(uint8_t * data, size_t * datalength, uint8_t type, long *intp)
00324 {
00325     uint32_t mask;
00326     long value = *intp;
00327     size_t size = sizeof(long);
00328 
00329     /*
00330      * Truncate unnecessary bytes off of the most significant end of 
00331      * this 2's complement integer. Skip any leading sequence of 
00332      * 9 consecutive 1's or 0's.
00333      */
00334     mask = 0x1FFUL << ((8 * (sizeof(long) - 1)) - 1);
00335     while (((value & mask) == 0 || (value & mask) == mask) && size > 1) {
00336         size--;
00337         value <<= 8;
00338     }
00339     /* We know the size, so let's build the header. */
00340     if ((data = AsnHeaderBuild(data, datalength, type, size)) == NULL) {
00341         return NULL;
00342     }
00343     /* Check if there's enough space for the value. */
00344     if (*datalength < size) {
00345         return NULL;
00346     }
00347     *datalength -= size;
00348 
00349     /* Store the value, MSB first. */
00350     mask = 0xFFUL << (8 * (sizeof(long) - 1));
00351     while (size--) {
00352         *data++ = (uint8_t) ((value & mask) >> (8 * (sizeof(long) - 1)));
00353         value <<= 8;
00354     }
00355     return data;
00356 }
00357 
00375 CONST uint8_t *AsnUnsignedParse(CONST uint8_t * data, size_t * datalength, uint8_t * type, uint32_t * intp)
00376 {
00377     CONST uint8_t *bufp = data;
00378     uint32_t asn_length;
00379 
00380     /* Get the type. */
00381     *type = *bufp++;
00382     /* Parse the length. */
00383     if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
00384         return NULL;
00385     }
00386     /* Check for length overflow. */
00387     if (asn_length > sizeof(long) + 1 || (asn_length == sizeof(long) + 1 && *bufp != 0x00)) {
00388         return NULL;
00389     }
00390     /* Check for sufficient data. */
00391     if (asn_length + (bufp - data) > *datalength) {
00392         return NULL;
00393     }
00394     /* Update the number of valid bytes. */
00395     *datalength -= (int) asn_length + (bufp - data);
00396     /* Determine sign. */
00397     if (*bufp & 0x80) {
00398         *intp = -1;
00399     } else {
00400         *intp = 0;
00401     }
00402     /* Retrieve the value. */
00403     while (asn_length--) {
00404         *intp <<= 8;
00405         *intp |= *bufp++;
00406     }
00407     return bufp;
00408 }
00409 
00425 uint8_t *AsnUnsignedBuild(uint8_t * data, size_t * datalength, uint8_t type, uint32_t * intp)
00426 {
00427     int msb;
00428     uint32_t mask;
00429     uint32_t value = *intp;
00430     size_t size = sizeof(uint32_t);
00431 
00432     /* Check if MSB is set. */
00433     if (value & (0x80UL << (8 * (sizeof(long) - 1)))) {
00434         msb = 1;
00435         size++;
00436     } else {
00437         msb = 0;
00438         /*
00439          * Truncate unnecessary bytes off of the most significant end.
00440          * Skip any leading sequence of 9 consecutive 1's or 0's.
00441          */
00442         mask = 0x1FFUL << ((8 * (sizeof(long) - 1)) - 1);
00443         while ((((value & mask) == 0) || ((value & mask) == mask)) && size > 1) {
00444             size--;
00445             value <<= 8;
00446         }
00447     }
00448     /* We know the size, so let's build the header. */
00449     if ((data = AsnHeaderBuild(data, datalength, type, size)) == NULL) {
00450         return NULL;
00451     }
00452     /* Check if there's enough space for the value. */
00453     if (*datalength < size) {
00454         return NULL;
00455     }
00456     *datalength -= size;
00457     /* Add leading null byte if MSB set. */
00458     if (msb) {
00459         *data++ = '\0';
00460         size--;
00461     }
00462     /* Store the value, MSB first. */
00463     mask = 0xFFUL << (8 * (sizeof(long) - 1));
00464     while (size--) {
00465         *data++ = (uint8_t) ((value & mask) >> (8 * (sizeof(long) - 1)));
00466         value <<= 8;
00467     }
00468     return data;
00469 }
00470 
00491 CONST uint8_t *AsnOctetStringParse(CONST uint8_t * data, size_t * datalength, uint8_t * type, uint8_t * string, size_t * strlength)
00492 {
00493     CONST uint8_t *bufp = data;
00494     uint32_t asn_length;
00495 
00496     /* Get the type. */
00497     *type = *bufp++;
00498     /* Get the length. */
00499     if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
00500         return NULL;
00501     }
00502     /* Check for overflow. */
00503     if (asn_length > *strlength || asn_length + (bufp - data) > *datalength) {
00504         return NULL;
00505     }
00506     if (asn_length) {
00507         /* Store value and update lengths. */
00508         memcpy(string, bufp, asn_length);
00509         *strlength = (size_t) asn_length;
00510     }
00511     *datalength -= (size_t) (asn_length + (bufp - data));
00512 
00513     return bufp + asn_length;
00514 }
00515 
00533 uint8_t *AsnOctetStringBuild(uint8_t * data, size_t * datalength, uint8_t type, CONST uint8_t * string, size_t strlength)
00534 {
00535     if ((data = AsnHeaderBuild(data, datalength, type, strlength)) == NULL) {
00536         return NULL;
00537     }
00538     if (strlength) {
00539         /* Check for overflow. */
00540         if (*datalength < strlength) {
00541             return NULL;
00542         }
00543         *datalength -= strlength;
00544         if (string) {
00545             memcpy(data, string, strlength);
00546         } else {
00547             memset(data, 0, strlength);
00548         }
00549         data += strlength;
00550     }
00551     return data;
00552 }
00553 
00574 CONST uint8_t *AsnOidParse(CONST uint8_t * data, size_t * datalength, uint8_t * type, OID * objid, size_t * objidlength)
00575 {
00576     CONST uint8_t *bufp = data;
00577     OID *oidp = objid + 1;
00578     uint32_t subidentifier;
00579     long length;
00580     uint32_t asn_length;
00581 
00582     /* Get type and length. */
00583     *type = *bufp++;
00584     if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
00585         return NULL;
00586     }
00587     /* Check for overflow and update number of remaining bytes. */
00588     if (asn_length + (bufp - data) > *datalength) {
00589         /* Message overflow. */
00590         return NULL;
00591     }
00592     *datalength -= (int) asn_length + (bufp - data);
00593 
00594     /* Handle invalid object ID encodings of the form 06 00 robustly. */
00595     if (asn_length == 0) {
00596         objid[0] = objid[1] = 0;
00597     }
00598     length = asn_length;
00599     /* Account for expansion of first byte. */
00600     (*objidlength)--;
00601     while (length > 0 && (*objidlength)-- > 0) {
00602         subidentifier = 0;
00603         /*
00604          * Shift and add in low order 7 bits.
00605          * Last byte has high bit clear.
00606          */
00607         do {
00608             subidentifier = (subidentifier << 7) + (*(uint8_t *) bufp & ~ASN_BIT8);
00609             length--;
00610         } while (*bufp++ & ASN_BIT8);
00611         *oidp++ = (OID) subidentifier;
00612     }
00613 
00614     /*
00615      * The first two subidentifiers are encoded into the first component 
00616      * with the value (X * 40) + Y, where
00617      *
00618      *  X is the value of the first subidentifier.
00619      *  Y is the value of the second subidentifier.
00620      */
00621     subidentifier = objid[1];
00622     if (subidentifier == 0x2B) {
00623         objid[0] = 1;
00624         objid[1] = 3;
00625     } else {
00626         objid[1] = (uint8_t) (subidentifier % 40);
00627         objid[0] = (uint8_t) ((subidentifier - objid[1]) / 40);
00628     }
00629     *objidlength = oidp - objid;
00630 
00631     return bufp;
00632 }
00633 
00650 uint8_t *AsnOidBuild(uint8_t * data, size_t * datalength, uint8_t type, CONST OID * objid, size_t objidlength)
00651 {
00652     uint8_t *buf;
00653     uint32_t objid_val;
00654     uint32_t first_objid_val;
00655     size_t asnlength;
00656     CONST OID *op = objid;
00657     size_t i;
00658 
00659     if (objidlength == 0) {
00660         first_objid_val = 0;
00661         objidlength++;
00662     } else if (objid[0] > 2) {
00663         /* First sub identifier is bad. */
00664         return NULL;
00665     } else if (objidlength == 1) {
00666         first_objid_val = op[0] * 40;
00667     } else if (op[1] > 40 && op[0] < 2) {
00668         /* Second sub identifier is bad. */
00669         return NULL;
00670     } else if (objidlength > MAX_OID_LEN) {
00671         /* Bad object ID length. */
00672         return NULL;
00673     } else {
00674         first_objid_val = op[0] * 40 + op[1];
00675         objidlength--;
00676     }
00677 
00678     /*
00679      * Determine the number of bytes needed to store the encoded value.
00680      */
00681     if ((buf = malloc(MAX_OID_LEN * sizeof(OID))) == NULL) {
00682         return NULL;
00683     }
00684     asnlength = 0;
00685     for (i = 0; i < objidlength; i++) {
00686         if (i) {
00687             objid_val = *op++;
00688         } else {
00689             objid_val = first_objid_val;
00690             op = objid + 2;
00691         }
00692         if (objid_val < 0x80UL) {
00693             buf[i] = 1;
00694             asnlength += 1;
00695         } else if (objid_val < 0x4000UL) {
00696             buf[i] = 2;
00697             asnlength += 2;
00698         } else if (objid_val < 0x200000UL) {
00699             buf[i] = 3;
00700             asnlength += 3;
00701         } else if (objid_val < 0x10000000UL) {
00702             buf[i] = 4;
00703             asnlength += 4;
00704         } else {
00705             buf[i] = 5;
00706             asnlength += 5;
00707         }
00708     }
00709     /* Build the header after knowing the length. */
00710     if ((data = AsnHeaderBuild(data, datalength, type, asnlength)) == NULL || asnlength > *datalength) {
00711         free(buf);
00712         return NULL;
00713     }
00714 
00715     /*
00716      * Store the encoded OID value 
00717      */
00718     for (i = 0; i < objidlength; i++) {
00719         if (i) {
00720             objid_val = *op++;
00721         } else {
00722             objid_val = first_objid_val;
00723             op = objid + 2;
00724         }
00725         switch (buf[i]) {
00726         case 1:
00727             *data++ = (uint8_t) objid_val;
00728             break;
00729         case 2:
00730             *data++ = (uint8_t) ((objid_val >> 7) | 0x80);
00731             *data++ = (uint8_t) (objid_val & 0x07f);
00732             break;
00733         case 3:
00734             *data++ = (uint8_t) ((objid_val >> 14) | 0x80);
00735             *data++ = (uint8_t) ((objid_val >> 7 & 0x7f) | 0x80);
00736             *data++ = (uint8_t) (objid_val & 0x07f);
00737             break;
00738         case 4:
00739             *data++ = (uint8_t) ((objid_val >> 21) | 0x80);
00740             *data++ = (uint8_t) ((objid_val >> 14 & 0x7f) | 0x80);
00741             *data++ = (uint8_t) ((objid_val >> 7 & 0x7f) | 0x80);
00742             *data++ = (uint8_t) (objid_val & 0x07f);
00743             break;
00744         case 5:
00745             *data++ = (uint8_t) ((objid_val >> 28) | 0x80);
00746             *data++ = (uint8_t) ((objid_val >> 21 & 0x7f) | 0x80);
00747             *data++ = (uint8_t) ((objid_val >> 14 & 0x7f) | 0x80);
00748             *data++ = (uint8_t) ((objid_val >> 7 & 0x7f) | 0x80);
00749             *data++ = (uint8_t) (objid_val & 0x07f);
00750             break;
00751         }
00752     }
00753 
00754     *datalength -= asnlength;
00755     free(buf);
00756 
00757     return data;
00758 }
00759 
00775 CONST uint8_t *AsnNullParse(CONST uint8_t * data, size_t * datalength, uint8_t * type)
00776 {
00777     CONST uint8_t *bufp = data;
00778     uint32_t asn_length;
00779 
00780     *type = *bufp++;
00781     if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
00782         return NULL;
00783     }
00784     if (asn_length) {
00785         return NULL;
00786     }
00787     *datalength -= (bufp - data);
00788 
00789     return bufp;
00790 }
00791 
00806 uint8_t *AsnNullBuild(uint8_t * data, size_t * datalength, uint8_t type)
00807 {
00808     return AsnHeaderBuild(data, datalength, type, 0);
00809 }
00810 
00831 CONST uint8_t *AsnBitStringParse(CONST uint8_t * data, size_t * datalength, uint8_t * type, uint8_t * string, size_t * strlength)
00832 {
00833     CONST uint8_t *bufp = data;
00834     uint32_t asn_length;
00835 
00836     *type = *bufp++;
00837     if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
00838         return NULL;
00839     }
00840     if (asn_length + (bufp - data) > *datalength) {
00841         return NULL;
00842     }
00843     if (asn_length < 1 || (size_t) asn_length > *strlength) {
00844         return NULL;
00845     }
00846     if (*bufp > 7) {
00847         return NULL;
00848     }
00849     memcpy(string, bufp, asn_length);
00850     *strlength = (size_t) asn_length;
00851     *datalength -= (size_t) asn_length + (bufp - data);
00852 
00853     return bufp + asn_length;
00854 }
00855 
00873 uint8_t *AsnBitStringBuild(uint8_t * data, size_t * datalength, uint8_t type, CONST uint8_t * string, size_t strlength)
00874 {
00875     if ((data = AsnHeaderBuild(data, datalength, type, strlength)) == NULL) {
00876         return NULL;
00877     }
00878     if (strlength) {
00879         if (strlength > *datalength) {
00880             return NULL;
00881         }
00882         memcpy((char *) data, (char *) string, strlength);
00883         *datalength -= strlength;
00884         data += strlength;
00885     }
00886     return data;
00887 }
00888 
00906 CONST uint8_t *AsnUnsigned64Parse(CONST uint8_t * data, size_t * datalength, uint8_t * type, UNSIGNED64 * cp)
00907 {
00908     CONST uint8_t *bufp = data;
00909     uint32_t asn_length;
00910     uint32_t low = 0;
00911     uint32_t high = 0;
00912     size_t intsize = 4;
00913 
00914     *type = *bufp++;
00915     if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
00916         return NULL;
00917     }
00918     if (asn_length + (bufp - data) > *datalength) {
00919         return NULL;
00920     }
00921     if ((asn_length > (intsize * 2 + 1)) || ((asn_length == (intsize * 2) + 1) && *bufp != 0x00)) {
00922         return NULL;
00923     }
00924     *datalength -= (int) asn_length + (bufp - data);
00925     if (*bufp & 0x80) {
00926         low = (uint32_t) - 1;
00927         high = (uint32_t) - 1;
00928     }
00929     while (asn_length--) {
00930         high = (high << 8) | ((low & 0xFF000000) >> 24);
00931         low = (low << 8) | *bufp++;
00932     }
00933     cp->low = low;
00934     cp->high = high;
00935     return bufp;
00936 }
00937 
00953 uint8_t *AsnUnsigned64Build(uint8_t * data, size_t * datalength, uint8_t type, CONST UNSIGNED64 * cp)
00954 {
00955     uint32_t low;
00956     uint32_t high;
00957     uint32_t mask;
00958     uint32_t mask2;
00959     int add_null_byte = 0;
00960     size_t intsize;
00961 
00962     intsize = 8;
00963     low = cp->low;
00964     high = cp->high;
00965     mask = 0xFFUL << (8 * (sizeof(long) - 1));
00966     /*
00967      * mask is 0xFF000000 on a big-endian machine
00968      */
00969     if ((uint8_t) ((high & mask) >> (8 * (sizeof(long) - 1))) & 0x80) {
00970         /* if MSB is set */
00971         add_null_byte = 1;
00972         intsize++;
00973     }
00974     /*
00975      * Truncate "unnecessary" bytes off of the most significant end of 
00976      * this 2's complement integer.
00977      * There should be no sequence of 9 consecutive 1's or 0's at the most
00978      * significant end of the integer.
00979      */
00980     mask2 = 0x1FFUL << ((8 * (sizeof(long) - 1)) - 1);
00981     /*
00982      * mask2 is 0xFF800000 on a big-endian machine
00983      */
00984     while ((((high & mask2) == 0) || ((high & mask2) == mask2))
00985            && intsize > 1) {
00986         intsize--;
00987         high = (high << 8)
00988             | ((low & mask) >> (8 * (sizeof(long) - 1)));
00989         low <<= 8;
00990     }
00991     data = AsnHeaderBuild(data, datalength, type, intsize);
00992     if (data == NULL || *datalength < intsize) {
00993         return NULL;
00994     }
00995     *datalength -= intsize;
00996     if (add_null_byte == 1) {
00997         *data++ = '\0';
00998         intsize--;
00999     }
01000     while (intsize--) {
01001         *data++ = (uint8_t) ((high & mask) >> (8 * (sizeof(long) - 1)));
01002         high = (high << 8)
01003             | ((low & mask) >> (8 * (sizeof(long) - 1)));
01004         low <<= 8;
01005 
01006     }
01007     return data;
01008 }