* export.c: New.
authorWerner Koch <wk@gnupg.org>
Thu, 21 Mar 2002 14:42:14 +0000 (14:42 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 21 Mar 2002 14:42:14 +0000 (14:42 +0000)
* gpgsm.c: Add command --export.
* server.c (cmd_export): New.

sm/ChangeLog
sm/Makefile.am
sm/export.c [new file with mode: 0644]
sm/gpgsm.c
sm/gpgsm.h
sm/server.c

index 4041b2e..4ef0102 100644 (file)
@@ -1,3 +1,9 @@
+2002-03-21  Werner Koch  <wk@gnupg.org>
+
+       * export.c: New.
+       * gpgsm.c: Add command --export.
+       * server.c (cmd_export): New.
+       
 2002-03-13  Werner Koch  <wk@gnupg.org>
 
        * decrypt.c (gpgsm_decrypt): Allow multiple recipients.
index 8bdbc01..3061cb5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2001 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 #
 # This file is part of GnuPG.
 #
@@ -43,6 +43,7 @@ gpgsm_SOURCES = \
        encrypt.c \
        decrypt.c \
        import.c \
+       export.c \
        certreqgen.c 
 
 
diff --git a/sm/export.c b/sm/export.c
new file mode 100644 (file)
index 0000000..ce2909f
--- /dev/null
@@ -0,0 +1,241 @@
+/* export.c
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h> 
+#include <time.h>
+#include <assert.h>
+
+#include <gcrypt.h>
+#include <ksba.h>
+
+#include "gpgsm.h"
+#include "keydb.h"
+
+static void print_short_info (KsbaCert cert, FILE *fp);
+
+
+
+/* Export all certificates or just those given in NAMES. */
+void
+gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
+{
+  KEYDB_HANDLE hd;
+  KEYDB_SEARCH_DESC *desc = NULL;
+  int ndesc;
+  Base64Context b64writer = NULL;
+  KsbaWriter writer;
+  STRLIST sl;
+  KsbaCert cert = NULL;
+  int rc=0;
+  int count = 0;
+
+  hd = keydb_new (0);
+  if (!hd)
+    {
+      log_error ("keydb_new failed\n");
+      goto leave;
+    }
+
+  if (!names)
+    ndesc = 1;
+  else
+    {
+      for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
+        ;
+    }
+
+  desc = xtrycalloc (ndesc, sizeof *desc);
+  if (!ndesc)
+    {
+      log_error ("%s\n", gnupg_strerror (GNUPG_Out_Of_Core));
+      goto leave;
+    }
+
+  if (!names)
+    desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
+  else 
+    {
+      for (ndesc=0, sl=names; sl; sl = sl->next) 
+        {
+          rc = keydb_classify_name (sl->d, desc+ndesc);
+          if (rc)
+            {
+              log_error ("key `%s' not found: %s\n",
+                         sl->d, gnupg_strerror (rc));
+              rc = 0;
+            }
+          else
+            ndesc++;
+        }
+    }
+
+
+  while (!(rc = keydb_search (hd, desc, ndesc)))
+    {
+      const unsigned char *image;
+      size_t imagelen;
+
+      if (!names) 
+        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+
+      rc = keydb_get_cert (hd, &cert);
+      if (rc) 
+        {
+          log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc));
+          goto leave;
+        }
+
+      image = ksba_cert_get_image (cert, &imagelen);
+      if (!image)
+        {
+          log_error ("ksba_cert_get_image failed\n");
+          goto leave;
+        }
+
+      if (ctrl->create_pem)
+        {
+          if (count)
+            putc ('\n', fp);
+          print_short_info (cert, fp);
+          putc ('\n', stdout);
+        }
+      count++;
+
+      if (!b64writer)
+        {
+          ctrl->pem_name = "CERTIFICATE";
+          rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer);
+          if (rc)
+            {
+              log_error ("can't create writer: %s\n", gnupg_strerror (rc));
+              goto leave;
+            }
+        }
+
+      rc = ksba_writer_write (writer, image, imagelen);
+      if (rc)
+        {
+          log_error ("write error: %s\n", ksba_strerror (rc));
+          goto leave;
+        }
+
+      if (ctrl->create_pem)
+        {
+          /* We want one certificate per PEM block */
+          rc = gpgsm_finish_writer (b64writer);
+          if (rc) 
+            {
+              log_error ("write failed: %s\n", gnupg_strerror (rc));
+              goto leave;
+            }
+          gpgsm_destroy_writer (b64writer);
+          b64writer = NULL;
+        }
+      
+      ksba_cert_release (cert); 
+      cert = NULL;
+    }
+  if (rc && rc != -1)
+    log_error ("keydb_search failed: %s\n", gnupg_strerror (rc));
+  else if (b64writer)
+    {
+      rc = gpgsm_finish_writer (b64writer);
+      if (rc) 
+        {
+          log_error ("write failed: %s\n", gnupg_strerror (rc));
+          goto leave;
+        }
+    }
+  
+ leave:
+  gpgsm_destroy_writer (b64writer);
+  ksba_cert_release (cert);
+  xfree (desc);
+  keydb_release (hd);
+}
+
+
+/* Print some info about the certifciate CERT to FP */
+static void
+print_short_info (KsbaCert cert, FILE *fp)
+{
+  char *p;
+  KsbaSexp sexp;
+  int idx;
+
+  fputs ("Issuer ...: ", fp); 
+  p = ksba_cert_get_issuer (cert, 0);
+  if (p)
+    {
+      print_sanitized_string (fp, p, '\n');
+      xfree (p);
+      for (idx=1; (p = ksba_cert_get_issuer (cert, idx)); idx++)
+        {
+          fputs ("\n   aka ...: ", fp); 
+          print_sanitized_string (fp, p, '\n');
+          xfree (p);
+        }
+    }
+  putc ('\n', stdout);
+
+  fputs ("Serial ...: ", fp); 
+  sexp = ksba_cert_get_serial (cert);
+  if (sexp)
+    {
+      int len;
+      const unsigned char *s = sexp;
+      
+      if (*s == '(')
+        {
+          s++;
+          for (len=0; *s && *s != ':' && digitp (s); s++)
+            len = len*10 + atoi_1 (s);
+          if (*s == ':')
+            for (s++; len; len--, s++)
+              fprintf (fp, "%02X", *s);
+        }
+      xfree (sexp);
+    }
+  putc ('\n', stdout);
+
+  fputs ("Subject ..: ", fp); 
+  p = ksba_cert_get_subject (cert, 0);
+  if (p)
+    {
+      print_sanitized_string (fp, p, '\n');
+      xfree (p);
+      for (idx=1; (p = ksba_cert_get_subject (cert, idx)); idx++)
+        {
+          fputs ("\n    aka ..: ", fp); 
+          print_sanitized_string (fp, p, '\n');
+          xfree (p);
+        }
+    }
+  else
+    fputs ("none", fp);
+  putc ('\n', stdout);
+}
+
+
index f0fa98f..d86e5e2 100644 (file)
@@ -73,7 +73,6 @@ enum cmd_and_opt_values {
   aSendKeys,
   aRecvKeys,
   aExport,
-  aExportAll,
   aCheckKeys,
   aServer,                        
   aLearnCard,
@@ -214,10 +213,10 @@ static ARGPARSE_OPTS opts[] = {
     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
     { aKeygen,    "gen-key",  256, N_("generate a new key pair")},
     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
-    { aExport, "export"           , 256, N_("export keys") },
     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
-    { aImport, "import",      256     , N_("import/merge keys")},
+    { aImport, "import",      256     , N_("import certificates")},
+    { aExport, "export",      256     , N_("export certificates")},
     { aLearnCard, "learn-card", 256 ,N_("register a smartcard")},
     { aServer, "server",      256, N_("run in server mode")},
     
@@ -1186,8 +1185,14 @@ main ( int argc, char **argv)
         }
       break;
 
-      
     case aExport:
+      for (sl=NULL; argc; argc--, argv++)
+        add_to_strlist (&sl, *argv);
+      gpgsm_export (&ctrl, sl, stdout);
+      free_strlist(sl);
+      break;
+
+      
     case aSendKeys:
     case aRecvKeys:
       log_error ("this command has not yet been implemented\n");
index 40a5d51..a46627d 100644 (file)
@@ -188,6 +188,9 @@ void gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode);
 /*-- import.c --*/
 int gpgsm_import (CTRL ctrl, int in_fd);
 
