]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
changes to remove the KEYRING_HACK and make keyring access thread safe.
authorNikos <nmav@crystal.(none)>
Sat, 26 Jan 2008 21:08:18 +0000 (23:08 +0200)
committerNikos <nmav@crystal.(none)>
Sat, 26 Jan 2008 21:08:18 +0000 (23:08 +0200)
lib/auth_cert.h
lib/gnutls_cert.c
lib/gnutls_int.h
lib/gnutls_openpgp.c
lib/opencdk/keydb.c
lib/opencdk/keydb.h
lib/opencdk/opencdk.h
lib/opencdk/stream.c
lib/openpgp/compat.c
lib/openpgp/extras.c
lib/openpgp/openpgp.h

index d2db7ab1584f01c16e24e3988566210c821f5523..7d9381a8cb03f51f61c30bd7870592765c5d94a4 100644 (file)
@@ -64,12 +64,7 @@ typedef struct gnutls_certificate_credentials_st
 
   /* OpenPGP specific stuff */
 
-#ifndef KEYRING_HACK
   gnutls_openpgp_keyring_t keyring;
-#else
-  gnutls_datum_t keyring;
-  int keyring_format;
-#endif
 
   /* X509 specific stuff */
 
index 669deb33ccdbc58d57938ae477ad9336be1abfdb..dad38ad1c9dbb088de3b13fb2fdf80b0996fd074 100644 (file)
@@ -194,12 +194,8 @@ gnutls_certificate_free_credentials (gnutls_certificate_credentials_t sc)
 #endif
 
 #ifdef ENABLE_OPENPGP
-#ifndef KEYRING_HACK
   if (_E_gnutls_openpgp_keyring_deinit)
     _E_gnutls_openpgp_keyring_deinit( sc->keyring);
-#else
-  _gnutls_free_datum( &sc->keyring);
-#endif
 #endif
 
   gnutls_free (sc);
index d8d94c706d9abcefc730c81a536b46baf802d79e..679e563d045f23d655ef6a14a228097ff4147b01 100644 (file)
 #include <gnutls/gnutls.h>
 #include <gnutls/extra.h>
 
-/* FIXME: delete this once opencdk has reentrant keyring functions
- */
-#define KEYRING_HACK
-
 /*
  * They are not needed any more. You can simply enable
  * the gnutls_log callback to get error descriptions.
index 7968eab4c9e397c24f93eef5e7029b5c3dbdfaff..3a5f3c034f516f64e8421f1926969b29010e906c 100644 (file)
@@ -598,7 +598,6 @@ gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
                                            c, const opaque * data,
                                            size_t dlen, gnutls_openpgp_crt_fmt_t format)
 {
-#ifndef KEYRING_HACK
   cdk_stream_t inp;
   size_t count;
   uint8_t *buf;
@@ -628,21 +627,6 @@ gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
   }
   
   return 0;
-#else
-
-  c->keyring_format = format;
-
-  c->keyring.data = gnutls_malloc( dlen+1);
-  if (c->keyring.data == NULL)
-  {
-    gnutls_assert();
-    return GNUTLS_E_MEMORY_ERROR;
-  }
-  memcpy(c->keyring.data, data, dlen);
-  c->keyring.data[dlen]=0;
-  c->keyring.size = dlen;
-
-#endif
 }
 
 /*-
@@ -662,9 +646,6 @@ _gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
                             opaque * key_fpr, int key_fpr_size)
 {
   int rc = 0;
-#ifdef KEYRING_HACK
-  gnutls_openpgp_keyring_t kring;
-#endif
 
   if (!ret || !cred || !key_fpr)
     {
@@ -675,22 +656,8 @@ _gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
   if (key_fpr_size != 16 && key_fpr_size != 20)
     return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */
 
-#ifndef KEYRING_HACK
   rc = gnutls_openpgp_get_key (ret, cred->keyring, KEY_ATTR_FPR, key_fpr);
-#else
-  rc = gnutls_openpgp_keyring_init( &kring);
-  if ( rc < 0) {
-    gnutls_assert();
-    return rc;
-  }
-  
-  rc = gnutls_openpgp_keyring_import( kring, &cred->keyring, cred->keyring_format);
-  if ( rc < 0) {
-    gnutls_assert();
-    gnutls_openpgp_keyring_deinit( kring);
-    return rc;
-  }
-#endif
+
   if (rc >= 0) /* key was found */
     {
       rc = 0;
@@ -714,9 +681,7 @@ _gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
     }
 
   error:
-#ifdef KEYRING_HACK
-  gnutls_openpgp_keyring_deinit( kring);
-#endif
+
   return rc;
 }
 
index 4638ed3e5d2fdea709757cf561816099571e2b32..0a236ff753923f46319e8722ae70633a9c31585d 100644 (file)
 #define KEYID_CMP(a, b) ((a[0]) == (b[0]) && (a[1]) == (b[1]))
 #define KEYDB_CACHE_ENTRIES 8
 
-
-/* Internal key index structure. */
-struct key_idx_s 
-{
-  off_t offset;
-  u32 keyid[2];
-  byte fpr[KEY_FPR_LEN];
-};
-typedef struct key_idx_s *key_idx_t;
-
-
-/* Internal handle for the search operation. */
-struct cdk_dbsearch_s  
-{
-  union 
-    {    
-      char *pattern; /* A search is performed by pattern. */
-      u32 keyid[2];  /* A search by keyid. */
-      byte fpr[KEY_FPR_LEN]; /* A search by fingerprint. */
-    } u;
-  int type;
-};
-typedef struct cdk_dbsearch_s *cdk_dbsearch_t;
-
-/* Internal key cache to associate a key with an file offset. */
-struct key_table_s 
-{
-  struct key_table_s *next;
-  off_t offset;
-  cdk_dbsearch_t desc;
-};
-typedef struct key_table_s *key_table_t;
-
-/* Internal key database handle. */
-struct cdk_keydb_hd_s 
-{
-  int type;   /* type of the key db handle. */
-  int fp_ref; /* 1=means it is a reference and shall not be closed. */
-  cdk_stream_t fp;
-  cdk_stream_t idx;
-  cdk_dbsearch_t dbs;
-  char *name;            /* name of the underlying file or NULL. */
-  char *idx_name;        /* name of the index file or NULL. */
-  struct key_table_s *cache;
-  size_t ncache;
-  unsigned int secret:1;   /* contain secret keys. */
-  unsigned int isopen:1;   /* the underlying stream is opened. */
-  unsigned int no_cache:1; /* disable the index cache. */
-  unsigned int search:1;   /* handle is in search mode. */
-  
-  /* structure to store some stats about the keydb. */
-  struct {
-    size_t new_keys; /* amount of new keys that were imported. */
-  } stats;
-};
-
-
 static void keydb_cache_free (key_table_t cache);
