LCOV - code coverage report
Current view: top level - common - convert.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 96 94.8 %
Date: 2016-09-12 13:01:59 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /* convert.c - Hex conversion functions.
       2             :  *      Copyright (C) 2006, 2008 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * This file is free software; you can redistribute it and/or modify
       7             :  * it under the terms of either
       8             :  *
       9             :  *   - the GNU Lesser General Public License as published by the Free
      10             :  *     Software Foundation; either version 3 of the License, or (at
      11             :  *     your option) any later version.
      12             :  *
      13             :  * or
      14             :  *
      15             :  *   - the GNU General Public License as published by the Free
      16             :  *     Software Foundation; either version 2 of the License, or (at
      17             :  *     your option) any later version.
      18             :  *
      19             :  * or both in parallel, as here.
      20             :  *
      21             :  * This file is distributed in the hope that it will be useful,
      22             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24             :  * GNU General Public License for more details.
      25             :  *
      26             :  * You should have received a copy of the GNU General Public License
      27             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      28             :  */
      29             : 
      30             : #include <config.h>
      31             : #include <stdlib.h>
      32             : #include <errno.h>
      33             : #include <ctype.h>
      34             : 
      35             : #include "util.h"
      36             : 
      37             : 
      38             : #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
      39             : 
      40             : 
      41             : /* Convert STRING consisting of hex characters into its binary
      42             :    representation and store that at BUFFER.  BUFFER needs to be of
      43             :    LENGTH bytes.  The function checks that the STRING will convert
      44             :    exactly to LENGTH bytes. The string is delimited by either end of
      45             :    string or a white space character.  The function returns -1 on
      46             :    error or the length of the parsed string.  */
      47             : int
      48        1464 : hex2bin (const char *string, void *buffer, size_t length)
      49             : {
      50             :   int i;
      51        1464 :   const char *s = string;
      52             : 
      53       31961 :   for (i=0; i < length; )
      54             :     {
      55       29043 :       if (!hexdigitp (s) || !hexdigitp (s+1))
      56          10 :         return -1;           /* Invalid hex digits. */
      57       29033 :       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
      58       29033 :       s += 2;
      59             :     }
      60        1454 :   if (*s && (!isascii (*s) || !isspace (*s)) )
      61           6 :     return -1;             /* Not followed by Nul or white space.  */
      62        1448 :   if (i != length)
      63           0 :     return -1;             /* Not of expected length.  */
      64        1448 :   if (*s)
      65         400 :     s++; /* Skip the delimiter. */
      66        1448 :   return s - string;
      67             : }
      68             : 
      69             : 
      70             : /* Convert STRING consisting of hex characters into its binary representation
      71             :    and store that at BUFFER.  BUFFER needs to be of LENGTH bytes.  The
      72             :    function check that the STRING will convert exactly to LENGTH
      73             :    bytes. Colons between the hex digits are allowed, if one colon
      74             :    has been given a colon is expected very 2 characters. The string
      75             :    is delimited by either end of string or a white space character.
      76             :    The function returns -1 on error or the length of the parsed
      77             :    string.  */
      78             : int
      79          32 : hexcolon2bin (const char *string, void *buffer, size_t length)
      80             : {
      81             :   int i;
      82          32 :   const char *s = string;
      83          32 :   int need_colon = 0;
      84             : 
      85         389 :   for (i=0; i < length; )
      86             :     {
      87         339 :       if (i==1 && *s == ':')  /* Skip colons between hex digits.  */
      88             :         {
      89           5 :           need_colon = 1;
      90           5 :           s++;
      91             :         }
      92         334 :       else if (need_colon && *s == ':')
      93          53 :         s++;
      94         281 :       else if (need_colon)
      95           3 :         return -1;           /* Colon expected. */
      96         336 :       if (!hexdigitp (s) || !hexdigitp (s+1))
      97          11 :         return -1;           /* Invalid hex digits. */
      98         325 :       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
      99         325 :       s += 2;
     100             :     }
     101          18 :   if (*s == ':')
     102           2 :     return -1;             /* Trailing colons are not allowed.  */
     103          16 :   if (*s && (!isascii (*s) || !isspace (*s)) )
     104           4 :     return -1;             /* Not followed by Nul or white space.  */
     105          12 :   if (i != length)
     106           0 :     return -1;             /* Not of expected length.  */
     107          12 :   if (*s)
     108           6 :     s++; /* Skip the delimiter. */
     109          12 :   return s - string;
     110             : }
     111             : 
     112             : 
     113             : 
     114             : static char *
     115        4196 : do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
     116             : {
     117             :   const unsigned char *s;
     118             :   char *p;
     119             : 
     120        4196 :   if (!stringbuf)
     121             :     {
     122             :       /* Not really correct for with_colon but we don't care about the
     123             :          one wasted byte. */
     124         179 :       size_t n = with_colon? 3:2;
     125         179 :       size_t nbytes = n * length + 1;
     126         179 :       if (length &&  (nbytes-1) / n != length)
     127             :         {
     128           2 :           gpg_err_set_errno (ENOMEM);
     129           2 :           return NULL;
     130             :         }
     131         177 :       stringbuf = xtrymalloc (nbytes);
     132         177 :       if (!stringbuf)
     133           0 :         return NULL;
     134             :     }
     135             : 
     136       86062 :   for (s = buffer, p = stringbuf; length; length--, s++)
     137             :     {
     138       81868 :       if (with_colon && s != buffer)
     139         203 :         *p++ = ':';
     140       81868 :       *p++ = tohex ((*s>>4)&15);
     141       81868 :       *p++ = tohex (*s&15);
     142             :     }
     143        4194 :   *p = 0;
     144             : 
     145        4194 :   return stringbuf;
     146             : }
     147             : 
     148             : 
     149             : /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
     150             :    that at the provided STRINGBUF.  STRINGBUF must be allocated of at
     151             :    least (2*LENGTH+1) bytes or be NULL so that the function mallocs an
     152             :    appropriate buffer.  Returns STRINGBUF or NULL on error (which may
     153             :    only occur if STRINGBUF has been NULL and the internal malloc
     154             :    failed). */
     155             : char *
     156        4182 : bin2hex (const void *buffer, size_t length, char *stringbuf)
     157             : {
     158        4182 :   return do_bin2hex (buffer, length, stringbuf, 0);
     159             : }
     160             : 
     161             : /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
     162             :    that at the provided STRINGBUF.  STRINGBUF must be allocated of at
     163             :    least (3*LENGTH+1) bytes or be NULL so that the function mallocs an
     164             :    appropriate buffer.  Returns STRINGBUF or NULL on error (which may
     165             :    only occur if STRINGBUF has been NULL and the internal malloc
     166             :    failed). */
     167             : char *
     168          14 : bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
     169             : {
     170          14 :   return do_bin2hex (buffer, length, stringbuf, 1);
     171             : }
     172             : 
     173             : 
     174             : 
     175             : /* Convert HEXSTRING consisting of hex characters into string and
     176             :    store that at BUFFER.  HEXSTRING is either delimited by end of
     177             :    string or a white space character.  The function makes sure that
     178             :    the resulting string in BUFFER is terminated by a Nul byte.  Note
     179             :    that the retruned string may include embedded Nul bytes; the extra
     180             :    Nul byte at the end is used to make sure tha the result can always
     181             :    be used as a C-string.
     182             : 
     183             :    BUFSIZE is the available length of BUFFER; if the converted result
     184             :    plus a possible required extra Nul character does not fit into this
     185             :    buffer, the function returns NULL and won't change the existing
     186             :    content of BUFFER.  In-place conversion is possible as long as
     187             :    BUFFER points to HEXSTRING.
     188             : 
     189             :    If BUFFER is NULL and BUFSIZE is 0 the function scans HEXSTRING but
     190             :    does not store anything.  This may be used to find the end of
     191             :    HEXSTRING.
     192             : 
     193             :    On success the function returns a pointer to the next character
     194             :    after HEXSTRING (which is either end-of-string or a the next white
     195             :    space).  If BUFLEN is not NULL the number of valid vytes in BUFFER
     196             :    is stored there (an extra Nul byte is not counted); this will even
     197             :    be done if BUFFER has been passed as NULL. */
     198             : const char *
     199         257 : hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen)
     200             : {
     201         257 :   const char *s = hexstring;
     202             :   int idx, count;
     203         257 :   int need_nul = 0;
     204             : 
     205         257 :   if (buflen)
     206          74 :     *buflen = 0;
     207             : 
     208         257 :   for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++)
     209             :     ;
     210         257 :   if (*s && (!isascii (*s) || !isspace (*s)) )
     211             :     {
     212          30 :       gpg_err_set_errno (EINVAL);
     213          30 :       return NULL;   /* Not followed by Nul or white space.  */
     214             :     }
     215             :   /* We need to append a nul character.  However we don't want that if
     216             :      the hexstring already ends with "00".  */
     217         227 :   need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0'));
     218         227 :   if (need_nul)
     219         205 :     count++;
     220             : 
     221         227 :   if (buffer)
     222             :     {
     223         215 :       if (count > bufsize)
     224             :         {
     225           8 :           gpg_err_set_errno (EINVAL);
     226           8 :           return NULL; /* Too long.  */
     227             :         }
     228             : 
     229        1161 :       for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2)
     230         954 :         ((unsigned char*)buffer)[idx++] = xtoi_2 (s);
     231         207 :       if (need_nul)
     232         192 :         buffer[idx] = 0;
     233             :     }
     234             : 
     235         219 :   if (buflen)
     236          36 :     *buflen = count - need_nul;
     237         219 :   return s;
     238             : }
     239             : 
     240             : 
     241             : /* Same as hex2str but this function allocated a new string.  Returns
     242             :    NULL on error.  If R_COUNT is not NULL, the number of scanned bytes
     243             :    will be stored there.  ERRNO is set on error. */
     244             : char *
     245          22 : hex2str_alloc (const char *hexstring, size_t *r_count)
     246             : {
     247             :   const char *tail;
     248             :   size_t nbytes;
     249             :   char *result;
     250             : 
     251          22 :   tail = hex2str (hexstring, NULL, 0, &nbytes);
     252          22 :   if (!tail)
     253             :     {
     254          10 :       if (r_count)
     255          10 :         *r_count = 0;
     256          10 :       return NULL;
     257             :     }
     258          12 :   if (r_count)
     259          12 :     *r_count = tail - hexstring;
     260          12 :   result = xtrymalloc (nbytes+1);
     261          12 :   if (!result)
     262           0 :     return NULL;
     263          12 :   if (!hex2str (hexstring, result, nbytes+1, NULL))
     264           0 :     BUG ();
     265          12 :   return result;
     266             : }

Generated by: LCOV version 1.11