+/*-- export.c --*/
+void gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp);
+
 /*-- verify.c --*/
 int gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp);
 
@@ -227,6 +230,3 @@ int gpgsm_dirmngr_isvalid (KsbaCert cert);
 
 
 #endif /*GPGSM_H*/
-
-
-
index 9ec4834..13af393 100644 (file)
@@ -375,6 +375,48 @@ cmd_import (ASSUAN_CONTEXT ctx, char *line)
   return map_to_assuan_status (rc);
 }
 
+
+static int 
+cmd_export (ASSUAN_CONTEXT ctx, char *line)
+{
+  CTRL ctrl = assuan_get_pointer (ctx);
+  FILE *fp = assuan_get_data_fp (ctx);
+  char *p;
+  STRLIST list, sl;
+
+  if (!fp)
+    return set_error (General_Error, "no data stream");
+  
+  /* break the line down into an STRLIST */
+  list = NULL;
+  for (p=line; *p; line = p)
+    {
+      while (*p && *p != ' ')
+        p++;
+      if (*p)
+        *p++ = 0;
+      if (*line)
+        {
+          sl = xtrymalloc (sizeof *sl + strlen (line));
+          if (!sl)
+            {
+              free_strlist (list);
+              return ASSUAN_Out_Of_Core;
+            }
+          sl->flags = 0;
+          strcpy_escaped_plus (sl->d, line);
+          sl->next = list;
+          list = sl;
+        }
+    }
+
+  gpgsm_export (ctrl, list, fp);
+  free_strlist (list);
+  return 0;
+}
+
+
+
 /* MESSAGE FD=<n>
 
    Set the file descriptor to read a message which is used with
@@ -507,6 +549,7 @@ register_commands (ASSUAN_CONTEXT ctx)
     { "VERIFY",     0,  cmd_verify },
     { "SIGN",       0,  cmd_sign },
     { "IMPORT",     0,  cmd_import },
+    { "EXPORT",     0,  cmd_export },
     { "",     ASSUAN_CMD_INPUT, NULL }, 
     { "",     ASSUAN_CMD_OUTPUT, NULL }, 
     { "MESSAGE",    0,  cmd_message },