LCOV - code coverage report
Current view: top level - kbx - keybox-blob.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 318 416 76.4 %
Date: 2015-11-05 17:10:59 Functions: 24 27 88.9 %

          Line data    Source code
       1             : /* keybox-blob.c - KBX Blob handling
       2             :  * Copyright (C) 2000, 2001, 2002, 2003, 2008 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             : /*
      21             : * The keybox data format
      22             : 
      23             :    The KeyBox uses an augmented OpenPGP/X.509 key format.  This makes
      24             :    random access to a keyblock/certificate easier and also gives the
      25             :    opportunity to store additional information (e.g. the fingerprint)
      26             :    along with the key.  All integers are stored in network byte order,
      27             :    offsets are counted from the beginning of the Blob.
      28             : 
      29             : ** Overview of blob types
      30             : 
      31             :    | Byte 4 | Blob type    |
      32             :    |--------+--------------|
      33             :    |      0 | Empty blob   |
      34             :    |      1 | First blob   |
      35             :    |      2 | OpenPGP blob |
      36             :    |      3 | X.509 blob   |
      37             : 
      38             : ** The First blob
      39             : 
      40             :    The first blob of a plain KBX file has a special format:
      41             : 
      42             :    - u32  Length of this blob
      43             :    - byte Blob type (1)
      44             :    - byte Version number (1)
      45             :    - u16  Header flags
      46             :           bit 0 - RFU
      47             :           bit 1 - Is being or has been used for OpenPGP blobs
      48             :    - b4   Magic 'KBXf'
      49             :    - u32  RFU
      50             :    - u32  file_created_at
      51             :    - u32  last_maintenance_run
      52             :    - u32  RFU
      53             :    - u32  RFU
      54             : 
      55             : ** The OpenPGP and X.509 blobs
      56             : 
      57             :    The OpenPGP and X.509 blobs are very similiar, things which are
      58             :    X.509 specific are noted like [X.509: xxx]
      59             : 
      60             :    - u32  Length of this blob (including these 4 bytes)
      61             :    - byte Blob type
      62             :            2 = OpenPGP
      63             :            3 = X509
      64             :    - byte Version number of this blob type
      65             :            1 = The only defined value
      66             :    - u16  Blob flags
      67             :           bit 0 = contains secret key material (not used)
      68             :           bit 1 = ephemeral blob (e.g. used while quering external resources)
      69             :    - u32  Offset to the OpenPGP keyblock or the X.509 DER encoded
      70             :           certificate
      71             :    - u32  The length of the keyblock or certificate
      72             :    - u16  [NKEYS] Number of keys (at least 1!) [X509: always 1]
      73             :    - u16  Size of the key information structure (at least 28).
      74             :    - NKEYS times:
      75             :       - b20  The fingerprint of the key.
      76             :              Fingerprints are always 20 bytes, MD5 left padded with zeroes.
      77             :       - u32  Offset to the n-th key's keyID (a keyID is always 8 byte)
      78             :              or 0 if not known which is the case only for X.509.
      79             :       - u16  Key flags
      80             :              bit 0 = qualified signature (not yet implemented}
      81             :       - u16  RFU
      82             :       - bN   Optional filler up to the specified length of this
      83             :              structure.
      84             :    - u16  Size of the serial number (may be zero)
      85             :       -  bN  The serial number. N as giiven above.
      86             :    - u16  Number of user IDs
      87             :    - u16  [NUIDS] Size of user ID information structure
      88             :    - NUIDS times:
      89             : 
      90             :       For X509, the first user ID is the Issuer, the second the
      91             :       Subject and the others are subjectAltNames.  For OpenPGP we only
      92             :       store the information from UserID packets here.
      93             : 
      94             :       - u32  Blob offset to the n-th user ID
      95             :       - u32  Length of this user ID.
      96             :       - u16  User ID flags.
      97             :              (not yet used)
      98             :       - byte Validity
      99             :       - byte RFU
     100             : 
     101             :    - u16  [NSIGS] Number of signatures
     102             :    - u16  Size of signature information (4)
     103             :    - NSIGS times:
     104             :       - u32  Expiration time of signature with some special values:
     105             :              - 0x00000000 = not checked
     106             :              - 0x00000001 = missing key
     107             :              - 0x00000002 = bad signature
     108             :              - 0x10000000 = valid and expires at some date in 1978.
     109             :              - 0xffffffff = valid and does not expire
     110             :    - u8 Assigned ownertrust [X509: not used]
     111             :    - u8 All_Validity
     112             :         OpenPGP: See ../g10/trustdb/TRUST_* [not yet used]
     113             :         X509: Bit 4 set := key has been revoked.
     114             :                            Note that this value matches TRUST_FLAG_REVOKED
     115             :    - u16  RFU
     116             :    - u32  Recheck_after
     117             :    - u32  Latest timestamp in the keyblock (useful for KS syncronsiation?)
     118             :    - u32  Blob created at
     119             :    - u32  [NRES] Size of reserved space (not including this field)
     120             :    - bN   Reserved space of size NRES for future use.
     121             :    - bN   Arbitrary space for example used to store data which is not
     122             :           part of the keyblock or certificate.  For example the v3 key
     123             :           IDs go here.
     124             :    - bN   Space for the keyblock or certificate.
     125             :    - bN   RFU.  This is the remaining space after keyblock and before
     126             :           the checksum.  Is is not covered by the checksum.
     127             :    - b20  SHA-1 checksum (useful for KS syncronisation?)
     128             :           Note, that KBX versions before GnuPG 2.1 used an MD5
     129             :           checksum.  However it was only created but never checked.
     130             :           Thus we do not expect problems if we switch to SHA-1.  If
     131             :           the checksum fails and the first 4 bytes are zero, we can
     132             :           try again with MD5.  SHA-1 has the advantage that it is
     133             :           faster on CPUs with dedicated SHA-1 support.
     134             : 
     135             : 
     136             : */
     137             : 
     138             : 
     139             : #include <config.h>
     140             : #include <stdio.h>
     141             : #include <stdlib.h>
     142             : #include <string.h>
     143             : #include <errno.h>
     144             : #include <assert.h>
     145             : #include <time.h>
     146             : 
     147             : #include "keybox-defs.h"
     148             : #include <gcrypt.h>
     149             : 
     150             : #ifdef KEYBOX_WITH_X509
     151             : #include <ksba.h>
     152             : #endif
     153             : 
     154             : 
     155             : #include "../common/gettime.h"
     156             : 
     157             : 
     158             : /* special values of the signature status */
     159             : #define SF_NONE(a)  ( !(a) )
     160             : #define SF_NOKEY(a) ((a) & (1<<0))
     161             : #define SF_BAD(a)   ((a) & (1<<1))
     162             : #define SF_VALID(a) ((a) & (1<<29))
     163             : 
     164             : 
     165             : struct membuf {
     166             :   size_t len;
     167             :   size_t size;
     168             :   char *buf;
     169             :   int out_of_core;
     170             : };
     171             : 
     172             : 
     173             : /*  #if MAX_FINGERPRINT_LEN < 20 */
     174             : /*    #error fingerprints are 20 bytes */
     175             : /*  #endif */
     176             : 
     177             : struct keyboxblob_key {
     178             :   char   fpr[20];
     179             :   u32    off_kid;
     180             :   ulong  off_kid_addr;
     181             :   u16    flags;
     182             : };
     183             : struct keyboxblob_uid {
     184             :   u32    off;
     185             :   ulong  off_addr;
     186             :   char   *name;     /* used only with x509 */
     187             :   u32    len;
     188             :   u16    flags;
     189             :   byte   validity;
     190             : };
     191             : 
     192             : struct keyid_list {
     193             :     struct keyid_list *next;
     194             :     int seqno;
     195             :     byte kid[8];
     196             : };
     197             : 
     198             : struct fixup_list {
     199             :     struct fixup_list *next;
     200             :     u32 off;
     201             :     u32 val;
     202             : };
     203             : 
     204             : 
     205             : struct keyboxblob {
     206             :   byte *blob;
     207             :   size_t bloblen;
     208             :   off_t fileoffset;
     209             : 
     210             :   /* stuff used only by keybox_create_blob */
     211             :   unsigned char *serialbuf;
     212             :   const unsigned char *serial;
     213             :   size_t seriallen;
     214             :   int nkeys;
     215             :   struct keyboxblob_key *keys;
     216             :   int nuids;
     217             :   struct keyboxblob_uid *uids;
     218             :   int nsigs;
     219             :   u32  *sigs;
     220             :   struct fixup_list *fixups;
     221             :   int fixup_out_of_core;
     222             : 
     223             :   struct keyid_list *temp_kids;
     224             :   struct membuf bufbuf; /* temporary store for the blob */
     225             :   struct membuf *buf;
     226             : };
     227             : 
     228             : 
     229             : 
     230             : /* A simple implemention of a dynamic buffer.  Use init_membuf() to
     231             :    create a buffer, put_membuf to append bytes and get_membuf to
     232             :    release and return the buffer.  Allocation errors are detected but
     233             :    only returned at the final get_membuf(), this helps not to clutter
     234             :    the code with out of core checks.  */
     235             : 
     236             : static void
     237          64 : init_membuf (struct membuf *mb, int initiallen)
     238             : {
     239          64 :   mb->len = 0;
     240          64 :   mb->size = initiallen;
     241          64 :   mb->out_of_core = 0;
     242          64 :   mb->buf = xtrymalloc (initiallen);
     243          64 :   if (!mb->buf)
     244           0 :       mb->out_of_core = 1;
     245          64 : }
     246             : 
     247             : static void
     248        2547 : put_membuf (struct membuf *mb, const void *buf, size_t len)
     249             : {
     250        2547 :   if (mb->out_of_core)
     251           0 :     return;
     252             : 
     253        2547 :   if (mb->len + len >= mb->size)
     254             :     {
     255             :       char *p;
     256             : 
     257          44 :       mb->size += len + 1024;
     258          44 :       p = xtryrealloc (mb->buf, mb->size);
     259          44 :       if (!p)
     260             :         {
     261           0 :           mb->out_of_core = 1;
     262           0 :           return;
     263             :         }
     264          44 :       mb->buf = p;
     265             :     }
     266        2547 :   if (buf)
     267        2483 :     memcpy (mb->buf + mb->len, buf, len);
     268             :   else
     269          64 :     memset (mb->buf + mb->len, 0, len);
     270        2547 :   mb->len += len;
     271             : }
     272             : 
     273             : static void *
     274          64 : get_membuf (struct membuf *mb, size_t *len)
     275             : {
     276             :   char *p;
     277             : 
     278          64 :   if (mb->out_of_core)
     279             :     {
     280           0 :       xfree (mb->buf);
     281           0 :       mb->buf = NULL;
     282           0 :       return NULL;
     283             :     }
     284             : 
     285          64 :   p = mb->buf;
     286          64 :   *len = mb->len;
     287          64 :   mb->buf = NULL;
     288          64 :   mb->out_of_core = 1; /* don't allow a reuse */
     289          64 :   return p;
     290             : }
     291             : 
     292             : 
     293             : static void
     294         422 : put8 (struct membuf *mb, byte a )
     295             : {
     296         422 :   put_membuf (mb, &a, 1);
     297         422 : }
     298             : 
     299             : static void
     300         881 : put16 (struct membuf *mb, u16 a )
     301             : {
     302             :   unsigned char tmp[2];
     303         881 :   tmp[0] = a>>8;
     304         881 :   tmp[1] = a;
     305         881 :   put_membuf (mb, tmp, 2);
     306         881 : }
     307             : 
     308             : static void
     309         994 : put32 (struct membuf *mb, u32 a )
     310             : {
     311             :   unsigned char tmp[4];
     312         994 :   tmp[0] = a>>24;
     313         994 :   tmp[1] = a>>16;
     314         994 :   tmp[2] = a>>8;
     315         994 :   tmp[3] = a;
     316         994 :   put_membuf (mb, tmp, 4);
     317         994 : }
     318             : 
     319             : 
     320             : 
     321             : /* Store a value in the fixup list */
     322             : static void
     323         383 : add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
     324             : {
     325             :   struct fixup_list *fl;
     326             : 
     327         383 :   if (blob->fixup_out_of_core)
     328         383 :     return;
     329             : 
     330         383 :   fl = xtrycalloc(1, sizeof *fl);
     331         383 :   if (!fl)
     332           0 :     blob->fixup_out_of_core = 1;
     333             :   else
     334             :     {
     335         383 :       fl->off = off;
     336         383 :       fl->val = val;
     337         383 :       fl->next = blob->fixups;
     338         383 :       blob->fixups = fl;
     339             :     }
     340             : }
     341             : 
     342             : 
     343             : 
     344             : /*
     345             :   OpenPGP specific stuff
     346             : */
     347             : 
     348             : 
     349             : /* We must store the keyid at some place because we can't calculate
     350             :    the offset yet. This is only used for v3 keyIDs.  Function returns
     351             :    an index value for later fixup or -1 for out of core.  The value
     352             :    must be a non-zero value. */
     353             : static int
     354           0 : pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo)
     355             : {
     356             :   struct keyid_list *k, *r;
     357             : 
     358           0 :   k = xtrymalloc (sizeof *k);
     359           0 :   if (!k)
     360           0 :     return -1;
     361           0 :   memcpy (k->kid, kinfo->keyid, 8);
     362           0 :   k->seqno = 0;
     363           0 :   k->next = blob->temp_kids;
     364           0 :   blob->temp_kids = k;
     365           0 :   for (r=k; r; r = r->next)
     366           0 :     k->seqno++;
     367             : 
     368           0 :   return k->seqno;
     369             : }
     370             : 
     371             : 
     372             : /* Helper for pgp_create_key_part.  */
     373             : static gpg_error_t
     374         108 : pgp_create_key_part_single (KEYBOXBLOB blob, int n,
     375             :                             struct _keybox_openpgp_key_info *kinfo)
     376             : {
     377             :   size_t fprlen;
     378             :   int off;
     379             : 
     380         108 :   fprlen = kinfo->fprlen;
     381         108 :   if (fprlen > 20)
     382           0 :     fprlen = 20;
     383         108 :   memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
     384         108 :   if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */
     385             :     {
     386           0 :       memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen);
     387           0 :       memset (blob->keys[n].fpr, 0, 20 - fprlen);
     388           0 :       off = pgp_temp_store_kid (blob, kinfo);
     389           0 :       if (off == -1)
     390           0 :         return gpg_error_from_syserror ();
     391           0 :       blob->keys[n].off_kid = off;
     392             :     }
     393             :   else
     394         108 :     blob->keys[n].off_kid = 0; /* Will be fixed up later */
     395         108 :   blob->keys[n].flags = 0;
     396         108 :   return 0;
     397             : }
     398             : 
     399             : 
     400             : static gpg_error_t
     401          61 : pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
     402             : {
     403             :   gpg_error_t err;
     404          61 :   int n = 0;
     405             :   struct _keybox_openpgp_key_info *kinfo;
     406             : 
     407          61 :   err = pgp_create_key_part_single (blob, n++, &info->primary);
     408          61 :   if (err)
     409           0 :     return err;
     410          61 :   if (info->nsubkeys)
     411          94 :     for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
     412          47 :       if ((err=pgp_create_key_part_single (blob, n++, kinfo)))
     413           0 :         return err;
     414             : 
     415          61 :   assert (n == blob->nkeys);
     416          61 :   return 0;
     417             : }
     418             : 
     419             : 
     420             : static void
     421          61 : pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
     422             : {
     423          61 :   int n = 0;
     424             :   struct _keybox_openpgp_uid_info *u;
     425             : 
     426          61 :   if (info->nuids)
     427             :     {
     428         136 :       for (u = &info->uids; u; u = u->next)
     429             :         {
     430          75 :           blob->uids[n].off = u->off;
     431          75 :           blob->uids[n].len = u->len;
     432          75 :           blob->uids[n].flags = 0;
     433          75 :           blob->uids[n].validity = 0;
     434          75 :           n++;
     435             :         }
     436             :     }
     437             : 
     438          61 :   assert (n == blob->nuids);
     439          61 : }
     440             : 
     441             : 
     442             : static void
     443          61 : pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus)
     444             : {
     445             :   int n;
     446             : 
     447         327 :   for (n=0; n < blob->nsigs; n++)
     448             :     {
     449         266 :       blob->sigs[n] = sigstatus? sigstatus[n+1] : 0;
     450             :     }
     451          61 : }
     452             : 
     453             : 
     454             : static int
     455          61 : pgp_create_blob_keyblock (KEYBOXBLOB blob,
     456             :                           const unsigned char *image, size_t imagelen)
     457             : {
     458          61 :   struct membuf *a = blob->buf;
     459             :   int n;
     460          61 :   u32 kbstart = a->len;
     461             : 
     462          61 :   add_fixup (blob, 8, kbstart);
     463             : 
     464         136 :   for (n = 0; n < blob->nuids; n++)
     465          75 :     add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off);
     466             : 
     467          61 :   put_membuf (a, image, imagelen);
     468             : 
     469          61 :   add_fixup (blob, 12, a->len - kbstart);
     470          61 :   return 0;
     471             : }
     472             : 
     473             : 
     474             : 
     475             : #ifdef KEYBOX_WITH_X509
     476             : /*
     477             :    X.509 specific stuff
     478             :  */
     479             : 
     480             : /* Write the raw certificate out */
     481             : static int
     482           3 : x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
     483             : {
     484           3 :   struct membuf *a = blob->buf;
     485             :   const unsigned char *image;
     486             :   size_t length;
     487           3 :   u32 kbstart = a->len;
     488             : 
     489             :   /* Store our offset for later fixup */
     490           3 :   add_fixup (blob, 8, kbstart);
     491             : 
     492           3 :   image = ksba_cert_get_image (cert, &length);
     493           3 :   if (!image)
     494           0 :     return gpg_error (GPG_ERR_GENERAL);
     495           3 :   put_membuf (a, image, length);
     496             : 
     497           3 :   add_fixup (blob, 12, a->len - kbstart);
     498           3 :   return 0;
     499             : }
     500             : 
     501             : #endif /*KEYBOX_WITH_X509*/
     502             : 
     503             : /* Write a stored keyID out to the buffer */
     504             : static void
     505           0 : write_stored_kid (KEYBOXBLOB blob, int seqno)
     506             : {
     507             :   struct keyid_list *r;
     508             : 
     509           0 :   for ( r = blob->temp_kids; r; r = r->next )
     510             :     {
     511           0 :       if (r->seqno == seqno )
     512             :         {
     513           0 :           put_membuf (blob->buf, r->kid, 8);
     514           0 :           return;
     515             :         }
     516             :     }
     517           0 :   never_reached ();
     518             : }
     519             : 
     520             : /* Release a list of key IDs */
     521             : static void
     522          64 : release_kid_list (struct keyid_list *kl)
     523             : {
     524             :   struct keyid_list *r, *r2;
     525             : 
     526          64 :   for ( r = kl; r; r = r2 )
     527             :     {
     528           0 :       r2 = r->next;
     529           0 :       xfree (r);
     530             :     }
     531          64 : }
     532             : 
     533             : 
     534             : 
     535             : static int
     536          64 : create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
     537             : {
     538          64 :   struct membuf *a = blob->buf;
     539             :   int i;
     540             : 
     541          64 :   put32 ( a, 0 ); /* blob length, needs fixup */
     542          64 :   put8 ( a, blobtype);
     543          64 :   put8 ( a, 1 );  /* blob type version */
     544          64 :   put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
     545             : 
     546          64 :   put32 ( a, 0 ); /* offset to the raw data, needs fixup */
     547          64 :   put32 ( a, 0 ); /* length of the raw data, needs fixup */
     548             : 
     549          64 :   put16 ( a, blob->nkeys );
     550          64 :   put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
     551         175 :   for ( i=0; i < blob->nkeys; i++ )
     552             :     {
     553         111 :       put_membuf (a, blob->keys[i].fpr, 20);
     554         111 :       blob->keys[i].off_kid_addr = a->len;
     555         111 :       put32 ( a, 0 ); /* offset to keyid, fixed up later */
     556         111 :       put16 ( a, blob->keys[i].flags );
     557         111 :       put16 ( a, 0 ); /* reserved */
     558             :     }
     559             : 
     560          64 :   put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
     561          64 :   if (blob->serial)
     562           3 :     put_membuf (a, blob->serial, blob->seriallen);
     563             : 
     564          64 :   put16 ( a, blob->nuids );
     565          64 :   put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
     566         147 :   for (i=0; i < blob->nuids; i++)
     567             :     {
     568          83 :       blob->uids[i].off_addr = a->len;
     569          83 :       put32 ( a, 0 ); /* offset to userid, fixed up later */
     570          83 :       put32 ( a, blob->uids[i].len );
     571          83 :       put16 ( a, blob->uids[i].flags );
     572          83 :       put8  ( a, 0 ); /* validity */
     573          83 :       put8  ( a, 0 ); /* reserved */
     574             :     }
     575             : 
     576          64 :   put16 ( a, blob->nsigs );
     577          64 :   put16 ( a, 4 );  /* size of sig info */
     578         333 :   for (i=0; i < blob->nsigs; i++)
     579             :     {
     580         269 :       put32 ( a, blob->sigs[i]);
     581             :     }
     582             : 
     583          64 :   put8 ( a, 0 );  /* assigned ownertrust */
     584          64 :   put8 ( a, 0 );  /* validity of all user IDs */
     585          64 :   put16 ( a, 0 );  /* reserved */
     586          64 :   put32 ( a, 0 );  /* time of next recheck */
     587          64 :   put32 ( a, 0 );  /* newest timestamp (none) */
     588          64 :   put32 ( a, make_timestamp() );  /* creation time */
     589          64 :   put32 ( a, 0 );  /* size of reserved space */
     590             :   /* reserved space (which is currently of size 0) */
     591             : 
     592             :   /* space where we write keyIDs and and other stuff so that the
     593             :      pointers can actually point to somewhere */
     594          64 :   if (blobtype == KEYBOX_BLOBTYPE_PGP)
     595             :     {
     596             :       /* We need to store the keyids for all pgp v3 keys because those key
     597             :          IDs are not part of the fingerprint.  While we are doing that, we
     598             :          fixup all the keyID offsets */
     599         169 :       for (i=0; i < blob->nkeys; i++ )
     600             :         {
     601         108 :           if (blob->keys[i].off_kid)
     602             :             { /* this is a v3 one */
     603           0 :               add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
     604           0 :               write_stored_kid (blob, blob->keys[i].off_kid);
     605             :             }
     606             :           else
     607             :             { /* the better v4 key IDs - just store an offset 8 bytes back */
     608         108 :               add_fixup (blob, blob->keys[i].off_kid_addr,
     609         108 :                          blob->keys[i].off_kid_addr - 8);
     610             :             }
     611             :         }
     612             :     }
     613             : 
     614          64 :   if (blobtype == KEYBOX_BLOBTYPE_X509)
     615             :     {
     616             :       /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
     617             :          the utf-8 string represenation of them */
     618          11 :       for (i=0; i < blob->nuids; i++ )
     619             :         {
     620           8 :           if (blob->uids[i].name)
     621             :             { /* this is a v3 one */
     622           8 :               add_fixup (blob, blob->uids[i].off_addr, a->len);
     623           8 :               put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
     624             :             }
     625             :         }
     626             :     }
     627             : 
     628          64 :     return 0;
     629             : }
     630             : 
     631             : 
     632             : 
     633             : static int
     634          64 : create_blob_trailer (KEYBOXBLOB blob)
     635             : {
     636             :   (void)blob;
     637          64 :   return 0;
     638             : }
     639             : 
     640             : 
     641             : static int
     642          64 : create_blob_finish (KEYBOXBLOB blob)
     643             : {
     644          64 :   struct membuf *a = blob->buf;
     645             :   unsigned char *p;
     646             :   unsigned char *pp;
     647             :   size_t n;
     648             : 
     649             :   /* Write a placeholder for the checksum */
     650          64 :   put_membuf (a, NULL, 20);
     651             : 
     652             :   /* get the memory area */
     653          64 :   n = 0; /* (Just to avoid compiler warning.) */
     654          64 :   p = get_membuf (a, &n);
     655          64 :   if (!p)
     656           0 :     return gpg_error (GPG_ERR_ENOMEM);
     657          64 :   assert (n >= 20);
     658             : 
     659             :   /* fixup the length */
     660          64 :   add_fixup (blob, 0, n);
     661             : 
     662             :   /* do the fixups */
     663          64 :   if (blob->fixup_out_of_core)
     664           0 :     return gpg_error (GPG_ERR_ENOMEM);
     665             : 
     666             :   {
     667             :     struct fixup_list *fl;
     668         447 :     for (fl = blob->fixups; fl; fl = fl->next)
     669             :       {
     670         383 :         assert (fl->off+4 <= n);
     671         383 :         p[fl->off+0] = fl->val >> 24;
     672         383 :         p[fl->off+1] = fl->val >> 16;
     673         383 :         p[fl->off+2] = fl->val >>  8;
     674         383 :         p[fl->off+3] = fl->val;
     675             :       }
     676             :   }
     677             : 
     678             :   /* Compute and store the SHA-1 checksum. */
     679          64 :   gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20);
     680             : 
     681          64 :   pp = xtrymalloc (n);
     682          64 :   if ( !pp )
     683           0 :     return gpg_error_from_syserror ();
     684          64 :   memcpy (pp , p, n);
     685          64 :   blob->blob = pp;
     686          64 :   blob->bloblen = n;
     687             : 
     688          64 :   return 0;
     689             : }
     690             : 
     691             : 
     692             : 
     693             : gpg_error_t
     694          61 : _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
     695             :                              keybox_openpgp_info_t info,
     696             :                              const unsigned char *image,
     697             :                              size_t imagelen,
     698             :                              u32 *sigstatus,
     699             :                              int as_ephemeral)
     700             : {
     701             :   gpg_error_t err;
     702             :   KEYBOXBLOB blob;
     703             : 
     704          61 :   *r_blob = NULL;
     705             : 
     706             :   /* If we have a signature status vector, check that the number of
     707             :      elements matches the actual number of signatures.  */
     708          61 :   if (sigstatus && sigstatus[0] != info->nsigs)
     709           0 :     return gpg_error (GPG_ERR_INTERNAL);
     710             : 
     711          61 :   blob = xtrycalloc (1, sizeof *blob);
     712          61 :   if (!blob)
     713           0 :     return gpg_error_from_syserror ();
     714             : 
     715          61 :   blob->nkeys = 1 + info->nsubkeys;
     716          61 :   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
     717          61 :   if (!blob->keys)
     718             :     {
     719           0 :       err = gpg_error_from_syserror ();
     720           0 :       goto leave;
     721             :     }
     722             : 
     723          61 :   blob->nuids = info->nuids;
     724          61 :   if (blob->nuids)
     725             :     {
     726          61 :       blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
     727          61 :       if (!blob->uids)
     728             :         {
     729           0 :           err = gpg_error_from_syserror ();
     730           0 :           goto leave;
     731             :         }
     732             :     }
     733             : 
     734          61 :   blob->nsigs = info->nsigs;
     735          61 :   if (blob->nsigs)
     736             :     {
     737          59 :       blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
     738          59 :       if (!blob->sigs)
     739             :         {
     740           0 :           err = gpg_error_from_syserror ();
     741           0 :           goto leave;
     742             :         }
     743             :     }
     744             : 
     745          61 :   err = pgp_create_key_part (blob, info);
     746          61 :   if (err)
     747           0 :     goto leave;
     748          61 :   pgp_create_uid_part (blob, info);
     749          61 :   pgp_create_sig_part (blob, sigstatus);
     750             : 
     751          61 :   init_membuf (&blob->bufbuf, 1024);
     752          61 :   blob->buf = &blob->bufbuf;
     753          61 :   err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral);
     754          61 :   if (err)
     755           0 :     goto leave;
     756          61 :   err = pgp_create_blob_keyblock (blob, image, imagelen);
     757          61 :   if (err)
     758           0 :     goto leave;
     759          61 :   err = create_blob_trailer (blob);
     760          61 :   if (err)
     761           0 :     goto leave;
     762          61 :   err = create_blob_finish (blob);
     763          61 :   if (err)
     764           0 :     goto leave;
     765             : 
     766             :  leave:
     767          61 :   release_kid_list (blob->temp_kids);
     768          61 :   blob->temp_kids = NULL;
     769          61 :   if (err)
     770           0 :     _keybox_release_blob (blob);
     771             :   else
     772          61 :     *r_blob = blob;
     773          61 :   return err;
     774             : }
     775             : 
     776             : 
     777             : #ifdef KEYBOX_WITH_X509
     778             : 
     779             : /* Return an allocated string with the email address extracted from a
     780             :    DN.  Note hat we use this code also in ../sm/keylist.c.  */
     781             : static char *
     782           3 : x509_email_kludge (const char *name)
     783             : {
     784             :   const char *p, *string;
     785             :   unsigned char *buf;
     786             :   int n;
     787             : 
     788           3 :   string = name;
     789             :   for (;;)
     790             :     {
     791           3 :       p = strstr (string, "1.2.840.113549.1.9.1=#");
     792           3 :       if (!p)
     793           1 :         return NULL;
     794           2 :       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
     795             :         {
     796           2 :           name = p + 22;
     797           2 :           break;
     798             :         }
     799           0 :       string = p + 22;
     800           0 :     }
     801             : 
     802             : 
     803             :   /* This looks pretty much like an email address in the subject's DN
     804             :      we use this to add an additional user ID entry.  This way,
     805             :      OpenSSL generated keys get a nicer and usable listing.  */
     806           2 :   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
     807             :     ;
     808           2 :   if (!n)
     809           0 :     return NULL;
     810           2 :   buf = xtrymalloc (n+3);
     811           2 :   if (!buf)
     812           0 :     return NULL; /* oops, out of core */
     813           2 :   *buf = '<';
     814          73 :   for (n=1, p=name; hexdigitp (p); p +=2, n++)
     815          71 :     buf[n] = xtoi_2 (p);
     816           2 :   buf[n++] = '>';
     817           2 :   buf[n] = 0;
     818           2 :   return (char*)buf;
     819             : }
     820             : 
     821             : 
     822             : 
     823             : /* Note: We should move calculation of the digest into libksba and
     824             :    remove that parameter */
     825             : int
     826           3 : _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
     827             :                           unsigned char *sha1_digest, int as_ephemeral)
     828             : {
     829           3 :   int i, rc = 0;
     830             :   KEYBOXBLOB blob;
     831             :   unsigned char *sn;
     832             :   char *p;
     833           3 :   char **names = NULL;
     834             :   size_t max_names;
     835             : 
     836           3 :   *r_blob = NULL;
     837           3 :   blob = xtrycalloc (1, sizeof *blob);
     838           3 :   if( !blob )
     839           0 :     return gpg_error_from_syserror ();
     840             : 
     841           3 :   sn = ksba_cert_get_serial (cert);
     842           3 :   if (sn)
     843             :     {
     844             :       size_t n, len;
     845           3 :       n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
     846           3 :       if (n < 2)
     847             :         {
     848           0 :           xfree (sn);
     849           0 :           return gpg_error (GPG_ERR_GENERAL);
     850             :         }
     851           3 :       blob->serialbuf = sn;
     852           3 :       sn++; n--; /* skip '(' */
     853           6 :       for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
     854           3 :         len = len*10 + atoi_1 (sn);
     855           3 :       if (*sn != ':')
     856             :         {
     857           0 :           xfree (blob->serialbuf);
     858           0 :           blob->serialbuf = NULL;
     859           0 :           return gpg_error (GPG_ERR_GENERAL);
     860             :         }
     861           3 :       sn++;
     862           3 :       blob->serial = sn;
     863           3 :       blob->seriallen = len;
     864             :     }
     865             : 
     866           3 :   blob->nkeys = 1;
     867             : 
     868             :   /* create list of names */
     869           3 :   blob->nuids = 0;
     870           3 :   max_names = 100;
     871           3 :   names = xtrymalloc (max_names * sizeof *names);
     872           3 :   if (!names)
     873             :     {
     874           0 :       rc = gpg_error_from_syserror ();
     875           0 :       goto leave;
     876             :     }
     877             : 
     878           3 :   p = ksba_cert_get_issuer (cert, 0);
     879           3 :   if (!p)
     880             :     {
     881           0 :       rc =  gpg_error (GPG_ERR_MISSING_VALUE);
     882           0 :       goto leave;
     883             :     }
     884           3 :   names[blob->nuids++] = p;
     885           6 :   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
     886             :     {
     887           3 :       if (blob->nuids >= max_names)
     888             :         {
     889             :           char **tmp;
     890             : 
     891           0 :           max_names += 100;
     892           0 :           tmp = xtryrealloc (names, max_names * sizeof *names);
     893           0 :           if (!tmp)
     894             :             {
     895           0 :               rc = gpg_error_from_syserror ();
     896           0 :               goto leave;
     897             :             }
     898           0 :           names = tmp;
     899             :         }
     900           3 :       names[blob->nuids++] = p;
     901           3 :       if (!i && (p=x509_email_kludge (p)))
     902           2 :         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
     903             :     }
     904             : 
     905             :   /* space for signature information */
     906           3 :   blob->nsigs = 1;
     907             : 
     908           3 :   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
     909           3 :   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
     910           3 :   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
     911           3 :   if (!blob->keys || !blob->uids || !blob->sigs)
     912             :     {
     913           0 :       rc = gpg_error (GPG_ERR_ENOMEM);
     914           0 :       goto leave;
     915             :     }
     916             : 
     917           3 :   memcpy (blob->keys[0].fpr, sha1_digest, 20);
     918           3 :   blob->keys[0].off_kid = 0; /* We don't have keyids */
     919           3 :   blob->keys[0].flags = 0;
     920             : 
     921             :   /* issuer and subject names */
     922          11 :   for (i=0; i < blob->nuids; i++)
     923             :     {
     924           8 :       blob->uids[i].name = names[i];
     925           8 :       blob->uids[i].len = strlen(names[i]);
     926           8 :       names[i] = NULL;
     927           8 :       blob->uids[i].flags = 0;
     928           8 :       blob->uids[i].validity = 0;
     929             :     }
     930           3 :   xfree (names);
     931           3 :   names = NULL;
     932             : 
     933             :   /* signatures */
     934           3 :   blob->sigs[0] = 0; /* not yet checked */
     935             : 
     936             :   /* Create a temporary buffer for further processing */
     937           3 :   init_membuf (&blob->bufbuf, 1024);
     938           3 :   blob->buf = &blob->bufbuf;
     939             :   /* write out what we already have */
     940           3 :   rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral);
     941           3 :   if (rc)
     942           0 :     goto leave;
     943           3 :   rc = x509_create_blob_cert (blob, cert);
     944           3 :   if (rc)
     945           0 :     goto leave;
     946           3 :   rc = create_blob_trailer (blob);
     947           3 :   if (rc)
     948           0 :     goto leave;
     949           3 :   rc = create_blob_finish ( blob );
     950           3 :   if (rc)
     951           0 :     goto leave;
     952             : 
     953             : 
     954             :  leave:
     955           3 :   release_kid_list (blob->temp_kids);
     956           3 :   blob->temp_kids = NULL;
     957           3 :   if (names)
     958             :     {
     959           0 :       for (i=0; i < blob->nuids; i++)
     960           0 :         xfree (names[i]);
     961           0 :       xfree (names);
     962             :     }
     963           3 :   if (rc)
     964             :     {
     965           0 :       _keybox_release_blob (blob);
     966           0 :       *r_blob = NULL;
     967             :     }
     968             :   else
     969             :     {
     970           3 :       *r_blob = blob;
     971             :     }
     972           3 :   return rc;
     973             : }
     974             : #endif /*KEYBOX_WITH_X509*/
     975             : 
     976             : 
     977             : 
     978             : int
     979       83701 : _keybox_new_blob (KEYBOXBLOB *r_blob,
     980             :                   unsigned char *image, size_t imagelen, off_t off)
     981             : {
     982             :   KEYBOXBLOB blob;
     983             : 
     984       83701 :   *r_blob = NULL;
     985       83701 :   blob = xtrycalloc (1, sizeof *blob);
     986       83701 :   if (!blob)
     987           0 :     return gpg_error_from_syserror ();
     988             : 
     989       83701 :   blob->blob = image;
     990       83701 :   blob->bloblen = imagelen;
     991       83701 :   blob->fileoffset = off;
     992       83701 :   *r_blob = blob;
     993       83701 :   return 0;
     994             : }
     995             : 
     996             : 
     997             : void
     998       89509 : _keybox_release_blob (KEYBOXBLOB blob)
     999             : {
    1000             :   int i;
    1001       89509 :   if (!blob)
    1002       95255 :     return;
    1003             :   /* hmmm: release membuf here?*/
    1004       83763 :   xfree (blob->keys );
    1005       83763 :   xfree (blob->serialbuf);
    1006       83846 :   for (i=0; i < blob->nuids; i++)
    1007          83 :     xfree (blob->uids[i].name);
    1008       83763 :   xfree (blob->uids );
    1009       83763 :   xfree (blob->sigs );
    1010       83763 :   xfree (blob->blob );
    1011       83763 :   xfree (blob );
    1012             : }
    1013             : 
    1014             : 
    1015             : 
    1016             : const unsigned char *
    1017      255551 : _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
    1018             : {
    1019      255551 :   *n = blob->bloblen;
    1020      255551 :   return blob->blob;
    1021             : }
    1022             : 
    1023             : off_t
    1024           5 : _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
    1025             : {
    1026           5 :   return blob->fileoffset;
    1027             : }
    1028             : 
    1029             : 
    1030             : 
    1031             : void
    1032           0 : _keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp)
    1033             : {
    1034           0 :   if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER)
    1035             :     {
    1036           0 :       u32 val = make_timestamp ();
    1037             : 
    1038             :       /* Update the last maintenance run times tamp. */
    1039           0 :       blob->blob[20]   = (val >> 24);
    1040           0 :       blob->blob[20+1] = (val >> 16);
    1041           0 :       blob->blob[20+2] = (val >>  8);
    1042           0 :       blob->blob[20+3] = (val      );
    1043             : 
    1044           0 :       if (for_openpgp)
    1045           0 :         blob->blob[7] |= 0x02;  /* OpenPGP data may be available.  */
    1046             :     }
    1047           0 : }

Generated by: LCOV version 1.11