LCOV - code coverage report
Current view: top level - kbx - keybox-blob.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 327 424 77.1 %
Date: 2016-09-12 12:29:17 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 similar, 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          69 : init_membuf (struct membuf *mb, int initiallen)
     238             : {
     239          69 :   mb->len = 0;
     240          69 :   mb->size = initiallen;
     241          69 :   mb->out_of_core = 0;
     242          69 :   mb->buf = xtrymalloc (initiallen);
     243          69 :   if (!mb->buf)
     244           0 :       mb->out_of_core = 1;
     245          69 : }
     246             : 
     247             : static void
     248        2762 : put_membuf (struct membuf *mb, const void *buf, size_t len)
     249             : {
     250        2762 :   if (mb->out_of_core)
     251           0 :     return;
     252             : 
     253        2762 :   if (mb->len + len >= mb->size)
     254             :     {
     255             :       char *p;
     256             : 
     257          48 :       mb->size += len + 1024;
     258          48 :       p = xtryrealloc (mb->buf, mb->size);
     259          48 :       if (!p)
     260             :         {
     261           0 :           mb->out_of_core = 1;
     262           0 :           return;
     263             :         }
     264          48 :       mb->buf = p;
     265             :     }
     266        2762 :   if (buf)
     267        2693 :     memcpy (mb->buf + mb->len, buf, len);
     268             :   else
     269          69 :     memset (mb->buf + mb->len, 0, len);
     270        2762 :   mb->len += len;
     271             : }
     272             : 
     273             : static void *
     274         138 : get_membuf (struct membuf *mb, size_t *len)
     275             : {
     276             :   char *p;
     277             : 
     278         138 :   if (mb->out_of_core)
     279             :     {
     280          69 :       xfree (mb->buf);
     281          69 :       mb->buf = NULL;
     282          69 :       return NULL;
     283             :     }
     284             : 
     285          69 :   p = mb->buf;
     286          69 :   *len = mb->len;
     287          69 :   mb->buf = NULL;
     288          69 :   mb->out_of_core = 1; /* don't allow a reuse */
     289          69 :   return p;
     290             : }
     291             : 
     292             : 
     293             : static void
     294         452 : put8 (struct membuf *mb, byte a )
     295             : {
     296         452 :   put_membuf (mb, &a, 1);
     297         452 : }
     298             : 
     299             : static void
     300         963 : put16 (struct membuf *mb, u16 a )
     301             : {
     302             :   unsigned char tmp[2];
     303         963 :   tmp[0] = a>>8;
     304         963 :   tmp[1] = a;
     305         963 :   put_membuf (mb, tmp, 2);
     306         963 : }
     307             : 
     308             : static void
     309        1071 : put32 (struct membuf *mb, u32 a )
     310             : {
     311             :   unsigned char tmp[4];
     312        1071 :   tmp[0] = a>>24;
     313        1071 :   tmp[1] = a>>16;
     314        1071 :   tmp[2] = a>>8;
     315        1071 :   tmp[3] = a;
     316        1071 :   put_membuf (mb, tmp, 4);
     317        1071 : }
     318             : 
     319             : 
     320             : 
     321             : /* Store a value in the fixup list */
     322             : static void
     323         419 : add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
     324             : {
     325             :   struct fixup_list *fl;
     326             : 
     327         419 :   if (blob->fixup_out_of_core)
     328         419 :     return;
     329             : 
     330         419 :   fl = xtrycalloc(1, sizeof *fl);
     331         419 :   if (!fl)
     332           0 :     blob->fixup_out_of_core = 1;
     333             :   else
     334             :     {
     335         419 :       fl->off = off;
     336         419 :       fl->val = val;
     337         419 :       fl->next = blob->fixups;
     338         419 :       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         124 : 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         124 :   fprlen = kinfo->fprlen;
     381         124 :   if (fprlen > 20)
     382           0 :     fprlen = 20;
     383         124 :   memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
     384         124 :   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         124 :     blob->keys[n].off_kid = 0; /* Will be fixed up later */
     395         124 :   blob->keys[n].flags = 0;
     396         124 :   return 0;
     397             : }
     398             : 
     399             : 
     400             : static gpg_error_t
     401          66 : pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
     402             : {
     403             :   gpg_error_t err;
     404          66 :   int n = 0;
     405             :   struct _keybox_openpgp_key_info *kinfo;
     406             : 
     407          66 :   err = pgp_create_key_part_single (blob, n++, &info->primary);
     408          66 :   if (err)
     409           0 :     return err;
     410          66 :   if (info->nsubkeys)
     411         110 :     for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
     412          58 :       if ((err=pgp_create_key_part_single (blob, n++, kinfo)))
     413           0 :         return err;
     414             : 
     415          66 :   assert (n == blob->nkeys);
     416          66 :   return 0;
     417             : }
     418             : 
     419             : 
     420             : static void
     421          66 : pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
     422             : {
     423          66 :   int n = 0;
     424             :   struct _keybox_openpgp_uid_info *u;
     425             : 
     426          66 :   if (info->nuids)
     427             :     {
     428         146 :       for (u = &info->uids; u; u = u->next)
     429             :         {
     430          80 :           blob->uids[n].off = u->off;
     431          80 :           blob->uids[n].len = u->len;
     432          80 :           blob->uids[n].flags = 0;
     433          80 :           blob->uids[n].validity = 0;
     434          80 :           n++;
     435             :         }
     436             :     }
     437             : 
     438          66 :   assert (n == blob->nuids);
     439          66 : }
     440             : 
     441             : 
     442             : static void
     443          66 : pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus)
     444             : {
     445             :   int n;
     446             : 
     447         348 :   for (n=0; n < blob->nsigs; n++)
     448             :     {
     449         282 :       blob->sigs[n] = sigstatus? sigstatus[n+1] : 0;
     450             :     }
     451          66 : }
     452             : 
     453             : 
     454             : static int
     455          66 : pgp_create_blob_keyblock (KEYBOXBLOB blob,
     456             :                           const unsigned char *image, size_t imagelen)
     457             : {
     458          66 :   struct membuf *a = blob->buf;
     459             :   int n;
     460          66 :   u32 kbstart = a->len;
     461             : 
     462          66 :   add_fixup (blob, 8, kbstart);
     463             : 
     464         146 :   for (n = 0; n < blob->nuids; n++)
     465          80 :     add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off);
     466             : 
     467          66 :   put_membuf (a, image, imagelen);
     468             : 
     469          66 :   add_fixup (blob, 12, a->len - kbstart);
     470          66 :   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          69 : release_kid_list (struct keyid_list *kl)
     523             : {
     524             :   struct keyid_list *r, *r2;
     525             : 
     526          69 :   for ( r = kl; r; r = r2 )
     527             :     {
     528           0 :       r2 = r->next;
     529           0 :       xfree (r);
     530             :     }
     531          69 : }
     532             : 
     533             : 
     534             : 
     535             : static int
     536          69 : create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
     537             : {
     538          69 :   struct membuf *a = blob->buf;
     539             :   int i;
     540             : 
     541          69 :   put32 ( a, 0 ); /* blob length, needs fixup */
     542          69 :   put8 ( a, blobtype);
     543          69 :   put8 ( a, 1 );  /* blob type version */
     544          69 :   put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
     545             : 
     546          69 :   put32 ( a, 0 ); /* offset to the raw data, needs fixup */
     547          69 :   put32 ( a, 0 ); /* length of the raw data, needs fixup */
     548             : 
     549          69 :   put16 ( a, blob->nkeys );
     550          69 :   put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
     551         196 :   for ( i=0; i < blob->nkeys; i++ )
     552             :     {
     553         127 :       put_membuf (a, blob->keys[i].fpr, 20);
     554         127 :       blob->keys[i].off_kid_addr = a->len;
     555         127 :       put32 ( a, 0 ); /* offset to keyid, fixed up later */
     556         127 :       put16 ( a, blob->keys[i].flags );
     557         127 :       put16 ( a, 0 ); /* reserved */
     558             :     }
     559             : 
     560          69 :   put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
     561          69 :   if (blob->serial)
     562           3 :     put_membuf (a, blob->serial, blob->seriallen);
     563             : 
     564          69 :   put16 ( a, blob->nuids );
     565          69 :   put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
     566         157 :   for (i=0; i < blob->nuids; i++)
     567             :     {
     568          88 :       blob->uids[i].off_addr = a->len;
     569          88 :       put32 ( a, 0 ); /* offset to userid, fixed up later */
     570          88 :       put32 ( a, blob->uids[i].len );
     571          88 :       put16 ( a, blob->uids[i].flags );
     572          88 :       put8  ( a, 0 ); /* validity */
     573          88 :       put8  ( a, 0 ); /* reserved */
     574             :     }
     575             : 
     576          69 :   put16 ( a, blob->nsigs );
     577          69 :   put16 ( a, 4 );  /* size of sig info */
     578         354 :   for (i=0; i < blob->nsigs; i++)
     579             :     {
     580         285 :       put32 ( a, blob->sigs[i]);
     581             :     }
     582             : 
     583          69 :   put8 ( a, 0 );  /* assigned ownertrust */
     584          69 :   put8 ( a, 0 );  /* validity of all user IDs */
     585          69 :   put16 ( a, 0 );  /* reserved */
     586          69 :   put32 ( a, 0 );  /* time of next recheck */
     587          69 :   put32 ( a, 0 );  /* newest timestamp (none) */
     588          69 :   put32 ( a, make_timestamp() );  /* creation time */
     589          69 :   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          69 :   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         190 :       for (i=0; i < blob->nkeys; i++ )
     600             :         {
     601         124 :           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         124 :               add_fixup (blob, blob->keys[i].off_kid_addr,
     609         124 :                          blob->keys[i].off_kid_addr - 8);
     610             :             }
     611             :         }
     612             :     }
     613             : 
     614          69 :   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          69 :     return 0;
     629             : }
     630             : 
     631             : 
     632             : 
     633             : static int
     634          69 : create_blob_trailer (KEYBOXBLOB blob)
     635             : {
     636             :   (void)blob;
     637          69 :   return 0;
     638             : }
     639             : 
     640             : 
     641             : static int
     642          69 : create_blob_finish (KEYBOXBLOB blob)
     643             : {
     644          69 :   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          69 :   put_membuf (a, NULL, 20);
     651             : 
     652             :   /* get the memory area */
     653          69 :   n = 0; /* (Just to avoid compiler warning.) */
     654          69 :   p = get_membuf (a, &n);
     655          69 :   if (!p)
     656           0 :     return gpg_error (GPG_ERR_ENOMEM);
     657          69 :   assert (n >= 20);
     658             : 
     659             :   /* fixup the length */
     660          69 :   add_fixup (blob, 0, n);
     661             : 
     662             :   /* do the fixups */
     663          69 :   if (blob->fixup_out_of_core)
     664             :     {
     665           0 :       xfree (p);
     666           0 :       return gpg_error (GPG_ERR_ENOMEM);
     667             :     }
     668             : 
     669             :   {
     670             :     struct fixup_list *fl, *next;
     671         488 :     for (fl = blob->fixups; fl; fl = next)
     672             :       {
     673         419 :         assert (fl->off+4 <= n);
     674         419 :         p[fl->off+0] = fl->val >> 24;
     675         419 :         p[fl->off+1] = fl->val >> 16;
     676         419 :         p[fl->off+2] = fl->val >>  8;
     677         419 :         p[fl->off+3] = fl->val;
     678         419 :         next = fl->next;
     679         419 :         xfree (fl);
     680             :       }
     681          69 :     blob->fixups = NULL;
     682             :   }
     683             : 
     684             :   /* Compute and store the SHA-1 checksum. */
     685          69 :   gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20);
     686             : 
     687          69 :   pp = xtrymalloc (n);
     688          69 :   if ( !pp )
     689             :     {
     690           0 :       xfree (p);
     691           0 :       return gpg_error_from_syserror ();
     692             :     }
     693          69 :   memcpy (pp , p, n);
     694          69 :   xfree (p);
     695          69 :   blob->blob = pp;
     696          69 :   blob->bloblen = n;
     697             : 
     698          69 :   return 0;
     699             : }
     700             : 
     701             : 
     702             : 
     703             : gpg_error_t
     704          66 : _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
     705             :                              keybox_openpgp_info_t info,
     706             :                              const unsigned char *image,
     707             :                              size_t imagelen,
     708             :                              u32 *sigstatus,
     709             :                              int as_ephemeral)
     710             : {
     711             :   gpg_error_t err;
     712             :   KEYBOXBLOB blob;
     713             : 
     714          66 :   *r_blob = NULL;
     715             : 
     716             :   /* If we have a signature status vector, check that the number of
     717             :      elements matches the actual number of signatures.  */
     718          66 :   if (sigstatus && sigstatus[0] != info->nsigs)
     719           0 :     return gpg_error (GPG_ERR_INTERNAL);
     720             : 
     721          66 :   blob = xtrycalloc (1, sizeof *blob);
     722          66 :   if (!blob)
     723           0 :     return gpg_error_from_syserror ();
     724             : 
     725          66 :   blob->nkeys = 1 + info->nsubkeys;
     726          66 :   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
     727          66 :   if (!blob->keys)
     728             :     {
     729           0 :       err = gpg_error_from_syserror ();
     730           0 :       goto leave;
     731             :     }
     732             : 
     733          66 :   blob->nuids = info->nuids;
     734          66 :   if (blob->nuids)
     735             :     {
     736          66 :       blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
     737          66 :       if (!blob->uids)
     738             :         {
     739           0 :           err = gpg_error_from_syserror ();
     740           0 :           goto leave;
     741             :         }
     742             :     }
     743             : 
     744          66 :   blob->nsigs = info->nsigs;
     745          66 :   if (blob->nsigs)
     746             :     {
     747          64 :       blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
     748          64 :       if (!blob->sigs)
     749             :         {
     750           0 :           err = gpg_error_from_syserror ();
     751           0 :           goto leave;
     752             :         }
     753             :     }
     754             : 
     755          66 :   err = pgp_create_key_part (blob, info);
     756          66 :   if (err)
     757           0 :     goto leave;
     758          66 :   pgp_create_uid_part (blob, info);
     759          66 :   pgp_create_sig_part (blob, sigstatus);
     760             : 
     761          66 :   init_membuf (&blob->bufbuf, 1024);
     762          66 :   blob->buf = &blob->bufbuf;
     763          66 :   err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral);
     764          66 :   if (err)
     765           0 :     goto leave;
     766          66 :   err = pgp_create_blob_keyblock (blob, image, imagelen);
     767          66 :   if (err)
     768           0 :     goto leave;
     769          66 :   err = create_blob_trailer (blob);
     770          66 :   if (err)
     771           0 :     goto leave;
     772          66 :   err = create_blob_finish (blob);
     773          66 :   if (err)
     774           0 :     goto leave;
     775             : 
     776             :  leave:
     777          66 :   release_kid_list (blob->temp_kids);
     778          66 :   blob->temp_kids = NULL;
     779          66 :   if (err)
     780           0 :     _keybox_release_blob (blob);
     781             :   else
     782          66 :     *r_blob = blob;
     783          66 :   return err;
     784             : }
     785             : 
     786             : 
     787             : #ifdef KEYBOX_WITH_X509
     788             : 
     789             : /* Return an allocated string with the email address extracted from a
     790             :    DN.  Note hat we use this code also in ../sm/keylist.c.  */
     791             : static char *
     792           3 : x509_email_kludge (const char *name)
     793             : {
     794             :   const char *p, *string;
     795             :   unsigned char *buf;
     796             :   int n;
     797             : 
     798           3 :   string = name;
     799             :   for (;;)
     800             :     {
     801           3 :       p = strstr (string, "1.2.840.113549.1.9.1=#");
     802           3 :       if (!p)
     803           1 :         return NULL;
     804           2 :       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
     805             :         {
     806           2 :           name = p + 22;
     807           2 :           break;
     808             :         }
     809           0 :       string = p + 22;
     810           0 :     }
     811             : 
     812             : 
     813             :   /* This looks pretty much like an email address in the subject's DN
     814             :      we use this to add an additional user ID entry.  This way,
     815             :      OpenSSL generated keys get a nicer and usable listing.  */
     816           2 :   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
     817             :     ;
     818           2 :   if (!n)
     819           0 :     return NULL;
     820           2 :   buf = xtrymalloc (n+3);
     821           2 :   if (!buf)
     822           0 :     return NULL; /* oops, out of core */
     823           2 :   *buf = '<';
     824          73 :   for (n=1, p=name; hexdigitp (p); p +=2, n++)
     825          71 :     buf[n] = xtoi_2 (p);
     826           2 :   buf[n++] = '>';
     827           2 :   buf[n] = 0;
     828           2 :   return (char*)buf;
     829             : }
     830             : 
     831             : 
     832             : 
     833             : /* Note: We should move calculation of the digest into libksba and
     834             :    remove that parameter */
     835             : int
     836           3 : _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
     837             :                           unsigned char *sha1_digest, int as_ephemeral)
     838             : {
     839           3 :   int i, rc = 0;
     840             :   KEYBOXBLOB blob;
     841             :   unsigned char *sn;
     842             :   char *p;
     843           3 :   char **names = NULL;
     844             :   size_t max_names;
     845             : 
     846           3 :   *r_blob = NULL;
     847           3 :   blob = xtrycalloc (1, sizeof *blob);
     848           3 :   if( !blob )
     849           0 :     return gpg_error_from_syserror ();
     850             : 
     851           3 :   sn = ksba_cert_get_serial (cert);
     852           3 :   if (sn)
     853             :     {
     854             :       size_t n, len;
     855           3 :       n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
     856           3 :       if (n < 2)
     857             :         {
     858           0 :           xfree (sn);
     859           0 :           return gpg_error (GPG_ERR_GENERAL);
     860             :         }
     861           3 :       blob->serialbuf = sn;
     862           3 :       sn++; n--; /* skip '(' */
     863           6 :       for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
     864           3 :         len = len*10 + atoi_1 (sn);
     865           3 :       if (*sn != ':')
     866             :         {
     867           0 :           xfree (blob->serialbuf);
     868           0 :           blob->serialbuf = NULL;
     869           0 :           return gpg_error (GPG_ERR_GENERAL);
     870             :         }
     871           3 :       sn++;
     872           3 :       blob->serial = sn;
     873           3 :       blob->seriallen = len;
     874             :     }
     875             : 
     876           3 :   blob->nkeys = 1;
     877             : 
     878             :   /* create list of names */
     879           3 :   blob->nuids = 0;
     880           3 :   max_names = 100;
     881           3 :   names = xtrymalloc (max_names * sizeof *names);
     882           3 :   if (!names)
     883             :     {
     884           0 :       rc = gpg_error_from_syserror ();
     885           0 :       goto leave;
     886             :     }
     887             : 
     888           3 :   p = ksba_cert_get_issuer (cert, 0);
     889           3 :   if (!p)
     890             :     {
     891           0 :       rc =  gpg_error (GPG_ERR_MISSING_VALUE);
     892           0 :       goto leave;
     893             :     }
     894           3 :   names[blob->nuids++] = p;
     895           6 :   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
     896             :     {
     897           3 :       if (blob->nuids >= max_names)
     898             :         {
     899             :           char **tmp;
     900             : 
     901           0 :           max_names += 100;
     902           0 :           tmp = xtryrealloc (names, max_names * sizeof *names);
     903           0 :           if (!tmp)
     904             :             {
     905           0 :               rc = gpg_error_from_syserror ();
     906           0 :               goto leave;
     907             :             }
     908           0 :           names = tmp;
     909             :         }
     910           3 :       names[blob->nuids++] = p;
     911           3 :       if (!i && (p=x509_email_kludge (p)))
     912           2 :         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
     913             :     }
     914             : 
     915             :   /* space for signature information */
     916           3 :   blob->nsigs = 1;
     917             : 
     918           3 :   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
     919           3 :   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
     920           3 :   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
     921           3 :   if (!blob->keys || !blob->uids || !blob->sigs)
     922             :     {
     923           0 :       rc = gpg_error (GPG_ERR_ENOMEM);
     924           0 :       goto leave;
     925             :     }
     926             : 
     927           3 :   memcpy (blob->keys[0].fpr, sha1_digest, 20);
     928           3 :   blob->keys[0].off_kid = 0; /* We don't have keyids */
     929           3 :   blob->keys[0].flags = 0;
     930             : 
     931             :   /* issuer and subject names */
     932          11 :   for (i=0; i < blob->nuids; i++)
     933             :     {
     934           8 :       blob->uids[i].name = names[i];
     935           8 :       blob->uids[i].len = strlen(names[i]);
     936           8 :       names[i] = NULL;
     937           8 :       blob->uids[i].flags = 0;
     938           8 :       blob->uids[i].validity = 0;
     939             :     }
     940           3 :   xfree (names);
     941           3 :   names = NULL;
     942             : 
     943             :   /* signatures */
     944           3 :   blob->sigs[0] = 0; /* not yet checked */
     945             : 
     946             :   /* Create a temporary buffer for further processing */
     947           3 :   init_membuf (&blob->bufbuf, 1024);
     948           3 :   blob->buf = &blob->bufbuf;
     949             :   /* write out what we already have */
     950           3 :   rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral);
     951           3 :   if (rc)
     952           0 :     goto leave;
     953           3 :   rc = x509_create_blob_cert (blob, cert);
     954           3 :   if (rc)
     955           0 :     goto leave;
     956           3 :   rc = create_blob_trailer (blob);
     957           3 :   if (rc)
     958           0 :     goto leave;
     959           3 :   rc = create_blob_finish ( blob );
     960           3 :   if (rc)
     961           0 :     goto leave;
     962             : 
     963             : 
     964             :  leave:
     965           3 :   release_kid_list (blob->temp_kids);
     966           3 :   blob->temp_kids = NULL;
     967           3 :   if (names)
     968             :     {
     969           0 :       for (i=0; i < blob->nuids; i++)
     970           0 :         xfree (names[i]);
     971           0 :       xfree (names);
     972             :     }
     973           3 :   if (rc)
     974             :     {
     975           0 :       _keybox_release_blob (blob);
     976           0 :       *r_blob = NULL;
     977             :     }
     978             :   else
     979             :     {
     980           3 :       *r_blob = blob;
     981             :     }
     982           3 :   return rc;
     983             : }
     984             : #endif /*KEYBOX_WITH_X509*/
     985             : 
     986             : 
     987             : 
     988             : int
     989       81041 : _keybox_new_blob (KEYBOXBLOB *r_blob,
     990             :                   unsigned char *image, size_t imagelen, off_t off)
     991             : {
     992             :   KEYBOXBLOB blob;
     993             : 
     994       81041 :   *r_blob = NULL;
     995       81041 :   blob = xtrycalloc (1, sizeof *blob);
     996       81041 :   if (!blob)
     997           0 :     return gpg_error_from_syserror ();
     998             : 
     999       81041 :   blob->blob = image;
    1000       81041 :   blob->bloblen = imagelen;
    1001       81041 :   blob->fileoffset = off;
    1002       81041 :   *r_blob = blob;
    1003       81041 :   return 0;
    1004             : }
    1005             : 
    1006             : 
    1007             : void
    1008       86937 : _keybox_release_blob (KEYBOXBLOB blob)
    1009             : {
    1010             :   int i;
    1011       86937 :   if (!blob)
    1012       92764 :     return;
    1013       81110 :   if (blob->buf)
    1014             :     {
    1015             :       size_t len;
    1016          69 :       xfree (get_membuf (blob->buf, &len));
    1017             :     }
    1018       81110 :   xfree (blob->keys );
    1019       81110 :   xfree (blob->serialbuf);
    1020       81198 :   for (i=0; i < blob->nuids; i++)
    1021          88 :     xfree (blob->uids[i].name);
    1022       81110 :   xfree (blob->uids );
    1023       81110 :   xfree (blob->sigs );
    1024       81110 :   xfree (blob->blob );
    1025       81110 :   xfree (blob );
    1026             : }
    1027             : 
    1028             : 
    1029             : 
    1030             : const unsigned char *
    1031      248007 : _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
    1032             : {
    1033      248007 :   *n = blob->bloblen;
    1034      248007 :   return blob->blob;
    1035             : }
    1036             : 
    1037             : off_t
    1038           5 : _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
    1039             : {
    1040           5 :   return blob->fileoffset;
    1041             : }
    1042             : 
    1043             : 
    1044             : 
    1045             : void
    1046           0 : _keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp)
    1047             : {
    1048           0 :   if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER)
    1049             :     {
    1050           0 :       u32 val = make_timestamp ();
    1051             : 
    1052             :       /* Update the last maintenance run times tamp. */
    1053           0 :       blob->blob[20]   = (val >> 24);
    1054           0 :       blob->blob[20+1] = (val >> 16);
    1055           0 :       blob->blob[20+2] = (val >>  8);
    1056           0 :       blob->blob[20+3] = (val      );
    1057             : 
    1058           0 :       if (for_openpgp)
    1059           0 :         blob->blob[7] |= 0x02;  /* OpenPGP data may be available.  */
    1060             :     }
    1061           0 : }

Generated by: LCOV version 1.11