From 28c31524be84f20b34573c78bd3a94a81e4b1d61 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 Feb 2017 15:16:48 +0100 Subject: [PATCH] common: Remove gpgsm dependencies from ksba-io-support. * common/ksba-io-support.c: Include ksba-io-support.h instead of ../sm/gpgsm.h. Include util.h. (writer_cb_parm_s): Remove const from 'pem_name'. (gpgsm_destroy_writer): Free 'pem_name'. (gpgsm_create_reader): Rename to ... (gnupg_ksba_create_reader): this. Replace args CTRL and ALLOW_MULTI_PEM by a new arg FLAGS. Change the code to evaluate FLAGS. Change all callers to pass the FLAGS. (gpgsm_create_writer): Rename to ... (gnupg_ksba_create_writer): this. Replace arg CTRL by new arg FLAGS. Add arg PEM_NAME. Evaluate FLAGS. Store a copy of PEM_NAME. Change all callers to pass the FLAGS and PEM_NAME. Signed-off-by: Werner Koch --- common/ksba-io-support.c | 106 ++++++++++++++++++++++++++------------- common/ksba-io-support.h | 33 ++++++++++++ sm/certreqgen.c | 6 ++- sm/decrypt.c | 11 +++- sm/encrypt.c | 5 +- sm/export.c | 10 +++- sm/gpgsm.h | 18 +------ sm/import.c | 7 ++- sm/sign.c | 5 +- sm/verify.c | 11 +++- 10 files changed, 150 insertions(+), 62 deletions(-) diff --git a/common/ksba-io-support.c b/common/ksba-io-support.c index da7b4d6c7..48a7ac1cc 100644 --- a/common/ksba-io-support.c +++ b/common/ksba-io-support.c @@ -36,13 +36,12 @@ #include #include #include - -#include "../sm/gpgsm.h" - - #include +#include "util.h" #include "i18n.h" +#include "ksba-io-support.h" + #ifdef HAVE_DOSISH_SYSTEM #define LF "\r\n" @@ -50,6 +49,7 @@ #define LF "\n" #endif + /* Data used by the reader callbacks. */ struct reader_cb_parm_s { @@ -87,7 +87,7 @@ struct writer_cb_parm_s { estream_t stream; /* Output stream. */ - const char *pem_name; + char *pem_name; /* Malloced. */ int wrote_begin; int did_finish; @@ -550,18 +550,30 @@ base64_finish_write (struct writer_cb_parm_s *parm) -/* Create a reader for the given file descriptor. Depending on the - control information an input decoding is automagically chosen. - The function returns a Base64Context object which must be passed to - the gpgme_destroy_reader function. The created KsbaReader object - is also returned, but the caller must not call the - ksba_reader_release function on. If ALLOW_MULTI_PEM is true, the - reader expects that the caller uses ksba_reader_clear after EOF - until no more objects were found. */ -int -gpgsm_create_reader (Base64Context *ctx, - ctrl_t ctrl, estream_t fp, int allow_multi_pem, - ksba_reader_t *r_reader) +/* Create a reader for the stream FP. FLAGS can be used to specify + * the expected input encoding. + * + * The function returns a Base64Context object which must be passed to + * the gpgme_destroy_reader function. The created ksba_reader_t + * object is stored at R_READER - the caller must not call the + * ksba_reader_release function on. + * + * The supported flags are: + * + * GNUPG_KSBA_IO_PEM - Assume the input is PEM encoded + * GNUPG_KSBA_IO_BASE64 - Assume the input is Base64 encoded. + * GNUPG_KSBA_IO_AUTODETECT - The reader tries to detect the encoding. + * GNUPG_KSBA_IO_MULTIPEM - The reader expects that the caller uses + * ksba_reader_clear after EOF until no more + * objects were found. + * + * Note that the PEM flag has a higher priority than the BASE64 flag + * which in turn has a gight priority than the AUTODETECT flag. + */ +gpg_error_t +gnupg_ksba_create_reader (Base64Context *ctx, + unsigned int flags, estream_t fp, + ksba_reader_t *r_reader) { int rc; ksba_reader_t r; @@ -570,7 +582,7 @@ gpgsm_create_reader (Base64Context *ctx, *ctx = xtrycalloc (1, sizeof **ctx); if (!*ctx) return out_of_core (); - (*ctx)->u.rparm.allow_multi_pem = allow_multi_pem; + (*ctx)->u.rparm.allow_multi_pem = !!(flags & GNUPG_KSBA_IO_MULTIPEM); rc = ksba_reader_new (&r); if (rc) @@ -580,18 +592,18 @@ gpgsm_create_reader (Base64Context *ctx, } (*ctx)->u.rparm.fp = fp; - if (ctrl->is_pem) + if ((flags & GNUPG_KSBA_IO_PEM)) { (*ctx)->u.rparm.assume_pem = 1; (*ctx)->u.rparm.assume_base64 = 1; rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); } - else if (ctrl->is_base64) + else if ((flags & GNUPG_KSBA_IO_BASE64)) { (*ctx)->u.rparm.assume_base64 = 1; rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); } - else if (ctrl->autodetect_encoding) + else if ((flags & GNUPG_KSBA_IO_AUTODETECT)) { (*ctx)->u.rparm.autodetect = 1; rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); @@ -630,15 +642,27 @@ gpgsm_destroy_reader (Base64Context ctx) -/* Create a writer for the given STREAM. Depending on - the control information an output encoding is automagically - chosen. The function returns a Base64Context object which must be - passed to the gpgme_destroy_writer function. The created - KsbaWriter object is also returned, but the caller must not call - the ksba_reader_release function on it. */ -int -gpgsm_create_writer (Base64Context *ctx, ctrl_t ctrl, estream_t stream, - ksba_writer_t *r_writer) +/* Create a writer for the given STREAM. Depending on FLAGS an output + * encoding is chosen. In PEM mode PEM_NAME is used for the header + * and footer lines; if PEM_NAME is NULL the string "CMS OBJECT" is + * used. + * + * The function returns a Base64Context object which must be passed to + * the gpgme_destroy_writer function. The created ksba_writer_t + * object is stored at R_WRITER - the caller must not call the + * ksba_reader_release function on it. + * + * The supported flags are: + * + * GNUPG_KSBA_IO_PEM - Write output as PEM + * GNUPG_KSBA_IO_BASE64 - Write output as plain Base64; note that the PEM + * flag overrides this flag. + * + */ +gpg_error_t +gnupg_ksba_create_writer (Base64Context *ctx, unsigned int flags, + const char *pem_name, estream_t stream, + ksba_writer_t *r_writer) { int rc; ksba_writer_t w; @@ -646,7 +670,7 @@ gpgsm_create_writer (Base64Context *ctx, ctrl_t ctrl, estream_t stream, *r_writer = NULL; *ctx = xtrycalloc (1, sizeof **ctx); if (!*ctx) - return out_of_core (); + return gpg_error_from_syserror (); rc = ksba_writer_new (&w); if (rc) @@ -655,12 +679,22 @@ gpgsm_create_writer (Base64Context *ctx, ctrl_t ctrl, estream_t stream, return rc; } - if (ctrl->create_pem || ctrl->create_base64) + if ((flags & GNUPG_KSBA_IO_PEM) || (flags & GNUPG_KSBA_IO_BASE64)) { (*ctx)->u.wparm.stream = stream; - if (ctrl->create_pem) - (*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name - : "CMS OBJECT"; + if ((flags & GNUPG_KSBA_IO_PEM)) + { + (*ctx)->u.wparm.pem_name = xtrystrdup (pem_name + ? pem_name + : "CMS OBJECT"); + if (!(*ctx)->u.wparm.pem_name) + { + rc = gpg_error_from_syserror (); + ksba_writer_release (w); + xfree (*ctx); *ctx = NULL; + return rc; + } + } rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm); } else if (stream) @@ -700,6 +734,7 @@ gpgsm_finish_writer (Base64Context ctx) return base64_finish_write (parm); } + void gpgsm_destroy_writer (Base64Context ctx) { @@ -707,5 +742,6 @@ gpgsm_destroy_writer (Base64Context ctx) return; ksba_writer_release (ctx->u2.writer); + xfree (ctx->u.wparm.pem_name); xfree (ctx); } diff --git a/common/ksba-io-support.h b/common/ksba-io-support.h index 7028686de..0f448ec25 100644 --- a/common/ksba-io-support.h +++ b/common/ksba-io-support.h @@ -30,4 +30,37 @@ #ifndef GNUPG_KSBA_IO_SUPPORT_H #define GNUPG_KSBA_IO_SUPPORT_H +/* Flags used with gnupg_ksba_create_reader and + * gnupg_ksba_create_writer. */ +#define GNUPG_KSBA_IO_PEM 1 /* X.509 PEM format. */ +#define GNUPG_KSBA_IO_BASE64 2 /* Plain Base64 format. */ +#define GNUPG_KSBA_IO_AUTODETECT 4 /* Try toautodeect the format. */ +#define GNUPG_KSBA_IO_MULTIPEM 8 /* Allow more than one PEM chunk. */ + + +/* Context object. */ +typedef struct base64_context_s *Base64Context; + + + +gpg_error_t gnupg_ksba_create_reader (Base64Context *ctx, + unsigned int flags, + estream_t fp, + ksba_reader_t *r_reader); + +int gpgsm_reader_eof_seen (Base64Context ctx); +void gpgsm_destroy_reader (Base64Context ctx); + +gpg_error_t gnupg_ksba_create_writer (Base64Context *ctx, + unsigned int flags, + const char *pem_name, + estream_t stream, + ksba_writer_t *r_writer); + +int gpgsm_finish_writer (Base64Context ctx); +void gpgsm_destroy_writer (Base64Context ctx); + + + + #endif /*GNUPG_KSBA_IO_SUPPORT_H*/ diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 9b4ffc92a..2290d3d83 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -744,7 +744,11 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para, create_cert = !!get_parameter_value (para, pSERIAL, 0); ctrl->pem_name = create_cert? "CERTIFICATE" : "CERTIFICATE REQUEST"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) log_error ("can't create writer: %s\n", gpg_strerror (rc)); else diff --git a/sm/decrypt.c b/sm/decrypt.c index a2907f668..35c0b8dc7 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -274,14 +274,21 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) goto leave; } - rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader); + rc = gnupg_ksba_create_reader + (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) + | (ctrl->autodetect_encoding? GNUPG_KSBA_IO_AUTODETECT : 0)), + in_fp, &reader); if (rc) { log_error ("can't create reader: %s\n", gpg_strerror (rc)); goto leave; } - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); diff --git a/sm/encrypt.c b/sm/encrypt.c index 2c664f83a..468f78503 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -364,7 +364,10 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) encparm.fp = data_fp; ctrl->pem_name = "ENCRYPTED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); diff --git a/sm/export.c b/sm/export.c index a32414edb..8e3f2de87 100644 --- a/sm/export.c +++ b/sm/export.c @@ -263,7 +263,10 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) if (!b64writer) { ctrl->pem_name = "CERTIFICATE"; - rc = gpgsm_create_writer (&b64writer, ctrl, stream, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 :0)), + ctrl->pem_name, stream, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); @@ -433,7 +436,10 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) ctrl->pem_name = "PRIVATE KEY"; else ctrl->pem_name = "RSA PRIVATE KEY"; - err = gpgsm_create_writer (&b64writer, ctrl, stream, &writer); + err = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, stream, &writer); if (err) { log_error ("can't create writer: %s\n", gpg_strerror (err)); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 76ff327de..df96770f1 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -33,6 +33,7 @@ #include "../common/status.h" #include "../common/audit.h" #include "../common/session-env.h" +#include "../common/ksba-io-support.h" #define MAX_DIGEST_LEN 64 @@ -205,10 +206,6 @@ struct server_control_s }; -/* Data structure used in base64.c. */ -typedef struct base64_context_s *Base64Context; - - /* An object to keep a list of certificates. */ struct certlist_s { @@ -262,19 +259,6 @@ int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits); char *gpgsm_get_certid (ksba_cert_t cert); -/*-- base64.c --*/ -int gpgsm_create_reader (Base64Context *ctx, - ctrl_t ctrl, estream_t fp, int allow_multi_pem, - ksba_reader_t *r_reader); -int gpgsm_reader_eof_seen (Base64Context ctx); -void gpgsm_destroy_reader (Base64Context ctx); -int gpgsm_create_writer (Base64Context *ctx, - ctrl_t ctrl, estream_t stream, - ksba_writer_t *r_writer); -int gpgsm_finish_writer (Base64Context ctx); -void gpgsm_destroy_writer (Base64Context ctx); - - /*-- certdump.c --*/ void gpgsm_print_serial (estream_t fp, ksba_const_sexp_t p); void gpgsm_print_time (estream_t fp, ksba_isotime_t t); diff --git a/sm/import.c b/sm/import.c index 4a8ecf73c..2a0710891 100644 --- a/sm/import.c +++ b/sm/import.c @@ -288,7 +288,12 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) goto leave; } - rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader); + rc = gnupg_ksba_create_reader + (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) + | (ctrl->autodetect_encoding? GNUPG_KSBA_IO_AUTODETECT : 0) + | GNUPG_KSBA_IO_MULTIPEM), + fp, &reader); if (rc) { log_error ("can't create reader: %s\n", gpg_strerror (rc)); diff --git a/sm/sign.c b/sm/sign.c index 9153d588c..b5a486c8f 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -340,7 +340,10 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, } ctrl->pem_name = "SIGNED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); diff --git a/sm/verify.c b/sm/verify.c index a04688375..b80948fc1 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -125,7 +125,11 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) goto leave; } - rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader); + rc = gnupg_ksba_create_reader + (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) + | (ctrl->autodetect_encoding? GNUPG_KSBA_IO_AUTODETECT : 0)), + in_fp, &reader); if (rc) { log_error ("can't create reader: %s\n", gpg_strerror (rc)); @@ -134,7 +138,10 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) if (out_fp) { - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + rc = gnupg_ksba_create_writer + (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) + | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), + ctrl->pem_name, out_fp, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc));