LCOV - code coverage report
Current view: top level - src - parsetlv.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 47 0.0 %
Date: 2016-11-29 15:07:43 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /* parsetlv.c -  ASN.1 TLV functions
       2             :  * Copyright (C) 2005, 2007, 2008, 2012 g10 Code GmbH
       3             :  *
       4             :  * This file is free software; you can redistribute it and/or modify
       5             :  * it under the terms of the GNU Lesser General Public License as
       6             :  * published by the Free Software Foundation; either version 2.1 of
       7             :  * the License, or (at your option) any later version.
       8             :  *
       9             :  * This file is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU Lesser General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #ifdef HAVE_CONFIG_H
      19             : # include <config.h>
      20             : #endif
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : 
      25             : #include "parsetlv.h"
      26             : 
      27             : 
      28             : /* Simple but pretty complete ASN.1 BER parser.  Parse the data at the
      29             :    address of BUFFER with a length given at the address of SIZE.  On
      30             :    success return 0 and update BUFFER and SIZE to point to the value.
      31             :    Do not update them on error.  The information about the object are
      32             :    stored in the caller allocated TI structure.  */
      33             : int
      34           0 : _gpgme_parse_tlv (char const **buffer, size_t *size, tlvinfo_t *ti)
      35             : {
      36             :   int c;
      37             :   unsigned long tag;
      38           0 :   const unsigned char *buf = (const unsigned char *)(*buffer);
      39           0 :   size_t length = *size;
      40             : 
      41           0 :   ti->cls = 0;
      42           0 :   ti->tag = 0;
      43           0 :   ti->is_cons = 0;
      44           0 :   ti->is_ndef = 0;
      45           0 :   ti->length = 0;
      46           0 :   ti->nhdr = 0;
      47             : 
      48           0 :   if (!length)
      49           0 :     return -1;
      50           0 :   c = *buf++; length--; ++ti->nhdr;
      51             : 
      52           0 :   ti->cls = (c & 0xc0) >> 6;
      53           0 :   ti->is_cons = !!(c & 0x20);
      54           0 :   tag = c & 0x1f;
      55             : 
      56           0 :   if (tag == 0x1f)
      57             :     {
      58           0 :       tag = 0;
      59             :       do
      60             :         {
      61           0 :           tag <<= 7;
      62           0 :           if (!length)
      63           0 :             return -1;
      64           0 :           c = *buf++; length--; ++ti->nhdr;
      65           0 :           tag |= c & 0x7f;
      66             :         }
      67           0 :       while (c & 0x80);
      68             :     }
      69           0 :   ti->tag = tag;
      70             : 
      71           0 :   if (!length)
      72           0 :     return -1;
      73           0 :   c = *buf++; length--; ++ti->nhdr;
      74             : 
      75           0 :   if ( !(c & 0x80) )
      76           0 :     ti->length = c;
      77           0 :   else if (c == 0x80)
      78           0 :     ti->is_ndef = 1;
      79           0 :   else if (c == 0xff)
      80           0 :     return -1;
      81             :   else
      82             :     {
      83           0 :       unsigned long len = 0;
      84           0 :       int count = (c & 0x7f);
      85             : 
      86           0 :       if (count > sizeof (len) || count > sizeof (size_t))
      87           0 :         return -1;
      88             : 
      89           0 :       for (; count; count--)
      90             :         {
      91           0 :           len <<= 8;
      92           0 :           if (!length)
      93           0 :             return -1;
      94           0 :           c = *buf++; length--; ++ti->nhdr;
      95           0 :           len |= c & 0xff;
      96             :         }
      97           0 :       ti->length = len;
      98             :     }
      99             : 
     100           0 :   *buffer = (void*)buf;
     101           0 :   *size = length;
     102           0 :   return 0;
     103             : }

Generated by: LCOV version 1.11