-static int keydb_search_copy (cdk_dbsearch_t *r_dst, cdk_dbsearch_t src);
-static void keydb_search_free (cdk_dbsearch_t dbs);
+static int keydb_search_copy (cdk_keydb_search_t *r_dst, cdk_keydb_search_t src);
 static int classify_data (const byte * buf, size_t len);
 static cdk_kbnode_t find_selfsig_node (cdk_kbnode_t key, cdk_pkt_pubkey_t pk);
-
      
 static char*
 keydb_idx_mkname (const char *file)
@@ -198,14 +139,14 @@ keydb_idx_build (const char *file)
  * Rebuild the key index files for the given key database.
  **/
 cdk_error_t
-cdk_keydb_idx_rebuild (cdk_keydb_hd_t db)
+cdk_keydb_idx_rebuild (cdk_keydb_hd_t db, cdk_keydb_search_t dbs)
 {
   struct stat stbuf;
   char *tmp_idx_name;
   cdk_error_t rc;
   int err;
   
-  if (!db || !db->name)
+  if (!db || !db->name|| !dbs)
     return CDK_Inv_Value;
   if (db->secret)
     return 0;
@@ -220,17 +161,17 @@ cdk_keydb_idx_rebuild (cdk_keydb_hd_t db)
   if (err)
     return 0;  
   
-  cdk_stream_close (db->idx);
-  db->idx = NULL;
-  if (!db->idx_name) 
+  cdk_stream_close (dbs->idx);
+  dbs->idx = NULL;
+  if (!dbs->idx_name) 
     {
-      db->idx_name = keydb_idx_mkname (db->name);
-      if (!db->idx_name)
+      dbs->idx_name = keydb_idx_mkname (db->name);
+      if (!dbs->idx_name)
        return CDK_Out_Of_Core;
     }
   rc = keydb_idx_build (db->name);
   if (!rc)
-    rc = cdk_stream_open (db->idx_name, &db->idx);
+    rc = cdk_stream_open (dbs->idx_name, &dbs->idx);
   return rc;
 }
 
@@ -447,19 +388,9 @@ cdk_keydb_free (cdk_keydb_hd_t hd)
       hd->fp = NULL;
     }
   
-  if (hd->idx)
-    {
-      cdk_stream_close (hd->idx);
-      hd->idx = NULL;
-    }
   
   hd->isopen = 0;
-  hd->no_cache = 0;
   hd->secret = 0;
-  keydb_cache_free (hd->cache);
-  hd->cache = NULL;
-  keydb_search_free (hd->dbs);
-  hd->dbs = NULL;
   cdk_free (hd);
 }
 
@@ -468,6 +399,7 @@ cdk_error_t
 _cdk_keydb_open (cdk_keydb_hd_t hd, cdk_stream_t *ret_kr)
 {
   cdk_error_t rc, ec;
+  cdk_stream_t kr;
 
   if (!hd || !ret_kr)
     return CDK_Inv_Value;
@@ -475,76 +407,33 @@ _cdk_keydb_open (cdk_keydb_hd_t hd, cdk_stream_t *ret_kr)
   rc = 0;
   if ((hd->type == CDK_DBTYPE_DATA || hd->type == CDK_DBTYPE_STREAM) 
       && hd->fp)
-    cdk_stream_seek (hd->fp, 0);
+    {
+      kr =  hd->fp;
+      cdk_stream_seek (kr, 0);
+    }
   else if (hd->type == CDK_DBTYPE_PK_KEYRING ||
           hd->type == CDK_DBTYPE_SK_KEYRING)
     {
-      if (!hd->isopen && hd->name)
-       {
-         rc = cdk_stream_open (hd->name, &hd->fp);
-         if (rc)
-           goto leave;
-         if (cdk_armor_filter_use (hd->fp))
-           cdk_stream_set_armor_flag (hd->fp, 0);
-         hd->isopen = 1;
-         /* We disable the index cache for smaller keyrings. */
-         if (cdk_stream_get_length (hd->fp) < 524288)
-           {
-             hd->no_cache = 1;
-             goto leave;
-           }
-         cdk_free (hd->idx_name);        
-         hd->idx_name = keydb_idx_mkname (hd->name);
-         if (!hd->idx_name)
-           {
-             rc = CDK_Out_Of_Core;
-             goto leave;
-            }
-         ec = cdk_stream_open (hd->idx_name, &hd->idx);
-         if (ec && !hd->secret)
-           {
-             rc = keydb_idx_build (hd->name);
-             if (!rc)
-               rc = cdk_stream_open (hd->idx_name, &hd->idx);
-             if (!rc)
-               _cdk_log_debug ("create key index table\n");
-             else
-               {
-                 /* This is no real error, it just means we can't create
-                    the index at the given directory. maybe we've no write
-                    access. in this case, we simply disable the index. */
-                 _cdk_log_debug ("disable key index table err=%d\n", rc);
-                 rc = 0;
-                 hd->no_cache = 1;
-               }
-            }
-        }
-      else 
-       {
-         /* We use the cache to search keys, so we always rewind the
-            STREAM. Except when the _NEXT search mode is used because
-            this mode is an enumeration and no seeking is needed. */
-         if (!hd->search ||
-             (hd->search && hd->dbs->type != CDK_DBSEARCH_NEXT))
-           cdk_stream_seek (hd->fp, 0);
-        }
+      rc = cdk_stream_open (hd->name, &kr);
+
+      if (rc)
+        goto leave;
+
+      if (cdk_armor_filter_use (kr))
+        cdk_stream_set_armor_flag (kr, 0);
     }
   else
     return CDK_Inv_Mode;
   
   leave:
-  if (rc) 
-    {
-      cdk_stream_close (hd->fp);
-      hd->fp = NULL;
-    }
-  *ret_kr = hd->fp;
+
+  *ret_kr = kr;
   return rc;
 }
 
 
 static int
