LCOV - code coverage report
Current view: top level - dirmngr - certcache.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 613 0.0 %
Date: 2016-09-12 12:29:17 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 function.  */
     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 :       return 0; /* We do not consider this a severe error.  */
     352             :     }
     353             : 
     354           0 :   while ( (ep=readdir (dir)) )
     355             :     {
     356           0 :       p = ep->d_name;
     357           0 :       if (*p == '.' || !*p)
     358           0 :         continue; /* Skip any hidden files and invalid entries.  */
     359           0 :       n = strlen (p);
     360           0 :       if ( n < 5 || (strcmp (p+n-4,".crt") && strcmp (p+n-4,".der")))
     361           0 :         continue; /* Not the desired "*.crt" or "*.der" pattern.  */
     362             : 
     363           0 :       xfree (fname);
     364           0 :       fname = make_filename (dirname, p, NULL);
     365           0 :       fp = es_fopen (fname, "rb");
     366           0 :       if (!fp)
     367             :         {
     368           0 :           log_error (_("can't open '%s': %s\n"),
     369           0 :                      fname, strerror (errno));
     370           0 :           continue;
     371             :         }
     372             : 
     373           0 :       err = create_estream_ksba_reader (&reader, fp);
     374           0 :       if (err)
     375             :         {
     376           0 :           es_fclose (fp);
     377           0 :           continue;
     378             :         }
     379             : 
     380           0 :       err = ksba_cert_new (&cert);
     381           0 :       if (!err)
     382           0 :         err = ksba_cert_read_der (cert, reader);
     383           0 :       ksba_reader_release (reader);
     384           0 :       es_fclose (fp);
     385           0 :       if (err)
     386             :         {
     387           0 :           log_error (_("can't parse certificate '%s': %s\n"),
     388             :                      fname, gpg_strerror (err));
     389           0 :           ksba_cert_release (cert);
     390           0 :           continue;
     391             :         }
     392             : 
     393           0 :       err = put_cert (cert, 1, are_trusted, NULL);
     394           0 :       if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
     395           0 :         log_info (_("certificate '%s' already cached\n"), fname);
     396           0 :       else if (!err)
     397             :         {
     398           0 :           if (are_trusted)
     399           0 :             log_info (_("trusted certificate '%s' loaded\n"), fname);
     400             :           else
     401           0 :             log_info (_("certificate '%s' loaded\n"), fname);
     402           0 :           if (opt.verbose)
     403             :             {
     404           0 :               p = get_fingerprint_hexstring_colon (cert);
     405           0 :               log_info (_("  SHA1 fingerprint = %s\n"), p);
     406           0 :               xfree (p);
     407             : 
     408           0 :               cert_log_name (_("   issuer ="), cert);
     409           0 :               cert_log_subject (_("  subject ="), cert);
     410             :             }
     411             :         }
     412             :       else
     413           0 :         log_error (_("error loading certificate '%s': %s\n"),
     414             :                      fname, gpg_strerror (err));
     415           0 :       ksba_cert_release (cert);
     416             :     }
     417             : 
     418           0 :   xfree (fname);
     419           0 :   closedir (dir);
     420           0 :   return 0;
     421             : }
     422             : 
     423             : 
     424             : /* Initialize the certificate cache if not yet done.  */
     425             : void
     426           0 : cert_cache_init (void)
     427             : {
     428             :   char *dname;
     429             : 
     430           0 :   if (initialization_done)
     431           0 :     return;
     432           0 :   init_cache_lock ();
     433           0 :   acquire_cache_write_lock ();
     434             : 
     435           0 :   dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL);
     436           0 :   load_certs_from_dir (dname, 1);
     437           0 :   xfree (dname);
     438             : 
     439           0 :   dname = make_filename (gnupg_sysconfdir (), "extra-certs", NULL);
     440           0 :   load_certs_from_dir (dname, 0);
     441           0 :   xfree (dname);
     442             : 
     443           0 :   initialization_done = 1;
     444           0 :   release_cache_lock ();
     445             : 
     446           0 :   cert_cache_print_stats ();
     447             : }
     448             : 
     449             : /* Deinitialize the certificate cache.  With FULL set to true even the
     450             :    unused certificate slots are released. */
     451             : void
     452           0 : cert_cache_deinit (int full)
     453             : {
     454             :   cert_item_t ci, ci2;
     455             :   int i;
     456             : 
     457           0 :   if (!initialization_done)
     458           0 :     return;
     459             : 
     460           0 :   acquire_cache_write_lock ();
     461             : 
     462           0 :   for (i=0; i < 256; i++)
     463           0 :     for (ci=cert_cache[i]; ci; ci = ci->next)
     464           0 :       clean_cache_slot (ci);
     465             : 
     466           0 :   if (full)
     467             :     {
     468           0 :       for (i=0; i < 256; i++)
     469             :         {
     470           0 :           for (ci=cert_cache[i]; ci; ci = ci2)
     471             :             {
     472           0 :               ci2 = ci->next;
     473           0 :               xfree (ci);
     474             :             }
     475           0 :           cert_cache[i] = NULL;
     476             :         }
     477             :     }
     478             : 
     479           0 :   total_loaded_certificates = 0;
     480           0 :   total_extra_certificates = 0;
     481           0 :   initialization_done = 0;
     482           0 :   release_cache_lock ();
     483             : }
     484             : 
     485             : /* Print some statistics to the log file.  */
     486             : void
     487           0 : cert_cache_print_stats (void)
     488             : {
     489           0 :   log_info (_("permanently loaded certificates: %u\n"),
     490             :             total_loaded_certificates);
     491           0 :   log_info (_("    runtime cached certificates: %u\n"),
     492             :             total_extra_certificates);
     493           0 : }
     494             : 
     495             : 
     496             : /* Put CERT into the certificate cache.  */
     497             : gpg_error_t
     498           0 : cache_cert (ksba_cert_t cert)
     499             : {
     500             :   gpg_error_t err;
     501             : 
     502           0 :   acquire_cache_write_lock ();
     503           0 :   err = put_cert (cert, 0, 0, NULL);
     504           0 :   release_cache_lock ();
     505           0 :   if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
     506           0 :     log_info (_("certificate already cached\n"));
     507           0 :   else if (!err)
     508           0 :     log_info (_("certificate cached\n"));
     509             :   else
     510           0 :     log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
     511           0 :   return err;
     512             : }
     513             : 
     514             : 
     515             : /* Put CERT into the certificate cache and store the fingerprint of
     516             :    the certificate into FPR_BUFFER.  If the certificate is already in
     517             :    the cache do not print a warning; just store the
     518             :    fingerprint. FPR_BUFFER needs to be at least 20 bytes. */
     519             : gpg_error_t
     520           0 : cache_cert_silent (ksba_cert_t cert, void *fpr_buffer)
     521             : {
     522             :   gpg_error_t err;
     523             : 
     524           0 :   acquire_cache_write_lock ();
     525           0 :   err = put_cert (cert, 0, 0, fpr_buffer);
     526           0 :   release_cache_lock ();
     527           0 :   if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
     528           0 :     err = 0;
     529           0 :   if (err)
     530           0 :     log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
     531           0 :   return err;
     532             : }
     533             : 
     534             : 
     535             : 
     536             : /* Return a certificate object for the given fingerprint.  FPR is
     537             :    expected to be a 20 byte binary SHA-1 fingerprint.  If no matching
     538             :    certificate is available in the cache NULL is returned.  The caller
     539             :    must release a returned certificate.  Note that although we are
     540             :    using reference counting the caller should not just compare the
     541             :    pointers to check for identical certificates. */
     542             : ksba_cert_t
     543           0 : get_cert_byfpr (const unsigned char *fpr)
     544             : {
     545             :   cert_item_t ci;
     546             : 
     547           0 :   acquire_cache_read_lock ();
     548           0 :   for (ci=cert_cache[*fpr]; ci; ci = ci->next)
     549           0 :     if (ci->cert && !memcmp (ci->fpr, fpr, 20))
     550             :       {
     551           0 :         ksba_cert_ref (ci->cert);
     552           0 :         release_cache_lock ();
     553           0 :         return ci->cert;
     554             :       }
     555             : 
     556           0 :   release_cache_lock ();
     557           0 :   return NULL;
     558             : }
     559             : 
     560             : /* Return a certificate object for the given fingerprint.  STRING is
     561             :    expected to be a SHA-1 fingerprint in standard hex notation with or
     562             :    without colons.  If no matching certificate is available in the
     563             :    cache NULL is returned.  The caller must release a returned
     564             :    certificate.  Note that although we are using reference counting
     565             :    the caller should not just compare the pointers to check for
     566             :    identical certificates. */
     567             : ksba_cert_t
     568           0 : get_cert_byhexfpr (const char *string)
     569             : {
     570             :   unsigned char fpr[20];
     571             :   const char *s;
     572             :   int i;
     573             : 
     574           0 :   if (strchr (string, ':'))
     575             :     {
     576           0 :       for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1);)
     577             :         {
     578           0 :           if (s[2] && s[2] != ':')
     579           0 :             break; /* Invalid string. */
     580           0 :           fpr[i++] = xtoi_2 (s);
     581           0 :           s += 2;
     582           0 :           if (i!= 20 && *s == ':')
     583           0 :             s++;
     584             :         }
     585             :     }
     586             :   else
     587             :     {
     588           0 :       for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1); s+=2 )
     589           0 :         fpr[i++] = xtoi_2 (s);
     590             :     }
     591           0 :   if (i!=20 || *s)
     592             :     {
     593           0 :       log_error (_("invalid SHA1 fingerprint string '%s'\n"), string);
     594           0 :       return NULL;
     595             :     }
     596             : 
     597           0 :   return get_cert_byfpr (fpr);
     598             : }
     599             : 
     600             : 
     601             : 
     602             : /* Return the certificate matching ISSUER_DN and SERIALNO.  */
     603             : ksba_cert_t
     604           0 : get_cert_bysn (const char *issuer_dn, ksba_sexp_t serialno)
     605             : {
     606             :   /* Simple and inefficient implementation.   fixme! */
     607             :   cert_item_t ci;
     608             :   int i;
     609             : 
     610           0 :   acquire_cache_read_lock ();
     611           0 :   for (i=0; i < 256; i++)
     612             :     {
     613           0 :       for (ci=cert_cache[i]; ci; ci = ci->next)
     614           0 :         if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn)
     615           0 :             && !compare_serialno (ci->sn, serialno))
     616             :           {
     617           0 :             ksba_cert_ref (ci->cert);
     618           0 :             release_cache_lock ();
     619           0 :             return ci->cert;
     620             :           }
     621             :     }
     622             : 
     623           0 :   release_cache_lock ();
     624           0 :   return NULL;
     625             : }
     626             : 
     627             : 
     628             : /* Return the certificate matching ISSUER_DN.  SEQ should initially be
     629             :    set to 0 and bumped up to get the next issuer with that DN. */
     630             : ksba_cert_t
     631           0 : get_cert_byissuer (const char *issuer_dn, unsigned int seq)
     632             : {
     633             :   /* Simple and very inefficient implementation and API.  fixme! */
     634             :   cert_item_t ci;
     635             :   int i;
     636             : 
     637           0 :   acquire_cache_read_lock ();
     638           0 :   for (i=0; i < 256; i++)
     639             :     {
     640           0 :       for (ci=cert_cache[i]; ci; ci = ci->next)
     641           0 :         if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn))
     642           0 :           if (!seq--)
     643             :             {
     644           0 :               ksba_cert_ref (ci->cert);
     645           0 :               release_cache_lock ();
     646           0 :               return ci->cert;
     647             :             }
     648             :     }
     649             : 
     650           0 :   release_cache_lock ();
     651           0 :   return NULL;
     652             : }
     653             : 
     654             : 
     655             : /* Return the certificate matching SUBJECT_DN.  SEQ should initially be
     656             :    set to 0 and bumped up to get the next subject with that DN. */
     657             : ksba_cert_t
     658           0 : get_cert_bysubject (const char *subject_dn, unsigned int seq)
     659             : {
     660             :   /* Simple and very inefficient implementation and API.  fixme! */
     661             :   cert_item_t ci;
     662             :   int i;
     663             : 
     664           0 :   if (!subject_dn)
     665           0 :     return NULL;
     666             : 
     667           0 :   acquire_cache_read_lock ();
     668           0 :   for (i=0; i < 256; i++)
     669             :     {
     670           0 :       for (ci=cert_cache[i]; ci; ci = ci->next)
     671           0 :         if (ci->cert && ci->subject_dn
     672           0 :             && !strcmp (ci->subject_dn, subject_dn))
     673           0 :           if (!seq--)
     674             :             {
     675           0 :               ksba_cert_ref (ci->cert);
     676           0 :               release_cache_lock ();
     677           0 :               return ci->cert;
     678             :             }
     679             :     }
     680             : 
     681           0 :   release_cache_lock ();
     682           0 :   return NULL;
     683             : }
     684             : 
     685             : 
     686             : 
     687             : /* Return a value describing the the class of PATTERN.  The offset of
     688             :    the actual string to be used for the comparison is stored at
     689             :    R_OFFSET.  The offset of the serialnumer is stored at R_SN_OFFSET. */
     690             : static enum pattern_class
     691           0 : classify_pattern (const char *pattern, size_t *r_offset, size_t *r_sn_offset)
     692             : {
     693             :   enum pattern_class result;
     694             :   const char *s;
     695           0 :   int hexprefix = 0;
     696             :   int hexlength;
     697             : 
     698           0 :   *r_offset = *r_sn_offset = 0;
     699             : 
     700             :   /* Skip leading spaces. */
     701           0 :   for(s = pattern; *s && spacep (s); s++ )
     702             :     ;
     703             : 
     704           0 :   switch (*s)
     705             :     {
     706             :     case 0:  /* Empty string is an error. */
     707           0 :       result = PATTERN_UNKNOWN;
     708           0 :       break;
     709             : 
     710             :     case '.': /* An email address, compare from end.  */
     711           0 :       result = PATTERN_UNKNOWN;  /* Not implemented.  */
     712           0 :       break;
     713             : 
     714             :     case '<': /* An email address.  */
     715           0 :       result = PATTERN_EMAIL;
     716           0 :       s++;
     717           0 :       break;
     718             : 
     719             :     case '@': /* Part of an email address.  */
     720           0 :       result = PATTERN_EMAIL_SUBSTR;
     721           0 :       s++;
     722           0 :       break;
     723             : 
     724             :     case '=':  /* Exact compare. */
     725           0 :       result = PATTERN_UNKNOWN; /* Does not make sense for X.509.  */
     726           0 :       break;
     727             : 
     728             :     case '*':  /* Case insensitive substring search.  */
     729           0 :       result = PATTERN_SUBSTR;
     730           0 :       s++;
     731           0 :       break;
     732             : 
     733             :     case '+':  /* Compare individual words. */
     734           0 :       result = PATTERN_UNKNOWN;  /* Not implemented.  */
     735           0 :       break;
     736             : 
     737             :     case '/': /* Subject's DN. */
     738           0 :       s++;
     739           0 :       if (!*s || spacep (s))
     740           0 :         result = PATTERN_UNKNOWN; /* No DN or prefixed with a space. */
     741             :       else
     742           0 :         result = PATTERN_SUBJECT;
     743           0 :       break;
     744             : 
     745             :     case '#': /* Serial number or issuer DN. */
     746             :       {
     747             :         const char *si;
     748             : 
     749           0 :         s++;
     750           0 :         if ( *s == '/')
     751             :           {
     752             :             /* An issuer's DN is indicated by "#/" */
     753           0 :             s++;
     754           0 :             if (!*s || spacep (s))
     755           0 :               result = PATTERN_UNKNOWN; /* No DN or prefixed with a space. */
     756             :             else
     757           0 :               result = PATTERN_ISSUER;
     758             :           }
     759             :         else
     760             :           { /* Serialnumber + optional issuer ID. */
     761           0 :             for (si=s; *si && *si != '/'; si++)
     762           0 :               if (!strchr("01234567890abcdefABCDEF", *si))
     763           0 :                 break;
     764           0 :             if (*si && *si != '/')
     765           0 :               result = PATTERN_UNKNOWN; /* Invalid digit in serial number. */
     766             :             else
     767             :               {
     768           0 :                 *r_sn_offset = s - pattern;
     769           0 :                 if (!*si)
     770           0 :                   result = PATTERN_SERIALNO;
     771             :                 else
     772             :                   {
     773           0 :                     s = si+1;
     774           0 :                     if (!*s || spacep (s))
     775           0 :                       result = PATTERN_UNKNOWN; /* No DN or prefixed
     776             :                                                    with a space. */
     777             :                     else
     778           0 :                       result = PATTERN_SERIALNO_ISSUER;
     779             :                   }
     780             :               }
     781             :           }
     782             :       }
     783           0 :       break;
     784             : 
     785             :     case ':': /* Unified fingerprint. */
     786             :       {
     787             :         const char *se, *si;
     788             :         int i;
     789             : 
     790           0 :         se = strchr (++s, ':');
     791           0 :         if (!se)
     792           0 :           result = PATTERN_UNKNOWN;
     793             :         else
     794             :           {
     795           0 :             for (i=0, si=s; si < se; si++, i++ )
     796           0 :               if (!strchr("01234567890abcdefABCDEF", *si))
     797           0 :                 break;
     798           0 :             if ( si < se )
     799           0 :               result = PATTERN_UNKNOWN; /* Invalid digit. */
     800           0 :             else if (i == 32)
     801           0 :               result = PATTERN_FINGERPRINT16;
     802           0 :             else if (i == 40)
     803           0 :               result = PATTERN_FINGERPRINT20;
     804             :             else
     805           0 :               result = PATTERN_UNKNOWN; /* Invalid length for a fingerprint. */
     806             :           }
     807             :       }
     808           0 :       break;
     809             : 
     810             :     case '&': /* Keygrip. */
     811           0 :       result = PATTERN_UNKNOWN;  /* Not implemented.  */
     812           0 :       break;
     813             : 
     814             :     default:
     815           0 :       if (s[0] == '0' && s[1] == 'x')
     816             :         {
     817           0 :           hexprefix = 1;
     818           0 :           s += 2;
     819             :         }
     820             : 
     821           0 :       hexlength = strspn(s, "0123456789abcdefABCDEF");
     822             : 
     823             :       /* Check if a hexadecimal number is terminated by EOS or blank. */
     824           0 :       if (hexlength && s[hexlength] && !spacep (s+hexlength))
     825             :         {
     826             :           /* If the "0x" prefix is used a correct termination is required. */
     827           0 :           if (hexprefix)
     828             :             {
     829           0 :               result = PATTERN_UNKNOWN;
     830           0 :               break; /* switch */
     831             :             }
     832           0 :           hexlength = 0;  /* Not a hex number.  */
     833             :         }
     834             : 
     835           0 :       if (hexlength == 8 || (!hexprefix && hexlength == 9 && *s == '0'))
     836             :         {
     837           0 :           if (hexlength == 9)
     838           0 :             s++;
     839           0 :           result = PATTERN_SHORT_KEYID;
     840             :         }
     841           0 :       else if (hexlength == 16 || (!hexprefix && hexlength == 17 && *s == '0'))
     842             :         {
     843           0 :           if (hexlength == 17)
     844           0 :             s++;
     845           0 :           result = PATTERN_LONG_KEYID;
     846             :         }
     847           0 :       else if (hexlength == 32 || (!hexprefix && hexlength == 33 && *s == '0'))
     848             :         {
     849           0 :           if (hexlength == 33)
     850           0 :             s++;
     851           0 :           result = PATTERN_FINGERPRINT16;
     852             :         }
     853           0 :       else if (hexlength == 40 || (!hexprefix && hexlength == 41 && *s == '0'))
     854             :         {
     855           0 :           if (hexlength == 41)
     856           0 :             s++;
     857           0 :           result = PATTERN_FINGERPRINT20;
     858             :         }
     859           0 :       else if (!hexprefix)
     860             :         {
     861             :           /* The fingerprints used with X.509 are often delimited by
     862             :              colons, so we try to single this case out. */
     863           0 :           result = PATTERN_UNKNOWN;
     864           0 :           hexlength = strspn (s, ":0123456789abcdefABCDEF");
     865           0 :           if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength)))
     866             :             {
     867             :               int i, c;
     868             : 
     869           0 :               for (i=0; i < 20; i++, s += 3)
     870             :                 {
     871           0 :                   c = hextobyte(s);
     872           0 :                   if (c == -1 || (i < 19 && s[2] != ':'))
     873             :                     break;
     874             :                 }
     875           0 :               if (i == 20)
     876           0 :                 result = PATTERN_FINGERPRINT20;
     877             :             }
     878           0 :           if (result == PATTERN_UNKNOWN) /* Default to substring match. */
     879             :             {
     880           0 :               result = PATTERN_SUBSTR;
     881             :             }
     882             :         }
     883             :       else /* A hex number with a prefix but with a wrong length.  */
     884           0 :         result = PATTERN_UNKNOWN;
     885             :     }
     886             : 
     887           0 :   if (result != PATTERN_UNKNOWN)
     888           0 :     *r_offset = s - pattern;
     889           0 :   return result;
     890             : }
     891             : 
     892             : 
     893             : 
     894             : /* Given PATTERN, which is a string as used by GnuPG to specify a
     895             :    certificate, return all matching certificates by calling the
     896             :    supplied function RETFNC.  */
     897             : gpg_error_t
     898           0 : get_certs_bypattern (const char *pattern,
     899             :                      gpg_error_t (*retfnc)(void*,ksba_cert_t),
     900             :                      void *retfnc_data)
     901             : {
     902           0 :   gpg_error_t err = GPG_ERR_BUG;
     903             :   enum pattern_class class;
     904             :   size_t offset, sn_offset;
     905             :   const char *hexserialno;
     906           0 :   ksba_sexp_t serialno = NULL;
     907           0 :   ksba_cert_t cert = NULL;
     908             :   unsigned int seq;
     909             : 
     910           0 :   if (!pattern || !retfnc)
     911           0 :     return gpg_error (GPG_ERR_INV_ARG);
     912             : 
     913           0 :   class = classify_pattern (pattern, &offset, &sn_offset);
     914           0 :   hexserialno = pattern + sn_offset;
     915           0 :   pattern += offset;
     916           0 :   switch (class)
     917             :     {
     918             :     case PATTERN_UNKNOWN:
     919           0 :       err = gpg_error (GPG_ERR_INV_NAME);
     920           0 :       break;
     921             : 
     922             :     case PATTERN_FINGERPRINT20:
     923           0 :       cert = get_cert_byhexfpr (pattern);
     924           0 :       err = cert? 0 : gpg_error (GPG_ERR_NOT_FOUND);
     925           0 :       break;
     926             : 
     927             :     case PATTERN_SERIALNO_ISSUER:
     928           0 :       serialno = hexsn_to_sexp (hexserialno);
     929           0 :       if (!serialno)
     930           0 :         err = gpg_error_from_syserror ();
     931             :       else
     932             :         {
     933           0 :           cert = get_cert_bysn (pattern, serialno);
     934           0 :           err = cert? 0 : gpg_error (GPG_ERR_NOT_FOUND);
     935             :         }
     936           0 :       break;
     937             : 
     938             :     case PATTERN_ISSUER:
     939           0 :       for (seq=0,err=0; !err && (cert = get_cert_byissuer (pattern, seq)); seq++)
     940             :         {
     941           0 :           err = retfnc (retfnc_data, cert);
     942           0 :           ksba_cert_release (cert);
     943           0 :           cert = NULL;
     944             :         }
     945           0 :       if (!err && !seq)
     946           0 :         err = gpg_error (GPG_ERR_NOT_FOUND);
     947           0 :       break;
     948             : 
     949             :     case PATTERN_SUBJECT:
     950           0 :       for (seq=0,err=0; !err && (cert = get_cert_bysubject (pattern, seq));seq++)
     951             :         {
     952           0 :           err = retfnc (retfnc_data, cert);
     953           0 :           ksba_cert_release (cert);
     954           0 :           cert = NULL;
     955             :         }
     956           0 :       if (!err && !seq)
     957           0 :         err = gpg_error (GPG_ERR_NOT_FOUND);
     958           0 :       break;
     959             : 
     960             :     case PATTERN_EMAIL:
     961             :     case PATTERN_EMAIL_SUBSTR:
     962             :     case PATTERN_FINGERPRINT16:
     963             :     case PATTERN_SHORT_KEYID:
     964             :     case PATTERN_LONG_KEYID:
     965             :     case PATTERN_SUBSTR:
     966             :     case PATTERN_SERIALNO:
     967             :       /* Not supported.  */
     968           0 :       err = gpg_error (GPG_ERR_INV_NAME);
     969             :     }
     970             : 
     971             : 
     972           0 :   if (!err && cert)
     973           0 :     err = retfnc (retfnc_data, cert);
     974           0 :   ksba_cert_release (cert);
     975           0 :   xfree (serialno);
     976           0 :   return err;
     977             : }
     978             : 
     979             : 
     980             : 
     981             : 
     982             : 
     983             : /* Return the certificate matching ISSUER_DN and SERIALNO; if it is
     984             :    not already in the cache, try to find it from other resources.  */
     985             : ksba_cert_t
     986           0 : find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno)
     987             : {
     988             :   gpg_error_t err;
     989             :   ksba_cert_t cert;
     990           0 :   cert_fetch_context_t context = NULL;
     991             :   char *hexsn, *buf;
     992             : 
     993             :   /* First check whether it has already been cached.  */
     994           0 :   cert = get_cert_bysn (issuer_dn, serialno);
     995           0 :   if (cert)
     996           0 :     return cert;
     997             : 
     998             :   /* Ask back to the service requester to return the certificate.
     999             :      This is because we can assume that he already used the
    1000             :      certificate while checking for the CRL. */
    1001           0 :   hexsn = serial_hex (serialno);
    1002           0 :   if (!hexsn)
    1003             :     {
    1004           0 :       log_error ("serial_hex() failed\n");
    1005           0 :       return NULL;
    1006             :     }
    1007           0 :   buf = xtrymalloc (1 + strlen (hexsn) + 1 + strlen (issuer_dn) + 1);
    1008           0 :   if (!buf)
    1009             :     {
    1010           0 :       log_error ("can't allocate enough memory: %s\n", strerror (errno));
    1011           0 :       xfree (hexsn);
    1012           0 :       return NULL;
    1013             :     }
    1014           0 :   strcpy (stpcpy (stpcpy (stpcpy (buf, "#"), hexsn),"/"), issuer_dn);
    1015           0 :   xfree (hexsn);
    1016           0 :   cert = get_cert_local (ctrl, buf);
    1017           0 :   xfree (buf);
    1018           0 :   if (cert)
    1019             :     {
    1020           0 :       cache_cert (cert);
    1021           0 :       return cert; /* Done. */
    1022             :     }
    1023             : 
    1024           0 :   if (DBG_LOOKUP)
    1025           0 :     log_debug ("find_cert_bysn: certificate not returned by caller"
    1026             :                " - doing lookup\n");
    1027             : 
    1028             :   /* Retrieve the certificate from external resources. */
    1029           0 :   while (!cert)
    1030             :     {
    1031             :       ksba_sexp_t sn;
    1032             :       char *issdn;
    1033             : 
    1034           0 :       if (!context)
    1035             :         {
    1036           0 :           err = ca_cert_fetch (ctrl, &context, issuer_dn);
    1037           0 :           if (err)
    1038             :             {
    1039           0 :               log_error (_("error fetching certificate by S/N: %s\n"),
    1040             :                          gpg_strerror (err));
    1041           0 :               break;
    1042             :             }
    1043             :         }
    1044             : 
    1045           0 :       err = fetch_next_ksba_cert (context, &cert);
    1046           0 :       if (err)
    1047             :         {
    1048           0 :           log_error (_("error fetching certificate by S/N: %s\n"),
    1049             :                      gpg_strerror (err) );
    1050           0 :           break;
    1051             :         }
    1052             : 
    1053           0 :       issdn = ksba_cert_get_issuer (cert, 0);
    1054           0 :       if (strcmp (issuer_dn, issdn))
    1055             :         {
    1056           0 :           log_debug ("find_cert_bysn: Ooops: issuer DN does not match\n");
    1057           0 :           ksba_cert_release (cert);
    1058           0 :           cert = NULL;
    1059           0 :           ksba_free (issdn);
    1060           0 :           break;
    1061             :         }
    1062             : 
    1063           0 :       sn = ksba_cert_get_serial (cert);
    1064             : 
    1065           0 :       if (DBG_LOOKUP)
    1066             :         {
    1067           0 :           log_debug ("   considering certificate (#");
    1068           0 :           dump_serial (sn);
    1069           0 :           log_printf ("/");
    1070           0 :           dump_string (issdn);
    1071           0 :           log_printf (")\n");
    1072             :         }
    1073             : 
    1074           0 :       if (!compare_serialno (serialno, sn))
    1075             :         {
    1076           0 :           ksba_free (sn);
    1077           0 :           ksba_free (issdn);
    1078           0 :           cache_cert (cert);
    1079           0 :           if (DBG_LOOKUP)
    1080           0 :             log_debug ("   found\n");
    1081           0 :           break; /* Ready.  */
    1082             :         }
    1083             : 
    1084           0 :       ksba_free (sn);
    1085           0 :       ksba_free (issdn);
    1086           0 :       ksba_cert_release (cert);
    1087           0 :       cert = NULL;
    1088             :     }
    1089             : 
    1090           0 :   end_cert_fetch (context);
    1091           0 :   return cert;
    1092             : }
    1093             : 
    1094             : 
    1095             : /* Return the certificate matching SUBJECT_DN and (if not NULL)
    1096             :    KEYID. If it is not already in the cache, try to find it from other
    1097             :    resources.  Note, that the external search does not work for user
    1098             :    certificates because the LDAP lookup is on the caCertificate
    1099             :    attribute. For our purposes this is just fine.  */
    1100             : ksba_cert_t
    1101           0 : find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid)
    1102             : {
    1103             :   gpg_error_t err;
    1104             :   int seq;
    1105           0 :   ksba_cert_t cert = NULL;
    1106           0 :   cert_fetch_context_t context = NULL;
    1107             :   ksba_sexp_t subj;
    1108             : 
    1109             :   /* If we have certificates from an OCSP request we first try to use
    1110             :      them.  This is because these certificates will really be the
    1111             :      required ones and thus even in the case that they can't be
    1112             :      uniquely located by the following code we can use them.  This is
    1113             :      for example required by Telesec certificates where a keyId is
    1114             :      used but the issuer certificate comes without a subject keyId! */
    1115           0 :   if (ctrl->ocsp_certs && subject_dn)
    1116             :     {
    1117             :       cert_item_t ci;
    1118             :       cert_ref_t cr;
    1119             :       int i;
    1120             : 
    1121             :       /* For efficiency reasons we won't use get_cert_bysubject here. */
    1122           0 :       acquire_cache_read_lock ();
    1123           0 :       for (i=0; i < 256; i++)
    1124           0 :         for (ci=cert_cache[i]; ci; ci = ci->next)
    1125           0 :           if (ci->cert && ci->subject_dn
    1126           0 :               && !strcmp (ci->subject_dn, subject_dn))
    1127           0 :             for (cr=ctrl->ocsp_certs; cr; cr = cr->next)
    1128           0 :               if (!memcmp (ci->fpr, cr->fpr, 20))
    1129             :                 {
    1130           0 :                   ksba_cert_ref (ci->cert);
    1131           0 :                   release_cache_lock ();
    1132           0 :                   return ci->cert; /* We use this certificate. */
    1133             :                 }
    1134           0 :       release_cache_lock ();
    1135           0 :       if (DBG_LOOKUP)
    1136           0 :         log_debug ("find_cert_bysubject: certificate not in ocsp_certs\n");
    1137             :     }
    1138             : 
    1139             : 
    1140             :   /* First we check whether the certificate is cached.  */
    1141           0 :   for (seq=0; (cert = get_cert_bysubject (subject_dn, seq)); seq++)
    1142             :     {
    1143           0 :       if (!keyid)
    1144           0 :         break; /* No keyid requested, so return the first one found. */
    1145           0 :       if (!ksba_cert_get_subj_key_id (cert, NULL, &subj)
    1146           0 :           && !cmp_simple_canon_sexp (keyid, subj))
    1147             :         {
    1148           0 :           xfree (subj);
    1149           0 :           break; /* Found matching cert. */
    1150             :         }
    1151           0 :       xfree (subj);
    1152           0 :       ksba_cert_release (cert);
    1153             :     }
    1154           0 :   if (cert)
    1155           0 :     return cert; /* Done.  */
    1156             : 
    1157           0 :   if (DBG_LOOKUP)
    1158           0 :     log_debug ("find_cert_bysubject: certificate not in cache\n");
    1159             : 
    1160             :   /* Ask back to the service requester to return the certificate.
    1161             :      This is because we can assume that he already used the
    1162             :      certificate while checking for the CRL. */
    1163           0 :   if (keyid)
    1164           0 :     cert = get_cert_local_ski (ctrl, subject_dn, keyid);
    1165             :   else
    1166             :     {
    1167             :       /* In contrast to get_cert_local_ski, get_cert_local uses any
    1168             :          passed pattern, so we need to make sure that an exact subject
    1169             :          search is done. */
    1170             :       char *buf;
    1171             : 
    1172           0 :       buf = xtrymalloc (1 + strlen (subject_dn) + 1);
    1173           0 :       if (!buf)
    1174             :         {
    1175           0 :           log_error ("can't allocate enough memory: %s\n", strerror (errno));
    1176           0 :           return NULL;
    1177             :         }
    1178           0 :       strcpy (stpcpy (buf, "/"), subject_dn);
    1179           0 :       cert = get_cert_local (ctrl, buf);
    1180           0 :       xfree (buf);
    1181             :     }
    1182           0 :   if (cert)
    1183             :     {
    1184           0 :       cache_cert (cert);
    1185           0 :       return cert; /* Done. */
    1186             :     }
    1187             : 
    1188           0 :   if (DBG_LOOKUP)
    1189           0 :     log_debug ("find_cert_bysubject: certificate not returned by caller"
    1190             :                " - doing lookup\n");
    1191             : 
    1192             :   /* Locate the certificate using external resources. */
    1193           0 :   while (!cert)
    1194             :     {
    1195             :       char *subjdn;
    1196             : 
    1197           0 :       if (!context)
    1198             :         {
    1199           0 :           err = ca_cert_fetch (ctrl, &context, subject_dn);
    1200           0 :           if (err)
    1201             :             {
    1202           0 :               log_error (_("error fetching certificate by subject: %s\n"),
    1203             :                          gpg_strerror (err));
    1204           0 :               break;
    1205             :             }
    1206             :         }
    1207             : 
    1208           0 :       err = fetch_next_ksba_cert (context, &cert);
    1209           0 :       if (err)
    1210             :         {
    1211           0 :           log_error (_("error fetching certificate by subject: %s\n"),
    1212             :                      gpg_strerror (err) );
    1213           0 :           break;
    1214             :         }
    1215             : 
    1216           0 :       subjdn = ksba_cert_get_subject (cert, 0);
    1217           0 :       if (strcmp (subject_dn, subjdn))
    1218             :         {
    1219           0 :           log_info ("find_cert_bysubject: subject DN does not match\n");
    1220           0 :           ksba_cert_release (cert);
    1221           0 :           cert = NULL;
    1222           0 :           ksba_free (subjdn);
    1223           0 :           continue;
    1224             :         }
    1225             : 
    1226             : 
    1227           0 :       if (DBG_LOOKUP)
    1228             :         {
    1229           0 :           log_debug ("   considering certificate (/");
    1230           0 :           dump_string (subjdn);
    1231           0 :           log_printf (")\n");
    1232             :         }
    1233           0 :       ksba_free (subjdn);
    1234             : 
    1235             :       /* If no key ID has been provided, we return the first match.  */
    1236           0 :       if (!keyid)
    1237             :         {
    1238           0 :           cache_cert (cert);
    1239           0 :           if (DBG_LOOKUP)
    1240           0 :             log_debug ("   found\n");
    1241           0 :           break; /* Ready.  */
    1242             :         }
    1243             : 
    1244             :       /* With the key ID given we need to compare it.  */
    1245           0 :       if (!ksba_cert_get_subj_key_id (cert, NULL, &subj))
    1246             :         {
    1247           0 :           if (!cmp_simple_canon_sexp (keyid, subj))
    1248             :             {
    1249           0 :               ksba_free (subj);
    1250           0 :               cache_cert (cert);
    1251           0 :               if (DBG_LOOKUP)
    1252           0 :                 log_debug ("   found\n");
    1253           0 :               break; /* Ready.  */
    1254             :             }
    1255             :         }
    1256             : 
    1257           0 :       ksba_free (subj);
    1258           0 :       ksba_cert_release (cert);
    1259           0 :       cert = NULL;
    1260             :     }
    1261             : 
    1262           0 :   end_cert_fetch (context);
    1263           0 :   return cert;
    1264             : }
    1265             : 
    1266             : 
    1267             : 
    1268             : /* Return 0 if the certificate is a trusted certificate. Returns
    1269             :    GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
    1270             :    case of systems errors. */
    1271             : gpg_error_t
    1272           0 : is_trusted_cert (ksba_cert_t cert)
    1273             : {
    1274             :   unsigned char fpr[20];
    1275             :   cert_item_t ci;
    1276             : 
    1277           0 :   cert_compute_fpr (cert, fpr);
    1278             : 
    1279           0 :   acquire_cache_read_lock ();
    1280           0 :   for (ci=cert_cache[*fpr]; ci; ci = ci->next)
    1281           0 :     if (ci->cert && !memcmp (ci->fpr, fpr, 20))
    1282             :       {
    1283           0 :         if (ci->flags.trusted)
    1284             :           {
    1285           0 :             release_cache_lock ();
    1286           0 :             return 0; /* Yes, it is trusted. */
    1287             :           }
    1288           0 :         break;
    1289             :       }
    1290             : 
    1291           0 :   release_cache_lock ();
    1292           0 :   return gpg_error (GPG_ERR_NOT_TRUSTED);
    1293             : }
    1294             : 
    1295             : 
    1296             : 
    1297             : /* Given the certificate CERT locate the issuer for this certificate
    1298             :    and return it at R_CERT.  Returns 0 on success or
    1299             :    GPG_ERR_NOT_FOUND.  */
    1300             : gpg_error_t
    1301           0 : find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert)
    1302             : {
    1303             :   gpg_error_t err;
    1304             :   char *issuer_dn;
    1305           0 :   ksba_cert_t issuer_cert = NULL;
    1306             :   ksba_name_t authid;
    1307             :   ksba_sexp_t authidno;
    1308             :   ksba_sexp_t keyid;
    1309             : 
    1310           0 :   *r_cert = NULL;
    1311             : 
    1312           0 :   issuer_dn = ksba_cert_get_issuer (cert, 0);
    1313           0 :   if (!issuer_dn)
    1314             :     {
    1315           0 :       log_error (_("no issuer found in certificate\n"));
    1316           0 :       err = gpg_error (GPG_ERR_BAD_CERT);
    1317           0 :       goto leave;
    1318             :     }
    1319             : 
    1320             :   /* First we need to check whether we can return that certificate
    1321             :      using the authorithyKeyIdentifier.  */
    1322           0 :   err = ksba_cert_get_auth_key_id (cert, &keyid, &authid, &authidno);
    1323           0 :   if (err)
    1324             :     {
    1325           0 :       log_info (_("error getting authorityKeyIdentifier: %s\n"),
    1326             :                 gpg_strerror (err));
    1327             :     }
    1328             :   else
    1329             :     {
    1330           0 :       const char *s = ksba_name_enum (authid, 0);
    1331           0 :       if (s && *authidno)
    1332             :         {
    1333           0 :           issuer_cert = find_cert_bysn (ctrl, s, authidno);
    1334             :         }
    1335           0 :       if (!issuer_cert && keyid)
    1336             :         {
    1337             :           /* Not found by issuer+s/n.  Now that we have an AKI
    1338             :              keyIdentifier look for a certificate with a matching
    1339             :              SKI. */
    1340           0 :           issuer_cert = find_cert_bysubject (ctrl, issuer_dn, keyid);
    1341             :         }
    1342             :       /* Print a note so that the user does not feel too helpless when
    1343             :          an issuer certificate was found and gpgsm prints BAD
    1344             :          signature because it is not the correct one. */
    1345           0 :       if (!issuer_cert)
    1346             :         {
    1347           0 :           log_info ("issuer certificate ");
    1348           0 :           if (keyid)
    1349             :             {
    1350           0 :               log_printf ("{");
    1351           0 :               dump_serial (keyid);
    1352           0 :               log_printf ("} ");
    1353             :             }
    1354           0 :           if (authidno)
    1355             :             {
    1356           0 :               log_printf ("(#");
    1357           0 :               dump_serial (authidno);
    1358           0 :               log_printf ("/");
    1359           0 :               dump_string (s);
    1360           0 :               log_printf (") ");
    1361             :             }
    1362           0 :           log_printf ("not found using authorityKeyIdentifier\n");
    1363             :         }
    1364           0 :       ksba_name_release (authid);
    1365           0 :       xfree (authidno);
    1366           0 :       xfree (keyid);
    1367             :     }
    1368             : 
    1369             :   /* If this did not work, try just with the issuer's name and assume
    1370             :      that there is only one such certificate.  We only look into our
    1371             :      cache then. */
    1372           0 :   if (err || !issuer_cert)
    1373             :     {
    1374           0 :       issuer_cert = get_cert_bysubject (issuer_dn, 0);
    1375           0 :       if (issuer_cert)
    1376           0 :         err = 0;
    1377             :     }
    1378             : 
    1379             :  leave:
    1380           0 :   if (!err && !issuer_cert)
    1381           0 :     err = gpg_error (GPG_ERR_NOT_FOUND);
    1382             : 
    1383           0 :   xfree (issuer_dn);
    1384             : 
    1385           0 :   if (err)
    1386           0 :     ksba_cert_release (issuer_cert);
    1387             :   else
    1388           0 :     *r_cert = issuer_cert;
    1389             : 
    1390           0 :   return err;
    1391             : }

Generated by: LCOV version 1.11