* base64.c: New. Changed all other functions to use this instead
[gnupg.git] / sm / verify.c
index 6b4ef5c..6f4a1d2 100644 (file)
 #include "keydb.h"
 #include "i18n.h"
 
-struct reader_cb_parm_s {
-  FILE *fp;
-};
-
-
 /* FIXME: Move this to jnlib */
-char *
+static char *
 strtimestamp (time_t atime)
 {
   char *buffer = xmalloc (15);
   
   if (atime < 0) 
-    {
-      strcpy (buffer, "????" "-??" "-??");
-    }
+    strcpy (buffer, "????" "-??" "-??");
+  else if (!atime)
+    strcpy (buffer, "none");
   else
     {
       struct tm *tp;
@@ -62,38 +57,6 @@ strtimestamp (time_t atime)
 
 
 
-
-/* FIXME: We need to write a generic reader callback which should be able
-   to detect and convert base-64 */
-static int
-reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
-{
-  struct reader_cb_parm_s *parm = cb_value;
-  size_t n;
-  int c = 0;
-
-  *nread = 0;
-  if (!buffer)
-    return -1; /* not supported */
-
-  for (n=0; n < count; n++)
-    {
-      c = getc (parm->fp);
-      if (c == EOF)
-        {
-          if ( ferror (parm->fp) )
-            return -1;
-          if (n)
-            break; /* return what we have before an EOF */
-          return -1;
-        }
-      *(byte *)buffer++ = c;
-    }
-
-  *nread = n;
-  return 0;
-}
-
 /* fixme: duplicated from import.c */
 static void
 store_cert (KsbaCert cert)
@@ -109,12 +72,12 @@ store_cert (KsbaCert cert)
     }
   rc = keydb_locate_writable (kh, 0);
   if (rc)
-      log_error (_("error finding writable keyDB: %s\n"), gpgsm_strerror (rc));
+      log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc));
 
   rc = keydb_insert_cert (kh, cert);
   if (rc)
     {
-      log_error (_("error storing certificate: %s\n"), gpgsm_strerror (rc));
+      log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc));
     }
   keydb_release (kh);               
 }
@@ -127,16 +90,38 @@ print_integer (unsigned char *p)
   unsigned long len;
 
   if (!p)
-    printf ("none");
+    log_printf ("none");
   else
     {
       len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
       for (p+=4; len; len--, p++)
-        printf ("%02X", *p);
+        log_printf ("%02X", *p);
+    }
+}
+
+static void
+print_time (time_t t)
+{
+
+  if (!t)
+    log_printf ("none");
+  else if ( t == (time_t)(-1) )
+    log_printf ("error");
+  else
+    {
+      struct tm *tp;
+
+      tp = gmtime (&t);
+      log_printf ("%04d-%02d-%02d %02d:%02d:%02d",
+                  1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+                  tp->tm_hour, tp->tm_min, tp->tm_sec);
+      assert (!tp->tm_isdst);
     }
 }
 
 
+
+
 static void
 hash_data (int fd, GCRY_MD_HD md)
 {
@@ -170,53 +155,41 @@ int
 gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
 {
   int i, rc;
+  Base64Context b64reader = NULL;
   KsbaError err;
-  KsbaReader reader = NULL;
-  KsbaWriter writer = NULL;
+  KsbaReader reader;
   KsbaCMS cms = NULL;
   KsbaStopReason stopreason;
   KsbaCert cert;
   KEYDB_HANDLE kh;
   GCRY_MD_HD data_md = NULL;
-  struct reader_cb_parm_s rparm;
   int signer;
+  const char *algoid;
   int algo;
   int is_detached;
-
-  memset (&rparm, 0, sizeof rparm);
+  FILE *fp = NULL;
 
   kh = keydb_new (0);
   if (!kh)
     {
       log_error (_("failed to allocated keyDB handle\n"));
-      rc = GPGSM_General_Error;
+      rc = GNUPG_General_Error;
       goto leave;
     }
 
 
-  rparm.fp = fdopen ( dup (in_fd), "rb");
-  if (!rparm.fp)
+  fp = fdopen ( dup (in_fd), "rb");
+  if (!fp)
     {
       log_error ("fdopen() failed: %s\n", strerror (errno));
       rc = seterr (IO_Error);
       goto leave;
     }
 
-  /* setup a skaba reader which uses a callback function so that we can 
-     strip off a base64 encoding when necessary */
-  reader = ksba_reader_new ();
-  writer = ksba_writer_new ();
-  if (!reader || !writer)
-    {
-      rc = seterr (Out_Of_Core);
-      goto leave;
-    }
-
-  rc = ksba_reader_set_cb (reader, reader_cb, &rparm );
+  rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader);
   if (rc)
     {
-      ksba_reader_release (reader);
-      rc = map_ksba_err (rc);
+      log_error ("can't create reader: %s\n", gnupg_strerror (rc));
       goto leave;
     }
 
@@ -227,7 +200,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       goto leave;
     }
 
