LCOV - code coverage report
Current view: top level - source4/heimdal/lib/asn1 - der_put.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 182 267 68.2 %
Date: 2021-09-23 10:06:22 Functions: 18 21 85.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
      47       45441 : der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
      48             : {
      49       45441 :     unsigned char *base = p;
      50       45441 :     unsigned val = *v;
      51             : 
      52       45441 :     if (val) {
      53      270360 :         while (len > 0 && val) {
      54      181062 :             *p-- = val % 256;
      55      181062 :             val /= 256;
      56      181062 :             --len;
      57             :         }
      58       45441 :         if (val != 0)
      59           0 :             return ASN1_OVERFLOW;
      60             :         else {
      61       45441 :             if(p[1] >= 128) {
      62         342 :                 if(len < 1)
      63           0 :                     return ASN1_OVERFLOW;
      64         342 :                 *p-- = 0;
      65             :             }
      66       45441 :             *size = base - p;
      67       45441 :             return 0;
      68             :         }
      69           0 :     } else if (len < 1)
      70           0 :         return ASN1_OVERFLOW;
      71             :     else {
      72           0 :         *p    = 0;
      73           0 :         *size = 1;
      74           0 :         return 0;
      75             :     }
      76             : }
      77             : 
      78             : int
      79     4790562 : der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
      80             : {
      81     4790562 :     unsigned char *base = p;
      82     4790562 :     int val = *v;
      83             : 
      84     4790562 :     if(val >= 0) {
      85             :         do {
      86     5568915 :             if(len < 1)
      87           0 :                 return ASN1_OVERFLOW;
      88     5568915 :             *p-- = val % 256;
      89     5568915 :             len--;
      90     5568915 :             val /= 256;
      91     5568915 :         } while(val);
      92     4704299 :         if(p[1] >= 128) {
      93      113956 :             if(len < 1)
      94           0 :                 return ASN1_OVERFLOW;
      95      113956 :             *p-- = 0;
      96      113956 :             len--;
      97             :         }
      98             :     } else {
      99       86263 :         val = ~val;
     100             :         do {
     101      326402 :             if(len < 1)
     102           0 :                 return ASN1_OVERFLOW;
     103      326402 :             *p-- = ~(val % 256);
     104      326402 :             len--;
     105      326402 :             val /= 256;
     106      326402 :         } while(val);
     107       86263 :         if(p[1] < 128) {
     108        6335 :             if(len < 1)
     109           0 :                 return ASN1_OVERFLOW;
     110        6335 :             *p-- = 0xff;
     111        6335 :             len--;
     112             :         }
     113             :     }
     114     4790562 :     *size = base - p;
     115     4790562 :     return 0;
     116             : }
     117             : 
     118             : 
     119             : int
     120    26646699 : der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
     121             : {
     122    26646699 :     if (len < 1)
     123           0 :         return ASN1_OVERFLOW;
     124             : 
     125    26646699 :     if (val < 128) {
     126    22396984 :         *p = val;
     127    22396984 :         *size = 1;
     128             :     } else {
     129     4131620 :         size_t l = 0;
     130             : 
     131    16004203 :         while(val > 0) {
     132     7622868 :             if(len < 2)
     133           0 :                 return ASN1_OVERFLOW;
     134     7622868 :             *p-- = val % 256;
     135     7622868 :             val /= 256;
     136     7622868 :             len--;
     137     7622868 :             l++;
     138             :         }
     139     4249715 :         *p = 0x80 | l;
     140     4249715 :         if(size)
     141     4249715 :             *size = l + 1;
     142             :     }
     143    25947382 :     return 0;
     144             : }
     145             : 
     146             : int
     147        1012 : der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
     148             : {
     149        1012 :     if(len < 1)
     150           0 :         return ASN1_OVERFLOW;
     151        1012 :     if(*data != 0)
     152        1012 :         *p = 0xff;
     153             :     else
     154           0 :         *p = 0;
     155        1012 :     *size = 1;
     156        1012 :     return 0;
     157             : }
     158             : 
     159             : int
     160     2285758 : der_put_general_string (unsigned char *p, size_t len,
     161             :                         const heim_general_string *str, size_t *size)
     162             : {
     163     2285758 :     size_t slen = strlen(*str);
     164             : 
     165     2285758 :     if (len < slen)
     166           0 :         return ASN1_OVERFLOW;
     167     2285758 :     p -= slen;
     168     2345559 :     memcpy (p+1, *str, slen);
     169     2285758 :     *size = slen;
     170     2285758 :     return 0;
     171             : }
     172             : 
     173             : int
     174         794 : der_put_utf8string (unsigned char *p, size_t len,
     175             :                     const heim_utf8_string *str, size_t *size)
     176             : {
     177         794 :     return der_put_general_string(p, len, str, size);
     178             : }
     179             : 
     180             : int
     181         172 : der_put_printable_string (unsigned char *p, size_t len,
     182             :                           const heim_printable_string *str, size_t *size)
     183             : {
     184         172 :     return der_put_octet_string(p, len, str, size);
     185             : }
     186             : 
     187             : int
     188         172 : der_put_ia5_string (unsigned char *p, size_t len,
     189             :                     const heim_ia5_string *str, size_t *size)
     190             : {
     191         172 :     return der_put_octet_string(p, len, str, size);
     192             : }
     193             : 
     194             : int
     195           0 : der_put_bmp_string (unsigned char *p, size_t len,
     196             :                     const heim_bmp_string *data, size_t *size)
     197             : {
     198             :     size_t i;
     199           0 :     if (len / 2 < data->length)
     200           0 :         return ASN1_OVERFLOW;
     201           0 :     p -= data->length * 2;
     202           0 :     for (i = 0; i < data->length; i++) {
     203           0 :         p[1] = (data->data[i] >> 8) & 0xff;
     204           0 :         p[2] = data->data[i] & 0xff;
     205           0 :         p += 2;
     206             :     }
     207           0 :     if (size) *size = data->length * 2;
     208           0 :     return 0;
     209             : }
     210             : 
     211             : int
     212           0 : der_put_universal_string (unsigned char *p, size_t len,
     213             :                           const heim_universal_string *data, size_t *size)
     214             : {
     215             :     size_t i;
     216           0 :     if (len / 4 < data->length)
     217           0 :         return ASN1_OVERFLOW;
     218           0 :     p -= data->length * 4;
     219           0 :     for (i = 0; i < data->length; i++) {
     220           0 :         p[1] = (data->data[i] >> 24) & 0xff;
     221           0 :         p[2] = (data->data[i] >> 16) & 0xff;
     222           0 :         p[3] = (data->data[i] >> 8) & 0xff;
     223           0 :         p[4] = data->data[i] & 0xff;
     224           0 :         p += 4;
     225             :     }
     226           0 :     if (size) *size = data->length * 4;
     227           0 :     return 0;
     228             : }
     229             : 
     230             : int
     231           0 : der_put_visible_string (unsigned char *p, size_t len,
     232             :                          const heim_visible_string *str, size_t *size)
     233             : {
     234           0 :     return der_put_general_string(p, len, str, size);
     235             : }
     236             : 
     237             : int
     238     2261736 : der_put_octet_string (unsigned char *p, size_t len,
     239             :                       const heim_octet_string *data, size_t *size)
     240             : {
     241     2261736 :     if (len < data->length)
     242           0 :         return ASN1_OVERFLOW;
     243     2261736 :     p -= data->length;
     244     2322133 :     memcpy (p+1, data->data, data->length);
     245     2261736 :     *size = data->length;
     246     2261736 :     return 0;
     247             : }
     248             : 
     249             : int
     250         332 : der_put_heim_integer (unsigned char *p, size_t len,
     251             :                      const heim_integer *data, size_t *size)
     252             : {
     253         332 :     unsigned char *buf = data->data;
     254         332 :     int hibitset = 0;
     255             : 
     256         332 :     if (data->length == 0) {
     257          53 :         if (len < 1)
     258           0 :             return ASN1_OVERFLOW;
     259          53 :         *p-- = 0;
     260          53 :         if (size)
     261          53 :             *size = 1;
     262          53 :         return 0;
     263             :     }
     264         279 :     if (len < data->length)
     265           0 :         return ASN1_OVERFLOW;
     266             : 
     267         279 :     len -= data->length;
     268             : 
     269         279 :     if (data->negative) {
     270             :         int i, carry;
     271           0 :         for (i = data->length - 1, carry = 1; i >= 0; i--) {
     272           0 :             *p = buf[i] ^ 0xff;
     273           0 :             if (carry)
     274           0 :                 carry = !++*p;
     275           0 :             p--;
     276             :         }
     277           0 :         if (p[1] < 128) {
     278           0 :             if (len < 1)
     279           0 :                 return ASN1_OVERFLOW;
     280           0 :             *p-- = 0xff;
     281           0 :             len--;
     282           0 :             hibitset = 1;
     283             :         }
     284             :     } else {
     285         279 :         p -= data->length;
     286         279 :         memcpy(p + 1, buf, data->length);
     287             : 
     288         279 :         if (p[1] >= 128) {
     289         114 :             if (len < 1)
     290           0 :                 return ASN1_OVERFLOW;
     291         114 :             p[0] = 0;
     292         114 :             len--;
     293         114 :             hibitset = 1;
     294             :         }
     295             :     }
     296         279 :     if (size)
     297         279 :         *size = data->length + hibitset;
     298         279 :     return 0;
     299             : }
     300             : 
     301             : int
     302      935551 : der_put_generalized_time (unsigned char *p, size_t len,
     303             :                           const time_t *data, size_t *size)
     304             : {
     305             :     heim_octet_string k;
     306             :     size_t l;
     307             :     int e;
     308             : 
     309      935551 :     e = _heim_time2generalizedtime (*data, &k, 1);
     310      935551 :     if (e)
     311           0 :         return e;
     312      935551 :     e = der_put_octet_string(p, len, &k, &l);
     313      935551 :     free(k.data);
     314      935551 :     if(e)
     315           0 :         return e;
     316      935551 :     if(size)
     317      935551 :         *size = l;
     318      910619 :     return 0;
     319             : }
     320             : 
     321             : int
     322         132 : der_put_utctime (unsigned char *p, size_t len,
     323             :                  const time_t *data, size_t *size)
     324             : {
     325             :     heim_octet_string k;
     326             :     size_t l;
     327             :     int e;
     328             : 
     329         132 :     e = _heim_time2generalizedtime (*data, &k, 0);
     330         132 :     if (e)
     331           0 :         return e;
     332         132 :     e = der_put_octet_string(p, len, &k, &l);
     333         132 :     free(k.data);
     334         132 :     if(e)
     335           0 :         return e;
     336         132 :     if(size)
     337         132 :         *size = l;
     338         132 :     return 0;
     339             : }
     340             : 
     341             : int
     342        3588 : der_put_oid (unsigned char *p, size_t len,
     343             :              const heim_oid *data, size_t *size)
     344             : {
     345        3588 :     unsigned char *base = p;
     346             :     int n;
     347             : 
     348       17774 :     for (n = data->length - 1; n >= 2; --n) {
     349       14186 :         unsigned u = data->components[n];
     350             : 
     351       14186 :         if (len < 1)
     352           0 :             return ASN1_OVERFLOW;
     353       14186 :         *p-- = u % 128;
     354       14186 :         u /= 128;
     355       14186 :         --len;
     356       33222 :         while (u > 0) {
     357        4850 :             if (len < 1)
     358           0 :                 return ASN1_OVERFLOW;
     359        4850 :             *p-- = 128 + u % 128;
     360        4850 :             u /= 128;
     361        4850 :             --len;
     362             :         }
     363             :     }
     364        3588 :     if (len < 1)
     365           0 :         return ASN1_OVERFLOW;
     366        3588 :     *p-- = 40 * data->components[0] + data->components[1];
     367        3588 :     *size = base - p;
     368        3588 :     return 0;
     369             : }
     370             : 
     371             : int
     372    26564762 : der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
     373             :              unsigned int tag, size_t *size)
     374             : {
     375    26564762 :     if (tag <= 30) {
     376    26564762 :         if (len < 1)
     377           0 :             return ASN1_OVERFLOW;
     378    26564762 :         *p = MAKE_TAG(class, type, tag);
     379    26564762 :         *size = 1;
     380             :     } else {
     381           0 :         size_t ret = 0;
     382           0 :         unsigned int continuation = 0;
     383             : 
     384             :         do {
     385           0 :             if (len < 1)
     386           0 :                 return ASN1_OVERFLOW;
     387           0 :             *p-- = tag % 128 | continuation;
     388           0 :             len--;
     389           0 :             ret++;
     390           0 :             tag /= 128;
     391           0 :             continuation = 0x80;
     392           0 :         } while(tag > 0);
     393           0 :         if (len < 1)
     394           0 :             return ASN1_OVERFLOW;
     395           0 :         *p-- = MAKE_TAG(class, type, 0x1f);
     396           0 :         ret++;
     397           0 :         *size = ret;
     398             :     }
     399    25866729 :     return 0;
     400             : }
     401             : 
     402             : int
     403    26564762 : der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
     404             :                         Der_class class, Der_type type,
     405             :                         unsigned int tag, size_t *size)
     406             : {
     407    26564762 :     size_t ret = 0;
     408             :     size_t l;
     409             :     int e;
     410             : 
     411    26564762 :     e = der_put_length (p, len, len_val, &l);
     412    26564762 :     if(e)
     413           0 :         return e;
     414    26564762 :     p -= l;
     415    26564762 :     len -= l;
     416    26564762 :     ret += l;
     417    26564762 :     e = der_put_tag (p, len, class, type, tag, &l);
     418    26564762 :     if(e)
     419           0 :         return e;
     420             : 
     421    26564762 :     ret += l;
     422    26564762 :     *size = ret;
     423    26564762 :     return 0;
     424             : }
     425             : 
     426             : int
     427     1871366 : _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
     428             : {
     429             :      struct tm tm;
     430     1871366 :      const size_t len = gtimep ? 15 : 13;
     431             : 
     432     1871366 :      s->data = malloc(len + 1);
     433     1871366 :      if (s->data == NULL)
     434           0 :          return ENOMEM;
     435     1871366 :      s->length = len;
     436     1871366 :      if (_der_gmtime(t, &tm) == NULL)
     437           0 :          return ASN1_BAD_TIMEFORMAT;
     438     1871366 :      if (gtimep)
     439     5613306 :          snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
     440     3742204 :                    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
     441             :                    tm.tm_hour, tm.tm_min, tm.tm_sec);
     442             :      else
     443         792 :          snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
     444         528 :                    tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
     445             :                    tm.tm_hour, tm.tm_min, tm.tm_sec);
     446             : 
     447     1821502 :      return 0;
     448             : }
     449             : 
     450             : int
     451         198 : der_put_bit_string (unsigned char *p, size_t len,
     452             :                     const heim_bit_string *data, size_t *size)
     453             : {
     454         198 :     size_t data_size = (data->length + 7) / 8;
     455         198 :     if (len < data_size + 1)
     456           0 :         return ASN1_OVERFLOW;
     457         198 :     p -= data_size + 1;
     458             : 
     459         198 :     memcpy (p+2, data->data, data_size);
     460         198 :     if (data->length && (data->length % 8) != 0)
     461           0 :         p[1] = 8 - (data->length % 8);
     462             :     else
     463         198 :         p[1] = 0;
     464         198 :     *size = data_size + 1;
     465         198 :     return 0;
     466             : }
     467             : 
     468             : int
     469         192 : _heim_der_set_sort(const void *a1, const void *a2)
     470             : {
     471         192 :     const struct heim_octet_string *s1 = a1, *s2 = a2;
     472             :     int ret;
     473             : 
     474         192 :     ret = memcmp(s1->data, s2->data,
     475         192 :                  s1->length < s2->length ? s1->length : s2->length);
     476         192 :     if(ret)
     477         192 :         return ret;
     478           0 :     return s1->length - s2->length;
     479             : }

Generated by: LCOV version 1.13