LCOV - code coverage report
Current view: top level - kbx - keybox-openpgp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 136 239 56.9 %
Date: 2015-11-05 17:10:59 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* keybox-openpgp.c - OpenPGP key parsing
       2             :  * Copyright (C) 2001, 2003, 2011 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /* This is a simple OpenPGP parser suitable for all OpenPGP key
      21             :    material.  It just provides the functionality required to build and
      22             :    parse an KBX OpenPGP key blob.  Thus it is not a complete parser.
      23             :    However it is self-contained and optimized for fast in-memory
      24             :    parsing.  Note that we don't support old ElGamal v3 keys
      25             :    anymore. */
      26             : 
      27             : #include <config.h>
      28             : #include <stdlib.h>
      29             : #include <stdio.h>
      30             : #include <string.h>
      31             : #include <errno.h>
      32             : #include <assert.h>
      33             : 
      34             : #include "keybox-defs.h"
      35             : 
      36             : #include <gcrypt.h>
      37             : 
      38             : #include "../common/openpgpdefs.h"
      39             : #include "host2net.h"
      40             : 
      41             : /* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
      42             :    which has a maximum length as stored at BUFLEN.  Return the header
      43             :    information of that packet and advance the pointer stored at BUFPTR
      44             :    to the next packet; also adjust the length stored at BUFLEN to
      45             :    match the remaining bytes. If there are no more packets, store NULL
      46             :    at BUFPTR.  Return an non-zero error code on failure or the
      47             :    following data on success:
      48             : 
      49             :    R_DATAPKT = Pointer to the begin of the packet data.
      50             :    R_DATALEN = Length of this data.  This has already been checked to fit
      51             :                into the buffer.
      52             :    R_PKTTYPE = The packet type.
      53             :    R_NTOTAL  = The total number of bytes of this packet
      54             : 
      55             :    Note that these values are only updated on success.
      56             : */
      57             : static gpg_error_t
      58         449 : next_packet (unsigned char const **bufptr, size_t *buflen,
      59             :              unsigned char const **r_data, size_t *r_datalen, int *r_pkttype,
      60             :              size_t *r_ntotal)
      61             : {
      62         449 :   const unsigned char *buf = *bufptr;
      63         449 :   size_t len = *buflen;
      64             :   int c, ctb, pkttype;
      65             :   unsigned long pktlen;
      66             : 
      67         449 :   if (!len)
      68           0 :     return gpg_error (GPG_ERR_NO_DATA);
      69             : 
      70         449 :   ctb = *buf++; len--;
      71         449 :   if ( !(ctb & 0x80) )
      72           0 :     return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */
      73             : 
      74         449 :   pktlen = 0;
      75         449 :   if ((ctb & 0x40))  /* New style (OpenPGP) CTB.  */
      76             :     {
      77           0 :       pkttype = (ctb & 0x3f);
      78           0 :       if (!len)
      79           0 :         return gpg_error (GPG_ERR_INV_PACKET); /* No 1st length byte. */
      80           0 :       c = *buf++; len--;
      81           0 :       if (pkttype == PKT_COMPRESSED)
      82           0 :         return gpg_error (GPG_ERR_UNEXPECTED); /* ... packet in a keyblock. */
      83           0 :       if ( c < 192 )
      84           0 :         pktlen = c;
      85           0 :       else if ( c < 224 )
      86             :         {
      87           0 :           pktlen = (c - 192) * 256;
      88           0 :           if (!len)
      89           0 :             return gpg_error (GPG_ERR_INV_PACKET); /* No 2nd length byte. */
      90           0 :           c = *buf++; len--;
      91           0 :           pktlen += c + 192;
      92             :         }
      93           0 :       else if (c == 255)
      94             :         {
      95           0 :           if (len <4 )
      96           0 :             return gpg_error (GPG_ERR_INV_PACKET); /* No length bytes. */
      97           0 :           pktlen = buf32_to_ulong (buf);
      98           0 :           buf += 4;
      99           0 :           len -= 4;
     100             :       }
     101             :       else /* Partial length encoding is not allowed for key packets. */
     102           0 :         return gpg_error (GPG_ERR_UNEXPECTED);
     103             :     }
     104             :   else /* Old style CTB.  */
     105             :     {
     106             :       int lenbytes;
     107             : 
     108         449 :       pktlen = 0;
     109         449 :       pkttype = (ctb>>2)&0xf;
     110         449 :       lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
     111         449 :       if (!lenbytes) /* Not allowed in key packets.  */
     112           0 :         return gpg_error (GPG_ERR_UNEXPECTED);
     113         449 :       if (len < lenbytes)
     114           0 :         return gpg_error (GPG_ERR_INV_PACKET); /* Not enough length bytes.  */
     115        1042 :       for (; lenbytes; lenbytes--)
     116             :         {
     117         593 :           pktlen <<= 8;
     118         593 :           pktlen |= *buf++; len--;
     119             :         }
     120             :     }
     121             : 
     122             :   /* Do some basic sanity check.  */
     123         449 :   switch (pkttype)
     124             :     {
     125             :     case PKT_SIGNATURE:
     126             :     case PKT_SECRET_KEY:
     127             :     case PKT_PUBLIC_KEY:
     128             :     case PKT_SECRET_SUBKEY:
     129             :     case PKT_MARKER:
     130             :     case PKT_RING_TRUST:
     131             :     case PKT_USER_ID:
     132             :     case PKT_PUBLIC_SUBKEY:
     133             :     case PKT_OLD_COMMENT:
     134             :     case PKT_ATTRIBUTE:
     135             :     case PKT_COMMENT:
     136             :     case PKT_GPG_CONTROL:
     137         449 :       break; /* Okay these are allowed packets. */
     138             :     default:
     139           0 :       return gpg_error (GPG_ERR_UNEXPECTED);
     140             :     }
     141             : 
     142         449 :   if (pkttype == 63 && pktlen == 0xFFFFFFFF)
     143             :     /* Sometimes the decompressing layer enters an error state in
     144             :        which it simply outputs 0xff for every byte read.  If we have a
     145             :        stream of 0xff bytes, then it will be detected as a new format
     146             :        packet with type 63 and a 4-byte encoded length that is 4G-1.
     147             :        Since packets with type 63 are private and we use them as a
     148             :        control packet, which won't be 4 GB, we reject such packets as
     149             :        invalid.  */
     150           0 :     return gpg_error (GPG_ERR_INV_PACKET);
     151             : 
     152         449 :   if (pktlen > len)
     153           0 :     return gpg_error (GPG_ERR_INV_PACKET); /* Packet length header too long. */
     154             : 
     155         449 :   *r_data = buf;
     156         449 :   *r_datalen = pktlen;
     157         449 :   *r_pkttype = pkttype;
     158         449 :   *r_ntotal = (buf - *bufptr) + pktlen;
     159             : 
     160         449 :   *bufptr = buf + pktlen;
     161         449 :   *buflen = len - pktlen;
     162         449 :   if (!*buflen)
     163          61 :     *bufptr = NULL;
     164             : 
     165         449 :   return 0;
     166             : }
     167             : 
     168             : 
     169             : /* Parse a key packet and store the information in KI. */
     170             : static gpg_error_t
     171         108 : parse_key (const unsigned char *data, size_t datalen,
     172             :            struct _keybox_openpgp_key_info *ki)
     173             : {
     174             :   gpg_error_t err;
     175         108 :   const unsigned char *data_start = data;
     176             :   int i, version, algorithm;
     177             :   size_t n;
     178             :   int npkey;
     179             :   unsigned char hashbuffer[768];
     180         108 :   const unsigned char *mpi_n = NULL;
     181         108 :   size_t mpi_n_len = 0, mpi_e_len = 0;
     182             :   gcry_md_hd_t md;
     183         108 :   int is_ecc = 0;
     184             : 
     185         108 :   if (datalen < 5)
     186           0 :     return gpg_error (GPG_ERR_INV_PACKET);
     187         108 :   version = *data++; datalen--;
     188         108 :   if (version < 2 || version > 4 )
     189           0 :     return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */
     190             : 
     191             :   /*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/
     192         108 :   data +=4; datalen -=4;
     193             : 
     194         108 :   if (version < 4)
     195             :     {
     196           0 :       if (datalen < 2)
     197           0 :         return gpg_error (GPG_ERR_INV_PACKET);
     198           0 :       data +=2; datalen -= 2;
     199             :     }
     200             : 
     201         108 :   if (!datalen)
     202           0 :     return gpg_error (GPG_ERR_INV_PACKET);
     203         108 :   algorithm = *data++; datalen--;
     204             : 
     205         108 :   switch (algorithm)
     206             :     {
     207             :     case PUBKEY_ALGO_RSA:
     208             :     case PUBKEY_ALGO_RSA_E:
     209             :     case PUBKEY_ALGO_RSA_S:
     210          18 :       npkey = 2;
     211          18 :       break;
     212             :     case PUBKEY_ALGO_ELGAMAL_E:
     213             :     case PUBKEY_ALGO_ELGAMAL:
     214          40 :       npkey = 3;
     215          40 :       break;
     216             :     case PUBKEY_ALGO_DSA:
     217          40 :       npkey = 4;
     218          40 :       break;
     219             :     case PUBKEY_ALGO_ECDH:
     220           4 :       npkey = 3;
     221           4 :       is_ecc = 1;
     222           4 :       break;
     223             :     case PUBKEY_ALGO_ECDSA:
     224             :     case PUBKEY_ALGO_EDDSA:
     225           6 :       npkey = 2;
     226           6 :       is_ecc = 1;
     227           6 :       break;
     228             :     default: /* Unknown algorithm. */
     229           0 :       return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
     230             :     }
     231             : 
     232         108 :   ki->algo = algorithm;
     233             : 
     234         448 :   for (i=0; i < npkey; i++ )
     235             :     {
     236             :       unsigned int nbits, nbytes;
     237             : 
     238         340 :       if (datalen < 2)
     239           0 :         return gpg_error (GPG_ERR_INV_PACKET);
     240             : 
     241         340 :       if (is_ecc && (i == 0 || i == 2))
     242             :         {
     243          14 :           nbytes = data[0];
     244          14 :           if (nbytes < 2 || nbytes > 254)
     245           0 :             return gpg_error (GPG_ERR_INV_PACKET);
     246          14 :           nbytes++; /* The size byte itself.  */
     247          28 :           if (datalen < nbytes)
     248           0 :             return gpg_error (GPG_ERR_INV_PACKET);
     249             :         }
     250             :       else
     251             :         {
     252         326 :           nbits = ((data[0]<<8)|(data[1]));
     253         326 :           data += 2;
     254         326 :           datalen -= 2;
     255         326 :           nbytes = (nbits+7) / 8;
     256         326 :           if (datalen < nbytes)
     257           0 :             return gpg_error (GPG_ERR_INV_PACKET);
     258             :           /* For use by v3 fingerprint calculation we need to know the RSA
     259             :              modulus and exponent. */
     260         326 :           if (i==0)
     261             :             {
     262          98 :               mpi_n = data;
     263          98 :               mpi_n_len = nbytes;
     264             :             }
     265         228 :           else if (i==1)
     266         108 :             mpi_e_len = nbytes;
     267             :         }
     268             : 
     269         340 :       data += nbytes; datalen -= nbytes;
     270             :     }
     271         108 :   n = data - data_start;
     272             : 
     273         108 :   if (version < 4)
     274             :     {
     275             :       /* We do not support any other algorithm than RSA in v3
     276             :          packets. */
     277           0 :       if (algorithm < 1 || algorithm > 3)
     278           0 :         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
     279             : 
     280           0 :       err = gcry_md_open (&md, GCRY_MD_MD5, 0);
     281           0 :       if (err)
     282           0 :         return err; /* Oops */
     283           0 :       gcry_md_write (md, mpi_n, mpi_n_len);
     284           0 :       gcry_md_write (md, mpi_n+mpi_n_len+2, mpi_e_len);
     285           0 :       memcpy (ki->fpr, gcry_md_read (md, 0), 16);
     286           0 :       gcry_md_close (md);
     287           0 :       ki->fprlen = 16;
     288             : 
     289           0 :       if (mpi_n_len < 8)
     290             :         {
     291             :           /* Moduli less than 64 bit are out of the specs scope.  Zero
     292             :              them out because this is what gpg does too. */
     293           0 :           memset (ki->keyid, 0, 8);
     294             :         }
     295             :       else
     296           0 :         memcpy (ki->keyid, mpi_n + mpi_n_len - 8, 8);
     297             :     }
     298             :   else
     299             :     {
     300             :       /* Its a pitty that we need to prefix the buffer with the tag
     301             :          and a length header: We can't simply pass it to the fast
     302             :          hashing function for that reason.  It might be a good idea to
     303             :          have a scatter-gather enabled hash function. What we do here
     304             :          is to use a static buffer if this one is large enough and
     305             :          only use the regular hash functions if this buffer is not
     306             :          large enough. */
     307         108 :       if ( 3 + n < sizeof hashbuffer )
     308             :         {
     309         108 :           hashbuffer[0] = 0x99;     /* CTB */
     310         108 :           hashbuffer[1] = (n >> 8); /* 2 byte length header. */
     311         108 :           hashbuffer[2] = n;
     312         108 :           memcpy (hashbuffer + 3, data_start, n);
     313         108 :           gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
     314             :         }
     315             :       else
     316             :         {
     317           0 :           err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
     318           0 :           if (err)
     319           0 :             return err; /* Oops */
     320           0 :           gcry_md_putc (md, 0x99 );     /* CTB */
     321           0 :           gcry_md_putc (md, (n >> 8) ); /* 2 byte length header. */
     322           0 :           gcry_md_putc (md, n );
     323           0 :           gcry_md_write (md, data_start, n);
     324           0 :           memcpy (ki->fpr, gcry_md_read (md, 0), 20);
     325           0 :           gcry_md_close (md);
     326             :         }
     327         108 :       ki->fprlen = 20;
     328         108 :       memcpy (ki->keyid, ki->fpr+12, 8);
     329             :     }
     330             : 
     331         108 :   return 0;
     332             : }
     333             : 
     334             : 
     335             : 
     336             : /* The caller must pass the address of an INFO structure which will
     337             :    get filled on success with information pertaining to the OpenPGP
     338             :    keyblock IMAGE of length IMAGELEN.  Note that a caller does only
     339             :    need to release this INFO structure if the function returns
     340             :    success.  If NPARSED is not NULL the actual number of bytes parsed
     341             :    will be stored at this address.  */
     342             : gpg_error_t
     343          61 : _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
     344             :                        size_t *nparsed, keybox_openpgp_info_t info)
     345             : {
     346          61 :   gpg_error_t err = 0;
     347             :   const unsigned char *image_start, *data;
     348             :   size_t n, datalen;
     349             :   int pkttype;
     350          61 :   int first = 1;
     351          61 :   int read_error = 0;
     352          61 :   struct _keybox_openpgp_key_info *k, **ktail = NULL;
     353          61 :   struct _keybox_openpgp_uid_info *u, **utail = NULL;
     354             : 
     355          61 :   memset (info, 0, sizeof *info);
     356          61 :   if (nparsed)
     357          61 :     *nparsed = 0;
     358             : 
     359          61 :   image_start = image;
     360         571 :   while (image)
     361             :     {
     362         449 :       err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n);
     363         449 :       if (err)
     364             :         {
     365           0 :           read_error = 1;
     366           0 :           break;
     367             :         }
     368             : 
     369         449 :       if (first)
     370             :         {
     371          61 :           if (pkttype == PKT_PUBLIC_KEY)
     372             :             ;
     373           0 :           else if (pkttype == PKT_SECRET_KEY)
     374           0 :             info->is_secret = 1;
     375             :           else
     376             :             {
     377           0 :               err = gpg_error (GPG_ERR_UNEXPECTED);
     378           0 :               if (nparsed)
     379           0 :                 *nparsed += n;
     380           0 :               break;
     381             :             }
     382          61 :           first = 0;
     383             :         }
     384         388 :       else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
     385             :         break; /* Next keyblock encountered - ready. */
     386             : 
     387         449 :       if (nparsed)
     388         449 :         *nparsed += n;
     389             : 
     390         449 :       if (pkttype == PKT_SIGNATURE)
     391             :         {
     392             :           /* For now we only count the total number of signatures. */
     393         266 :           info->nsigs++;
     394             :         }
     395         183 :       else if (pkttype == PKT_USER_ID)
     396             :         {
     397          75 :           info->nuids++;
     398          75 :           if (info->nuids == 1)
     399             :             {
     400          61 :               info->uids.off = data - image_start;
     401          61 :               info->uids.len = datalen;
     402          61 :               utail = &info->uids.next;
     403             :             }
     404             :           else
     405             :             {
     406          14 :               u = xtrycalloc (1, sizeof *u);
     407          14 :               if (!u)
     408             :                 {
     409           0 :                   err = gpg_error_from_syserror ();
     410           0 :                   break;
     411             :                 }
     412          14 :               u->off = data - image_start;
     413          14 :               u->len = datalen;
     414          14 :               *utail = u;
     415          14 :               utail = &u->next;
     416             :             }
     417             :         }
     418         108 :       else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
     419             :         {
     420          61 :           err = parse_key (data, datalen, &info->primary);
     421         122 :           if (err)
     422           0 :             break;
     423             :         }
     424          47 :       else if( pkttype == PKT_PUBLIC_SUBKEY && datalen && *data == '#' )
     425             :         {
     426             :           /* Early versions of GnuPG used old PGP comment packets;
     427             :            * luckily all those comments are prefixed by a hash
     428             :            * sign - ignore these packets. */
     429             :         }
     430          47 :       else if (pkttype == PKT_PUBLIC_SUBKEY || pkttype == PKT_SECRET_SUBKEY)
     431             :         {
     432          47 :           info->nsubkeys++;
     433          47 :           if (info->nsubkeys == 1)
     434             :             {
     435          47 :               err = parse_key (data, datalen, &info->subkeys);
     436          47 :               if (err)
     437             :                 {
     438           0 :                   info->nsubkeys--;
     439             :                   /* We ignore subkeys with unknown algorithms. */
     440           0 :                   if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
     441           0 :                       || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
     442           0 :                     err = 0;
     443           0 :                   if (err)
     444           0 :                     break;
     445             :                 }
     446             :               else
     447          47 :                 ktail = &info->subkeys.next;
     448             :             }
     449             :           else
     450             :             {
     451           0 :               k = xtrycalloc (1, sizeof *k);
     452           0 :               if (!k)
     453             :                 {
     454           0 :                   err = gpg_error_from_syserror ();
     455           0 :                   break;
     456             :                 }
     457           0 :               err = parse_key (data, datalen, k);
     458           0 :               if (err)
     459             :                 {
     460           0 :                   xfree (k);
     461           0 :                   info->nsubkeys--;
     462             :                   /* We ignore subkeys with unknown algorithms. */
     463           0 :                   if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
     464           0 :                       || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
     465           0 :                     err = 0;
     466           0 :                   if (err)
     467           0 :                     break;
     468             :                 }
     469             :               else
     470             :                 {
     471           0 :                   *ktail = k;
     472           0 :                   ktail = &k->next;
     473             :                 }
     474             :             }
     475             :         }
     476             :     }
     477             : 
     478          61 :   if (err)
     479             :     {
     480           0 :       _keybox_destroy_openpgp_info (info);
     481           0 :       if (!read_error)
     482             :         {
     483             :           /* Packet parsing worked, thus we should be able to skip the
     484             :              rest of the keyblock.  */
     485           0 :           while (image)
     486             :             {
     487           0 :               if (next_packet (&image, &imagelen,
     488             :                                &data, &datalen, &pkttype, &n) )
     489           0 :                 break; /* Another error - stop here. */
     490             : 
     491           0 :               if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
     492             :                 break; /* Next keyblock encountered - ready. */
     493             : 
     494           0 :               if (nparsed)
     495           0 :                 *nparsed += n;
     496             :             }
     497             :         }
     498             :     }
     499             : 
     500          61 :   return err;
     501             : }
     502             : 
     503             : 
     504             : /* Release any malloced data in INFO but not INFO itself! */
     505             : void
     506          61 : _keybox_destroy_openpgp_info (keybox_openpgp_info_t info)
     507             : {
     508             :   struct _keybox_openpgp_key_info *k, *k2;
     509             :   struct _keybox_openpgp_uid_info *u, *u2;
     510             : 
     511          61 :   assert (!info->primary.next);
     512          61 :   for (k=info->subkeys.next; k; k = k2)
     513             :     {
     514           0 :       k2 = k->next;
     515           0 :       xfree (k);
     516             :     }
     517             : 
     518          75 :   for (u=info->uids.next; u; u = u2)
     519             :     {
     520          14 :       u2 = u->next;
     521          14 :       xfree (u);
     522             :     }
     523          61 : }

Generated by: LCOV version 1.11