From 208b08af799bb4d612d55bfbf5df526090e33be1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Mar 2002 14:42:14 +0000 Subject: [PATCH] * export.c: New. * gpgsm.c: Add command --export. * server.c (cmd_export): New. --- sm/ChangeLog | 6 ++ sm/Makefile.am | 3 +- sm/export.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++++ sm/gpgsm.c | 13 ++- sm/gpgsm.h | 6 +- sm/server.c | 43 +++++++++ 6 files changed, 304 insertions(+), 8 deletions(-) create mode 100644 sm/export.c diff --git a/sm/ChangeLog b/sm/ChangeLog index 4041b2e44..4ef0102b0 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,9 @@ +2002-03-21 Werner Koch + + * export.c: New. + * gpgsm.c: Add command --export. + * server.c (cmd_export): New. + 2002-03-13 Werner Koch * decrypt.c (gpgsm_decrypt): Allow multiple recipients. diff --git a/sm/Makefile.am b/sm/Makefile.am index 8bdbc011b..3061cb51b 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -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 index 000000000..ce2909fdf --- /dev/null +++ b/sm/export.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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); +} + + diff --git a/sm/gpgsm.c b/sm/gpgsm.c index f0fa98fc7..d86e5e2b8 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -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"); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 40a5d5130..a46627da3 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -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*/ - - - diff --git a/sm/server.c b/sm/server.c index 9ec4834e2..13af393ba 100644 --- a/sm/server.c +++ b/sm/server.c @@ -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= 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 },