-  err = ksba_cms_set_reader_writer (cms, reader, writer);
+  err = ksba_cms_set_reader_writer (cms, reader, NULL);
   if (err)
     {
       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
@@ -263,16 +236,20 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       if (stopreason == KSBA_SR_BEGIN_DATA)
         {
           log_error ("error: only detached signatures are supportted\n");
-          rc = GPGSM_Not_Implemented;
+          rc = GNUPG_Not_Implemented;
           goto leave;
         }
 
       if (stopreason == KSBA_SR_NEED_HASH
           || stopreason == KSBA_SR_BEGIN_DATA)
         { /* We are now able to enable the hash algorithms */
-          for (i=0; (algo = ksba_cms_get_digest_algo_list (cms, i)) >= 0; i++)
+          for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
             {
-              if (algo)
+              algo = gcry_md_map_name (algoid);
+              if (!algo)
+                log_error ("unknown hash algorithm `%s'\n",
+                           algoid? algoid:"?");
+              else
                 gcry_md_enable (data_md, algo);
             }
           if (is_detached)
@@ -280,7 +257,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
               if (data_fd == -1)
                 {
                   log_error ("detached signature but no data given\n");
-                  rc = GPGSM_Bad_Signature;
+                  rc = GNUPG_Bad_Signature;
                   goto leave;
                 }
               hash_data (data_fd, data_md);  
@@ -292,7 +269,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
   if (data_fd != -1 && !is_detached)
     {
       log_error ("data given for a non-detached signature");
-      rc = GPGSM_Conflict;
+      rc = GNUPG_Conflict;
       goto leave;
     }
 
@@ -311,26 +288,38 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
     {
       char *issuer = NULL;
       char *sigval = NULL;
+      time_t sigtime;
       unsigned char *serial;
       char *msgdigest = NULL;
       size_t msgdigestlen;
-      time_t sigcreated;
 
       err = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
       if (err)
         break;
-      printf ("signer %d - issuer: `%s'\n", signer, issuer? issuer:"[NONE]");
-      printf ("signer %d - serial: ", signer);
+      log_debug ("signer %d - issuer: `%s'\n", signer, issuer? issuer:"[NONE]");
+      log_debug ("signer %d - serial: ", signer);
       print_integer (serial);
-      putchar ('\n');
+      log_printf ("\n");
+
+      err = ksba_cms_get_signing_time (cms, signer, &sigtime);
+      if (err)
+        {
+          log_debug ("error getting signing time: %s\n", ksba_strerror (err));
+          sigtime = (time_t)-1;
+        }
+      log_debug ("signer %d - sigtime: ", signer);
+      print_time (sigtime);  
+      log_printf ("\n");
+
 
       err = ksba_cms_get_message_digest (cms, signer,
                                          &msgdigest, &msgdigestlen);
       if (err)
         break;
 
-      algo = ksba_cms_get_digest_algo (cms, signer);
-      printf ("signer %d - digest algo: %d\n", signer, algo);
+      algoid = ksba_cms_get_digest_algo (cms, signer);
+      algo = gcry_md_map_name (algoid);
+      log_debug ("signer %d - digest algo: %d\n", signer, algo);
       if ( !gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED, &algo, NULL) )
         {
           log_debug ("digest algo %d has not been enabled\n", algo);
@@ -338,8 +327,12 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
         }
 
       sigval = ksba_cms_get_sig_val (cms, signer);
-      printf ("signer %d - signature: `%s'\n",
-              signer, sigval? sigval: "[ERROR]");
+      if (!sigval)
+        {
+          log_error ("no signature value available\n");
+          goto next_signer;
+        }
+      log_debug ("signer %d - signature: `%s'\n", signer, sigval);
 
       /* Find the certificate of the signer */
       keydb_search_reset (kh);
@@ -347,14 +340,14 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       if (rc)
         {
           log_debug ("failed to find the certificate: %s\n",
-                     gpgsm_strerror(rc));
+                     gnupg_strerror(rc));
           goto next_signer;
         }
 
       rc = keydb_get_cert (kh, &cert);
       if (rc)
         {
-          log_debug ("failed to get cert: %s\n", gpgsm_strerror (rc));
+          log_debug ("failed to get cert: %s\n", gnupg_strerror (rc));
           goto next_signer;
         }
 
@@ -401,7 +394,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
 
       if (rc)
         {
-          log_error ("invalid signature: %s\n", gpgsm_strerror (rc));
+          log_error ("invalid signature: %s\n", gnupg_strerror (rc));
           gpgsm_status (ctrl, STATUS_BADSIG, NULL);
           goto next_signer;
         }
@@ -411,9 +404,9 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
         char *buf, *fpr, *tstr;
 
         fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
-        tstr = strtimestamp ( 42 /*fixme: get right time */);
+        tstr = strtimestamp (sigtime);
         buf = xmalloc ( strlen(fpr) + strlen (tstr) + 100);
-        sprintf (buf, "%s %s %lu", fpr, tstr, (unsigned long)42 );
+        sprintf (buf, "%s %s %lu", fpr, tstr, (unsigned long)sigtime );
         xfree (tstr);
         xfree (fpr);
         gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
@@ -423,9 +416,9 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       rc = gpgsm_validate_path (cert);
       if (rc)
         {
-          log_error ("invalid certification path: %s\n", gpgsm_strerror (rc));
-          if (rc == GPGSM_Bad_Certificate_Path
-              || rc == GPGSM_Bad_Certificate)
+          log_error ("invalid certification path: %s\n", gnupg_strerror (rc));
+          if (rc == GNUPG_Bad_Certificate_Path
+              || rc == GNUPG_Bad_Certificate)
             gpgsm_status (ctrl, STATUS_TRUST_NEVER, NULL);
           else
             gpgsm_status (ctrl, STATUS_TRUST_UNDEFINED, NULL);
@@ -455,11 +448,11 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
 
  leave:
   ksba_cms_release (cms);
-  ksba_reader_release (reader);
+  gpgsm_destroy_reader (b64reader);
   keydb_release (kh); 
   gcry_md_close (data_md);
-  if (rparm.fp)
-    fclose (rparm.fp);
+  if (fp)
+    fclose (fp);
   return rc;
 }