-find_by_keyid (cdk_kbnode_t knode, cdk_dbsearch_t ks)
+find_by_keyid (cdk_kbnode_t knode, cdk_keydb_search_t ks)
 {
   cdk_kbnode_t node;
   u32 keyid[2];
@@ -580,7 +469,7 @@ find_by_keyid (cdk_kbnode_t knode, cdk_dbsearch_t ks)
 
 
 static int
-find_by_fpr (cdk_kbnode_t knode, cdk_dbsearch_t ks)
+find_by_fpr (cdk_kbnode_t knode, cdk_keydb_search_t ks)
 {
   cdk_kbnode_t node;
   byte fpr[KEY_FPR_LEN];
@@ -607,7 +496,7 @@ find_by_fpr (cdk_kbnode_t knode, cdk_dbsearch_t ks)
 
 
 static int
-find_by_pattern (cdk_kbnode_t knode, cdk_dbsearch_t ks)
+find_by_pattern (cdk_kbnode_t knode, cdk_keydb_search_t ks)
 {
   cdk_kbnode_t node;
   size_t uidlen;
@@ -647,19 +536,6 @@ find_by_pattern (cdk_kbnode_t knode, cdk_dbsearch_t ks)
 }
 
 
-static void
-keydb_search_free (cdk_dbsearch_t dbs)
-{
-  if (!dbs)
-    return;
-  if (dbs->type == CDK_DBSEARCH_EXACT || 
-      dbs->type == CDK_DBSEARCH_SUBSTR)
-    cdk_free (dbs->u.pattern);
-  dbs->type = 0;
-  cdk_free (dbs);    
-}
-
-
 static void
 keydb_cache_free (key_table_t cache)
 {
@@ -669,7 +545,6 @@ keydb_cache_free (key_table_t cache)
     {
       c2 = cache->next;
       cache->offset = 0;
-      keydb_search_free (cache->desc);
       cdk_free (cache);
       cache = c2;
     }
@@ -677,35 +552,34 @@ keydb_cache_free (key_table_t cache)
 
 
 static key_table_t
-keydb_cache_find (key_table_t cache, cdk_dbsearch_t desc)
+keydb_cache_find ( cdk_keydb_search_t desc)
 {
+  key_table_t cache = desc->cache;
   key_table_t t;
   
   for (t = cache; t; t = t->next)
     {
-      if (t->desc->type != desc->type)
-       continue;
-      switch (t->desc->type)
+      switch (desc->type)
        {
        case CDK_DBSEARCH_SHORT_KEYID:
        case CDK_DBSEARCH_KEYID:
-         if (KEYID_CMP (t->desc->u.keyid, desc->u.keyid))
+         if (KEYID_CMP (desc->u.keyid, desc->u.keyid))
            return t;
          break;
 
        case CDK_DBSEARCH_EXACT:
-         if (strlen (t->desc->u.pattern) == strlen (desc->u.pattern) &&
-             !strcmp (t->desc->u.pattern, desc->u.pattern))
+         if (strlen (desc->u.pattern) == strlen (desc->u.pattern) &&
+             !strcmp (desc->u.pattern, desc->u.pattern))
            return t;
          break;
 
        case CDK_DBSEARCH_SUBSTR:
-         if (strstr (t->desc->u.pattern, desc->u.pattern))
+         if (strstr (desc->u.pattern, desc->u.pattern))
            return t;
          break;
          
        case CDK_DBSEARCH_FPR:
-         if (!memcmp (t->desc->u.fpr, desc->u.fpr, KEY_FPR_LEN))
+         if (!memcmp (desc->u.fpr, desc->u.fpr, KEY_FPR_LEN))
            return t;
          break;
         }
@@ -716,32 +590,30 @@ keydb_cache_find (key_table_t cache, cdk_dbsearch_t desc)
   
 
 static cdk_error_t
-keydb_cache_add (cdk_keydb_hd_t hd, cdk_dbsearch_t dbs, off_t offset)
+keydb_cache_add ( cdk_keydb_search_t dbs, off_t offset)
 {
   key_table_t k;
 
-  if (!hd)
-    return CDK_Inv_Value;
-  
-  if (hd->ncache > KEYDB_CACHE_ENTRIES)
+  if (dbs->ncache > KEYDB_CACHE_ENTRIES)
     return 0; /* FIXME: we should replace the last entry. */
   k = cdk_calloc (1, sizeof *k);
   if (!k)
     return CDK_Out_Of_Core;
+
   k->offset = offset;
-  keydb_search_copy (&k->desc, dbs);
-  k->next = hd->cache;
-  hd->cache = k;
-  hd->ncache++;
+
+  k->next = dbs->cache;
+  dbs->cache = k;
+  dbs->ncache++;
   _cdk_log_debug ("cache: add entry off=%d type=%d\n", offset, dbs->type);
   return 0;
 }
 
       
 static cdk_error_t
-keydb_search_copy (cdk_dbsearch_t *r_dst, cdk_dbsearch_t src)
+keydb_search_copy (cdk_keydb_search_t *r_dst, cdk_keydb_search_t src)
 {
-  cdk_dbsearch_t dst;
+  cdk_keydb_search_t dst;
   
   if (!r_dst || !src)
     return CDK_Inv_Value;
@@ -750,6 +622,8 @@ keydb_search_copy (cdk_dbsearch_t *r_dst, cdk_dbsearch_t src)
   dst = cdk_calloc (1, sizeof *dst);
   if (!dst)
     return CDK_Out_Of_Core;
+    
+  dst->off = src->off;
   dst->type = src->type;
   switch (src->type)
     {
@@ -774,6 +648,46 @@ keydb_search_copy (cdk_dbsearch_t *r_dst, cdk_dbsearch_t src)
   return 0;
 }
 
+static cdk_error_t idx_init( cdk_keydb_hd_t db, cdk_keydb_search_t dbs)
+{
+cdk_error_t ec, rc = 0;
+
+         if (cdk_stream_get_length (db->fp) < 524288)
+           {
+             dbs->no_cache = 1;
+             goto leave;
+           }
+
+         dbs->idx_name = keydb_idx_mkname (db->name);
+         if (!dbs->idx_name)
+           {
+             rc = CDK_Out_Of_Core;
+             goto leave;
+            }
+         ec = cdk_stream_open (dbs->idx_name, &dbs->idx);
+
+         if (ec && !db->secret)
+           {
+             rc = keydb_idx_build (db->name);
+             if (!rc)
+               rc = cdk_stream_open (dbs->idx_name, &dbs->idx);
+             if (!rc)
+               _cdk_log_debug ("create key index table\n");
+             else
+               {
+                 /* This is no real error, it just means we can't create
+                    the index at the given directory. maybe we've no write
+                    access. in this case, we simply disable the index. */
+                 _cdk_log_debug ("disable key index table err=%d\n", rc);
+                 rc = 0;
+                 dbs->no_cache = 1;
+               }
+            }
+
+leave:
+
+  return rc;
+}
 
 /**
  * cdk_keydb_search_start:
@@ -787,10 +701,10 @@ keydb_search_copy (cdk_dbsearch_t *r_dst, cdk_dbsearch_t src)
 cdk_error_t
 cdk_keydb_search_start (cdk_keydb_search_t* st, cdk_keydb_hd_t db, int type, void *desc)
 {
-  cdk_dbsearch_t dbs;
   u32 *keyid;
   char *p, tmp[3];
   int i;
+  cdk_error_t rc;
   
   if (!db)
     return CDK_Inv_Value;
@@ -801,36 +715,40 @@ cdk_keydb_search_start (cdk_keydb_search_t* st, cdk_keydb_hd_t db, int type, voi
   if (!(*st))
     return CDK_Out_Of_Core;
 
-  dbs = cdk_calloc (1, sizeof *dbs);
-  if (!dbs)
-    return CDK_Out_Of_Core;
-  dbs->type = type;
+  rc = idx_init( db, *st);
+  if (rc != CDK_Success)
+    {
+      free(*st);
+      return rc;
+    }
+
+  (*st)->type = type;
   switch (type) 
     {
     case CDK_DBSEARCH_EXACT:
     case CDK_DBSEARCH_SUBSTR:
-      cdk_free (dbs->u.pattern);
-      dbs->u.pattern = cdk_strdup (desc);
-      if (!dbs->u.pattern)
+      cdk_free ((*st)->u.pattern);
+      (*st)->u.pattern = cdk_strdup (desc);
+      if (!(*st)->u.pattern)
        {
-         cdk_free (dbs);
+         cdk_free (*st);
          return CDK_Out_Of_Core;
        }
       break;
       
     case CDK_DBSEARCH_SHORT_KEYID:
       keyid = desc;
-      dbs->u.keyid[1] = keyid[0];
+      (*st)->u.keyid[1] = keyid[0];
       break;
       
     case CDK_DBSEARCH_KEYID:
       keyid = desc;
-      dbs->u.keyid[0] = keyid[0];
-      dbs->u.keyid[1] = keyid[1];
+      (*st)->u.keyid[0] = keyid[0];
+      (*st)->u.keyid[1] = keyid[1];
       break;
       
     case CDK_DBSEARCH_FPR:
-      memcpy (dbs->u.fpr, desc, KEY_FPR_LEN);
+      memcpy ((*st)->u.fpr, desc, KEY_FPR_LEN);
       break;
       
     case CDK_DBSEARCH_NEXT:
@@ -838,16 +756,16 @@ cdk_keydb_search_start (cdk_keydb_search_t* st, cdk_keydb_hd_t db, int type, voi
       
     case CDK_DBSEARCH_AUTO:
       /* Override the type with the actual db search type. */
-      dbs->type = classify_data (desc, strlen (desc));
-      switch (dbs->type)
+      (*st)->type = classify_data (desc, strlen (desc));
+      switch ((*st)->type)
        {
        case CDK_DBSEARCH_SUBSTR:
        case CDK_DBSEARCH_EXACT:
-         cdk_free (dbs->u.pattern);
-         p = dbs->u.pattern = cdk_strdup (desc);
+         cdk_free ((*st)->u.pattern);
+         p = (*st)->u.pattern = cdk_strdup (desc);
          if (!p) 
            {
-             cdk_free (dbs);
+             cdk_free (*st);
              return CDK_Out_Of_Core;
            }
          break;
@@ -859,17 +777,17 @@ cdk_keydb_search_start (cdk_keydb_search_t* st, cdk_keydb_hd_t db, int type, voi
            p += 2;
          if (strlen (p) == 8)
            {
-             dbs->u.keyid[0] = 0;
-             dbs->u.keyid[1] = strtoul (p, NULL, 16);
+             (*st)->u.keyid[0] = 0;
+             (*st)->u.keyid[1] = strtoul (p, NULL, 16);
            }
          else if (strlen (p) == 16)
            {
-             dbs->u.keyid[0] = strtoul (p    , NULL, 16);
-             dbs->u.keyid[1] = strtoul (p + 8, NULL, 16);
+             (*st)->u.keyid[0] = strtoul (p    , NULL, 16);
+             (*st)->u.keyid[1] = strtoul (p + 8, NULL, 16);
            }
          else 
            { /* Invalid key ID object. */
-             cdk_free (dbs);
+             cdk_free (*st);
              return CDK_Inv_Mode;
          }
          break;
@@ -878,7 +796,7 @@ cdk_keydb_search_start (cdk_keydb_search_t* st, cdk_keydb_hd_t db, int type, voi
          p = desc;
          if (strlen (p) != 2*KEY_FPR_LEN)
            {
-             cdk_free (dbs);
+             cdk_free (*st);
              return CDK_Inv_Mode;
            }
          for (i = 0; i < KEY_FPR_LEN; i++)
@@ -886,26 +804,24 @@ cdk_keydb_search_start (cdk_keydb_search_t* st, cdk_keydb_hd_t db, int type, voi
              tmp[0] = p[2*i];
              tmp[1] = p[2*i+1];
              tmp[2] = 0x00;
-             dbs->u.fpr[i] = strtoul (tmp, NULL, 16);
+             (*st)->u.fpr[i] = strtoul (tmp, NULL, 16);
            }
          break;
        }
       break;
       
     default:
-      cdk_free (dbs);
+      cdk_free (*st);
       _cdk_log_debug ("cdk_keydb_search_start: invalid mode = %d\n", type);
       return CDK_Inv_Mode;
     }
   
-  keydb_search_free (db->dbs);
-  db->dbs = dbs;
   return 0;
 }
 
 
 static cdk_error_t
-keydb_pos_from_cache (cdk_keydb_hd_t hd, cdk_dbsearch_t ks,
+keydb_pos_from_cache (cdk_keydb_hd_t hd, cdk_keydb_search_t ks,
                       int *r_cache_hit, off_t *r_off)
 {
   key_table_t c;
@@ -917,7 +833,7 @@ keydb_pos_from_cache (cdk_keydb_hd_t hd, cdk_dbsearch_t ks,
   *r_cache_hit = 0;
   *r_off = 0;
   
-  c = keydb_cache_find (hd->cache, ks);
+  c = keydb_cache_find ( ks);
   if (c != NULL)
     {      
       _cdk_log_debug ("cache: found entry in cache.\n");
@@ -927,21 +843,21 @@ keydb_pos_from_cache (cdk_keydb_hd_t hd, cdk_dbsearch_t ks,
     }
   
   /* No index cache available so we just return here. */
-  if (!hd->idx)
+  if (!ks->idx)
     return 0;
   
-  if (hd->idx)
+  if (ks->idx)
     {
       if (ks->type == CDK_DBSEARCH_KEYID)
        {
-         if (keydb_idx_search (hd->idx, ks->u.keyid, NULL, r_off))
+         if (keydb_idx_search (ks->idx, ks->u.keyid, NULL, r_off))
            return CDK_Error_No_Key;
          _cdk_log_debug ("cache: found keyid entry in idx table.\n");
          *r_cache_hit = 1;
         }
       else if (ks->type == CDK_DBSEARCH_FPR)
        {
-         if (keydb_idx_search (hd->idx, NULL, ks->u.fpr, r_off))
+         if (keydb_idx_search (ks->idx, NULL, ks->u.fpr, r_off))
            return CDK_Error_No_Key;
          _cdk_log_debug ("cache: found fpr entry in idx table.\n");
          *r_cache_hit = 1;
@@ -953,14 +869,24 @@ keydb_pos_from_cache (cdk_keydb_hd_t hd, cdk_dbsearch_t ks,
 
 void cdk_keydb_search_release( cdk_keydb_search_t st)
 {
-  free( st);
+  keydb_cache_free ( st->cache);
+
+  if (st->idx)
+    cdk_stream_close (st->idx);
+
+  if (!st)
+    return;
+  if (st->type == CDK_DBSEARCH_EXACT || 
+      st->type == CDK_DBSEARCH_SUBSTR)
+    cdk_free (st->u.pattern);
+
+  cdk_free (st);
 }
 
 /**
  * cdk_keydb_search:
  * @st: the search handle
  * @hd: the keydb object
- * @ks: the keydb search object
  * @ret_key: kbnode object to store the key
  *
  * Search for a key in the given keyring. The search mode is handled
@@ -971,7 +897,6 @@ cdk_keydb_search (cdk_keydb_search_t st, cdk_keydb_hd_t hd, cdk_kbnode_t *ret_ke
 {
   cdk_stream_t kr;
   cdk_kbnode_t knode;
-  cdk_dbsearch_t ks;
   cdk_error_t rc = 0;
   off_t pos = 0, off = 0;
   int key_found = 0, cache_hit = 0;  
@@ -981,33 +906,34 @@ cdk_keydb_search (cdk_keydb_search_t st, cdk_keydb_hd_t hd, cdk_kbnode_t *ret_ke
   
   *ret_key = NULL;
   kr = NULL;
-  hd->search = 1;  
+
   rc = _cdk_keydb_open (hd, &kr);
   if (rc)
     return rc;
   
-  if (!hd->no_cache)
+  if (!st->no_cache)
     {
       /* It is possible the index is not up-to-date and thus we do
          not find the requesed key. In this case, we reset cache hit
          and continue our normal search procedure. */
-      rc = keydb_pos_from_cache (hd, hd->dbs, &cache_hit, &off);
+      rc = keydb_pos_from_cache (hd, st, &cache_hit, &off);
       if (rc)
        cache_hit = 0;
     }
   
   knode = NULL;
-  ks = hd->dbs;
+
   while (!key_found && !rc)
     {
-      if (cache_hit && ks->type != CDK_DBSEARCH_NEXT)
+      if (cache_hit && st->type != CDK_DBSEARCH_NEXT)
        cdk_stream_seek (kr, off);
-      else if ( ks->type == CDK_DBSEARCH_NEXT)
+      else if ( st->type == CDK_DBSEARCH_NEXT)
         cdk_stream_seek (kr, st->off);
 
       pos = cdk_stream_tell (kr);
 
       rc = cdk_keydb_get_keyblock (kr, &knode);
+
       if (rc) 
        {
          if (rc == CDK_EOF)
@@ -1016,20 +942,20 @@ cdk_keydb_search (cdk_keydb_search_t st, cdk_keydb_hd_t hd, cdk_kbnode_t *ret_ke
            return rc;
        }
       
-      switch (ks->type)
+      switch (st->type)
        {
        case CDK_DBSEARCH_SHORT_KEYID:
        case CDK_DBSEARCH_KEYID:
-         key_found = find_by_keyid (knode, ks);
+         key_found = find_by_keyid (knode, st);
          break;
          
        case CDK_DBSEARCH_FPR:
-         key_found = find_by_fpr (knode, ks);
+         key_found = find_by_fpr (knode, st);
          break;
           
        case CDK_DBSEARCH_EXACT:
        case CDK_DBSEARCH_SUBSTR:
-         key_found = find_by_pattern (knode, ks);
+         key_found = find_by_pattern (knode, st);
          break;
          
        case CDK_DBSEARCH_NEXT:
@@ -1040,8 +966,8 @@ cdk_keydb_search (cdk_keydb_search_t st, cdk_keydb_hd_t hd, cdk_kbnode_t *ret_ke
       
       if (key_found)
        {
-         if (!keydb_cache_find (hd->cache, ks))
-           keydb_cache_add (hd, ks, pos);
+         if (!keydb_cache_find ( st))
+           keydb_cache_add ( st, pos);
          break;
         }
       
@@ -1049,7 +975,6 @@ cdk_keydb_search (cdk_keydb_search_t st, cdk_keydb_hd_t hd, cdk_kbnode_t *ret_ke
       knode = NULL;
     }
 
-  hd->search = 0;
   if (key_found && rc == CDK_EOF)
     rc = 0;
   else if (rc == CDK_EOF && !key_found)
@@ -1798,10 +1723,10 @@ cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t *r_knode)
   u32 keyid[2], main_keyid[2];
   off_t old_off;
   int key_seen, got_key;  
-  
+
   if (!inp || !r_knode)
     return CDK_Inv_Value;
-  
+
   /* Reset all values. */
   keyid[0] = keyid[1] = 0;
   main_keyid[0] = main_keyid[1] = 0;
@@ -1812,7 +1737,7 @@ cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t *r_knode)
   *r_knode = NULL;
   rc = CDK_EOF;
   while (!cdk_stream_eof (inp))
-    {      
+    {
       cdk_pkt_new (&pkt);
       old_off = cdk_stream_tell (inp);
       rc = cdk_pkt_read (inp, pkt);
@@ -1828,6 +1753,7 @@ cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t *r_knode)
              return rc;
            }
        }
+
       if (pkt->pkttype == CDK_PKT_PUBLIC_KEY || 
          pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
          pkt->pkttype == CDK_PKT_SECRET_KEY || 
@@ -1882,7 +1808,7 @@ cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t *r_knode)
       else
        _cdk_kbnode_add (knode, node);
     }
-  
+
   if (got_key)
     {
       keydb_merge_selfsig (knode, main_keyid);
@@ -2118,8 +2044,6 @@ cdk_keydb_import (cdk_keydb_hd_t hd, cdk_kbnode_t knode)
     }
   
   cdk_stream_close (out);
-  if (!hd->no_cache)
-    cdk_keydb_idx_rebuild (hd);
   hd->stats.new_keys++;
   
   return 0;
@@ -2160,13 +2084,13 @@ _cdk_keydb_check_userid (cdk_keydb_hd_t hd, u32 *keyid, const char *id)
  
   check = 0;
   cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_KEYID, keyid);
-  if (unode && find_by_keyid (unode, hd->dbs))
+  if (unode && find_by_keyid (unode, st))
     check++;
   cdk_keydb_search_release( st);
   cdk_kbnode_release (unode);
   
   cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_EXACT, (char *)id);
-  if (knode && find_by_pattern (knode, hd->dbs))
+  if (knode && find_by_pattern (knode, st))
     check++;
   cdk_keydb_search_release( st);
   cdk_kbnode_release (knode);
@@ -2312,7 +2236,7 @@ cdk_listkey_next (cdk_listkey_t ctx, cdk_kbnode_t *ret_key)
   else if (ctx->type)
     {
       cdk_kbnode_t node;
-      struct cdk_dbsearch_s ks;
+      struct cdk_keydb_search_s ks;
       cdk_error_t rc;
       
       for (;;)
index 932a17b79891d78860aa49fe6e418f323ced96b5..054d2c4a559bcaf9435fd266258ef8fe6b370d4a 100644 (file)
@@ -1,6 +1,52 @@
+/* Internal key index structure. */
+struct key_idx_s 
+{
+  off_t offset;
+  u32 keyid[2];
+  byte fpr[KEY_FPR_LEN];
+};
+typedef struct key_idx_s *key_idx_t;
+
+/* Internal key cache to associate a key with an file offset. */
+struct key_table_s 
+{
+  struct key_table_s *next;
+  off_t offset;
+};
+typedef struct key_table_s *key_table_t;
 
 typedef struct cdk_keydb_search_s
 {
-   off_t off; /* last file offset */
+  off_t off; /* last file offset */
+  union 
+    {    
+      char *pattern; /* A search is performed by pattern. */
+      u32 keyid[2];  /* A search by keyid. */
+      byte fpr[KEY_FPR_LEN]; /* A search by fingerprint. */
+    } u;
+  int type;
+  struct key_table_s *cache;
+  size_t ncache;
+  unsigned int no_cache:1; /* disable the index cache. */
+
+  cdk_stream_t idx;
+  char *idx_name;        /* name of the index file or NULL. */
+
 } cdk_keydb_search_s;
 
+/* Internal key database handle. */
+struct cdk_keydb_hd_s 
+{
+  int type;   /* type of the key db handle. */
+  int fp_ref; /* 1=means it is a reference and shall not be closed. */
+  cdk_stream_t fp;
+  char *name;            /* name of the underlying file or NULL. */
+  unsigned int secret:1;   /* contain secret keys. */
+  unsigned int isopen:1;   /* the underlying stream is opened. */
+  
+  /* structure to store some stats about the keydb. */
+  struct {
+    size_t new_keys; /* amount of new keys that were imported. */
+  } stats;
+};
+
index b488bc9c50a099164342e6c02531065be2b764a4..43ed3252c0e4455d8086b1b23e0c25f3edb56d4a 100644 (file)
@@ -996,7 +996,7 @@ cdk_error_t cdk_keydb_get_sk (cdk_keydb_hd_t khd, unsigned int * keyid,
 cdk_error_t cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t * ret_key);
 
 /* Rebuild the key db index if possible. */
-cdk_error_t cdk_keydb_idx_rebuild (cdk_keydb_hd_t hd);
+cdk_error_t cdk_keydb_idx_rebuild (cdk_keydb_hd_t db, cdk_keydb_search_t dbs);
 
 /* Export one or more keys from the given key db handle into
    the stream @OUT. The export is done by substring search and
index 2e43b8bff4c6f95d38c0aea8507dec4943fc51e5..0360c43146e99622ec7c0ee62d87a7869a648fd4 100644 (file)
@@ -43,6 +43,7 @@
 static int stream_flush (cdk_stream_t s);
 static int stream_filter_write (cdk_stream_t s);
 static int stream_cache_flush (cdk_stream_t s, FILE *fp);
+struct stream_filter_s* filter_add (cdk_stream_t s, filter_fnct_t fnc, int type);
 
 /* Customized tmpfile() version from misc.c */
 FILE *my_tmpfile (void);
@@ -146,7 +147,7 @@ cdk_stream_new_from_cbs (cdk_stream_cbs_t cbs, void *opa,
  * @file: The name of the new file
  * @ret_s: The new STREAM object
  * 
- * Create a new stream into into the given file.
+ * Create a new stream into the given file.
  **/
 cdk_error_t
 cdk_stream_new (const char *file, cdk_stream_t *ret_s)
@@ -185,7 +186,6 @@ cdk_stream_new (const char *file, cdk_stream_t *ret_s)
   return 0;
 }
 
-
 /**
  * cdk_stream_create: 
  * @file: the filename
@@ -569,6 +569,21 @@ filter_search (cdk_stream_t s, filter_fnct_t fnc)
   return NULL;
 }
 
+static inline
+void set_opaque( struct stream_filter_s* f)
+{
+  switch (f->type) 
+    {    
+    case fARMOR   : f->opaque = &f->u.afx; break;
+    case fCIPHER  : f->opaque = &f->u.cfx; break;
+    case fLITERAL : f->opaque = &f->u.pfx; break;
+    case fCOMPRESS: f->opaque = &f->u.zfx; break;
+    case fHASH    : f->opaque = &f->u.mfx; break;
+    case fTEXT    : f->opaque = &f->u.tfx; break;
+    default       : f->opaque = NULL;
+    }
+
+}
 
 struct stream_filter_s*
 filter_add (cdk_stream_t s, filter_fnct_t fnc, int type)
@@ -588,21 +603,12 @@ filter_add (cdk_stream_t s, filter_fnct_t fnc, int type)
   f->flags.enabled = 1;
   f->tmp = NULL;
   f->type = type;
-  switch (type) 
-    {    
-    case fARMOR   : f->opaque = &f->u.afx; break;
-    case fCIPHER  : f->opaque = &f->u.cfx; break;
-    case fLITERAL : f->opaque = &f->u.pfx; break;
-    case fCOMPRESS: f->opaque = &f->u.zfx; break;
-    case fHASH    : f->opaque = &f->u.mfx; break;
-    case fTEXT    : f->opaque = &f->u.tfx; break;
-    default       : f->opaque = NULL;
-    }
-  
+
+  set_opaque(f);
+
   return f;
 }
 
-
 static int
 stream_get_mode (cdk_stream_t s)
 {
@@ -866,11 +872,14 @@ cdk_stream_read (cdk_stream_t s, void *buf, size_t buflen)
        }
       s->flags.filtrated = 1;
     }
+
   if (!buf && !buflen)
     return 0;
+
   nread = fread (buf, 1, buflen, s->fp);
   if (!nread)
     nread = EOF;
+
   if (feof (s->fp))
     {
       s->error = 0;
index c04d861ab7152d4ede3d4691080b8090a450e424..7bcf38f147ac398394cc1227588ea1ec6db6a9e2 100644 (file)
@@ -70,7 +70,6 @@ _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
       goto leave;
     }
 
-#ifndef KEYRING_HACK
   if (cred->keyring != NULL)
     {
       ret = gnutls_openpgp_crt_verify_ring (key, cred->keyring, 0, &verify);
@@ -80,33 +79,6 @@ _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
          goto leave;
        }
     }
-#else
-  {
-  gnutls_openpgp_keyring_t kring;
-  
-  ret = gnutls_openpgp_keyring_init( &kring);
-  if ( ret < 0) {
-    gnutls_assert();
-    return ret;
-  }
-
-  ret = gnutls_openpgp_keyring_import( kring, &cred->keyring, cred->keyring_format);
-  if ( ret < 0) {
-    gnutls_assert();
-    gnutls_openpgp_keyring_deinit( kring);
-    return ret;
-  }
-
-  ret = gnutls_openpgp_crt_verify_ring (key, kring, 0, &verify);
-  if (ret < 0)
-  {
-    gnutls_assert ();
-    gnutls_openpgp_keyring_deinit( kring);
-    return ret;
-  }
-  gnutls_openpgp_keyring_deinit( kring);
-  }
-#endif
 
   /* Now try the self signature. */
   ret = gnutls_openpgp_crt_verify_self (key, 0, &verify_self);
@@ -118,15 +90,10 @@ _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
 
   *status = verify_self | verify;
 
-#ifndef KEYRING_HACK
   /* If we only checked the self signature. */
   if (!cred->keyring)
-#else
-  if (!cred->keyring.data || !cred->keyring.size)
-#endif
     *status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
 
-
   ret = 0;
 
 leave:
index d9a28f3c3cba90addca42ce63ceb260602c6af86..2b994520074e6a45b6f0169f6fefc2432bd430bf 100644 (file)
@@ -48,7 +48,7 @@ gnutls_openpgp_keyring_init (gnutls_openpgp_keyring_t * keyring)
   *keyring = gnutls_calloc (1, sizeof (gnutls_openpgp_keyring_int));
 
   if (*keyring)
-    return 0; /* success */
+    return 0;                  /* success */
   return GNUTLS_E_MEMORY_ERROR;
 }
 
@@ -71,14 +71,6 @@ gnutls_openpgp_keyring_deinit (gnutls_openpgp_keyring_t keyring)
       cdk_keydb_free (keyring->db);
       keyring->db = NULL;
     }
-  
-  /* In some cases the stream is also stored outside the keydb context
-     and we need to close it here then. */
-  if (keyring->db_stream)
-    {
-      cdk_stream_close (keyring->db_stream);
-      keyring->db_stream = NULL;
-    }  
 
   gnutls_free (keyring);
 }
@@ -110,8 +102,8 @@ gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring,
       cdk_pk_release (pk);
       return 0;
     }
-  
-  _gnutls_debug_log ("PGP: key not found %08lX\n", (unsigned long)id[1]);
+
+  _gnutls_debug_log ("PGP: key not found %08lX\n", (unsigned long) id[1]);
   return GNUTLS_E_NO_CERTIFICATE_FOUND;
 }
 
@@ -130,44 +122,88 @@ gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring,
  **/
 int
 gnutls_openpgp_keyring_import (gnutls_openpgp_keyring_t keyring,
-                              const gnutls_datum_t *data,
+                              const gnutls_datum_t * data,
                               gnutls_openpgp_crt_fmt_t format)
 {
   cdk_error_t err;
-  cdk_stream_t input;
-  
+  cdk_stream_t input = NULL;
+  size_t raw_len = 0, i;
+  opaque *raw_data = NULL;
+
   _gnutls_debug_log ("PGP: keyring import format '%s'\n",
-                    format == GNUTLS_OPENPGP_FMT_RAW? "raw" : "base64");
-  
-  if (format == GNUTLS_OPENPGP_FMT_RAW)
+                    format == GNUTLS_OPENPGP_FMT_RAW ? "raw" : "base64");
+
+  /* Create a new stream from the given data, decode it, and import
+   * the raw database. This to avoid using opencdk streams which are
+   * not thread safe.
+   */
+  if (format == GNUTLS_OPENPGP_FMT_BASE64)
     {
-      err = cdk_keydb_new (&keyring->db, CDK_DBTYPE_DATA,
-                          data->data, data->size);
+      err = cdk_stream_tmp_from_mem (data->data, data->size, &input);
+      if (!err)
+       err = cdk_stream_set_armor_flag (input, 0);
       if (err)
-       gnutls_assert ();
-      return _gnutls_map_cdk_rc (err);
+       {
+         gnutls_assert ();
+         err = _gnutls_map_cdk_rc (err);
+         goto error;
+       }
+
+      raw_len = cdk_stream_get_length (input);
+      if (raw_len == 0)
+       {
+         gnutls_assert ();
+         err = GNUTLS_E_BASE64_DECODING_ERROR;
+         goto error;
+       }
+
+      raw_data = gnutls_malloc (raw_len);
+      if (raw_data == NULL)
+       {
+         gnutls_assert ();
+         err = GNUTLS_E_MEMORY_ERROR;
+         goto error;
+       }
+
+#if 0
+      i = 0;
+      do {
+          err = cdk_stream_getc( input);
+          if (err != EOF) raw_data[i++] = err;
+      } while( err != EOF);
+
+      raw_len = i;
+#else
+      ssize_t written=0;
+      do 
+        {
+          err = cdk_stream_read (input, raw_data+written, raw_len-written);
+
+          if (err > 0) written += err;
+        }
+      while( written < raw_len && err != EOF && err > 0);
+      
+      raw_len = written;
+#endif
+      
     }
-  
-  /* Create a new stream from the given data, which means to
-     allocate a new stream and to write the data in the stream.
-     Then push the armor filter to decode the data and to store
-     it in the raw format. */
-  err = cdk_stream_tmp_from_mem (data->data, data->size, &input);
-  if (!err)
-    err = cdk_stream_set_armor_flag (input, 0);
-  if (!err)
-    err = cdk_keydb_new_from_stream (&keyring->db, 0, input);  
-  if (err)
-    {
-      cdk_stream_close (input);
-      gnutls_assert ();
+  else
+    {                          /* RAW */
+      raw_len = data->size;
+      raw_data = data->data;
     }
-  else 
-    /* The keydb function will not close the stream itself, so we need to
-       store it separately to close it later. */
-    keyring->db_stream = input;
-  
+
+  err = cdk_keydb_new (&keyring->db, CDK_DBTYPE_DATA, raw_data, raw_len);
+  if (err)
+    gnutls_assert ();
+
   return _gnutls_map_cdk_rc (err);
+
+error:
+  gnutls_free (raw_data);
+  cdk_stream_close (input);
+
+  return err;
 }
 
 #define knode_is_pkey(node) \
@@ -190,31 +226,33 @@ gnutls_openpgp_keyring_get_crt_count (gnutls_openpgp_keyring_t ring)
   cdk_error_t err;
   cdk_keydb_search_t st;
   int ret = 0;
-  
-  err = cdk_keydb_search_start&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
-  if (err != CDK_Success) 
+
+  err = cdk_keydb_search_start (&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
+  if (err != CDK_Success)
     {
-      gnutls_assert();
-      return _gnutls_map_cdk_rc(err);
+      gnutls_assert ();
+      return _gnutls_map_cdk_rc (err);
+    }
+
+  do
+    {
+      err = cdk_keydb_search (st, ring->db, &knode);
+      if (err != CDK_Error_No_Key && err != CDK_Success)
+       {
+         gnutls_assert ();
+         cdk_keydb_search_release (st);
+         return _gnutls_map_cdk_rc (err);
+       }
+
+      if (knode_is_pkey (knode))
+       ret++;
+
+      cdk_kbnode_release (knode);
+
     }
+  while (err != CDK_Error_No_Key);
 
-  do { 
-    err = cdk_keydb_search( st, ring->db, &knode);
-    if (err != CDK_Error_No_Key && err != CDK_Success)
-      {
-        gnutls_assert();
-        cdk_keydb_search_release(st);
-        return _gnutls_map_cdk_rc(err);
-      }
-    
-    if (knode_is_pkey( knode))
-      ret++;
-
-    cdk_kbnode_release(knode);
-    
-  } while( err != CDK_Error_No_Key);
-
-  cdk_keydb_search_release(st);
+  cdk_keydb_search_release (st);
   return ret;
 }
 
@@ -232,47 +270,49 @@ gnutls_openpgp_keyring_get_crt_count (gnutls_openpgp_keyring_t ring)
   *
   **/
 int
-gnutls_openpgp_keyring_get_crt (gnutls_openpgp_keyring_t ring, unsigned int idx, 
-  gnutls_openpgp_crt_t* cert)
+gnutls_openpgp_keyring_get_crt (gnutls_openpgp_keyring_t ring,
+                               unsigned int idx,
+                               gnutls_openpgp_crt_t * cert)
 {
   cdk_kbnode_t knode;
   cdk_error_t err;
-  int ret = 0;
+  int ret = 0, count = 0;
   cdk_keydb_search_t st;
 
-  err = cdk_keydb_search_start&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
-  if (err != CDK_Success) 
+  err = cdk_keydb_search_start (&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
+  if (err != CDK_Success)
     {
-      gnutls_assert();
-      return _gnutls_map_cdk_rc(err);
+      gnutls_assert ();
+      return _gnutls_map_cdk_rc (err);
     }
-  
-  do { 
-    err = cdk_keydb_search( st, ring->db, &knode);
-    if (err != CDK_EOF && err != CDK_Success)
-      {
-        gnutls_assert();
-        cdk_keydb_search_release(st);
-        return _gnutls_map_cdk_rc(err);
-      }
-    
-    if (idx == ret) 
-      {
-        ret = gnutls_openpgp_crt_init( cert);
-        if (ret == 0)
-          (*cert)->knode = knode;
-        cdk_keydb_search_release(st);
-        return ret;
-      }
-    
-    if (knode_is_pkey( knode))
-      ret++;
-
-    cdk_kbnode_release(knode);
-    
-  } while( err != CDK_EOF);
-
-  cdk_keydb_search_release(st);
+
+  do
+    {
+      err = cdk_keydb_search (st, ring->db, &knode);
+      if (err != CDK_EOF && err != CDK_Success)
+       {
+         gnutls_assert ();
+         cdk_keydb_search_release (st);
+         return _gnutls_map_cdk_rc (err);
+       }
+
+      if (idx == count && err == CDK_Success)
+       {
+         ret = gnutls_openpgp_crt_init (cert);
+         if (ret == 0)
+           (*cert)->knode = knode;
+         cdk_keydb_search_release (st);
+         return ret;
+       }
+
+      if (knode_is_pkey (knode))
+       count++;
+
+      cdk_kbnode_release (knode);
+
+    }
+  while (err != CDK_EOF);
+
+  cdk_keydb_search_release (st);
   return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 }
-
index 9eacadfd10826030494734328372e8a5ee9aec91..7548dafe7382b07f1752fd54d11ac62d01563c73 100644 (file)
@@ -30,7 +30,6 @@ typedef struct gnutls_openpgp_privkey_int
 typedef struct gnutls_openpgp_keyring_int
 {
   cdk_keydb_hd_t db;
-  cdk_stream_t   db_stream;
 } gnutls_openpgp_keyring_int;
 
 int _gnutls_map_cdk_rc (int rc);