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 v4-17-test 1498b464 Lines: 190 370 51.4 %
Date: 2024-06-13 04:01:37 Functions: 16 24 66.7 %

          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       73512 : der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
      48             : {
      49       73512 :     unsigned char *base = p;
      50       73512 :     unsigned val = *v;
      51             : 
      52       73512 :     *size = 0;
      53             : 
      54       73512 :     if (val) {
      55      440326 :         while (len > 0 && val) {
      56      293302 :             *p-- = val % 256;
      57      293302 :             val /= 256;
      58      293302 :             --len;
      59             :         }
      60       73512 :         if (val != 0)
      61           0 :             return ASN1_OVERFLOW;
      62             :         else {
      63       73512 :             if(p[1] >= 128) {
      64       16430 :                 if(len < 1)
      65           0 :                     return ASN1_OVERFLOW;
      66       16430 :                 *p-- = 0;
      67             :             }
      68       73512 :             *size = base - p;
      69       73512 :             return 0;
      70             :         }
      71           0 :     } else if (len < 1)
      72           0 :         return ASN1_OVERFLOW;
      73             :     else {
      74           0 :         *p    = 0;
      75           0 :         *size = 1;
      76           0 :         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     4594707 : der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
     116             : {
     117     4594707 :     unsigned char *base = p;
     118     4594707 :     int val = *v;
     119             : 
     120     4594707 :     *size = 0;
     121             : 
     122     4594707 :     if(val >= 0) {
     123             :         do {
     124     5131443 :             if(len < 1)
     125           0 :                 return ASN1_OVERFLOW;
     126     5131443 :             *p-- = val % 256;
     127     5131443 :             len--;
     128     5131443 :             val /= 256;
     129     5131443 :         } while(val);
     130     4511201 :         if(p[1] >= 128) {
     131      283786 :             if(len < 1)
     132           0 :                 return ASN1_OVERFLOW;
     133      283786 :             *p-- = 0;
     134      283786 :             len--;
     135             :         }
     136             :     } else {
     137       83506 :         val = ~val;
     138             :         do {
     139      318821 :             if(len < 1)
     140           0 :                 return ASN1_OVERFLOW;
     141      318821 :             *p-- = ~(val % 256);
     142      318821 :             len--;
     143      318821 :             val /= 256;
     144      318821 :         } while(val);
     145       83506 :         if(p[1] < 128) {
     146        5159 :             if(len < 1)
     147           0 :                 return ASN1_OVERFLOW;
     148        5159 :             *p-- = 0xff;
     149        5159 :             len--;
     150             :         }
     151             :     }
     152     4594707 :     *size = base - p;
     153     4594707 :     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             :        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             :        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    26064139 : der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
     201             : {
     202    26064139 :     if (size)
     203    26064139 :         *size = 0;
     204             : 
     205    26064139 :     if (len < 1)
     206           0 :         return ASN1_OVERFLOW;
     207             : 
     208    26064139 :     if (val < 128) {
     209    21111255 :         *p = val;
     210    21111255 :         if (size)
     211    21111255 :             *size = 1;
     212             :     } else {
     213     4952884 :         size_t l = 0;
     214             : 
     215    18332229 :         while(val > 0) {
     216     8426461 :             if(len < 2)
     217           0 :                 return ASN1_OVERFLOW;
     218     8426461 :             *p-- = val % 256;
     219     8426461 :             val /= 256;
     220     8426461 :             len--;
     221     8426461 :             l++;
     222             :         }
     223     4952884 :         *p = 0x80 | l;
     224     4952884 :         if(size)
     225     4952884 :             *size = l + 1;
     226             :     }
     227    26064139 :     return 0;
     228             : }
     229             : 
     230             : int ASN1CALL
     231         956 : der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
     232             : {
     233         956 :     *size = 0;
     234             : 
     235         956 :     if(len < 1)
     236           0 :         return ASN1_OVERFLOW;
     237         956 :     if(*data != 0)
     238         956 :         *p = 0xff;
     239             :     else
     240           0 :         *p = 0;
     241         956 :     *size = 1;
     242         956 :     return 0;
     243             : }
     244             : 
     245             : int ASN1CALL
     246     2064344 : der_put_general_string (unsigned char *p, size_t len,
     247             :                         const heim_general_string *str, size_t *size)
     248             : {
     249             :     size_t slen;
     250             : 
     251     2064344 :     assert(p != NULL && str != NULL && *str != NULL && size != NULL);
     252     2064344 :     *size = 0;
     253     2064344 :     slen = strlen(*str);
     254     2064344 :     if (len < slen)
     255           0 :         return ASN1_OVERFLOW;
     256     2064344 :     p -= slen;
     257     2064344 :     memcpy (p+1, *str, slen);
     258     2064344 :     *size = slen;
     259     2064344 :     return 0;
     260             : }
     261             : 
     262             : int ASN1CALL
     263        1296 : der_put_utf8string (unsigned char *p, size_t len,
     264             :                     const heim_utf8_string *str, size_t *size)
     265             : {
     266        1296 :     return der_put_general_string(p, len, str, size);
     267             : }
     268             : 
     269             : int ASN1CALL
     270         177 : der_put_printable_string (unsigned char *p, size_t len,
     271             :                           const heim_printable_string *str, size_t *size)
     272             : {
     273         177 :     return der_put_octet_string(p, len, str, size);
     274             : }
     275             : 
     276             : int ASN1CALL
     277          24 : der_put_ia5_string (unsigned char *p, size_t len,
     278             :                     const heim_ia5_string *str, size_t *size)
     279             : {
     280          24 :     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             :     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             :     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     2410070 : der_put_octet_string (unsigned char *p, size_t len,
     338             :                       const heim_octet_string *data, size_t *size)
     339             : {
     340     2410070 :     assert(p != NULL && data != NULL && size != NULL);
     341             : 
     342     2410070 :     *size = 0;
     343     2410070 :     if (len < data->length)
     344           0 :         return ASN1_OVERFLOW;
     345     2410070 :     p -= data->length;
     346     2410070 :     memcpy (p+1, data->data, data->length);
     347     2410070 :     *size = data->length;
     348     2410070 :     return 0;
     349             : }
     350             : 
     351             : int ASN1CALL
     352         460 : der_put_heim_integer (unsigned char *p, size_t len,
     353             :                      const heim_integer *data, size_t *size)
     354             : {
     355             :     unsigned char *buf;
     356         460 :     int hibitset = 0;
     357             : 
     358         460 :     assert(p != NULL);
     359             : 
     360         460 :     if (size)
     361         460 :         *size = 0;
     362             : 
     363         460 :     if (data->length == 0) {
     364          77 :         if (len < 1)
     365           0 :             return ASN1_OVERFLOW;
     366          77 :         *p-- = 0;
     367          77 :         if (size)
     368          77 :             *size = 1;
     369          77 :         return 0;
     370             :     }
     371         383 :     if (len < data->length)
     372           0 :         return ASN1_OVERFLOW;
     373             : 
     374         383 :     assert(data->data != NULL);
     375         383 :     buf = data->data;
     376         383 :     len -= data->length;
     377             : 
     378         383 :     if (data->negative) {
     379             :         ssize_t i;
     380             :         int carry;
     381         245 :         for (i = data->length - 1, carry = 1; i >= 0; i--) {
     382         196 :             *p = buf[i] ^ 0xff;
     383         196 :             if (carry)
     384          49 :                 carry = !++*p;
     385         196 :             p--;
     386             :         }
     387          49 :         if (p[1] < 128) {
     388           0 :             if (len < 1)
     389           0 :                 return ASN1_OVERFLOW;
     390           0 :             *p-- = 0xff;
     391           0 :             len--;
     392           0 :             hibitset = 1;
     393             :         }
     394             :     } else {
     395         334 :         p -= data->length;
     396         334 :         memcpy(p + 1, buf, data->length);
     397             : 
     398         334 :         if (p[1] >= 128) {
     399         143 :             if (len < 1)
     400           0 :                 return ASN1_OVERFLOW;
     401         143 :             p[0] = 0;
     402         143 :             len--;
     403         143 :             hibitset = 1;
     404             :         }
     405             :     }
     406         383 :     if (size)
     407         383 :         *size = data->length + hibitset;
     408         383 :     return 0;
     409             : }
     410             : 
     411             : int ASN1CALL
     412      888398 : der_put_generalized_time (unsigned char *p, size_t len,
     413             :                           const time_t *data, size_t *size)
     414             : {
     415             :     heim_octet_string k;
     416             :     size_t l;
     417             :     int e;
     418             : 
     419      888398 :     e = _heim_time2generalizedtime (*data, &k, 1);
     420      888398 :     if (e)
     421           0 :         return e;
     422      888398 :     e = der_put_octet_string(p, len, &k, &l);
     423      888398 :     free(k.data);
     424      888398 :     if(e)
     425           0 :         return e;
     426      888398 :     if(size)
     427      888398 :         *size = l;
     428      888398 :     return 0;
     429             : }
     430             : 
     431             : int ASN1CALL
     432           0 : der_put_utctime (unsigned char *p, size_t len,
     433             :                  const time_t *data, size_t *size)
     434             : {
     435             :     heim_octet_string k;
     436             :     size_t l;
     437             :     int e;
     438             : 
     439           0 :     e = _heim_time2generalizedtime (*data, &k, 0);
     440           0 :     if (e)
     441           0 :         return e;
     442           0 :     e = der_put_octet_string(p, len, &k, &l);
     443           0 :     free(k.data);
     444           0 :     if(e)
     445           0 :         return e;
     446           0 :     if(size)
     447           0 :         *size = l;
     448           0 :     return 0;
     449             : }
     450             : 
     451             : int ASN1CALL
     452        1784 : der_put_oid (unsigned char *p, size_t len,
     453             :              const heim_oid *data, size_t *size)
     454             : {
     455        1784 :     unsigned char *base = p;
     456             :     size_t n;
     457             : 
     458       10275 :     for (n = data->length - 1; n >= 2; --n) {
     459        8491 :         unsigned u = data->components[n];
     460             : 
     461        8491 :         if (len < 1)
     462           0 :             return ASN1_OVERFLOW;
     463        8491 :         *p-- = u % 128;
     464        8491 :         u /= 128;
     465        8491 :         --len;
     466       19980 :         while (u > 0) {
     467        2998 :             if (len < 1)
     468           0 :                 return ASN1_OVERFLOW;
     469        2998 :             *p-- = 128 + u % 128;
     470        2998 :             u /= 128;
     471        2998 :             --len;
     472             :         }
     473             :     }
     474        1784 :     if (len < 1)
     475           0 :         return ASN1_OVERFLOW;
     476        1784 :     *p-- = 40 * data->components[0] + data->components[1];
     477        1784 :     *size = base - p;
     478        1784 :     return 0;
     479             : }
     480             : 
     481             : /*
     482             :  * Output a copy of the DER TLV at `p' with a different outermost tag.
     483             :  *
     484             :  * This is used in the implementation of IMPLICIT tags in generated decoder
     485             :  * functions.
     486             :  */
     487             : int ASN1CALL
     488           0 : der_replace_tag(const unsigned char *p, size_t len,
     489             :                 unsigned char **out, size_t *outlen,
     490             :                 Der_class class, Der_type type,
     491             :                 unsigned int tag)
     492             : {
     493             :     Der_class found_class;
     494             :     Der_type found_type;
     495             :     unsigned int found_tag;
     496             :     size_t payload_len, l, tag_len, len_len;
     497             :     int e;
     498             : 
     499           0 :     assert(p != NULL && out != NULL && outlen != NULL);
     500             : 
     501           0 :     e = der_get_tag(p, len, &found_class, &found_type, &found_tag, &l);
     502           0 :     if (e)
     503           0 :         return e;
     504           0 :     if (found_type != type)
     505           0 :         return ASN1_TYPE_MISMATCH;
     506             :     /* We don't care what found_class and found_tag are though */
     507           0 :     tag_len = der_length_tag(tag);
     508           0 :     p += l;
     509           0 :     len -= l;
     510           0 :     e = der_get_length(p, len, &payload_len, &len_len);
     511           0 :     if (e)
     512           0 :         return e;
     513           0 :     if (payload_len > len)
     514           0 :         return ASN1_OVERFLOW;
     515             :     /*
     516             :      * `p' now points at the payload; `*out' + the length of the tag points at
     517             :      * where we should copy the DER length and the payload.
     518             :      */
     519           0 :     if ((*out = malloc(*outlen = tag_len + len_len + payload_len)) == NULL)
     520           0 :         return ENOMEM;
     521           0 :     memcpy(*out + tag_len, p, len_len + payload_len);
     522             : 
     523             :     /* Put the new tag */
     524           0 :     e = der_put_tag(*out + tag_len - 1, tag_len, class, type, tag, &l);
     525           0 :     if (e)
     526           0 :         return e;
     527           0 :     if (l != tag_len)
     528           0 :         return ASN1_OVERFLOW;
     529           0 :     return 0;
     530             : }
     531             : 
     532             : #if 0
     533             : int ASN1CALL
     534             : der_encode_implicit(unsigned char *p, size_t len,
     535             :                     asn1_generic_encoder_f encoder,
     536             :                     void *obj, size_t *size,
     537             :                     Der_type type,
     538             :                     unsigned int ttag, Der_class iclass, unsigned int itag)
     539             : {
     540             :     size_t ttaglen = der_length_tag(ttag);
     541             :     size_t itaglen = der_length_tag(itag);
     542             :     size_t l;
     543             :     unsigned char *p2;
     544             :     int e;
     545             : 
     546             :     assert(p != NULL && size != NULL);
     547             : 
     548             :     /* Attempt to encode in place */
     549             :     e = encoder(p, len, obj, size);
     550             :     if (e == 0) {
     551             :         /* Fits!  Rewrite tag, adjust reported size. */
     552             :         e = der_put_tag(p + ttaglen - 1, itaglen, iclass, type, itag, &l);
     553             :         if (e == 0) {
     554             :             (*size) -= ttaglen;
     555             :             (*size) += itaglen;
     556             :         }
     557             :         return e;
     558             :     }
     559             :     if (e != ASN1_OVERFLOW || itaglen <= ttaglen)
     560             :         return e;
     561             : 
     562             :     /*
     563             :      * Did not fit because ttaglen > itaglen and this was the last / only thing
     564             :      * being encoded in a buffer of just the right size.
     565             :      */
     566             :     if ((p2 = malloc(len + ttaglen - itaglen)) == NULL)
     567             :         e = ENOMEM;
     568             :     if (e == 0)
     569             :         e = encoder(p2 + len + ttaglen - itaglen - 1, len + ttaglen - itaglen,
     570             :                     obj, size);
     571             :     if (e == 0)
     572             :         e = der_put_tag(p2 + ttaglen - 1, itaglen, iclass, type, itag, &l);
     573             :     if (e == 0) {
     574             :         (*size) -= ttaglen;
     575             :         (*size) += itaglen;
     576             :         memcpy(p - *size, p2 + ttaglen - itaglen, *size);
     577             :     }
     578             :     free(p2);
     579             :     return e;
     580             : }
     581             : #endif
     582             : 
     583             : int ASN1CALL
     584    25984466 : der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
     585             :              unsigned int tag, size_t *size)
     586             : {
     587    25984466 :     if (tag <= 30) {
     588    25984466 :         if (len < 1)
     589           0 :             return ASN1_OVERFLOW;
     590    25984466 :         *p = MAKE_TAG(class, type, tag);
     591    25984466 :         *size = 1;
     592             :     } else {
     593           0 :         size_t ret = 0;
     594           0 :         unsigned int continuation = 0;
     595             : 
     596             :         do {
     597           0 :             if (len < 1)
     598           0 :                 return ASN1_OVERFLOW;
     599           0 :             *p-- = tag % 128 | continuation;
     600           0 :             len--;
     601           0 :             ret++;
     602           0 :             tag /= 128;
     603           0 :             continuation = 0x80;
     604           0 :         } while(tag > 0);
     605           0 :         if (len < 1)
     606           0 :             return ASN1_OVERFLOW;
     607           0 :         *p-- = MAKE_TAG(class, type, 0x1f);
     608           0 :         ret++;
     609           0 :         *size = ret;
     610             :     }
     611    25984466 :     return 0;
     612             : }
     613             : 
     614             : int ASN1CALL
     615    25984237 : der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
     616             :                         Der_class class, Der_type type,
     617             :                         unsigned int tag, size_t *size)
     618             : {
     619    25984237 :     size_t ret = 0;
     620             :     size_t l;
     621             :     int e;
     622             : 
     623    25984237 :     e = der_put_length (p, len, len_val, &l);
     624    25984237 :     if(e)
     625           0 :         return e;
     626    25984237 :     p -= l;
     627    25984237 :     len -= l;
     628    25984237 :     ret += l;
     629    25984237 :     e = der_put_tag (p, len, class, type, tag, &l);
     630    25984237 :     if(e)
     631           0 :         return e;
     632             : 
     633    25984237 :     ret += l;
     634    25984237 :     *size = ret;
     635    25984237 :     return 0;
     636             : }
     637             : 
     638             : int
     639     1776796 : _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
     640             : {
     641             :      struct tm tm;
     642     1776796 :      const size_t len = gtimep ? 15 : 13;
     643             :      int bytes;
     644             : 
     645     1776796 :      s->data = NULL;
     646     1776796 :      s->length = 0;
     647     1776796 :      if (_der_gmtime(t, &tm) == NULL)
     648           0 :          return ASN1_BAD_TIMEFORMAT;
     649     1776796 :      s->data = malloc(len + 1);
     650     1776796 :      if (s->data == NULL)
     651           0 :          return ENOMEM;
     652     1776796 :      s->length = len;
     653     1776796 :      if (gtimep)
     654     5330388 :          bytes = snprintf(s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
     655     3553592 :                           tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
     656             :                           tm.tm_hour, tm.tm_min, tm.tm_sec);
     657             :      else
     658           0 :          bytes = snprintf(s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
     659           0 :                           tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
     660             :                           tm.tm_hour, tm.tm_min, tm.tm_sec);
     661             : 
     662     1776796 :      if (bytes > len)
     663           0 :          abort();
     664             : 
     665     1776796 :      return 0;
     666             : }
     667             : 
     668             : int ASN1CALL
     669          77 : der_put_bit_string (unsigned char *p, size_t len,
     670             :                     const heim_bit_string *data, size_t *size)
     671             : {
     672             :     size_t data_size;
     673             : 
     674          77 :     assert(p != NULL && data != NULL && size != NULL);
     675             : 
     676          77 :     *size = 0;
     677          77 :     data_size = (data->length + 7) / 8;
     678          77 :     if (len < data_size + 1)
     679           0 :         return ASN1_OVERFLOW;
     680          77 :     p -= data_size + 1;
     681             : 
     682          77 :     memcpy (p+2, data->data, data_size);
     683          77 :     if (data->length && (data->length % 8) != 0)
     684           0 :         p[1] = 8 - (data->length % 8);
     685             :     else
     686          77 :         p[1] = 0;
     687          77 :     *size = data_size + 1;
     688          77 :     return 0;
     689             : }
     690             : 
     691             : int
     692           0 : _heim_der_set_sort(const void *a1, const void *a2)
     693             : {
     694             :     const heim_octet_string *s1, *s2;
     695             :     int ret;
     696             : 
     697           0 :     assert(a1 != NULL && a2 != NULL);
     698           0 :     s1 = a1;
     699           0 :     s2 = a2;
     700           0 :     ret = memcmp(s1->data, s2->data,
     701           0 :                  s1->length < s2->length ? s1->length : s2->length);
     702           0 :     if (ret != 0)
     703           0 :         return ret;
     704           0 :     return (int)(s1->length - s2->length);
     705             : }

Generated by: LCOV version 1.13