LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/asn1 - der_put.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 225 403 55.8 %
Date: 2024-04-21 15:09:00 Functions: 18 24 75.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "der_locl.h"
      35             : 
      36             : RCSID("$Id$");
      37             : 
      38             : /*
      39             :  * All encoding functions take a pointer `p' to first position in
      40             :  * which to write, from the right, `len' which means the maximum
      41             :  * number of characters we are able to write.  The function returns
      42             :  * the number of characters written in `size' (if non-NULL).
      43             :  * The return value is 0 or an error.
      44             :  */
      45             : 
      46             : int ASN1CALL
      47       97946 : der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
      48             : {
      49       97946 :     unsigned char *base = p;
      50       97946 :     unsigned val = *v;
      51             : 
      52       97946 :     *size = 0;
      53             : 
      54       97946 :     if (val) {
      55      488690 :         while (len > 0 && val) {
      56      390745 :             *p-- = val % 256;
      57      390745 :             val /= 256;
      58      390745 :             --len;
      59             :         }
      60       97945 :         if (val != 0)
      61           0 :             return ASN1_OVERFLOW;
      62             :         else {
      63       97945 :             if(p[1] >= 128) {
      64       22504 :                 if(len < 1)
      65           0 :                     return ASN1_OVERFLOW;
      66       22504 :                 *p-- = 0;
      67             :             }
      68       97945 :             *size = base - p;
      69       97945 :             return 0;
      70             :         }
      71           1 :     } else if (len < 1)
      72           0 :         return ASN1_OVERFLOW;
      73             :     else {
      74           1 :         *p    = 0;
      75           1 :         *size = 1;
      76           1 :         return 0;
      77             :     }
      78             : }
      79             : 
      80             : int ASN1CALL
      81           0 : der_put_unsigned64 (unsigned char *p, size_t len, const uint64_t *v, size_t *size)
      82             : {
      83           0 :     unsigned char *base = p;
      84           0 :     uint64_t val = *v;
      85             : 
      86           0 :     *size = 0;
      87             : 
      88           0 :     if (val) {
      89           0 :        while (len > 0 && val) {
      90           0 :            *p-- = val % 256;
      91           0 :            val /= 256;
      92           0 :            --len;
      93             :        }
      94           0 :        if (val != 0)
      95           0 :            return ASN1_OVERFLOW;
      96             :        else {
      97           0 :            if(p[1] >= 128) {
      98           0 :                if(len < 1)
      99           0 :                    return ASN1_OVERFLOW;
     100           0 :                *p-- = 0;
     101             :            }
     102           0 :            *size = base - p;
     103           0 :            return 0;
     104             :        }
     105           0 :     } else if (len < 1)
     106           0 :        return ASN1_OVERFLOW;
     107             :     else {
     108           0 :        *p    = 0;
     109           0 :        *size = 1;
     110           0 :        return 0;
     111             :     }
     112             : }
     113             : 
     114             : int ASN1CALL
     115     6485470 : der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
     116             : {
     117     6485470 :     unsigned char *base = p;
     118     6485470 :     int val = *v;
     119             : 
     120     6485470 :     *size = 0;
     121             : 
     122     6485470 :     if(val >= 0) {
     123      259194 :         do {
     124     7254872 :             if(len < 1)
     125           0 :                 return ASN1_OVERFLOW;
     126     7254872 :             *p-- = val % 256;
     127     7254872 :             len--;
     128     7254872 :             val /= 256;
     129     7254872 :         } while(val);
     130     6377596 :         if(p[1] >= 128) {
     131      400923 :             if(len < 1)
     132           0 :                 return ASN1_OVERFLOW;
     133      400923 :             *p-- = 0;
     134      400923 :             len--;
     135             :         }
     136             :     } else {
     137      107874 :         val = ~val;
     138       13652 :         do {
     139      415951 :             if(len < 1)
     140           0 :                 return ASN1_OVERFLOW;
     141      415951 :             *p-- = ~(val % 256);
     142      415951 :             len--;
     143      415951 :             val /= 256;
     144      415951 :         } while(val);
     145      107874 :         if(p[1] < 128) {
     146        5332 :             if(len < 1)
     147           0 :                 return ASN1_OVERFLOW;
     148        5332 :             *p-- = 0xff;
     149        5332 :             len--;
     150             :         }
     151             :     }
     152     6485470 :     *size = base - p;
     153     6485470 :     return 0;
     154             : }
     155             : 
     156             : int ASN1CALL
     157           0 : der_put_integer64 (unsigned char *p, size_t len, const int64_t *v, size_t *size)
     158             : {
     159           0 :     unsigned char *base = p;
     160           0 :     int64_t val = *v;
     161             : 
     162           0 :     *size = 0;
     163             : 
     164           0 :     if(val >= 0) {
     165           0 :        do {
     166           0 :            if(len < 1)
     167           0 :                return ASN1_OVERFLOW;
     168           0 :            *p-- = val % 256;
     169           0 :            len--;
     170           0 :            val /= 256;
     171           0 :        } while(val);
     172           0 :        if(p[1] >= 128) {
     173           0 :            if(len < 1)
     174           0 :                return ASN1_OVERFLOW;
     175           0 :            *p-- = 0;
     176           0 :            len--;
     177             :        }
     178             :     } else {
     179           0 :        val = ~val;
     180           0 :        do {
     181           0 :            if(len < 1)
     182           0 :                return ASN1_OVERFLOW;
     183           0 :            *p-- = ~(val % 256);
     184           0 :            len--;
     185           0 :            val /= 256;
     186           0 :        } while(val);
     187           0 :        if(p[1] < 128) {
     188           0 :            if(len < 1)
     189           0 :                return ASN1_OVERFLOW;
     190           0 :            *p-- = 0xff;
     191           0 :            len--;
     192             :        }
     193             :     }
     194           0 :     *size = base - p;
     195           0 :     return 0;
     196             : }
     197             : 
     198             : 
     199             : int ASN1CALL
     200    36774342 : der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
     201             : {
     202    36774342 :     if (size)
     203    36774342 :         *size = 0;
     204             : 
     205    36774342 :     if (len < 1)
     206           0 :         return ASN1_OVERFLOW;
     207             : 
     208    36774342 :     if (val < 128) {
     209    29900454 :         *p = val;
     210    29900454 :         if (size)
     211    29900454 :             *size = 1;
     212             :     } else {
     213     6625659 :         size_t l = 0;
     214             : 
     215    18633200 :         while(val > 0) {
     216    11759312 :             if(len < 2)
     217           0 :                 return ASN1_OVERFLOW;
     218    11759312 :             *p-- = val % 256;
     219    11759312 :             val /= 256;
     220    11759312 :             len--;
     221    11759312 :             l++;
     222             :         }
     223     6873888 :         *p = 0x80 | l;
     224     6873888 :         if(size)
     225     6873888 :             *size = l + 1;
     226             :     }
     227    35462447 :     return 0;
     228             : }
     229             : 
     230             : int ASN1CALL
     231        1671 : der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
     232             : {
     233        1671 :     *size = 0;
     234             : 
     235        1671 :     if(len < 1)
     236           0 :         return ASN1_OVERFLOW;
     237        1671 :     if(*data != 0)
     238        1671 :         *p = 0xff;
     239             :     else
     240           0 :         *p = 0;
     241        1671 :     *size = 1;
     242        1671 :     return 0;
     243             : }
     244             : 
     245             : int ASN1CALL
     246     2939755 : der_put_general_string (unsigned char *p, size_t len,
     247             :                         const heim_general_string *str, size_t *size)
     248             : {
     249      105682 :     size_t slen;
     250             : 
     251     2939755 :     assert(p != NULL && str != NULL && *str != NULL && size != NULL);
     252     2939755 :     *size = 0;
     253     2939755 :     slen = strlen(*str);
     254     2939755 :     if (len < slen)
     255           0 :         return ASN1_OVERFLOW;
     256     2939755 :     p -= slen;
     257     2939755 :     memcpy (p+1, *str, slen);
     258     2939755 :     *size = slen;
     259     2939755 :     return 0;
     260             : }
     261             : 
     262             : int ASN1CALL
     263         895 : der_put_utf8string (unsigned char *p, size_t len,
     264             :                     const heim_utf8_string *str, size_t *size)
     265             : {
     266         895 :     return der_put_general_string(p, len, str, size);
     267             : }
     268             : 
     269             : int ASN1CALL
     270         369 : der_put_printable_string (unsigned char *p, size_t len,
     271             :                           const heim_printable_string *str, size_t *size)
     272             : {
     273         369 :     return der_put_octet_string(p, len, str, size);
     274             : }
     275             : 
     276             : int ASN1CALL
     277         192 : der_put_ia5_string (unsigned char *p, size_t len,
     278             :                     const heim_ia5_string *str, size_t *size)
     279             : {
     280         192 :     return der_put_octet_string(p, len, str, size);
     281             : }
     282             : 
     283             : int ASN1CALL
     284           0 : der_put_bmp_string (unsigned char *p, size_t len,
     285             :                     const heim_bmp_string *data, size_t *size)
     286             : {
     287           0 :     size_t i;
     288             : 
     289           0 :     assert(p != NULL && data != NULL);
     290             : 
     291           0 :     if (size)
     292           0 :         *size = 0;
     293             : 
     294           0 :     if (len / 2 < data->length)
     295           0 :         return ASN1_OVERFLOW;
     296           0 :     p -= data->length * 2;
     297           0 :     for (i = 0; i < data->length; i++) {
     298           0 :         p[1] = (data->data[i] >> 8) & 0xff;
     299           0 :         p[2] = data->data[i] & 0xff;
     300           0 :         p += 2;
     301             :     }
     302           0 :     if (size) *size = data->length * 2;
     303           0 :     return 0;
     304             : }
     305             : 
     306             : int ASN1CALL
     307           0 : der_put_universal_string (unsigned char *p, size_t len,
     308             :                           const heim_universal_string *data, size_t *size)
     309             : {
     310           0 :     size_t i;
     311             : 
     312           0 :     if (size)
     313           0 :         *size = 0;
     314             : 
     315           0 :     if (len / 4 < data->length)
     316           0 :         return ASN1_OVERFLOW;
     317           0 :     p -= data->length * 4;
     318           0 :     for (i = 0; i < data->length; i++) {
     319           0 :         p[1] = (data->data[i] >> 24) & 0xff;
     320           0 :         p[2] = (data->data[i] >> 16) & 0xff;
     321           0 :         p[3] = (data->data[i] >> 8) & 0xff;
     322           0 :         p[4] = data->data[i] & 0xff;
     323           0 :         p += 4;
     324             :     }
     325           0 :     if (size) *size = data->length * 4;
     326           0 :     return 0;
     327             : }
     328             : 
     329             : int ASN1CALL
     330           0 : der_put_visible_string (unsigned char *p, size_t len,
     331             :                          const heim_visible_string *str, size_t *size)
     332             : {
     333           0 :     return der_put_general_string(p, len, str, size);
     334             : }
     335             : 
     336             : int ASN1CALL
     337     3402716 : der_put_octet_string (unsigned char *p, size_t len,
     338             :                       const heim_octet_string *data, size_t *size)
     339             : {
     340     3402716 :     assert(p != NULL && data != NULL && size != NULL);
     341             : 
     342     3402716 :     *size = 0;
     343     3402716 :     if (len < data->length)
     344           0 :         return ASN1_OVERFLOW;
     345     3402716 :     p -= data->length;
     346     3402716 :     if (data->length)
     347     3117333 :         memcpy(p+1, data->data, data->length);
     348     3402716 :     *size = data->length;
     349     3402716 :     return 0;
     350             : }
     351             : 
     352             : int ASN1CALL
     353         830 : der_put_heim_integer (unsigned char *p, size_t len,
     354             :                      const heim_integer *data, size_t *size)
     355             : {
     356           0 :     unsigned char *buf;
     357         830 :     int hibitset = 0;
     358             : 
     359         830 :     assert(p != NULL);
     360             : 
     361         830 :     if (size)
     362         830 :         *size = 0;
     363             : 
     364         830 :     if (data->length == 0) {
     365         124 :         if (len < 1)
     366           0 :             return ASN1_OVERFLOW;
     367         124 :         *p-- = 0;
     368         124 :         if (size)
     369         124 :             *size = 1;
     370         124 :         return 0;
     371             :     }
     372         706 :     if (len < data->length)
     373           0 :         return ASN1_OVERFLOW;
     374             : 
     375         706 :     assert(data->data != NULL);
     376         706 :     buf = data->data;
     377         706 :     len -= data->length;
     378             : 
     379         706 :     if (data->negative) {
     380           0 :         ssize_t i;
     381           0 :         int carry;
     382             : 
     383             :         /*
     384             :          * We represent the parsed integer as a positive value with a
     385             :          * negativity flag.  But we need to put it on the wire as the shortest
     386             :          * twos-complement byte sequence possible.  So we're going to negate
     387             :          * the number as go.
     388             :          */
     389          59 :         if (data->length == 1 && *(unsigned char *)data->data == 1) {
     390           0 :             *(p--) = 0xff;
     391             :         } else {
     392         295 :             for (i = data->length - 1, carry = 1; i >= 0; i--) {
     393         236 :                 *p = buf[i] ^ 0xff;
     394         236 :                 if (carry)
     395          59 :                     carry = !++*p;
     396         236 :                 p--;
     397             :             }
     398          59 :             if (p[1] < 128) {
     399           0 :                 if (len < 1)
     400           0 :                     return ASN1_OVERFLOW;
     401           0 :                 *p-- = 0xff;
     402           0 :                 len--;
     403           0 :                 hibitset = 1;
     404             :             }
     405             :         }
     406             :     } else {
     407         647 :         p -= data->length;
     408         647 :         memcpy(p + 1, buf, data->length);
     409             : 
     410         647 :         if (p[1] >= 128) {
     411         260 :             if (len < 1)
     412           0 :                 return ASN1_OVERFLOW;
     413         260 :             p[0] = 0;
     414         260 :             len--;
     415         260 :             hibitset = 1;
     416             :         }
     417             :     }
     418         706 :     if (size)
     419         706 :         *size = data->length + hibitset;
     420         706 :     return 0;
     421             : }
     422             : 
     423             : int ASN1CALL
     424     1267166 : der_put_generalized_time (unsigned char *p, size_t len,
     425             :                           const time_t *data, size_t *size)
     426             : {
     427       43707 :     heim_octet_string k;
     428       43707 :     size_t l;
     429       43707 :     int e;
     430             : 
     431     1267166 :     e = _heim_time2generalizedtime (*data, &k, 1);
     432     1267166 :     if (e)
     433           0 :         return e;
     434     1267166 :     e = der_put_octet_string(p, len, &k, &l);
     435     1267166 :     free(k.data);
     436     1267166 :     if(e)
     437           0 :         return e;
     438     1267166 :     if(size)
     439     1267166 :         *size = l;
     440     1223459 :     return 0;
     441             : }
     442             : 
     443             : int ASN1CALL
     444         130 : der_put_utctime (unsigned char *p, size_t len,
     445             :                  const time_t *data, size_t *size)
     446             : {
     447           0 :     heim_octet_string k;
     448           0 :     size_t l;
     449           0 :     int e;
     450             : 
     451         130 :     e = _heim_time2generalizedtime (*data, &k, 0);
     452         130 :     if (e)
     453           0 :         return e;
     454         130 :     e = der_put_octet_string(p, len, &k, &l);
     455         130 :     free(k.data);
     456         130 :     if(e)
     457           0 :         return e;
     458         130 :     if(size)
     459         130 :         *size = l;
     460         130 :     return 0;
     461             : }
     462             : 
     463             : int ASN1CALL
     464        5500 : der_put_oid (unsigned char *p, size_t len,
     465             :              const heim_oid *data, size_t *size)
     466             : {
     467        5500 :     unsigned char *base = p;
     468           0 :     size_t n;
     469             : 
     470       28878 :     for (n = data->length - 1; n >= 2; --n) {
     471       23378 :         unsigned u = data->components[n];
     472             : 
     473       23378 :         if (len < 1)
     474           0 :             return ASN1_OVERFLOW;
     475       23378 :         *p-- = u % 128;
     476       23378 :         u /= 128;
     477       23378 :         --len;
     478       31428 :         while (u > 0) {
     479        8050 :             if (len < 1)
     480           0 :                 return ASN1_OVERFLOW;
     481        8050 :             *p-- = 128 + u % 128;
     482        8050 :             u /= 128;
     483        8050 :             --len;
     484             :         }
     485             :     }
     486        5500 :     if (len < 1)
     487           0 :         return ASN1_OVERFLOW;
     488        5500 :     *p-- = 40 * data->components[0] + data->components[1];
     489        5500 :     *size = base - p;
     490        5500 :     return 0;
     491             : }
     492             : 
     493             : /*
     494             :  * Output a copy of the DER TLV at `p' with a different outermost tag.
     495             :  *
     496             :  * This is used in the implementation of IMPLICIT tags in generated decoder
     497             :  * functions.
     498             :  */
     499             : int ASN1CALL
     500           0 : der_replace_tag(const unsigned char *p, size_t len,
     501             :                 unsigned char **out, size_t *outlen,
     502             :                 Der_class class, Der_type type,
     503             :                 unsigned int tag)
     504             : {
     505           0 :     Der_class found_class;
     506           0 :     Der_type found_type;
     507           0 :     unsigned int found_tag;
     508           0 :     size_t payload_len, l, tag_len, len_len;
     509           0 :     int e;
     510             : 
     511           0 :     assert(p != NULL && out != NULL && outlen != NULL);
     512             : 
     513           0 :     e = der_get_tag(p, len, &found_class, &found_type, &found_tag, &l);
     514           0 :     if (e)
     515           0 :         return e;
     516           0 :     if (found_type != type)
     517           0 :         return ASN1_TYPE_MISMATCH;
     518             :     /* We don't care what found_class and found_tag are though */
     519           0 :     tag_len = der_length_tag(tag);
     520           0 :     p += l;
     521           0 :     len -= l;
     522           0 :     e = der_get_length(p, len, &payload_len, &len_len);
     523           0 :     if (e)
     524           0 :         return e;
     525           0 :     if (payload_len > len)
     526           0 :         return ASN1_OVERFLOW;
     527             :     /*
     528             :      * `p' now points at the payload; `*out' + the length of the tag points at
     529             :      * where we should copy the DER length and the payload.
     530             :      */
     531           0 :     if ((*out = malloc(*outlen = tag_len + len_len + payload_len)) == NULL)
     532           0 :         return ENOMEM;
     533           0 :     memcpy(*out + tag_len, p, len_len + payload_len);
     534             : 
     535             :     /* Put the new tag */
     536           0 :     e = der_put_tag(*out + tag_len - 1, tag_len, class, type, tag, &l);
     537           0 :     if (e)
     538           0 :         return e;
     539           0 :     if (l != tag_len)
     540           0 :         return ASN1_OVERFLOW;
     541           0 :     return 0;
     542             : }
     543             : 
     544             : #if 0
     545             : int ASN1CALL
     546             : der_encode_implicit(unsigned char *p, size_t len,
     547             :                     asn1_generic_encoder_f encoder,
     548             :                     void *obj, size_t *size,
     549             :                     Der_type type,
     550             :                     unsigned int ttag, Der_class iclass, unsigned int itag)
     551             : {
     552             :     size_t ttaglen = der_length_tag(ttag);
     553             :     size_t itaglen = der_length_tag(itag);
     554             :     size_t l;
     555             :     unsigned char *p2;
     556             :     int e;
     557             : 
     558             :     assert(p != NULL && size != NULL);
     559             : 
     560             :     /* Attempt to encode in place */
     561             :     e = encoder(p, len, obj, size);
     562             :     if (e == 0) {
     563             :         /* Fits!  Rewrite tag, adjust reported size. */
     564             :         e = der_put_tag(p + ttaglen - 1, itaglen, iclass, type, itag, &l);
     565             :         if (e == 0) {
     566             :             (*size) -= ttaglen;
     567             :             (*size) += itaglen;
     568             :         }
     569             :         return e;
     570             :     }
     571             :     if (e != ASN1_OVERFLOW || itaglen <= ttaglen)
     572             :         return e;
     573             : 
     574             :     /*
     575             :      * Did not fit because ttaglen > itaglen and this was the last / only thing
     576             :      * being encoded in a buffer of just the right size.
     577             :      */
     578             :     if ((p2 = malloc(len + ttaglen - itaglen)) == NULL)
     579             :         e = ENOMEM;
     580             :     if (e == 0)
     581             :         e = encoder(p2 + len + ttaglen - itaglen - 1, len + ttaglen - itaglen,
     582             :                     obj, size);
     583             :     if (e == 0)
     584             :         e = der_put_tag(p2 + ttaglen - 1, itaglen, iclass, type, itag, &l);
     585             :     if (e == 0) {
     586             :         (*size) -= ttaglen;
     587             :         (*size) += itaglen;
     588             :         memcpy(p - *size, p2 + ttaglen - itaglen, *size);
     589             :     }
     590             :     free(p2);
     591             :     return e;
     592             : }
     593             : #endif
     594             : 
     595             : int ASN1CALL
     596    36671605 : der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
     597             :              unsigned int tag, size_t *size)
     598             : {
     599    36671605 :     if (tag <= 30) {
     600    36671605 :         if (len < 1)
     601           0 :             return ASN1_OVERFLOW;
     602    36671605 :         *p = MAKE_TAG(class, type, tag);
     603    36671605 :         *size = 1;
     604             :     } else {
     605           0 :         size_t ret = 0;
     606           0 :         unsigned int continuation = 0;
     607             : 
     608           0 :         do {
     609           0 :             if (len < 1)
     610           0 :                 return ASN1_OVERFLOW;
     611           0 :             *p-- = tag % 128 | continuation;
     612           0 :             len--;
     613           0 :             ret++;
     614           0 :             tag /= 128;
     615           0 :             continuation = 0x80;
     616           0 :         } while(tag > 0);
     617           0 :         if (len < 1)
     618           0 :             return ASN1_OVERFLOW;
     619           0 :         *p-- = MAKE_TAG(class, type, 0x1f);
     620           0 :         ret++;
     621           0 :         *size = ret;
     622             :     }
     623    35361428 :     return 0;
     624             : }
     625             : 
     626             : int ASN1CALL
     627    36671064 : der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
     628             :                         Der_class class, Der_type type,
     629             :                         unsigned int tag, size_t *size)
     630             : {
     631    36671064 :     size_t ret = 0;
     632     1310177 :     size_t l;
     633     1310177 :     int e;
     634             : 
     635    36671064 :     e = der_put_length (p, len, len_val, &l);
     636    36671064 :     if(e)
     637           0 :         return e;
     638    36671064 :     p -= l;
     639    36671064 :     len -= l;
     640    36671064 :     ret += l;
     641    36671064 :     e = der_put_tag (p, len, class, type, tag, &l);
     642    36671064 :     if(e)
     643           0 :         return e;
     644             : 
     645    36671064 :     ret += l;
     646    36671064 :     *size = ret;
     647    36671064 :     return 0;
     648             : }
     649             : 
     650             : int
     651     2534592 : _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
     652             : {
     653       87414 :      struct tm tm;
     654     2534592 :      const size_t len = gtimep ? 15 : 13;
     655       87414 :      int bytes;
     656             : 
     657     2534592 :      s->data = NULL;
     658     2534592 :      s->length = 0;
     659     2534592 :      if (_der_gmtime(t, &tm) == NULL)
     660           0 :          return ASN1_BAD_TIMEFORMAT;
     661     2534592 :      s->data = malloc(len + 1);
     662     2534592 :      if (s->data == NULL)
     663           0 :          return ENOMEM;
     664     2534592 :      s->length = len;
     665     2534592 :      if (gtimep)
     666     2534332 :          bytes = snprintf(s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
     667     2534332 :                           tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
     668             :                           tm.tm_hour, tm.tm_min, tm.tm_sec);
     669             :      else
     670         260 :          bytes = snprintf(s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
     671         260 :                           tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
     672             :                           tm.tm_hour, tm.tm_min, tm.tm_sec);
     673             : 
     674     2534592 :      if (bytes > len)
     675           0 :          abort();
     676             : 
     677     2447178 :      return 0;
     678             : }
     679             : 
     680             : int ASN1CALL
     681         278 : der_put_bit_string (unsigned char *p, size_t len,
     682             :                     const heim_bit_string *data, size_t *size)
     683             : {
     684           0 :     size_t data_size;
     685             : 
     686         278 :     assert(p != NULL && data != NULL && size != NULL);
     687             : 
     688         278 :     *size = 0;
     689         278 :     data_size = (data->length + 7) / 8;
     690         278 :     if (len < data_size + 1)
     691           0 :         return ASN1_OVERFLOW;
     692         278 :     p -= data_size + 1;
     693             : 
     694         278 :     memcpy (p+2, data->data, data_size);
     695         278 :     if (data->length && (data->length % 8) != 0)
     696           0 :         p[1] = 8 - (data->length % 8);
     697             :     else
     698         278 :         p[1] = 0;
     699         278 :     *size = data_size + 1;
     700         278 :     return 0;
     701             : }
     702             : 
     703             : int
     704         150 : _heim_der_set_sort(const void *a1, const void *a2)
     705             : {
     706           0 :     const heim_octet_string *s1, *s2;
     707           0 :     int ret;
     708             : 
     709         150 :     assert(a1 != NULL && a2 != NULL);
     710         150 :     s1 = a1;
     711         150 :     s2 = a2;
     712         150 :     ret = memcmp(s1->data, s2->data,
     713         150 :                  s1->length < s2->length ? s1->length : s2->length);
     714         150 :     if (ret != 0)
     715         150 :         return ret;
     716           0 :     return (int)(s1->length - s2->length);
     717             : }

Generated by: LCOV version 1.14