LCOV - code coverage report
Current view: top level - dirmngr - certcache.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 616 0.0 %
Date: 2015-11-05 17:10:59 Functions: 0 26 0.0 %

          Line data    Source code
       1             : /* certcache.c - Certificate caching
       2             :  *      Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
       3             :  *
       4             :  * This file is part of DirMngr.
       5             :  *
       6             :  * DirMngr 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 2 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * DirMngr 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             : #include <config.h>
      21             : 
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <errno.h>
      25             : #include <assert.h>
      26             : #include <sys/types.h>
      27             : #include <dirent.h>
      28             : #include <npth.h>
      29             : 
      30             : #include "dirmngr.h"
      31             : #include "misc.h"
      32             : #include "crlfetch.h"
      33             : #include "certcache.h"
      34             : 
      35             : 
      36             : #define MAX_EXTRA_CACHED_CERTS 1000
      37             : 
      38             : /* Constants used to classify search patterns.  */
      39             : enum pattern_class
      40             :   {
      41             :     PATTERN_UNKNOWN = 0,
      42             :     PATTERN_EMAIL,
      43             :     PATTERN_EMAIL_SUBSTR,
      44             :     PATTERN_FINGERPRINT16,
      45             :     PATTERN_FINGERPRINT20,
      46             :     PATTERN_SHORT_KEYID,
      47             :     PATTERN_LONG_KEYID,
      48             :     PATTERN_SUBJECT,
      49             :     PATTERN_SERIALNO,
      50             :     PATTERN_SERIALNO_ISSUER,
      51             :     PATTERN_ISSUER,
      52             :     PATTERN_SUBSTR
      53             :   };
      54             : 
      55             : 
      56             : /* A certificate cache item.  This consists of a the KSBA cert object
      57             :    and some meta data for easier lookup.  We use a hash table to keep
      58             :    track of all items and use the (randomly distributed) first byte of
      59             :    the fingerprint directly as the hash which makes it pretty easy. */
      60             : struct cert_item_s
      61             : {
      62             :   struct cert_item_s *next; /* Next item with the same hash value. */
      63             :   ksba_cert_t cert;         /* The KSBA cert object or NULL is this is
      64             :                                not a valid item.  */
      65             :   unsigned char fpr[20];    /* The fingerprint of this object. */
      66             :   char *issuer_dn;          /* The malloced issuer DN.  */
      67             :   ksba_sexp_t sn;           /* The malloced serial number  */
      68             :   char *subject_dn;         /* The malloced subject DN - maybe NULL.  */
      69             :   struct
      70             :   {
      71             :     unsigned int loaded:1;  /* It has been explicitly loaded.  */
      72             :     unsigned int trusted:1; /* This is a trusted root certificate.  */
      73             :   } flags;
      74             : };
      75             : typedef struct cert_item_s *cert_item_t;
      76             : 
      77             : /* The actual cert cache consisting of 256 slots for items indexed by
      78             :    the first byte of the fingerprint.  */
      79             : static cert_item_t cert_cache[256];
      80             : 
      81             : /* This is the global cache_lock variable. In general locking is not
      82             :    needed but it would take extra efforts to make sure that no
      83             :    indirect use of npth functions is done, so we simply lock it
      84             :    always.  Note: We can't use static initialization, as that is not
      85             :    available through w32-pth.  */
      86             : static npth_rwlock_t cert_cache_lock;
      87             : 
      88             : /* Flag to track whether the cache has been initialized.  */
      89             : static int initialization_done;
      90             : 
      91             : /* Total number of certificates loaded during initialization and
      92             :    cached during operation.  */
      93             : static unsigned int total_loaded_certificates;
      94             : static unsigned int total_extra_certificates;
      95             : 
      96             : 
      97             : 
      98             : /* Helper to do the cache locking.  */
      99             : static void
     100           0 : init_cache_lock (void)
     101             : {
     102             :   int err;
     103             : 
     104           0 :   err = npth_rwlock_init (&cert_cache_lock, NULL);
     105           0 :   if (err)
     106           0 :     log_fatal (_("can't initialize certificate cache lock: %s\n"),
     107             :                strerror (err));
     108           0 : }
     109             : 
     110             : static void
     111           0 : acquire_cache_read_lock (void)
     112             : {
     113             :   int err;
     114             : 
     115           0 :   err = npth_rwlock_rdlock (&cert_cache_lock);
     116           0 :   if (err)
     117           0 :     log_fatal (_("can't acquire read lock on the certificate cache: %s\n"),
     118             :                strerror (err));
     119           0 : }
     120             : 
     121             : static void
     122           0 : acquire_cache_write_lock (void)
     123             : {
     124             :   int err;
     125             : 
     126           0 :   err = npth_rwlock_wrlock (&cert_cache_lock);
     127           0 :   if (err)
     128           0 :     log_fatal (_("can't acquire write lock on the certificate cache: %s\n"),
     129             :                strerror (err));
     130           0 : }
     131             : 
     132             : static void
     133           0 : release_cache_lock (void)
     134             : {
     135             :   int err;
     136             : 
     137           0 :   err = npth_rwlock_unlock (&cert_cache_lock);
     138           0 :   if (err)
     139           0 :     log_fatal (_("can't release lock on the certificate cache: %s\n"),
     140             :                strerror (err));
     141           0 : }
     142             : 
     143             : 
     144             : /* Return false if both serial numbers match.  Can't be used for
     145             :    sorting. */
     146             : static int
     147           0 : compare_serialno (ksba_sexp_t serial1, ksba_sexp_t serial2 )
     148             : {
     149           0 :   unsigned char *a = serial1;
     150           0 :   unsigned char *b = serial2;
     151           0 :   return cmp_simple_canon_sexp (a, b);
     152             : }
     153             : 
     154             : 
     155             : 
     156             : /* Return a malloced canonical S-Expression with the serial number
     157             :    converted from the hex string HEXSN.  Return NULL on memory
     158             :    error. */
     159             : ksba_sexp_t
     160           0 : hexsn_to_sexp (const char *hexsn)
     161             : {
     162             :   char *buffer, *p;
     163             :   size_t len;
     164             :   char numbuf[40];
     165             : 
     166           0 :   len = unhexify (NULL, hexsn);
     167           0 :   snprintf (numbuf, sizeof numbuf, "(%u:", (unsigned int)len);
     168           0 :   buffer = xtrymalloc (strlen (numbuf) + len + 2 );
     169           0 :   if (!buffer)
     170           0 :     return NULL;
     171           0 :   p = stpcpy (buffer, numbuf);
     172           0 :   len = unhexify (p, hexsn);
     173           0 :   p[len] = ')';
     174           0 :   p[len+1] = 0;
     175             : 
     176           0 :   return buffer;
     177             : }
     178             : 
     179             : 
     180             : /* Compute the fingerprint of the certificate CERT and put it into
     181             :    the 20 bytes large buffer DIGEST.  Return address of this buffer.  */
     182             : unsigned char *
     183           0 : cert_compute_fpr (ksba_cert_t cert, unsigned char *digest)
     184             : {
     185             :   gpg_error_t err;
     186             :   gcry_md_hd_t md;
     187             : 
     188           0 :   err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
     189           0 :   if (err)
     190           0 :     log_fatal ("gcry_md_open failed: %s\n", gpg_strerror (err));
     191             : 
     192           0 :   err = ksba_cert_hash (cert, 0, HASH_FNC, md);
     193           0 :   if (err)
     194             :     {
     195           0 :       log_error ("oops: ksba_cert_hash failed: %s\n", gpg_strerror (err));
     196           0 :       memset (digest, 0xff, 20); /* Use a dummy value. */
     197             :     }
     198             :   else
     199             :     {
     200           0 :       gcry_md_final (md);
     201           0 :       memcpy (digest, gcry_md_read (md, GCRY_MD_SHA1), 20);
     202             :     }
     203           0 :   gcry_md_close (md);
     204           0 :   return digest;
     205             : }
     206             : 
     207             : 
     208             : /* Cleanup one slot.  This releases all resourses but keeps the actual
     209             :    slot in the cache marked for reuse. */
     210             : static void
     211           0 : clean_cache_slot (cert_item_t ci)
     212             : {
     213             :   ksba_cert_t cert;
     214             : 
     215           0 :   if (!ci->cert)
     216           0 :     return; /* Already cleaned.  */
     217             : 
     218           0 :   ksba_free (ci->sn);
     219           0 :   ci->sn = NULL;
     220           0 :   ksba_free (ci->issuer_dn);
     221           0 :   ci->issuer_dn = NULL;
     222           0 :   ksba_free (ci->subject_dn);
     223           0 :   ci->subject_dn = NULL;
     224           0 :   cert = ci->cert;
     225           0 :   ci->cert = NULL;
     226             : 
     227           0 :   ksba_cert_release (cert);
     228             : }
     229             : 
     230             : 
     231             : /* Put the certificate CERT into the cache.  It is assumed that the
     232             :    cache is locked while this function is called. If FPR_BUFFER is not
     233             :    NULL the fingerprint of the certificate will be stored there.
     234             :    FPR_BUFFER neds to point to a buffer of at least 20 bytes. The
     235             :    fingerprint will be stored on success or when the function returns
     236             :    gpg_err_code(GPG_ERR_DUP_VALUE). */
     237             : static gpg_error_t
     238           0 : put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer)
     239             : {
     240             :   unsigned char help_fpr_buffer[20], *fpr;
     241             :   cert_item_t ci;
     242             : 
     243           0 :   fpr = fpr_buffer? fpr_buffer : &help_fpr_buffer;
     244             : 
     245             :   /* If we already reached the caching limit, drop a couple of certs
     246             :      from the cache.  Our dropping strategy is simple: We keep a
     247             :      static index counter and use this to start looking for
     248             :      certificates, then we drop 5 percent of the oldest certificates
     249             :      starting at that index.  For a large cache this is a fair way of
     250             :      removing items. An LRU strategy would be better of course.
     251             :      Because we append new entries to the head of the list and we want
     252             :      to remove old ones first, we need to do this from the tail.  The
     253             :      implementation is not very efficient but compared to the long
     254             :      time it takes to retrieve a certifciate from an external resource
     255             :      it seems to be reasonable. */
     256           0 :   if (!is_loaded && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS)
     257             :     {
     258             :       static int idx;
     259             :       cert_item_t ci_mark;
     260             :       int i;
     261             :       unsigned int drop_count;
     262             : 
     263           0 :       drop_count = MAX_EXTRA_CACHED_CERTS / 20;
     264           0 :       if (drop_count < 2)
     265           0 :         drop_count = 2;
     266             : 
     267           0 :       log_info (_("dropping %u certificates from the cache\n"), drop_count);
     268           0 :       assert (idx < 256);
     269           0 :       for (i=idx; drop_count; i = ((i+1)%256))
     270             :         {
     271           0 :           ci_mark = NULL;
     272           0 :           for (ci = cert_cache[i]; ci; ci = ci->next)
     273           0 :             if (ci->cert && !ci->flags.loaded)
     274           0 :               ci_mark = ci;
     275           0 :           if (ci_mark)
     276             :             {
     277           0 :               clean_cache_slot (ci_mark);
     278           0 :               drop_count--;
     279           0 :               total_extra_certificates--;
     280             :             }
     281             :         }
     282           0 :       if (i==idx)
     283           0 :         idx++;
     284             :       else
     285           0 :         idx = i;
     286           0 :       idx %= 256;
     287             :     }
     288             : 
     289           0 :   cert_compute_fpr (cert, fpr);
     290           0 :   for (ci=cert_cache[*fpr]; ci; ci = ci->next)
     291           0 :     if (ci->cert && !memcmp (ci->fpr, fpr, 20))
     292           0 :       return gpg_error (GPG_ERR_DUP_VALUE);
     293             :   /* Try to reuse an existing entry.  */
     294           0 :   for (ci=cert_cache[*fpr]; ci; ci = ci->next)
     295           0 :     if (!ci->cert)
     296           0 :       break;
     297           0 :   if (!ci)
     298             :     { /* No: Create a new entry.  */
     299           0 :       ci = xtrycalloc (1, sizeof *ci);
     300           0 :       if (!ci)
     301           0 :         return gpg_error_from_errno (errno);
     302           0 :       ci->next = cert_cache[*fpr];
     303           0 :       cert_cache[*fpr] = ci;
     304             :     }
     305             :   else
     306           0 :     memset (&ci->flags, 0, sizeof ci->flags);
     307             : 
     308           0 :   ksba_cert_ref (cert);
     309           0 :   ci->cert = cert;
     310           0 :   memcpy (ci->fpr, fpr, 20);
     311           0 :   ci->sn = ksba_cert_get_serial (cert);
     312           0 :   ci->issuer_dn = ksba_cert_get_issuer (cert, 0);
     313           0 :   if (!ci->issuer_dn || !ci->sn)
     314             :     {
     315           0 :       clean_cache_slot (ci);
     316           0 :       return gpg_error (GPG_ERR_INV_CERT_OBJ);
     317             :     }
     318           0 :   ci->subject_dn = ksba_cert_get_subject (cert, 0);
     319           0 :   ci->flags.loaded  = !!is_loaded;
     320           0 :   ci->flags.trusted = !!is_trusted;
     321             : 
     322           0 :   if (is_loaded)
     323           0 :     total_loaded_certificates++;
     324             :   else
     325           0 :     total_extra_certificates++;
     326             : 
     327           0 :   return 0;
     328             : }
     329             : 
     330             : 
     331             : /* Load certificates from the directory DIRNAME.  All certificates
     332             :    matching the pattern "*.crt" or "*.der"  are loaded.  We assume that
     333             :    certificates are DER encoded and not PEM encapsulated. The cache
     334             :    should be in a locked state when calling this fucntion.  */
     335             : static gpg_error_t
     336           0 : load_certs_from_dir (const char *dirname, int are_trusted)
     337             : {
     338             :   gpg_error_t err;
     339             :   DIR *dir;
     340             :   struct dirent *ep;
     341             :   char *p;
     342             :   size_t n;
     343             :   estream_t fp;
     344             :   ksba_reader_t reader;
     345             :   ksba_cert_t cert;
     346           0 :   char *fname = NULL;
     347             : 
     348           0 :   dir = opendir (dirname);
     349           0 :   if (!dir)
     350             :     {
     351           0 :       if (opt.system_daemon)
     352           0 :         log_info (_("can't access directory '%s': %s\n"),
     353           0 :                   dirname, strerror (errno));
     354           0 :       return 0; /* We do not consider this a severe error.  */
     355             :     }
     356             : 
     357           0 :   while ( (ep=readdir (dir)) )
     358             :     {
     359           0 :       p = ep->d_name;
     360           0 :       if (*p == '.' || !*p)
     361           0 :         continue; /* Skip any hidden files and invalid entries.  */
     362           0 :       n = strlen (p);
     363           0 :       if ( n < 5 || (strcmp (p+n-4,".crt") && strcmp (p+n-4,".der")))
     364           0 :         continue; /* Not the desired "*.crt" or "*.der" pattern.  */
     365             : 
     366           0 :       xfree (fname);
     367           0 :       fname = make_filename (dirname, p, NULL);
     368           0 :       fp = es_fopen (fname, "rb");
     369           0 :       if (!fp)
     370             :         {
     371           0 :           log_error (_("can't open '%s': %s\n"),
     372           0 :                      fname, strerror (errno));
     373           0 :           continue;
     374             :         }
     375             : 
     376           0 :       err = create_estream_ksba_reader (&reader, fp);
     377           0 :       if (err)
     378             :         {
     379           0 :           es_fclose (fp);
     380           0 :           continue;
     381             :         }
     382             : 
     383           0 :       err = ksba_cert_new (&cert);
     384           0 :       if (!err)
     385           0 :         err = ksba_cert_read_der (cert, reader);
     386           0 :       ksba_reader_release (reader);
     387           0 :       es_fclose (fp);
     388           0 :       if (err)
     389             :         {
     390           0 :           log_error (_("can't parse certificate '%s': %s\n"),
     391             :                      fname, gpg_strerror (err));
     392           0 :           ksba_cert_release (cert);
     393           0 :           continue;
     394             :         }
     395             : 
     396           0 :       err = put_cert (cert, 1, are_trusted, NULL);
     397           0 :       if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
     398           0 :         log_info (_("certificate '%s' already cached\n"), fname);
     399           0 :       else if (!err)
     400             :         {
     401           0 :           if (are_trusted)
     402           0 :             log_info (_("trusted certificate '%s' loaded\n"), fname);
     403             :           else
     404           0 :             log_info (_("certificate '%s' loaded\n"), fname);
     405           0 :           if (opt.verbose)
     406             :             {
     407           0 :               p = get_fingerprint_hexstring_colon (cert);
     408           0 :               log_info (_("  SHA1 fingerprint = %s\n"), p);
     409           0 :               xfree (p);
     410             : 
     411           0 :               cert_log_name (_("   issuer ="), cert);
     412           0 :               cert_log_subject (_("  subject ="), cert);
     413             :             }
     414             :         }
     415             :       else
     416           0 :         log_error (_("error loading certificate '%s': %s\n"),
     417             :                      fname, gpg_strerror (err));
     418           0 :       ksba_cert_release (cert);
     419             :     }
     420             : 
     421           0 :   xfree (fname);
     422           0 :   closedir (dir);
     423           0 :   return 0;
     424             : }
     425             : 
     426             : 
     427             : /* Initialize the certificate cache if not yet done.  */
     428             : void
     429           0 : cert_cache_init (void)
     430             : {
     431             :   char *dname;
     432             : 
     433           0 :   if (initialization_done)
     434           0 :     return;
     435           0 :   init_cache_lock ();
     436           0 :   acquire_cache_write_lock ();
     437             : 
     438           0 :   dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL);
     439           0 :   load_certs_from_dir (dname, 1);
     440           0 :   xfree (dname);
     441             : 
     442           0 :   dname = make_filename (gnupg_sysconfdir (), "extra-certs", NULL);
     443           0 :   load_certs_from_dir (dname, 0);
     444           0 :   xfree (dname);
     445             : 
     446           0 :   initialization_done = 1;
     447           0 :   release_cache_lock ();
     448             : 
     449           0 :   cert_cache_print_stats ();
     450             : }
     451             : 
     452             : /* Deinitialize the certificate cache.  With FULL set to true even the
     453             :    unused certificate slots are released. */
     454             : void
     455           0 : cert_cache_deinit (int full)
     456             : {
     457             :   cert_item_t ci, ci2;
     458             :   int i;
     459             : 
     460           0 :   if (!initialization_done)
     461           0 :     return;
     462             : 
     463           0 :   acquire_cache_write_lock ();
     464             : 
     465           0 :   for (i=0; i < 256; i++)
     466           0 :     for (ci=cert_cache[i]; ci; ci = ci->next)
     467           0 :       clean_cache_slot (ci);
     468             : 
     469           0 :   if (full)
     470             :     {
     471           0 :       for (i=0; i < 256; i++)
     472             :         {
     473           0 :           for (ci=cert_cache[i]; ci; ci = ci2)
     474             :             {
     475           0 :               ci2 = ci->next;
     476           0 :               xfree (ci);
     477             :             }
     478           0 :           cert_cache[i] = NULL;
     479             :         }
     480             :     }
     481             : 
     482           0 :   total_loaded_certificates = 0;
     483           0 :   total_extra_certificates = 0;
     484           0 :   initialization_done = 0;
     485           0 :   release_cache_lock ();
     486             : }
     487             : 
     488             : /* Print some statistics to the log file.  */
     489             : void
     490           0 : cert_cache_print_stats (void)
     491             : {
     492           0 :   log_info (_("permanently loaded certificates: %u\n"),
     493             :             total_loaded_certificates);
     494           0 :   log_info (_("    runtime cached certificates: %u\n"),
     495             :             total_extra_certificates);
     496           0 : }
     497             : 
     498             : 
     499             : /* Put CERT into the certificate cache.  */
     500             : gpg_error_t
     501           0 : cache_cert (ksba_cert_t cert)
     502             : {
     503             :   gpg_error_t err;
     504             : 
     505           0 :   acquire_cache_write_lock ();
     506           0 :   err = put_cert (cert, 0, 0, NULL);
     507           0 :   release_cache_lock ();
     508           0 :   if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
     509           0 :     log_info (_("certificate already cached\n"));
     510           0 :   else if (!err)
     511           0 :     log_info (_("certificate cached\n"));
     512             :   else
     513           0 :     log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
     514           0 :   return err;
     515             : }
     516             : 
     517             : 
     518             : /* Put CERT into the certificate cache and store the fingerprint of
     519             :    the certificate into FPR_BUFFER.  If the certificate is already in
     520             :    the cache do not print a warning; just store the
     521             :    fingerprint. FPR_BUFFER needs to be at least 20 bytes. */
     522             : gpg_error_t
     523           0 : cache_cert_silent (ksba_cert_t cert, void *fpr_buffer)
     524             : {
     525             :   gpg_error_t err;
     526             : 
     527           0 :   acquire_cache_write_lock ();
     528           0 :   err = put_cert (cert, 0, 0, fpr_buffer);
     529           0 :   release_cache_lock ();
     530           0 :   if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
     531           0 :     err = 0;
     532           0 :   if (err)
     533           0 :     log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
     534           0 :   return err;
     535             : }
     536             : 
     537             : 
     538             : 
     539             : /* Return a certificate object for the given fingerprint.  FPR is
     540             :    expected to be a 20 byte binary SHA-1 fingerprint.  If no matching
     541             :    certificate is available in the cache NULL is returned.  The caller
     542             :    must release a returned certificate.  Note that although we are
     543             :    using reference counting the caller should not just compare the
     544             :    pointers to check for identical certificates. */
     545             : ksba_cert_t
     546           0 : get_cert_byfpr (const unsigned char *fpr)
     547             : {
     548             :   cert_item_t ci;
     549             : 
     550           0 :   acquire_cache_read_lock ();
     551           0 :   for (ci=cert_cache[*fpr]; ci; ci = ci->next)
     552           0 :     if (ci->cert && !memcmp (ci->fpr, fpr, 20))
     553             :       {
     554           0 :         ksba_cert_ref (ci->cert);
     555           0 :         release_cache_lock ();
     556           0 :         return ci->cert;
     557             :       }
     558             : 
     559           0 :   release_cache_lock ();
     560           0 :   return NULL;
     561             : }
     562             : 
     563             : /* Return a certificate object for the given fingerprint.  STRING is
     564             :    expected to be a SHA-1 fingerprint in standard hex notation with or
     565             :    without colons.  If no matching certificate is available in the
     566             :    cache NULL is returned.  The caller must release a returned
     567             :    certificate.  Note that although we are using reference counting
     568             :    the caller should not just compare the pointers to check for
     569             :    identical certificates. */
     570             : ksba_cert_t
     571           0 : get_cert_byhexfpr (const char *string)
     572             : {
     573             :   unsigned char fpr[20];
     574             :   const char *s;
     575             :   int i;
     576             : 
     577           0 :   if (strchr (string, ':'))
     578             :     {
     579           0 :       for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1);)
     580             :         {
     581           0 :           if (s[2] && s[2] != ':')
     582           0 :             break; /* Invalid string. */
     583           0 :           fpr[i++] = xtoi_2 (s);
     584           0 :           s += 2;
     585           0 :           if (i!= 20 && *s == ':')
     586           0 :             s++;
     587             :         }
     588             :     }
     589             :   else
     590             :     {
     591           0 :       for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1); s+=2 )
     592           0 :         fpr[i++] = xtoi_2 (s);
     593             :     }
     594           0 :   if (i!=20 || *s)
     595             :     {
     596           0 :       log_error (_("invalid SHA1 fingerprint string '%s'\n"), string);
     597           0 :       return NULL;
     598             :     }
     599             : 
     600           0 :   return get_cert_byfpr (fpr);
     601             : }
     602             : 
     603             : 
     604             : 
     605             : /* Return the certificate matching ISSUER_DN and SERIALNO.  */
     606             : ksba_cert_t
     607           0 : get_cert_bysn (const char *issuer_dn, ksba_sexp_t serialno)
     608             : {
     609             :   /* Simple and inefficient implementation.   fixme! */
     610             :   cert_item_t ci;
     611             :   int i;
     612             : 
     613           0 :   acquire_cache_read_lock ();
     614           0 :   for (i=0; i < 256; i++)
     615             :     {
     616           0 :       for (ci=cert_cache[i]; ci; ci = ci->next)
     617           0 :         if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn)
     618           0 :             && !compare_serialno (ci->sn, serialno))
     619             :           {
     620           0 :             ksba_cert_ref (ci->cert);
     621           0 :             release_cache_lock ();
     622           0 :             return ci->cert;
     623             :           }
     624             :     }
     625             : 
     626           0 :   release_cache_lock ();
     627           0 :   return NULL;
     628             : }
     629             : 
     630             : 
     631             : /* Return the certificate matching ISSUER_DN.  SEQ should initially be
     632             :    set to 0 and bumped up to get the next issuer with that DN. */
     633             : ksba_cert_t
     634           0 : get_cert_byissuer (const char *issuer_dn, unsigned int seq)
     635             : {
     636             :   /* Simple and very inefficient implementation and API.  fixme! */
     637             :   cert_item_t ci;
     638             :   int i;
     639             : 
     640           0 :   acquire_cache_read_lock ();
     641           0 :   for (i=0; i < 256; i++)
     642             :     {
     643           0 :       for (ci=cert_cache[i]; ci; ci = ci->next)
     644           0 :         if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn))
     645           0 :           if (!seq--)
     646             :             {
     647           0 :               ksba_cert_ref (ci->cert);
     648           0 :               release_cache_lock ();
     649           0 :               return ci->cert;
     650             :             }
     651             :     }
     652             : 
     653           0 :   release_cache_lock ();
     654           0 :   return NULL;
     655             : }
     656             : 
     657             : 
     658             : /* Return the certificate matching SUBJECT_DN.  SEQ should initially be
     659             :    set to 0 and bumped up to get the next subject with that DN. */
     660             : ksba_cert_t
     661           0 : get_cert_bysubject (const char *subject_dn, unsigned int seq)
     662             : {
     663             :   /* Simple and very inefficient implementation and API.  fixme! */
     664             :   cert_item_t ci;
     665             :   int i;
     666             : 
     667           0 :   if (!subject_dn)
     668           0 :     return NULL;
     669             : 
     670           0 :   acquire_cache_read_lock ();
     671           0 :   for (i=0; i < 256; i++)
     672             :     {
     673           0 :       for (ci=cert_cache[i]; ci; ci = ci->next)
     674           0 :         if (ci->cert && ci->subject_dn
     675           0 :             && !strcmp (ci->subject_dn, subject_dn))
     676           0 :           if (!seq--)
     677             :             {
     678           0 :               ksba_cert_ref (ci->cert);
     679           0 :               release_cache_lock ();
     680           0 :               return ci->cert;
     681             :             }
     682             :     }
     683             : 
     684           0 :   release_cache_lock ();
     685           0 :   return NULL;
     686             : }
     687             : 
     688             : 
     689             : 
     690             : /* Return a value decribing the the class of PATTERN.  The offset of
     691             :    the actual string to be used for the comparison is stored at
     692             :    R_OFFSET.  The offset of the serialnumer is stored at R_SN_OFFSET. */
     693             : static enum pattern_class
     694           0 : classify_pattern (const char *pattern, size_t *r_offset, size_t *r_sn_offset)
     695             : {
     696             :   enum pattern_class result;
     697             :   const char *s;
     698           0 :   int hexprefix = 0;
     699             :   int hexlength;
     700             : 
     701           0 :   *r_offset = *r_sn_offset = 0;
     702             : 
     703             :   /* Skip leading spaces. */
     704           0 :   for(s = pattern; *s && spacep (s); s++ )
     705             :     ;
     706             : 
     707           0 :   switch (*s)
     708             :     {
     709             :     case 0:  /* Empty string is an error. */
     710           0 :       result = PATTERN_UNKNOWN;
     711           0 :       break;
     712             : 
     713             :     case '.': /* An email address, compare from end.  */
     714           0 :       result = PATTERN_UNKNOWN;  /* Not implemented.  */
     715           0 :       break;
     716             : 
     717             :     case '<': /* An email address.  */
     718           0 :       result = PATTERN_EMAIL;
     719           0 :       s++;
     720           0 :       break;
     721             : 
     722             :     case '@': /* Part of an email address.  */
     723           0 :       result = PATTERN_EMAIL_SUBSTR;
     724           0 :       s++;
     725           0 :       break;
     726             : 
     727             :     case '=':  /* Exact compare. */
     728           0 :       result = PATTERN_UNKNOWN; /* Does not make sense for X.509.  */
     729           0 :       break;
     730             : 
     731             :     case '*':  /* Case insensitive substring search.  */
     732           0 :       result = PATTERN_SUBSTR;
     733           0 :       s++;
     734           0 :       break;
     735             : 
     736             :     case '+':  /* Compare individual words. */
     737           0 :       result = PATTERN_UNKNOWN;  /* Not implemented.  */
     738           0 :       break;
     739             : 
     740             :     case '/': /* Subject's DN. */
     741           0 :       s++;
     742           0 :       if (!*s || spacep (s))
     743           0 :         result = PATTERN_UNKNOWN; /* No DN or prefixed with a space. */
     744             :       else
     745           0 :         result = PATTERN_SUBJECT;
     746           0 :       break;
     747             : 
     748             :     case '#': /* Serial number or issuer DN. */
     749             :       {
     750             :         const char *si;
     751             : 
     752           0 :         s++;
     753           0 :         if ( *s == '/')
     754             :           {
     755             :             /* An issuer's DN is indicated by "#/" */
     756           0 :             s++;
     757           0 :             if (!*s || spacep (s))
     758           0 :               result = PATTERN_UNKNOWN; /* No DN or prefixed with a space. */
     759             :             else
     760           0 :               result = PATTERN_ISSUER;
     761             :           }
     762             :         else
     763             :           { /* Serialnumber + optional issuer ID. */
     764           0 :             for (si=s; *si && *si != '/'; si++)
     765           0 :               if (!strchr("01234567890abcdefABCDEF", *si))
     766           0 :                 break;
     767           0 :             if (*si && *si != '/')
     768           0 :               result = PATTERN_UNKNOWN; /* Invalid digit in serial number. */
     769             :             else
     770             :               {
     771           0 :                 *r_sn_offset = s - pattern;
     772           0 :                 if (!*si)
     773           0 :                   result = PATTERN_SERIALNO;
     774             :                 else
     775             :                   {
     776           0 :                     s = si+1;
     777           0 :                     if (!*s || spacep (s))
     778           0 :                       result = PATTERN_UNKNOWN; /* No DN or prefixed
     779             :                                                    with a space. */
     780             :                     else
     781           0 :                       result = PATTERN_SERIALNO_ISSUER;
     782             :                   }
     783             :               }
     784             :           }
     785             :       }
     786           0 :       break;
     787             : 
     788             :     case ':': /* Unified fingerprint. */
     789             :       {
     790             :         const char *se, *si;
     791             :         int i;
     792             : 
     793           0 :         se = strchr (++s, ':');
     794           0 :         if (!se)
     795           0 :           result = PATTERN_UNKNOWN;
     796             :         else
     797             :           {
     798           0 :             for (i=0, si=s; si < se; si++, i++ )
     799           0 :               if (!strchr("01234567890abcdefABCDEF", *si))
     800           0 :                 break;
     801           0 :             if ( si < se )
     802           0 :               result = PATTERN_UNKNOWN; /* Invalid digit. */
     803           0 :             else if (i == 32)
     804           0 :               result = PATTERN_FINGERPRINT16;
     805           0 :             else if (i == 40)
     806           0 :               result = PATTERN_FINGERPRINT20;
     807             :             else
     808           0 :               result = PATTERN_UNKNOWN; /* Invalid length for a fingerprint. */
     809             :           }
     810             :       }
     811           0 :       break;
     812             : 
     813             :     case '&': /* Keygrip. */
     814           0 :       result = PATTERN_UNKNOWN;  /* Not implemented.  */
     815           0 :       break;
     816             : 
     817             :     default:
     818           0 :       if (s[0] == '0' && s[1] == 'x')
     819             :         {
     820           0 :           hexprefix = 1;
     821           0 :           s += 2;
     822             :         }
     823             : 
     824           0 :       hexlength = strspn(s, "0123456789abcdefABCDEF");
     825             : 
     826             :       /* Check if a hexadecimal number is terminated by EOS or blank. */
     827           0 :       if (hexlength && s[hexlength] && !spacep (s+hexlength))
     828             :         {
     829             :           /* If the "0x" prefix is used a correct termination is required. */
     830           0 :           if (hexprefix)
     831             :             {
     832           0 :               result = PATTERN_UNKNOWN;
     833           0 :               break; /* switch */
     834             :             }
     835           0 :           hexlength = 0;  /* Not a hex number.  */
     836             :         }
     837             : 
     838           0 :       if (hexlength == 8 || (!hexprefix && hexlength == 9 && *s == '0'))
     839             :         {
     840           0 :           if (hexlength == 9)
     841           0 :             s++;
     842           0 :           result = PATTERN_SHORT_KEYID;
     843             :         }
     844           0 :       else if (hexlength == 16 || (!hexprefix && hexlength == 17 && *s == '0'))
     845             :         {
     846           0 :           if (hexlength == 17)
     847           0 :             s++;
     848           0 :           result = PATTERN_LONG_KEYID;
     849             :         }
     850           0 :       else if (hexlength == 32 || (!hexprefix && hexlength == 33 && *s == '0'))
     851             :         {
     852           0 :           if (hexlength == 33)
     853           0 :             s++;
     854           0 :           result = PATTERN_FINGERPRINT16;
     855             :         }
     856           0 :       else if (hexlength == 40 || (!hexprefix && hexlength == 41 && *s == '0'))
     857             :         {
     858           0 :           if (hexlength == 41)
     859           0 :             s++;
     860           0 :           result = PATTERN_FINGERPRINT20;
     861             :         }
     862           0 :       else if (!hexprefix)
     863             :         {
     864             :           /* The fingerprints used with X.509 are often delimited by
     865             :              colons, so we try to single this case out. */
     866           0 :           result = PATTERN_UNKNOWN;
     867           0 :           hexlength = strspn (s, ":0123456789abcdefABCDEF");
     868           0 :           if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength)))
     869             :             {
     870             :               int i, c;
     871             : 
     872           0 :               for (i=0; i < 20; i++, s += 3)
     873             :                 {
     874           0 :                   c = hextobyte(s);
     875           0 :                   if (c == -1 || (i < 19 && s[2] != ':'))
     876             :                     break;
     877             :                 }
     878           0 :               if (i == 20)
     879           0 :                 result = PATTERN_FINGERPRINT20;
     880             :             }
     881           0 :           if (result == PATTERN_UNKNOWN) /* Default to substring match. */
     882             :             {
     883           0 :               result = PATTERN_SUBSTR;
     884             :             }
     885             :         }
     886             :       else /* A hex number with a prefix but with a wrong length.  */
     887           0 :         result = PATTERN_UNKNOWN;
     888             :     }
     889             : 
     890           0 :   if (result != PATTERN_UNKNOWN)
     891           0 :     *r_offset = s - pattern;
     892           0 :   return result;
     893             : }
     894             : 
     895             : 
     896             : 
     897             : /* Given PATTERN, which is a string as used by GnuPG to specify a
     898             :    certificate, return all matching certificates by calling the
     899             :    supplied function RETFNC.  */
     900             : gpg_error_t
     901           0 : get_certs_bypattern (const char *pattern,
     902             :                      gpg_error_t (*retfnc)(void*,ksba_cert_t),
     903             :                      void *retfnc_data)
     904             : {
     905           0 :   gpg_error_t err = GPG_ERR_BUG;
     906             :   enum pattern_class class;
     907             :   size_t offset, sn_offset;
     908             :   const char *hexserialno;
     909           0 :   ksba_sexp_t serialno = NULL;
     910           0 :   ksba_cert_t cert = NULL;
     911             :   unsigned int seq;
     912             : 
     913           0 :   if (!pattern || !retfnc)
     914           0 :     return gpg_error (GPG_ERR_INV_ARG);
     915             : 
     916           0 :   class = classify_pattern (pattern, &offset, &sn_offset);
     917           0 :   hexserialno = pattern + sn_offset;
     918           0 :   pattern += offset;
     919           0 :   switch (class)
     920             :     {
     921             :     case PATTERN_UNKNOWN:
     922           0 :       err = gpg_error (GPG_ERR_INV_NAME);
     923           0 :       break;
     924             : 
     925             :     case PATTERN_FINGERPRINT20:
     926           0 :       cert = get_cert_byhexfpr (pattern);
     927           0 :       err = cert? 0 : gpg_error (GPG_ERR_NOT_FOUND);
     928           0 :       break;
     929             : 
     930             :     case PATTERN_SERIALNO_ISSUER:
     931           0 :       serialno = hexsn_to_sexp (hexserialno);
     932           0 :       if (!serialno)
     933           0 :         err = gpg_error_from_syserror ();
     934             :       else
     935             :         {
     936           0 :           cert = get_cert_bysn (pattern, serialno);
     937           0 :           err = cert? 0 : gpg_error (GPG_ERR_NOT_FOUND);
     938             :         }
     939           0 :       break;
     940             : 
     941             :     case PATTERN_ISSUER:
     942           0 :       for (seq=0,err=0; !err && (cert = get_cert_byissuer (pattern, seq)); seq++)
     943             :         {
     944           0 :           err = retfnc (retfnc_data, cert);
     945           0 :           ksba_cert_release (cert);
     946           0 :           cert = NULL;
     947             :         }
     948           0 :       if (!err && !seq)
     949           0 :         err = gpg_error (GPG_ERR_NOT_FOUND);
     950           0 :       break;
     951             : 
     952             :     case PATTERN_SUBJECT:
     953           0 :       for (seq=0,err=0; !err && (cert = get_cert_bysubject (pattern, seq));seq++)
     954             :         {
     955           0 :           err = retfnc (retfnc_data, cert);
     956           0 :           ksba_cert_release (cert);
     957           0 :           cert = NULL;
     958             :         }
     959           0 :       if (!err && !seq)
     960           0 :         err = gpg_error (GPG_ERR_NOT_FOUND);
     961           0 :       break;
     962             : 
     963             :     case PATTERN_EMAIL:
     964             :     case PATTERN_EMAIL_SUBSTR:
     965             :     case PATTERN_FINGERPRINT16:
     966             :     case PATTERN_SHORT_KEYID:
     967             :     case PATTERN_LONG_KEYID:
     968             :     case PATTERN_SUBSTR:
     969             :     case PATTERN_SERIALNO:
     970             :       /* Not supported.  */
     971           0 :       err = gpg_error (GPG_ERR_INV_NAME);
     972             :     }
     973             : 
     974             : 
     975           0 :   if (!err && cert)
     976           0 :     err = retfnc (retfnc_data, cert);
     977           0 :   ksba_cert_release (cert);
     978           0 :   xfree (serialno);
     979           0 :   return err;
     980             : }
     981             : 
     982             : 
     983             : 
     984             : 
     985             : 
     986             : /* Return the certificate matching ISSUER_DN and SERIALNO; if it is
     987             :    not already in the cache, try to find it from other resources.  */
     988             : ksba_cert_t
     989           0 : find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno)
     990             : {
     991             :   gpg_error_t err;
     992             :   ksba_cert_t cert;
     993           0 :   cert_fetch_context_t context = NULL;
     994             :   char *hexsn, *buf;
     995             : 
     996             :   /* First check whether it has already been cached.  */
     997           0 :   cert = get_cert_bysn (issuer_dn, serialno);
     998           0 :   if (cert)
     999           0 :     return cert;
    1000             : 
    1001             :   /* Ask back to the service requester to return the certificate.
    1002             :      This is because we can assume that he already used the
    1003             :      certificate while checking for the CRL. */
    1004           0 :   hexsn = serial_hex (serialno);
    1005           0 :   if (!hexsn)
    1006             :     {
    1007           0 :       log_error ("serial_hex() failed\n");
    1008           0 :       return NULL;
    1009             :     }
    1010           0 :   buf = xtrymalloc (1 + strlen (hexsn) + 1 + strlen (issuer_dn) + 1);
    1011           0 :   if (!buf)
    1012             :     {
    1013           0 :       log_error ("can't allocate enough memory: %s\n", strerror (errno));
    1014           0 :       xfree (hexsn);
    1015           0 :       return NULL;
    1016             :     }
    1017           0 :   strcpy (stpcpy (stpcpy (stpcpy (buf, "#"), hexsn),"/"), issuer_dn);
    1018           0 :   xfree (hexsn);
    1019           0 :   cert = get_cert_local (ctrl, buf);
    1020           0 :   xfree (buf);
    1021           0 :   if (cert)
    1022             :     {
    1023           0 :       cache_cert (cert);
    1024           0 :       return cert; /* Done. */
    1025             :     }
    1026             : 
    1027           0 :   if (DBG_LOOKUP)
    1028           0 :     log_debug ("find_cert_bysn: certificate not returned by caller"
    1029             :                " - doing lookup\n");
    1030             : 
    1031             :   /* Retrieve the certificate from external resources. */
    1032           0 :   while (!cert)
    1033             :     {
    1034             :       ksba_sexp_t sn;
    1035             :       char *issdn;
    1036             : 
    1037           0 :       if (!context)
    1038             :         {
    1039           0 :           err = ca_cert_fetch (ctrl, &context, issuer_dn);
    1040           0 :           if (err)
    1041             :             {
    1042           0 :               log_error (_("error fetching certificate by S/N: %s\n"),
    1043             :                          gpg_strerror (err));
    1044           0 :               break;
    1045             :             }
    1046             :         }
    1047             : 
    1048           0 :       err = fetch_next_ksba_cert (context, &cert);
    1049           0 :       if (err)
    1050             :         {
    1051           0 :           log_error (_("error fetching certificate by S/N: %s\n"),
    1052             :                      gpg_strerror (err) );
    1053           0 :           break;
    1054             :         }
    1055             : 
    1056           0 :       issdn = ksba_cert_get_issuer (cert, 0);
    1057           0 :       if (strcmp (issuer_dn, issdn))
    1058             :         {
    1059           0 :           log_debug ("find_cert_bysn: Ooops: issuer DN does not match\n");
    1060           0 :           ksba_cert_release (cert);
    1061           0 :           cert = NULL;
    1062           0 :           ksba_free (issdn);
    1063           0 :           break;
    1064             :         }
    1065             : 
    1066           0 :       sn = ksba_cert_get_serial (cert);
    1067             : 
    1068           0 :       if (DBG_LOOKUP)
    1069             :         {
    1070           0 :           log_debug ("   considering certificate (#");
    1071           0 :           dump_serial (sn);
    1072           0 :           log_printf ("/");
    1073           0 :           dump_string (issdn);
    1074           0 :           log_printf (")\n");
    1075             :         }
    1076             : 
    1077           0 :       if (!compare_serialno (serialno, sn))
    1078             :         {
    1079           0 :           ksba_free (sn);
    1080           0 :           ksba_free (issdn);
    1081           0 :           cache_cert (cert);
    1082           0 :           if (DBG_LOOKUP)
    1083           0 :             log_debug ("   found\n");
    1084           0 :           break; /* Ready.  */
    1085             :         }
    1086             : 
    1087           0 :       ksba_free (sn);
    1088           0 :       ksba_free (issdn);
    1089           0 :       ksba_cert_release (cert);
    1090           0 :       cert = NULL;
    1091             :     }
    1092             : 
    1093           0 :   end_cert_fetch (context);
    1094           0 :   return cert;
    1095             : }
    1096             : 
    1097             : 
    1098             : /* Return the certificate matching SUBJECT_DN and (if not NULL)
    1099             :    KEYID. If it is not already in the cache, try to find it from other
    1100             :    resources.  Note, that the external search does not work for user
    1101             :    certificates because the LDAP lookup is on the caCertificate
    1102             :    attribute. For our purposes this is just fine.  */
    1103             : ksba_cert_t
    1104           0 : find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid)
    1105             : {
    1106             :   gpg_error_t err;
    1107             :   int seq;
    1108           0 :   ksba_cert_t cert = NULL;
    1109           0 :   cert_fetch_context_t context = NULL;
    1110             :   ksba_sexp_t subj;
    1111             : 
    1112             :   /* If we have certificates from an OCSP request we first try to use
    1113             :      them.  This is because these certificates will really be the
    1114             :      required ones and thus even in the case that they can't be
    1115             :      uniquely located by the following code we can use them.  This is
    1116             :      for example required by Telesec certificates where a keyId is
    1117             :      used but the issuer certificate comes without a subject keyId! */
    1118           0 :   if (ctrl->ocsp_certs && subject_dn)
    1119             :     {
    1120             :       cert_item_t ci;
    1121             :       cert_ref_t cr;
    1122             :       int i;
    1123             : 
    1124             :       /* For efficiency reasons we won't use get_cert_bysubject here. */
    1125           0 :       acquire_cache_read_lock ();
    1126           0 :       for (i=0; i < 256; i++)
    1127           0 :         for (ci=cert_cache[i]; ci; ci = ci->next)
    1128           0 :           if (ci->cert && ci->subject_dn
    1129           0 :               && !strcmp (ci->subject_dn, subject_dn))
    1130           0 :             for (cr=ctrl->ocsp_certs; cr; cr = cr->next)
    1131           0 :               if (!memcmp (ci->fpr, cr->fpr, 20))
    1132             :                 {
    1133           0 :                   ksba_cert_ref (ci->cert);
    1134           0 :                   release_cache_lock ();
    1135           0 :                   return ci->cert; /* We use this certificate. */
    1136             :                 }
    1137           0 :       release_cache_lock ();
    1138           0 :       if (DBG_LOOKUP)
    1139           0 :         log_debug ("find_cert_bysubject: certificate not in ocsp_certs\n");
    1140             :     }
    1141             : 
    1142             : 
    1143             :   /* First we check whether the certificate is cached.  */
    1144           0 :   for (seq=0; (cert = get_cert_bysubject (subject_dn, seq)); seq++)
    1145             :     {
    1146           0 :       if (!keyid)
    1147           0 :         break; /* No keyid requested, so return the first one found. */
    1148           0 :       if (!ksba_cert_get_subj_key_id (cert, NULL, &subj)
    1149           0 :           && !cmp_simple_canon_sexp (keyid, subj))
    1150             :         {
    1151           0 :           xfree (subj);
    1152           0 :           break; /* Found matching cert. */
    1153             :         }
    1154           0 :       xfree (subj);
    1155           0 :       ksba_cert_release (cert);
    1156             :     }
    1157           0 :   if (cert)
    1158           0 :     return cert; /* Done.  */
    1159             : 
    1160           0 :   if (DBG_LOOKUP)
    1161           0 :     log_debug ("find_cert_bysubject: certificate not in cache\n");
    1162             : 
    1163             :   /* Ask back to the service requester to return the certificate.
    1164             :      This is because we can assume that he already used the
    1165             :      certificate while checking for the CRL. */
    1166           0 :   if (keyid)
    1167           0 :     cert = get_cert_local_ski (ctrl, subject_dn, keyid);
    1168             :   else
    1169             :     {
    1170             :       /* In contrast to get_cert_local_ski, get_cert_local uses any
    1171             :          passed pattern, so we need to make sure that an exact subject
    1172             :          search is done. */
    1173             :       char *buf;
    1174             : 
    1175           0 :       buf = xtrymalloc (1 + strlen (subject_dn) + 1);
    1176           0 :       if (!buf)
    1177             :         {
    1178           0 :           log_error ("can't allocate enough memory: %s\n", strerror (errno));
    1179           0 :           return NULL;
    1180             :         }
    1181           0 :       strcpy (stpcpy (buf, "/"), subject_dn);
    1182           0 :       cert = get_cert_local (ctrl, buf);
    1183           0 :       xfree (buf);
    1184             :     }
    1185           0 :   if (cert)
    1186             :     {
    1187           0 :       cache_cert (cert);
    1188           0 :       return cert; /* Done. */
    1189             :     }
    1190             : 
    1191           0 :   if (DBG_LOOKUP)
    1192           0 :     log_debug ("find_cert_bysubject: certificate not returned by caller"
    1193             :                " - doing lookup\n");
    1194             : 
    1195             :   /* Locate the certificate using external resources. */
    1196           0 :   while (!cert)
    1197             :     {
    1198             :       char *subjdn;
    1199             : 
    1200           0 :       if (!context)
    1201             :         {
    1202           0 :           err = ca_cert_fetch (ctrl, &context, subject_dn);
    1203           0 :           if (err)
    1204             :             {
    1205           0 :               log_error (_("error fetching certificate by subject: %s\n"),
    1206             :                          gpg_strerror (err));
    1207           0 :               break;
    1208             :             }
    1209             :         }
    1210             : 
    1211           0 :       err = fetch_next_ksba_cert (context, &cert);
    1212           0 :       if (err)
    1213             :         {
    1214           0 :           log_error (_("error fetching certificate by subject: %s\n"),
    1215             :                      gpg_strerror (err) );
    1216           0 :           break;
    1217             :         }
    1218             : 
    1219           0 :       subjdn = ksba_cert_get_subject (cert, 0);
    1220           0 :       if (strcmp (subject_dn, subjdn))
    1221             :         {
    1222           0 :           log_info ("find_cert_bysubject: subject DN does not match\n");
    1223           0 :           ksba_cert_release (cert);
    1224           0 :           cert = NULL;
    1225           0 :           ksba_free (subjdn);
    1226           0 :           continue;
    1227             :         }
    1228             : 
    1229             : 
    1230           0 :       if (DBG_LOOKUP)
    1231             :         {
    1232           0 :           log_debug ("   considering certificate (/");
    1233           0 :           dump_string (subjdn);
    1234           0 :           log_printf (")\n");
    1235             :         }
    1236           0 :       ksba_free (subjdn);
    1237             : 
    1238             :       /* If no key ID has been provided, we return the first match.  */
    1239           0 :       if (!keyid)
    1240             :         {
    1241           0 :           cache_cert (cert);
    1242           0 :           if (DBG_LOOKUP)
    1243           0 :             log_debug ("   found\n");
    1244           0 :           break; /* Ready.  */
    1245             :         }
    1246             : 
    1247             :       /* With the key ID given we need to compare it.  */
    1248           0 :       if (!ksba_cert_get_subj_key_id (cert, NULL, &subj))
    1249             :         {
    1250           0 :           if (!cmp_simple_canon_sexp (keyid, subj))
    1251             :             {
    1252           0 :               ksba_free (subj);
    1253           0 :               cache_cert (cert);
    1254           0 :               if (DBG_LOOKUP)
    1255           0 :                 log_debug ("   found\n");
    1256           0 :               break; /* Ready.  */
    1257             :             }
    1258             :         }
    1259             : 
    1260           0 :       ksba_free (subj);
    1261           0 :       ksba_cert_release (cert);
    1262           0 :       cert = NULL;
    1263             :     }
    1264             : 
    1265           0 :   end_cert_fetch (context);
    1266           0 :   return cert;
    1267             : }
    1268             : 
    1269             : 
    1270             : 
    1271             : /* Return 0 if the certificate is a trusted certificate. Returns
    1272             :    GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
    1273             :    case of systems errors. */
    1274             : gpg_error_t
    1275           0 : is_trusted_cert (ksba_cert_t cert)
    1276             : {
    1277             :   unsigned char fpr[20];
    1278             :   cert_item_t ci;
    1279             : 
    1280           0 :   cert_compute_fpr (cert, fpr);
    1281             : 
    1282           0 :   acquire_cache_read_lock ();
    1283           0 :   for (ci=cert_cache[*fpr]; ci; ci = ci->next)
    1284           0 :     if (ci->cert && !memcmp (ci->fpr, fpr, 20))
    1285             :       {
    1286           0 :         if (ci->flags.trusted)
    1287             :           {
    1288           0 :             release_cache_lock ();
    1289           0 :             return 0; /* Yes, it is trusted. */
    1290             :           }
    1291           0 :         break;
    1292             :       }
    1293             : 
    1294           0 :   release_cache_lock ();
    1295           0 :   return gpg_error (GPG_ERR_NOT_TRUSTED);
    1296             : }
    1297             : 
    1298             : 
    1299             : 
    1300             : /* Given the certificate CERT locate the issuer for this certificate
    1301             :    and return it at R_CERT.  Returns 0 on success or
    1302             :    GPG_ERR_NOT_FOUND.  */
    1303             : gpg_error_t
    1304           0 : find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert)
    1305             : {
    1306             :   gpg_error_t err;
    1307             :   char *issuer_dn;
    1308           0 :   ksba_cert_t issuer_cert = NULL;
    1309             :   ksba_name_t authid;
    1310             :   ksba_sexp_t authidno;
    1311             :   ksba_sexp_t keyid;
    1312             : 
    1313           0 :   *r_cert = NULL;
    1314             : 
    1315           0 :   issuer_dn = ksba_cert_get_issuer (cert, 0);
    1316           0 :   if (!issuer_dn)
    1317             :     {
    1318           0 :       log_error (_("no issuer found in certificate\n"));
    1319           0 :       err = gpg_error (GPG_ERR_BAD_CERT);
    1320           0 :       goto leave;
    1321             :     }
    1322             : 
    1323             :   /* First we need to check whether we can return that certificate
    1324             :      using the authorithyKeyIdentifier.  */
    1325           0 :   err = ksba_cert_get_auth_key_id (cert, &keyid, &authid, &authidno);
    1326           0 :   if (err)
    1327             :     {
    1328           0 :       log_info (_("error getting authorityKeyIdentifier: %s\n"),
    1329             :                 gpg_strerror (err));
    1330             :     }
    1331             :   else
    1332             :     {
    1333           0 :       const char *s = ksba_name_enum (authid, 0);
    1334           0 :       if (s && *authidno)
    1335             :         {
    1336           0 :           issuer_cert = find_cert_bysn (ctrl, s, authidno);
    1337             :         }
    1338           0 :       if (!issuer_cert && keyid)
    1339             :         {
    1340             :           /* Not found by issuer+s/n.  Now that we have an AKI
    1341             :              keyIdentifier look for a certificate with a matching
    1342             :              SKI. */
    1343           0 :           issuer_cert = find_cert_bysubject (ctrl, issuer_dn, keyid);
    1344             :         }
    1345             :       /* Print a note so that the user does not feel too helpless when
    1346             :          an issuer certificate was found and gpgsm prints BAD
    1347             :          signature because it is not the correct one. */
    1348           0 :       if (!issuer_cert)
    1349             :         {
    1350           0 :           log_info ("issuer certificate ");
    1351           0 :           if (keyid)
    1352             :             {
    1353           0 :               log_printf ("{");
    1354           0 :               dump_serial (keyid);
    1355           0 :               log_printf ("} ");
    1356             :             }
    1357           0 :           if (authidno)
    1358             :             {
    1359           0 :               log_printf ("(#");
    1360           0 :               dump_serial (authidno);
    1361           0 :               log_printf ("/");
    1362           0 :               dump_string (s);
    1363           0 :               log_printf (") ");
    1364             :             }
    1365           0 :           log_printf ("not found using authorityKeyIdentifier\n");
    1366             :         }
    1367           0 :       ksba_name_release (authid);
    1368           0 :       xfree (authidno);
    1369           0 :       xfree (keyid);
    1370             :     }
    1371             : 
    1372             :   /* If this did not work, try just with the issuer's name and assume
    1373             :      that there is only one such certificate.  We only look into our
    1374             :      cache then. */
    1375           0 :   if (err || !issuer_cert)
    1376             :     {
    1377           0 :       issuer_cert = get_cert_bysubject (issuer_dn, 0);
    1378           0 :       if (issuer_cert)
    1379           0 :         err = 0;
    1380             :     }
    1381             : 
    1382             :  leave:
    1383           0 :   if (!err && !issuer_cert)
    1384           0 :     err = gpg_error (GPG_ERR_NOT_FOUND);
    1385             : 
    1386           0 :   xfree (issuer_dn);
    1387             : 
    1388           0 :   if (err)
    1389           0 :     ksba_cert_release (issuer_cert);
    1390             :   else
    1391           0 :     *r_cert = issuer_cert;
    1392             : 
    1393           0 :   return err;
    1394             : }

Generated by: LCOV version 1.11