core: Support usage of gpgtar for verifying a signed archive
* src/gpgme.h.in (gpgme_verify_flags_t): New enum. (GPGME_VERIFY_ARCHIVE): New const. (gpgme_op_verify_ext_start): New func. (gpgme_op_verify_ext): New func. * src/gpgme.def, src/libgpgme.vers: Add new functions. * src/verify.c (gpgme_op_verify_ext_start): New. (gpgme_op_verify_ext): New. (verify_start): Add arg FLAGS. Pass the flags to _gpgme_engine_op_verify. (gpgme_op_verify_start): Call gpgme_op_verify_ext_start with 0 for FLAGS. (gpgme_op_verify): Call gpgme_op_verify_ext with 0 for FLAGS. * src/engine.c, src/engine.h (_gpgme_engine_op_verify): Add arg FLAGS. * src/engine-backend.h (struct engine_ops): Add FLAGS to 'verify'. * src/engine-gpg.c (gpg_verify): Add arg FLAGS. Set use_gpgtar engine flag if GPGME_VERIFY_ARCHIVE flag is set. Check for new enough gpg. Use add_gpg_arg for gpg-only options without a value. Set extra options for gpgtar and pass input data to stdin when using gpgtar. * src/engine-gpgsm.c (gpgsm_verify): Add arg FLAGS. Return error if GPGME_VERIFY_ARCHIVE flag is set. * src/engine-uiserver.c (uiserver_verify): Ditto. * tests/run-verify.c (show_usage): New options --archive, --directory, and --diagnostics. (main): Parse new options. Verify and extract with gpgtar if --archive is given. Set file name of output data to value of --directory option. Print stderr of gpg/gpgtar if --diagnostics is given. -- GnuPG-bug-id: 6342
This commit is contained in:
parent
95ea3bf831
commit
5b79b32397
@ -122,9 +122,9 @@ struct engine_ops
|
||||
gpgme_sig_mode_t mode, int use_armor,
|
||||
int use_textmode, int include_certs,
|
||||
gpgme_ctx_t ctx /* FIXME */);
|
||||
gpgme_error_t (*verify) (void *engine, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext,
|
||||
gpgme_ctx_t ctx);
|
||||
gpgme_error_t (*verify) (void *engine, gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext, gpgme_ctx_t ctx);
|
||||
gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output,
|
||||
unsigned int flags);
|
||||
gpgme_error_t (*setexpire) (void *engine, gpgme_key_t key,
|
||||
|
@ -3666,20 +3666,43 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
|
||||
}
|
||||
|
||||
static gpgme_error_t
|
||||
gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext, gpgme_ctx_t ctx)
|
||||
gpg_verify (void *engine, gpgme_verify_flags_t flags, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext, gpgme_ctx_t ctx)
|
||||
{
|
||||
engine_gpg_t gpg = engine;
|
||||
gpgme_error_t err;
|
||||
|
||||
gpg->flags.use_gpgtar = !!(flags & GPGME_VERIFY_ARCHIVE);
|
||||
|
||||
if (gpg->flags.use_gpgtar && !have_gpg_version (gpg, "2.3.5"))
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
||||
err = append_args_from_sender (gpg, ctx);
|
||||
if (!err && gpg->flags.auto_key_import)
|
||||
err = add_arg (gpg, "--auto-key-import");
|
||||
err = add_gpg_arg (gpg, "--auto-key-import");
|
||||
if (!err && ctx->auto_key_retrieve)
|
||||
err = add_arg (gpg, "--auto-key-retrieve");
|
||||
err = add_gpg_arg (gpg, "--auto-key-retrieve");
|
||||
|
||||
if (err)
|
||||
;
|
||||
else if (gpg->flags.use_gpgtar)
|
||||
{
|
||||
const char *file_name = gpgme_data_get_file_name (plaintext);
|
||||
if (!err && file_name)
|
||||
{
|
||||
err = add_arg (gpg, "--directory");
|
||||
if (!err)
|
||||
err = add_arg (gpg, file_name);
|
||||
}
|
||||
/* gpgtar uses --decrypt also for signed-only archives */
|
||||
err = add_arg (gpg, "--decrypt");
|
||||
if (!err)
|
||||
err = add_input_size_hint (gpg, sig);
|
||||
if (!err)
|
||||
err = add_arg (gpg, "--");
|
||||
if (!err)
|
||||
err = add_data (gpg, sig, 0, 0);
|
||||
}
|
||||
else if (plaintext)
|
||||
{
|
||||
/* Normal or cleartext signature. */
|
||||
|
@ -2112,8 +2112,9 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext, gpgme_ctx_t ctx)
|
||||
gpgsm_verify (void *engine, gpgme_verify_flags_t flags, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext,
|
||||
gpgme_ctx_t ctx)
|
||||
{
|
||||
engine_gpgsm_t gpgsm = engine;
|
||||
gpgme_error_t err;
|
||||
@ -2123,6 +2124,9 @@ gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
if (!gpgsm)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (flags & GPGME_VERIFY_ARCHIVE)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
gpgsm->input_cb.data = sig;
|
||||
err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
|
||||
if (err)
|
||||
|
@ -1294,8 +1294,9 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
|
||||
|
||||
/* FIXME: Missing a way to specify --silent. */
|
||||
static gpgme_error_t
|
||||
uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext, gpgme_ctx_t ctx)
|
||||
uiserver_verify (void *engine, gpgme_verify_flags_t flags, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext,
|
||||
gpgme_ctx_t ctx)
|
||||
{
|
||||
engine_uiserver_t uiserver = engine;
|
||||
gpgme_error_t err;
|
||||
@ -1316,6 +1317,9 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
else
|
||||
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
|
||||
|
||||
if (flags & GPGME_VERIFY_ARCHIVE)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
if (gpgrt_asprintf (&cmd, "VERIFY%s", protocol) < 0)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
|
10
src/engine.c
10
src/engine.c
@ -940,9 +940,9 @@ _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext,
|
||||
gpgme_ctx_t ctx)
|
||||
_gpgme_engine_op_verify (engine_t engine, gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext, gpgme_ctx_t ctx)
|
||||
{
|
||||
if (!engine)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
@ -950,8 +950,8 @@ _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
|
||||
if (!engine->ops->verify)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext,
|
||||
ctx);
|
||||
return (*engine->ops->verify) (engine->engine, flags, sig, signed_text,
|
||||
plaintext, ctx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -166,7 +166,9 @@ gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in,
|
||||
gpgme_ctx_t ctx /* FIXME */);
|
||||
gpgme_error_t _gpgme_engine_op_trustlist (engine_t engine,
|
||||
const char *pattern);
|
||||
gpgme_error_t _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
|
||||
gpgme_error_t _gpgme_engine_op_verify (engine_t engine,
|
||||
gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig,
|
||||
gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext,
|
||||
gpgme_ctx_t ctx);
|
||||
|
@ -283,5 +283,7 @@ EXPORTS
|
||||
gpgme_op_receive_keys @209
|
||||
gpgme_op_receive_keys_start @210
|
||||
|
||||
gpgme_op_verify_ext @211
|
||||
gpgme_op_verify_ext_start @212
|
||||
; END
|
||||
|
||||
|
@ -1634,6 +1634,13 @@ typedef struct _gpgme_op_verify_result *gpgme_verify_result_t;
|
||||
/* Retrieve a pointer to the result of the verify operation. */
|
||||
gpgme_verify_result_t gpgme_op_verify_result (gpgme_ctx_t ctx);
|
||||
|
||||
/* The valid verify flags. */
|
||||
typedef enum
|
||||
{
|
||||
GPGME_VERIFY_ARCHIVE = 1
|
||||
}
|
||||
gpgme_verify_flags_t;
|
||||
|
||||
/* Verify within CTX that SIG is a valid signature for TEXT. */
|
||||
gpgme_error_t gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text,
|
||||
@ -1641,6 +1648,16 @@ gpgme_error_t gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
|
||||
gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext);
|
||||
gpgme_error_t gpgme_op_verify_ext_start (gpgme_ctx_t ctx,
|
||||
gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig,
|
||||
gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext);
|
||||
gpgme_error_t gpgme_op_verify_ext (gpgme_ctx_t ctx,
|
||||
gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig,
|
||||
gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -282,6 +282,9 @@ GPGME_1.0 {
|
||||
gpgme_op_receive_keys;
|
||||
gpgme_op_receive_keys_start;
|
||||
|
||||
gpgme_op_verify_ext;
|
||||
gpgme_op_verify_ext_start;
|
||||
|
||||
local:
|
||||
*;
|
||||
|
||||
|
47
src/verify.c
47
src/verify.c
@ -1135,8 +1135,9 @@ _gpgme_op_verify_init_result (gpgme_ctx_t ctx)
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext)
|
||||
verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
|
||||
@ -1153,26 +1154,45 @@ verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
|
||||
if (!sig)
|
||||
return gpg_error (GPG_ERR_NO_DATA);
|
||||
|
||||
return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext,
|
||||
ctx);
|
||||
return _gpgme_engine_op_verify (ctx->engine, flags, sig, signed_text,
|
||||
plaintext, ctx);
|
||||
}
|
||||
|
||||
|
||||
/* Decrypt ciphertext CIPHER and make a signature verification within
|
||||
CTX and store the resulting plaintext in PLAIN. */
|
||||
/* Old version of gpgme_op_verify_ext_start without FLAGS. */
|
||||
gpgme_error_t
|
||||
gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext)
|
||||
{
|
||||
return gpgme_op_verify_ext_start (ctx, 0, sig, signed_text, plaintext);
|
||||
}
|
||||
|
||||
|
||||
/* Old version of gpgme_op_verify_ext without FLAGS. */
|
||||
gpgme_error_t
|
||||
gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext)
|
||||
{
|
||||
return gpgme_op_verify_ext (ctx, 0, sig, signed_text, plaintext);
|
||||
}
|
||||
|
||||
|
||||
/* Decrypt ciphertext CIPHER and make a signature verification within
|
||||
CTX and store the resulting plaintext in PLAIN. */
|
||||
gpgme_error_t
|
||||
gpgme_op_verify_ext_start (gpgme_ctx_t ctx, gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext)
|
||||
{
|
||||
gpg_error_t err;
|
||||
TRACE_BEG (DEBUG_CTX, "gpgme_op_verify_start", ctx,
|
||||
"sig=%p, signed_text=%p, plaintext=%p",
|
||||
sig, signed_text, plaintext);
|
||||
"flags=0x%x, sig=%p, signed_text=%p, plaintext=%p",
|
||||
flags, sig, signed_text, plaintext);
|
||||
|
||||
if (!ctx)
|
||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||
|
||||
err = verify_start (ctx, 0, sig, signed_text, plaintext);
|
||||
err = verify_start (ctx, 0, flags, sig, signed_text, plaintext);
|
||||
return TRACE_ERR (err);
|
||||
}
|
||||
|
||||
@ -1180,19 +1200,20 @@ gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
|
||||
/* Decrypt ciphertext CIPHER and make a signature verification within
|
||||
CTX and store the resulting plaintext in PLAIN. */
|
||||
gpgme_error_t
|
||||
gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_op_verify_ext (gpgme_ctx_t ctx, gpgme_verify_flags_t flags,
|
||||
gpgme_data_t sig, gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
|
||||
TRACE_BEG (DEBUG_CTX, "gpgme_op_verify", ctx,
|
||||
"sig=%p, signed_text=%p, plaintext=%p",
|
||||
sig, signed_text, plaintext);
|
||||
"flags=0x%x, sig=%p, signed_text=%p, plaintext=%p",
|
||||
flags, sig, signed_text, plaintext);
|
||||
|
||||
if (!ctx)
|
||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||
|
||||
err = verify_start (ctx, 1, sig, signed_text, plaintext);
|
||||
err = verify_start (ctx, 1, flags, sig, signed_text, plaintext);
|
||||
if (!err)
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return TRACE_ERR (err);
|
||||
|
@ -235,6 +235,9 @@ show_usage (int ex)
|
||||
" --repeat N repeat the operation N times\n"
|
||||
" --auto-key-retrieve\n"
|
||||
" --auto-key-import\n"
|
||||
" --archive extract files from a signed archive FILE\n"
|
||||
" --directory DIR extract the files into the directory DIR\n"
|
||||
" --diagnostics print diagnostics\n"
|
||||
, stderr);
|
||||
exit (ex);
|
||||
}
|
||||
@ -246,10 +249,13 @@ main (int argc, char **argv)
|
||||
int last_argc = -1;
|
||||
const char *s;
|
||||
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
|
||||
gpgme_verify_flags_t flags = 0;
|
||||
int print_status = 0;
|
||||
const char *sender = NULL;
|
||||
const char *directory = NULL;
|
||||
int auto_key_retrieve = 0;
|
||||
int auto_key_import = 0;
|
||||
int diagnostics = 0;
|
||||
int repeats = 1;
|
||||
int i;
|
||||
|
||||
@ -312,12 +318,30 @@ main (int argc, char **argv)
|
||||
auto_key_import = 1;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--archive"))
|
||||
{
|
||||
flags |= GPGME_VERIFY_ARCHIVE;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--directory"))
|
||||
{
|
||||
argc--; argv++;
|
||||
if (!argc)
|
||||
show_usage (1);
|
||||
directory = *argv;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--diagnostics"))
|
||||
{
|
||||
diagnostics = 1;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strncmp (*argv, "--", 2))
|
||||
show_usage (1);
|
||||
|
||||
}
|
||||
|
||||
if (argc < 1 || argc > 2)
|
||||
if (argc < 1 || argc > 2 || (argc > 1 && (flags & GPGME_VERIFY_ARCHIVE)))
|
||||
show_usage (1);
|
||||
|
||||
init_gpgme (protocol);
|
||||
@ -330,6 +354,7 @@ main (int argc, char **argv)
|
||||
gpgme_data_t sig = NULL;
|
||||
FILE *fp_msg = NULL;
|
||||
gpgme_data_t msg = NULL;
|
||||
gpgme_data_t out = NULL;
|
||||
gpgme_verify_result_t result;
|
||||
|
||||
if (repeats > 1)
|
||||
@ -415,8 +440,48 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
err = gpgme_op_verify (ctx, sig, msg, NULL);
|
||||
if (directory && (flags & GPGME_VERIFY_ARCHIVE))
|
||||
{
|
||||
err = gpgme_data_new (&out);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr, PGM ": error allocating data object: %s\n",
|
||||
gpgme_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
err = gpgme_data_set_file_name (out, directory);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr, PGM ": error setting file name (out): %s\n",
|
||||
gpgme_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
err = gpgme_op_verify_ext (ctx, flags, sig, msg, out);
|
||||
result = gpgme_op_verify_result (ctx);
|
||||
|
||||
if (diagnostics)
|
||||
{
|
||||
gpgme_data_t diag;
|
||||
gpgme_error_t diag_err;
|
||||
|
||||
gpgme_data_new (&diag);
|
||||
diag_err = gpgme_op_getauditlog (ctx, diag, GPGME_AUDITLOG_DIAG);
|
||||
if (diag_err)
|
||||
{
|
||||
fprintf (stderr, PGM ": getting diagnostics failed: %s\n",
|
||||
gpgme_strerror (diag_err));
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs ("Begin Diagnostics:\n", stdout);
|
||||
print_data (diag);
|
||||
fputs ("End Diagnostics.\n", stdout);
|
||||
}
|
||||
gpgme_data_release (diag);
|
||||
}
|
||||
|
||||
if (result)
|
||||
print_result (result);
|
||||
if (err)
|
||||
@ -425,6 +490,7 @@ main (int argc, char **argv)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
gpgme_data_release (out);
|
||||
gpgme_data_release (msg);
|
||||
gpgme_data_release (sig);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user