* keylist.c (list_cert_colon): Fixed listing of crt record; the
[gnupg.git] / sm / keydb.c
index d8d0ad7..4f7bbb5 100644 (file)
@@ -35,8 +35,6 @@
 
 #define DIRSEP_C '/'
 
-#define spacep(a) ((a) == ' ' || (a) == '\t')
-
 static int active_handles;
 
 typedef enum {
@@ -834,14 +832,23 @@ keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
 
 int
 keydb_search_issuer_sn (KEYDB_HANDLE hd,
-                        const char *issuer, const unsigned char *serial)
+                        const char *issuer, KsbaConstSexp serial)
 {
   KEYDB_SEARCH_DESC desc;
   int rc;
+  const unsigned char *s;
   
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
-  desc.sn = serial;
+  s = serial;
+  if (*s !='(')
+    return GNUPG_Invalid_Value;
+  s++;
+  for (desc.snlen = 0; digitp (s); s++)
+    desc.snlen = 10*desc.snlen + atoi_1 (s);
+  if (*s !=':')
+    return GNUPG_Invalid_Value;
+  desc.sn = s+1;
   desc.u.name = issuer;
   rc = keydb_search (hd, &desc, 1);
   return rc;
@@ -902,7 +909,7 @@ classify_user_id (const char *name,
   memset (desc, 0, sizeof *desc);
   *force_exact = 0;
   /* skip leading spaces.  Fixme: what about trailing white space? */
-  for(s = name; *s && spacep(*s); s++ )
+  for(s = name; *s && spacep (s); s++ )
     ;
 
   switch (*s) 
@@ -948,7 +955,7 @@ classify_user_id (const char *name,
 
     case '/': /* subject's DN */
       s++;
-      if (!*s || spacep (*s))
+      if (!*s || spacep (s))
         return 0; /* no DN or prefixed with a space */
       desc->u.name = s;
       mode = KEYDB_SEARCH_MODE_SUBJECT;
@@ -962,7 +969,7 @@ classify_user_id (const char *name,
         if ( *s == '/')
           { /* "#/" indicates an issuer's DN */
             s++;
-            if (!*s || spacep (*s))
+            if (!*s || spacep (s))
               return 0; /* no DN or prefixed with a space */
             desc->u.name = s;
             mode = KEYDB_SEARCH_MODE_ISSUER;
@@ -975,13 +982,13 @@ classify_user_id (const char *name,
                   return 0; /* invalid digit in serial number*/
               }
             desc->sn = s;
-            desc->sn_is_string = 1;
+            desc->snlen = -1;
             if (!*si)
               mode = KEYDB_SEARCH_MODE_SN;
             else
               {
                 s = si+1;
-                if (!*s || spacep (*s))
+                if (!*s || spacep (s))
                   return 0; /* no DN or prefixed with a space */
                 desc->u.name = s;
                 mode = KEYDB_SEARCH_MODE_ISSUER_SN;
@@ -1029,7 +1036,7 @@ classify_user_id (const char *name,
         }
       
       /* check if a hexadecimal number is terminated by EOS or blank */
-      if (hexlength && s[hexlength] && !spacep(s[hexlength])) 
+      if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
         {
           if (hexprefix) /* a "0x" prefix without correct */
             return 0;   /* termination is an error */
@@ -1136,3 +1143,57 @@ keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
   return 0;
 }
 
+\f
+/* Store the certificate in the key Db but make sure that it does not
+   already exists.  We do this simply by comparing the fingerprint */
+int
+keydb_store_cert (KsbaCert cert)
+{
+  KEYDB_HANDLE kh;
+  int rc;
+  unsigned char fpr[20];
+
+  if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
+    {
+      log_error (_("failed to get the fingerprint\n"));
+      return GNUPG_General_Error;
+    }
+
+  kh = keydb_new (0);
+  if (!kh)
+    {
+      log_error (_("failed to allocate keyDB handle\n"));
+      return GNUPG_Out_Of_Core;
+    }
+
+  rc = keydb_search_fpr (kh, fpr);
+  if (rc != -1)
+    {
+      keydb_release (kh);
+      if (!rc)
+        return 0; /* okay */
+      log_error (_("problem looking for existing certificate: %s\n"),
+                 gnupg_strerror (rc));
+      return rc;
+    }
+
+  rc = keydb_locate_writable (kh, 0);
+  if (rc)
+    {
+      log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc));
+      keydb_release (kh);
+      return rc;
+    }
+
+  rc = keydb_insert_cert (kh, cert);
+  if (rc)
+    {
+      log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc));
+      keydb_release (kh);
+      return rc;
+    }
+  keydb_release (kh);               
+  return 0;
+}
+
+