* import.c (gpgsm_import): Try to identify the type of input and
[gnupg.git] / sm / import.c
index b3827e2..1463407 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include <gcrypt.h>
 #include <ksba.h>
 
 #include "gpgsm.h"
-
-struct reader_cb_parm_s {
-  FILE *fp;
-};
-
-
-static int
-reader_cb (void *cb_value, unsigned 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 beofre an EOF */
-          return -1;
-        }
-      *buffer++ = c;
-    }
-
-  *nread = n;
-  return 0;
-}
-
-
-static void
-print_integer (unsigned char *p)
-{
-  unsigned long len;
-
-  if (!p)
-    fputs ("none", stdout);
-  else
-    {
-      len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-      for (p+=4; len; len--, p++)
-        printf ("%02X", *p);
-    }
-}
-
-static void
-print_time (time_t t)
-{
-
-  if (!t)
-    fputs ("none", stdout);
-  else if ( t == (time_t)(-1) )
-    fputs ("error", stdout);
-  else
-    {
-      struct tm *tp;
-
-      tp = gmtime (&t);
-      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
-print_dn (char *p)
-{
-
-  if (!p)
-    fputs ("error", stdout);
-  else
-    printf ("`%s'", p);
-}
-
+#include "keydb.h"
+#include "i18n.h"
 
 
 \f
 int
-gpgsm_import (int in_fd)
+gpgsm_import (CTRL ctrl, int in_fd)
 {
   int rc;
-  KsbaReader reader = NULL;
+  Base64Context b64reader = NULL;
+  KsbaReader reader;
   KsbaCert cert = NULL;
-  struct reader_cb_parm_s rparm;
-
-  memset (&rparm, 0, sizeof rparm);
+  KsbaCMS cms = NULL;
+  FILE *fp = NULL;
+  KsbaContentType ct;
 
-  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 ();
-  if (!reader)
-    {
-      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;
     }
 
-  cert = ksba_cert_new ();
-  if (!cert)
-    {
-      rc = seterr (Out_Of_Core);
-      goto leave;
+  ct = ksba_cms_identify (reader);
+  if (ct == KSBA_CT_SIGNED_DATA)
+    { /* This is probably a signed-only message - import the certs */
+      KsbaStopReason stopreason;
+      int i;
+
+      cms = ksba_cms_new ();
+      if (!cms)
+        {
+          rc = seterr (Out_Of_Core);
+          goto leave;
+        }
+
+      rc = ksba_cms_set_reader_writer (cms, reader, NULL);
+      if (rc)
+        {
+          log_error ("ksba_cms_set_reader_writer failed: %s\n",
+                     ksba_strerror (rc));
+          rc = map_ksba_err (rc);
+          goto leave;
+        }
+
+
+      do 
+        {
+          rc = ksba_cms_parse (cms, &stopreason);
+          if (rc)
+            {
+              log_error ("ksba_cms_parse failed: %s\n", ksba_strerror (rc));
+              rc = map_ksba_err (rc);
+              goto leave;
+            }
+
+          if (stopreason == KSBA_SR_BEGIN_DATA)
+              log_info ("not a certs-only message\n");
+        }
+      while (stopreason != KSBA_SR_READY);   
+      
+      for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
+        {
+          if ( !gpgsm_basic_cert_check (cert) )
+            {
+              if (!keydb_store_cert (cert))
+                {
+                  if (opt.verbose)
+                    log_info ("certificate imported\n");
+                }
+            }
+          ksba_cert_release (cert); 
+          cert = NULL;
+        }
+
     }
+  else if (ct == KSBA_CT_NONE)
+    { /* Failed to identify this message - assume a certificate */
 
-  rc = ksba_cert_read_der (cert, reader);
-  if (rc)
+      cert = ksba_cert_new ();
+      if (!cert)
+        {
+          rc = seterr (Out_Of_Core);
+          goto leave;
+        }
+
+      rc = ksba_cert_read_der (cert, reader);
+      if (rc)
+        {
+          rc = map_ksba_err (rc);
+          goto leave;
+        }
+      
+      if ( !gpgsm_basic_cert_check (cert) )
+        {
+          if (!keydb_store_cert (cert))
+            {
+              if (opt.verbose)
+                log_info ("certificate imported\n");
+            }
+        }
+    }
+  else
     {
-      rc = map_ksba_err (rc);
-      goto leave;
+      log_error ("can't extract certificates from input\n");
+      rc = GNUPG_No_Data;
     }
-
-  {
-    unsigned char *p;
-    char *dn;
-    time_t t;
-    
-    p = ksba_cert_get_serial (cert);
-    fputs ("serial: ", stdout);
-    print_integer (p);
-    ksba_free (p);
-    putchar ('\n');
-
-    t = ksba_cert_get_validity (cert, 0);
-    fputs ("notBefore: ", stdout);
-    print_time (t);
-    putchar ('\n');
-    t = ksba_cert_get_validity (cert, 1);
-    fputs ("notAfter: ", stdout);
-    print_time (t);
-    putchar ('\n');
-    
-    dn = ksba_cert_get_issuer (cert);
-    fputs ("issuer: ", stdout);
-    print_dn (dn);
-    ksba_free (dn);
-    putchar ('\n');
-    
-    dn = ksba_cert_get_subject (cert);
-    fputs ("subject: ", stdout);
-    print_dn (dn);
-    ksba_free (dn);
-    putchar ('\n');
-
-    printf ("hash algo: %d\n", ksba_cert_get_digest_algo (cert));
-    
-    ksba_cert_hash (cert, NULL, NULL);
-  }
+   
 
  leave:
+  ksba_cms_release (cms);
   ksba_cert_release (cert);
-  ksba_reader_release (reader);
-  if (rparm.fp)
-    fclose (rparm.fp);
+  gpgsm_destroy_reader (b64reader);
+  if (fp)
+    fclose (fp);
   return rc;
 }