Fixed an email/DN bug.
[gnupg.git] / sm / keydb.c
index 17f04fe..1fbf9b6 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -70,13 +69,12 @@ static void unlock_all (KEYDB_HANDLE hd);
 
 /*
  * Register a resource (which currently may only be a keybox file).
- * The first keybox which is added by this function is
- * created if it does not exist.
- * Note: this function may be called before secure memory is
- * available.
+ * The first keybox which is added by this function is created if it
+ * does not exist.  If AUTO_CREATED is not NULL it will be set to true
+ * if the function has created a a new keybox. 
  */
 int
-keydb_add_resource (const char *url, int force, int secret)
+keydb_add_resource (const char *url, int force, int secret, int *auto_created)
 {
   static int any_secret, any_public;
   const char *resname = url;
@@ -86,6 +84,9 @@ keydb_add_resource (const char *url, int force, int secret)
   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
   const char *created_fname = NULL;
 
+  if (auto_created)
+    *auto_created = 0;
+
   /* Do we have an URL?
      gnupg-kbx:filename := this is a plain keybox
      filename := See what is is, but create as plain keybox.
@@ -194,6 +195,8 @@ keydb_add_resource (const char *url, int force, int secret)
           if (!opt.quiet)
             log_info (_("keybox `%s' created\n"), filename);
           created_fname = filename;
+          if (auto_created)
+            *auto_created = 1;
        }
        fclose (fp);
        fp = NULL;
@@ -696,9 +699,8 @@ keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
   else
     return gpg_error (GPG_ERR_GENERAL);
 
-  rc = lock_all (hd);
-  if (rc)
-    return rc;
+  if (!hd->locked)
+    return gpg_error (GPG_ERR_NOT_LOCKED);
 
   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
 
@@ -718,7 +720,7 @@ keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
 
 
 
-/* update the current keyblock with KB */
+/* Update the current keyblock with KB.  */
 int
 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
 {
@@ -759,7 +761,7 @@ keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
  * The current keyblock or cert will be deleted.
  */
 int
-keydb_delete (KEYDB_HANDLE hd)
+keydb_delete (KEYDB_HANDLE hd, int unlock)
 {
   int rc = -1;
   
@@ -785,7 +787,8 @@ keydb_delete (KEYDB_HANDLE hd)
       break;
     }
 
-  unlock_all (hd);
+  if (unlock)
+    unlock_all (hd);
   return rc;
 }
 
@@ -1010,33 +1013,6 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name)
 
 
 static int
-hextobyte (const char *string)
-{
-  const unsigned char *s = (const unsigned char *)string;
-  int c;
-
-  if( *s >= '0' && *s <= '9' )
-    c = 16 * (*s - '0');
-  else if ( *s >= 'A' && *s <= 'F' )
-    c = 16 * (10 + *s - 'A');
-  else if ( *s >= 'a' && *s <= 'f' )
-    c = 16 * (10 + *s - 'a');
-  else
-    return -1;
-  s++;
-  if ( *s >= '0' && *s <= '9' )
-    c += *s - '0';
-  else if ( *s >= 'A' && *s <= 'F' )
-    c += 10 + *s - 'A';
-  else if ( *s >= 'a' && *s <= 'f' )
-    c += 10 + *s - 'a';
-  else
-    return -1;
-  return c;
-}
-
-
-static int
 classify_user_id (const char *name, 
                   KEYDB_SEARCH_DESC *desc,
                   int *force_exact )
@@ -1162,7 +1138,15 @@ classify_user_id (const char *name,
         mode = KEYDB_SEARCH_MODE_FPR;
       } 
       break;
-           
+
+    case '&': /* Keygrip*/
+      {  
+        if (hex2bin (s+1, desc->u.grip, 20) < 0)
+          return 0; /* Invalid. */
+        mode = KEYDB_SEARCH_MODE_KEYGRIP;
+      } 
+      break;
+
     default:
       if (s[0] == '0' && s[1] == 'x')
         {
@@ -1337,6 +1321,10 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
   if (ephemeral)
     keydb_set_ephemeral (kh, 1);
   
+  rc = lock_all (kh);
+  if (rc)
+    return rc;
+
   rc = keydb_search_fpr (kh, fpr);
   if (rc != -1)
     {
@@ -1376,7 +1364,9 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
    transaction by locating the certificate in the DB and updating the
    flags. */
 gpg_error_t
-keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
+keydb_set_cert_flags (ksba_cert_t cert, int ephemeral, 
+                      int which, int idx, 
+                      unsigned int mask, unsigned int value)
 {
   KEYDB_HANDLE kh;
   gpg_error_t err;
@@ -1396,6 +1386,9 @@ keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
       return gpg_error (GPG_ERR_ENOMEM);;
     }
 
+  if (ephemeral)
+    keydb_set_ephemeral (kh, 1);
+
   err = keydb_lock (kh);
   if (err)
     {
@@ -1407,8 +1400,11 @@ keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
   err = keydb_search_fpr (kh, fpr);
   if (err)
     {
-      log_error (_("problem re-searching certificate: %s\n"),
-                 gpg_strerror (err));
+      if (err == -1)
+        err = gpg_error (GPG_ERR_NOT_FOUND);
+      else
+        log_error (_("problem re-searching certificate: %s\n"),
+                   gpg_strerror (err));
       keydb_release (kh);
       return err;
     }
@@ -1420,6 +1416,9 @@ keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
       keydb_release (kh);
       return err;
     }
+
+  value = ((old_value & ~mask) | (value & mask));
+
   if (value != old_value)
     {
       err = keydb_set_flags (kh, which, idx, value);
@@ -1430,6 +1429,7 @@ keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
           return err;
         }
     }
+
   keydb_release (kh);               
   return 0;
 }
@@ -1438,13 +1438,13 @@ keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
 /* Reset all the certificate flags we have stored with the certificates
    for performance reasons. */
 void
-keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names)
+keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
 {
   gpg_error_t err;
   KEYDB_HANDLE hd = NULL;
   KEYDB_SEARCH_DESC *desc = NULL;
   int ndesc;
-  STRLIST sl;
+  strlist_t sl;
   int rc=0;
   unsigned int old_value, value;
   
@@ -1467,7 +1467,7 @@ keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names)
   if (!ndesc)
     {
       log_error ("allocating memory failed: %s\n",
-                 gpg_strerror (OUT_OF_CORE (errno)));
+                 gpg_strerror (out_of_core ()));
       goto leave;
     }