core: Add extended versions of the encrypt functions.
* src/gpgme.h.in (gpgme_op_encrypt_ext_start) New. (gpgme_op_encrypt_ext): New. (gpgme_op_encrypt_sign_ext_start): New. (gpgme_op_encrypt_sign_ext): New. * src/libgpgme.vers, tests/run-encrypt.c: Add them. * src/encrypt.c (encrypt_start): Add arg recpstring. (gpgme_op_encrypt): Factor code out to ... (gpgme_op_encrypt_ext): new function with new arg recpstring. (gpgme_op_encrypt_start): Factor code out to ... (gpgme_op_encrypt_ext_start): new function with new arg recpstring. * src/encrypt-sign.c (encrypt_sign_start): Add arg recpstring. (gpgme_op_encrypt_sign): Factor code out to ... (gpgme_op_encrypt_sign_ext): new function with new arg recpstring. (gpgme_op_encrypt_sign_start): Factor code out to ... (gpgme_op_encrypt_sign_ext_start): new function with new arg recpstring. * src/engine-backend.h (struct engine_ops): Change fields encrypt and encrypt_sign. * src/engine.c (_gpgme_engine_op_encrypt): Add arg recpstring and pass to engine. (_gpgme_engine_op_encrypt_sign): Ditto. * src/engine-gpg.c (append_args_from_recipients_string): New. (gpg_encrypt): Add arg recpstring and call new function as needed. (gpg_encrypt_sign): Ditto. * src/engine-gpgsm.c (set_recipients_from_string): New. (gpgsm_encrypt): Add arg recpstring and call new function as needed. * src/engine-uiserver.c (set_recipients_from_string): New. (uiserver_encrypt): Add arg recpstring and call new function as needed. * tests/run-encrypt.c (xstrdup): New. (main): Add option --keystring. * src/gpgme-json.c (get_keys): Simplify. (op_encrypt): Modify to make use of the extended encrypt function. -- This new feature can be used to avoid the need for a key lookup and thus several extra calls to the backend. Note that run-test uses a semicolon as delimiter because that make testing the feature on the command line much easier. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
b99502274a
commit
a1f76b3b54
11
NEWS
11
NEWS
@ -5,11 +5,16 @@ Noteworthy changes in version 1.10.1 (unreleased)
|
|||||||
|
|
||||||
* Interface changes relative to the 1.10.0 release:
|
* Interface changes relative to the 1.10.0 release:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
gpgme_import_result_t EXTENDED: New field 'skipped_v3_keys'
|
gpgme_op_encrypt_ext NEW.
|
||||||
cpp: Key::locate NEW.
|
gpgme_op_encrypt_ext_start NEW.
|
||||||
cpp: Data::toString NEW.
|
gpgme_op_encrypt_sign_ext NEW.
|
||||||
|
gpgme_op_encrypt_sign_ext_start NEW.
|
||||||
|
gpgme_import_result_t EXTENDED: New field 'skipped_v3_keys'.
|
||||||
|
cpp: Key::locate NEW.
|
||||||
|
cpp: Data::toString NEW.
|
||||||
cpp: ImportResult::numV3KeysSkipped NEW.
|
cpp: ImportResult::numV3KeysSkipped NEW.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 1.10.0 (2017-12-12)
|
Noteworthy changes in version 1.10.0 (2017-12-12)
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
|
@ -6154,6 +6154,45 @@ pointer, and @code{GPG_ERR_UNUSABLE_PUBKEY} if @var{rset} does not
|
|||||||
contain any valid recipients.
|
contain any valid recipients.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun gpgme_error_t gpgme_op_encrypt_ext @
|
||||||
|
(@w{gpgme_ctx_t @var{ctx}}, @
|
||||||
|
@w{gpgme_key_t @var{recp}[]}, @
|
||||||
|
@w{const char *@var{recpstring}}, @
|
||||||
|
@w{gpgme_encrypt_flags_t @var{flags}}, @
|
||||||
|
@w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
|
||||||
|
|
||||||
|
@since{1.11.0}
|
||||||
|
|
||||||
|
This is an extended version of @code{gpgme_op_encrypt} with
|
||||||
|
@var{recpstring} as additional parameter. If @var{recp} is NULL and
|
||||||
|
@var{recpstring} is not NULL, the latter is expected to be a linefeed
|
||||||
|
delimited string with the set of key specifications. In contrast to
|
||||||
|
@var{recp} the keys are given directly as strings and there is no need
|
||||||
|
to first create key objects. The keys are passed verbatim to the
|
||||||
|
backend engine.
|
||||||
|
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefun gpgme_error_t gpgme_op_encrypt_ext_start @
|
||||||
|
(@w{gpgme_ctx_t @var{ctx}}, @
|
||||||
|
@w{gpgme_key_t @var{recp}[]}, @
|
||||||
|
@w{const char *@var{recpstring}}, @
|
||||||
|
@w{gpgme_encrypt_flags_t @var{flags}}, @
|
||||||
|
@w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
|
||||||
|
|
||||||
|
@since{1.11.0}
|
||||||
|
|
||||||
|
This is an extended version of @code{gpgme_op_encrypt_start} with
|
||||||
|
@var{recpstring} as additional parameter. If @var{recp} is NULL and
|
||||||
|
@var{recpstring} is not NULL, the latter is expected to be a linefeed
|
||||||
|
delimited string with the set of key specifications. In contrast to
|
||||||
|
@var{recp} the keys are given directly as strings and there is no need
|
||||||
|
to first create key objects. The keys are passed verbatim to the
|
||||||
|
backend engine.
|
||||||
|
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
@deftp {Data type} {gpgme_encrypt_result_t}
|
@deftp {Data type} {gpgme_encrypt_result_t}
|
||||||
This is a pointer to a structure used to store the result of a
|
This is a pointer to a structure used to store the result of a
|
||||||
@code{gpgme_op_encrypt} operation. After successfully encrypting
|
@code{gpgme_op_encrypt} operation. After successfully encrypting
|
||||||
@ -6203,6 +6242,44 @@ if @var{ctx}, @var{rset}, @var{plain} or @var{cipher} is not a valid
|
|||||||
pointer.
|
pointer.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun gpgme_error_t gpgme_op_encrypt_sign_ext @
|
||||||
|
(@w{gpgme_ctx_t @var{ctx}}, @
|
||||||
|
@w{gpgme_key_t @var{recp}[]}, @
|
||||||
|
@w{const char *@var{recpstring}}, @
|
||||||
|
@w{gpgme_encrypt_flags_t @var{flags}}, @
|
||||||
|
@w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
|
||||||
|
|
||||||
|
@since{1.11.0}
|
||||||
|
|
||||||
|
This is an extended version of @code{gpgme_op_encrypt_sign} with
|
||||||
|
@var{recpstring} as additional parameter. If @var{recp} is NULL and
|
||||||
|
@var{recpstring} is not NULL, the latter is expected to be a linefeed
|
||||||
|
delimited string with the set of key specifications. In contrast to
|
||||||
|
@var{recp} the keys are given directly as strings and there is no need
|
||||||
|
to first create the key objects. The keys are passed verbatim to the
|
||||||
|
backend engine.
|
||||||
|
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun gpgme_error_t gpgme_op_encrypt_sign_ext_start @
|
||||||
|
(@w{gpgme_ctx_t @var{ctx}}, @
|
||||||
|
@w{gpgme_key_t @var{recp}[]}, @
|
||||||
|
@w{const char *@var{recpstring}}, @
|
||||||
|
@w{gpgme_encrypt_flags_t @var{flags}}, @
|
||||||
|
@w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
|
||||||
|
|
||||||
|
@since{1.11.0}
|
||||||
|
|
||||||
|
This is an extended version of @code{gpgme_op_encrypt_sign_start} with
|
||||||
|
@var{recpstring} as additional parameter. If @var{recp} is NULL and
|
||||||
|
@var{recpstring} is not NULL, the latter is expected to be a linefeed
|
||||||
|
delimited string with the set of key specifications. In contrast to
|
||||||
|
@var{recp} the keys are given directly as strings and there is no need
|
||||||
|
to first create the key objects. The keys are passed verbatim to the
|
||||||
|
backend engine.
|
||||||
|
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
@node Miscellaneous
|
@node Miscellaneous
|
||||||
@section Miscellaneous operations
|
@section Miscellaneous operations
|
||||||
|
@ -62,6 +62,7 @@ encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
|||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher)
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
{
|
{
|
||||||
@ -72,7 +73,7 @@ encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
symmetric = !recp || (flags & GPGME_ENCRYPT_SYMMETRIC);
|
symmetric = (!recp && !recpstring) || (flags & GPGME_ENCRYPT_SYMMETRIC);
|
||||||
|
|
||||||
if (!plain)
|
if (!plain)
|
||||||
return gpg_error (GPG_ERR_NO_DATA);
|
return gpg_error (GPG_ERR_NO_DATA);
|
||||||
@ -103,53 +104,42 @@ encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
|||||||
: encrypt_sign_status_handler,
|
: encrypt_sign_status_handler,
|
||||||
ctx);
|
ctx);
|
||||||
|
|
||||||
return _gpgme_engine_op_encrypt_sign (ctx->engine, recp, flags, plain,
|
return _gpgme_engine_op_encrypt_sign (ctx->engine, recp, recpstring,
|
||||||
|
flags, plain,
|
||||||
cipher, ctx->use_armor,
|
cipher, ctx->use_armor,
|
||||||
ctx /* FIXME */);
|
ctx /* FIXME */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
/* Old version of gpgme_op_encrypt_sign_ext_start w/o RECPSTRING. */
|
||||||
store the resulting ciphertext in CIPHER. Also sign the ciphertext
|
|
||||||
with the signers in CTX. */
|
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher)
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
{
|
{
|
||||||
gpgme_error_t err;
|
return gpgme_op_encrypt_sign_ext_start (ctx, recp, NULL,
|
||||||
|
flags, plain, cipher);
|
||||||
TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign_start", ctx,
|
|
||||||
"flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
|
||||||
|
|
||||||
if (_gpgme_debug_trace () && recp)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (recp[i])
|
|
||||||
{
|
|
||||||
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
|
||||||
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
|
||||||
recp[i]->subkeys->fpr : "invalid");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = encrypt_sign_start (ctx, 0, recp, flags, plain, cipher);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
/* Old version of gpgme_op_encrypt_sign_ext w/o RECPSTRING. */
|
||||||
store the resulting ciphertext in CIPHER. Also sign the ciphertext
|
|
||||||
with the signers in CTX. */
|
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher)
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
|
{
|
||||||
|
return gpgme_op_encrypt_sign_ext (ctx, recp, NULL, flags, plain, cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
||||||
|
* store the resulting ciphertext in CIPHER. Also sign the ciphertext
|
||||||
|
* with the signers in CTX. */
|
||||||
|
gpgme_error_t
|
||||||
|
gpgme_op_encrypt_sign_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
{
|
{
|
||||||
gpgme_error_t err;
|
gpgme_error_t err;
|
||||||
|
|
||||||
@ -159,21 +149,70 @@ gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
|||||||
if (!ctx)
|
if (!ctx)
|
||||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||||
|
|
||||||
if (_gpgme_debug_trace () && recp)
|
if (_gpgme_debug_trace () && (recp || recpstring))
|
||||||
{
|
{
|
||||||
int i = 0;
|
if (recp)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
while (recp[i])
|
while (recp[i])
|
||||||
{
|
{
|
||||||
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
||||||
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
||||||
recp[i]->subkeys->fpr : "invalid");
|
recp[i]->subkeys->fpr : "invalid");
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE_LOG1 ("recipients = '%s'", recpstring);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = encrypt_sign_start (ctx, 1, recp, flags, plain, cipher);
|
err = encrypt_sign_start (ctx, 1, recp, recpstring, flags, plain, cipher);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = _gpgme_wait_one (ctx);
|
err = _gpgme_wait_one (ctx);
|
||||||
return TRACE_ERR (err);
|
return TRACE_ERR (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
||||||
|
store the resulting ciphertext in CIPHER. Also sign the ciphertext
|
||||||
|
with the signers in CTX. */
|
||||||
|
gpgme_error_t
|
||||||
|
gpgme_op_encrypt_sign_ext_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
|
{
|
||||||
|
gpgme_error_t err;
|
||||||
|
|
||||||
|
TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign_start", ctx,
|
||||||
|
"flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||||
|
|
||||||
|
if (_gpgme_debug_trace () && (recp || recpstring))
|
||||||
|
{
|
||||||
|
if (recp)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (recp[i])
|
||||||
|
{
|
||||||
|
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
||||||
|
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
||||||
|
recp[i]->subkeys->fpr : "invalid");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE_LOG1 ("recipients = '%s'", recpstring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = encrypt_sign_start (ctx, 0, recp, recpstring, flags, plain, cipher);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
120
src/encrypt.c
120
src/encrypt.c
@ -214,6 +214,7 @@ _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx)
|
|||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher)
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
{
|
{
|
||||||
@ -228,13 +229,13 @@ encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
symmetric = !recp || (flags & GPGME_ENCRYPT_SYMMETRIC);
|
symmetric = (!recp && !recpstring) || (flags & GPGME_ENCRYPT_SYMMETRIC);
|
||||||
|
|
||||||
if (!plain)
|
if (!plain)
|
||||||
return gpg_error (GPG_ERR_NO_DATA);
|
return gpg_error (GPG_ERR_NO_DATA);
|
||||||
if (!cipher)
|
if (!cipher)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
if (recp && ! *recp)
|
if (recp && !*recp)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
if (symmetric && ctx->passphrase_cb)
|
if (symmetric && ctx->passphrase_cb)
|
||||||
@ -252,48 +253,41 @@ encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
|
|||||||
: encrypt_status_handler,
|
: encrypt_status_handler,
|
||||||
ctx);
|
ctx);
|
||||||
|
|
||||||
return _gpgme_engine_op_encrypt (ctx->engine, recp, flags, plain, cipher,
|
return _gpgme_engine_op_encrypt (ctx->engine, recp, recpstring,
|
||||||
ctx->use_armor);
|
flags, plain, cipher, ctx->use_armor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Old version of gpgme_op_encrypt_ext without RECPSTRING. */
|
||||||
|
gpgme_error_t
|
||||||
|
gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
|
{
|
||||||
|
return gpgme_op_encrypt_ext (ctx, recp, NULL, flags, plain, cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Old version of gpgme_op_encrypt_ext_start without RECPSTRING. */
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher)
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
{
|
{
|
||||||
gpgme_error_t err;
|
return gpgme_op_encrypt_ext_start (ctx, recp, NULL, flags, plain, cipher);
|
||||||
|
|
||||||
TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_start", ctx,
|
|
||||||
"flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
|
||||||
|
|
||||||
if (_gpgme_debug_trace () && recp)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (recp[i])
|
|
||||||
{
|
|
||||||
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
|
||||||
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
|
||||||
recp[i]->subkeys->fpr : "invalid");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = encrypt_start (ctx, 0, recp, flags, plain, cipher);
|
|
||||||
return TRACE_ERR (err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
||||||
store the resulting ciphertext in CIPHER. */
|
* store the resulting ciphertext in CIPHER. RECPSTRING can be used
|
||||||
|
* instead of the RECP array to directly specify recipients as LF
|
||||||
|
* delimited strings; these may be any kind of recipient specification
|
||||||
|
* patterns as supported by the backend. */
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
gpgme_op_encrypt_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
gpgme_encrypt_flags_t flags,
|
const char *recpstring,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher)
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
{
|
{
|
||||||
gpgme_error_t err;
|
gpgme_error_t err;
|
||||||
|
|
||||||
@ -303,21 +297,67 @@ gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
|||||||
if (!ctx)
|
if (!ctx)
|
||||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||||
|
|
||||||
if (_gpgme_debug_trace () && recp)
|
if (_gpgme_debug_trace () && (recp || recpstring))
|
||||||
{
|
{
|
||||||
int i = 0;
|
if (recp)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
while (recp[i])
|
while (recp[i])
|
||||||
{
|
{
|
||||||
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
||||||
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
||||||
recp[i]->subkeys->fpr : "invalid");
|
recp[i]->subkeys->fpr : "invalid");
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE_LOG1 ("recipients = '%s'", recpstring);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = encrypt_start (ctx, 1, recp, flags, plain, cipher);
|
err = encrypt_start (ctx, 1, recp, recpstring, flags, plain, cipher);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = _gpgme_wait_one (ctx);
|
err = _gpgme_wait_one (ctx);
|
||||||
return TRACE_ERR (err);
|
return TRACE_ERR (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gpgme_error_t
|
||||||
|
gpgme_op_encrypt_ext_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain, gpgme_data_t cipher)
|
||||||
|
{
|
||||||
|
gpgme_error_t err;
|
||||||
|
|
||||||
|
TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_start", ctx,
|
||||||
|
"flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||||
|
|
||||||
|
if (_gpgme_debug_trace () && (recp || recpstring))
|
||||||
|
{
|
||||||
|
if (recp)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (recp[i])
|
||||||
|
{
|
||||||
|
TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
|
||||||
|
(recp[i]->subkeys && recp[i]->subkeys->fpr) ?
|
||||||
|
recp[i]->subkeys->fpr : "invalid");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE_LOG1 ("recipients = '%s'", recpstring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = encrypt_start (ctx, 0, recp, recpstring, flags, plain, cipher);
|
||||||
|
return TRACE_ERR (err);
|
||||||
|
}
|
||||||
|
@ -72,10 +72,12 @@ struct engine_ops
|
|||||||
gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
|
gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
|
||||||
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
|
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
|
||||||
gpgme_error_t (*encrypt) (void *engine, gpgme_key_t recp[],
|
gpgme_error_t (*encrypt) (void *engine, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph,
|
gpgme_data_t plain, gpgme_data_t ciph,
|
||||||
int use_armor);
|
int use_armor);
|
||||||
gpgme_error_t (*encrypt_sign) (void *engine, gpgme_key_t recp[],
|
gpgme_error_t (*encrypt_sign) (void *engine, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph,
|
gpgme_data_t plain, gpgme_data_t ciph,
|
||||||
int use_armor, gpgme_ctx_t ctx /* FIXME */);
|
int use_armor, gpgme_ctx_t ctx /* FIXME */);
|
||||||
|
@ -1914,17 +1914,64 @@ append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Take recipients from the LF delimited STRING and add -r args. */
|
||||||
|
static gpg_error_t
|
||||||
|
append_args_from_recipients_string (engine_gpg_t gpg, const char *string)
|
||||||
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
int any = 0;
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Skip leading white space */
|
||||||
|
while (*string == ' ' || *string == '\t')
|
||||||
|
string++;
|
||||||
|
if (!*string)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Look for the LF. */
|
||||||
|
s = strchr (string, '\n');
|
||||||
|
if (s)
|
||||||
|
n = s - string;
|
||||||
|
else
|
||||||
|
n = strlen (string);
|
||||||
|
while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
|
||||||
|
n--;
|
||||||
|
|
||||||
|
/* Add arg if it is not empty. */
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
err = add_arg (gpg, "-r");
|
||||||
|
if (!err)
|
||||||
|
err = add_arg_len (gpg, NULL, string, n);
|
||||||
|
if (!err)
|
||||||
|
any = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string += n + !!s;
|
||||||
|
}
|
||||||
|
while (!err);
|
||||||
|
|
||||||
|
if (!err && !any)
|
||||||
|
err = gpg_error (GPG_ERR_MISSING_KEY);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
||||||
{
|
{
|
||||||
engine_gpg_t gpg = engine;
|
engine_gpg_t gpg = engine;
|
||||||
gpgme_error_t err = 0;
|
gpgme_error_t err = 0;
|
||||||
|
|
||||||
if (recp)
|
if (recp || recpstring)
|
||||||
err = add_arg (gpg, "--encrypt");
|
err = add_arg (gpg, "--encrypt");
|
||||||
|
|
||||||
if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
|
if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
|
||||||
err = add_arg (gpg, "--symmetric");
|
err = add_arg (gpg, "--symmetric");
|
||||||
|
|
||||||
if (!err && use_armor)
|
if (!err && use_armor)
|
||||||
@ -1951,7 +1998,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
|||||||
&& have_gpg_version (gpg, "2.1.14"))
|
&& have_gpg_version (gpg, "2.1.14"))
|
||||||
err = add_arg (gpg, "--mimemode");
|
err = add_arg (gpg, "--mimemode");
|
||||||
|
|
||||||
if (recp)
|
if (recp || recpstring)
|
||||||
{
|
{
|
||||||
/* If we know that all recipients are valid (full or ultimate trust)
|
/* If we know that all recipients are valid (full or ultimate trust)
|
||||||
we can suppress further checks. */
|
we can suppress further checks. */
|
||||||
@ -1961,7 +2008,9 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
|||||||
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
|
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
|
||||||
err = add_arg (gpg, "--no-encrypt-to");
|
err = add_arg (gpg, "--no-encrypt-to");
|
||||||
|
|
||||||
if (!err)
|
if (!err && !recp && recpstring)
|
||||||
|
err = append_args_from_recipients_string (gpg, recpstring);
|
||||||
|
else if (!err)
|
||||||
err = append_args_from_recipients (gpg, recp);
|
err = append_args_from_recipients (gpg, recp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1995,6 +2044,7 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
|||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
|
gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags, gpgme_data_t plain,
|
gpgme_encrypt_flags_t flags, gpgme_data_t plain,
|
||||||
gpgme_data_t ciph, int use_armor,
|
gpgme_data_t ciph, int use_armor,
|
||||||
gpgme_ctx_t ctx /* FIXME */)
|
gpgme_ctx_t ctx /* FIXME */)
|
||||||
@ -2002,10 +2052,10 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
|
|||||||
engine_gpg_t gpg = engine;
|
engine_gpg_t gpg = engine;
|
||||||
gpgme_error_t err = 0;
|
gpgme_error_t err = 0;
|
||||||
|
|
||||||
if (recp)
|
if (recp || recpstring)
|
||||||
err = add_arg (gpg, "--encrypt");
|
err = add_arg (gpg, "--encrypt");
|
||||||
|
|
||||||
if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
|
if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
|
||||||
err = add_arg (gpg, "--symmetric");
|
err = add_arg (gpg, "--symmetric");
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -2023,7 +2073,7 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
|
|||||||
&& have_gpg_version (gpg, "2.1.14"))
|
&& have_gpg_version (gpg, "2.1.14"))
|
||||||
err = add_arg (gpg, "--mimemode");
|
err = add_arg (gpg, "--mimemode");
|
||||||
|
|
||||||
if (recp)
|
if (recp || recpstring)
|
||||||
{
|
{
|
||||||
/* If we know that all recipients are valid (full or ultimate trust)
|
/* If we know that all recipients are valid (full or ultimate trust)
|
||||||
we can suppress further checks. */
|
we can suppress further checks. */
|
||||||
@ -2033,7 +2083,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
|
|||||||
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
|
if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
|
||||||
err = add_arg (gpg, "--no-encrypt-to");
|
err = add_arg (gpg, "--no-encrypt-to");
|
||||||
|
|
||||||
if (!err)
|
if (!err && !recp && recpstring)
|
||||||
|
err = append_args_from_recipients_string (gpg, recpstring);
|
||||||
|
else if (!err)
|
||||||
err = append_args_from_recipients (gpg, recp);
|
err = append_args_from_recipients (gpg, recp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1327,8 +1327,57 @@ set_recipients (engine_gpgsm_t gpgsm, gpgme_key_t recp[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Take recipients from the LF delimited STRING and send RECIPIENT
|
||||||
|
* commands to gpgsm. */
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
set_recipients_from_string (engine_gpgsm_t gpgsm, const char *string)
|
||||||
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
char *line = NULL;
|
||||||
|
int no_pubkey = 0;
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while (*string == ' ' || *string == '\t')
|
||||||
|
string++;
|
||||||
|
if (!*string)
|
||||||
|
break;
|
||||||
|
|
||||||
|
s = strchr (string, '\n');
|
||||||
|
if (s)
|
||||||
|
n = s - string;
|
||||||
|
else
|
||||||
|
n = strlen (string);
|
||||||
|
while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
|
||||||
|
n--;
|
||||||
|
|
||||||
|
gpgrt_free (line);
|
||||||
|
if (gpgrt_asprintf (&line, "RECIPIENT %.*s", n, string) < 0)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
string += n + !!s;
|
||||||
|
|
||||||
|
err = gpgsm_assuan_simple_command (gpgsm, line, gpgsm->status.fnc,
|
||||||
|
gpgsm->status.fnc_value);
|
||||||
|
|
||||||
|
/* Fixme: Improve error reporting. */
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
|
||||||
|
no_pubkey++;
|
||||||
|
else if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gpgrt_free (line);
|
||||||
|
return err? err : no_pubkey? gpg_error (GPG_ERR_NO_PUBKEY) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gpgme_error_t
|
||||||
|
gpgsm_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
||||||
{
|
{
|
||||||
engine_gpgsm_t gpgsm = engine;
|
engine_gpgsm_t gpgsm = engine;
|
||||||
@ -1339,7 +1388,7 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
|||||||
if (!recp)
|
if (!recp)
|
||||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
if (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO)
|
if ((flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
|
||||||
{
|
{
|
||||||
err = gpgsm_assuan_simple_command (gpgsm,
|
err = gpgsm_assuan_simple_command (gpgsm,
|
||||||
"OPTION no-encrypt-to", NULL, NULL);
|
"OPTION no-encrypt-to", NULL, NULL);
|
||||||
@ -1359,7 +1408,10 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
|||||||
gpgsm_clear_fd (gpgsm, MESSAGE_FD);
|
gpgsm_clear_fd (gpgsm, MESSAGE_FD);
|
||||||
gpgsm->inline_data = NULL;
|
gpgsm->inline_data = NULL;
|
||||||
|
|
||||||
err = set_recipients (gpgsm, recp);
|
if (!recp && recpstring)
|
||||||
|
err = set_recipients_from_string (gpgsm, recpstring);
|
||||||
|
else
|
||||||
|
err = set_recipients (gpgsm, recp);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
err = start (gpgsm, "ENCRYPT");
|
err = start (gpgsm, "ENCRYPT");
|
||||||
|
@ -1075,8 +1075,58 @@ set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Take recipients from the LF delimited STRING and send RECIPIENT
|
||||||
|
* commands to gpgsm. */
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
set_recipients_from_string (engine_uiserver_t uiserver, const char *string)
|
||||||
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
char *line = NULL;
|
||||||
|
int no_pubkey = 0;
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while (*string == ' ' || *string == '\t')
|
||||||
|
string++;
|
||||||
|
if (!*string)
|
||||||
|
break;
|
||||||
|
|
||||||
|
s = strchr (string, '\n');
|
||||||
|
if (s)
|
||||||
|
n = s - string;
|
||||||
|
else
|
||||||
|
n = strlen (string);
|
||||||
|
while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
|
||||||
|
n--;
|
||||||
|
|
||||||
|
gpgrt_free (line);
|
||||||
|
if (gpgrt_asprintf (&line, "RECIPIENT %.*s", n, string) < 0)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
string += n + !!s;
|
||||||
|
|
||||||
|
err = uiserver_assuan_simple_command (uiserver, line,
|
||||||
|
uiserver->status.fnc,
|
||||||
|
uiserver->status.fnc_value);
|
||||||
|
|
||||||
|
/* Fixme: Improve error reporting. */
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
|
||||||
|
no_pubkey++;
|
||||||
|
else if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gpgrt_free (line);
|
||||||
|
return err? err : no_pubkey? gpg_error (GPG_ERR_NO_PUBKEY) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gpgme_error_t
|
||||||
|
uiserver_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
||||||
{
|
{
|
||||||
engine_uiserver_t uiserver = engine;
|
engine_uiserver_t uiserver = engine;
|
||||||
@ -1140,9 +1190,12 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
|
|||||||
|
|
||||||
uiserver->inline_data = NULL;
|
uiserver->inline_data = NULL;
|
||||||
|
|
||||||
if (recp)
|
if (recp || recpstring)
|
||||||
{
|
{
|
||||||
err = set_recipients (uiserver, recp);
|
if (recp)
|
||||||
|
err = set_recipients (uiserver, recp);
|
||||||
|
else
|
||||||
|
err = set_recipients_from_string (uiserver, recpstring);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
gpgrt_free (cmd);
|
gpgrt_free (cmd);
|
||||||
|
10
src/engine.c
10
src/engine.c
@ -721,6 +721,7 @@ _gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
|
|||||||
|
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
_gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
|
_gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
|
||||||
{
|
{
|
||||||
@ -730,13 +731,14 @@ _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
|
|||||||
if (!engine->ops->encrypt)
|
if (!engine->ops->encrypt)
|
||||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
|
return (*engine->ops->encrypt) (engine->engine, recp, recpstring,
|
||||||
use_armor);
|
flags, plain, ciph, use_armor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
_gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
|
_gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph,
|
gpgme_data_t plain, gpgme_data_t ciph,
|
||||||
int use_armor, gpgme_ctx_t ctx /* FIXME */)
|
int use_armor, gpgme_ctx_t ctx /* FIXME */)
|
||||||
@ -747,8 +749,8 @@ _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
|
|||||||
if (!engine->ops->encrypt_sign)
|
if (!engine->ops->encrypt_sign)
|
||||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
|
return (*engine->ops->encrypt_sign) (engine->engine, recp, recpstring,
|
||||||
plain, ciph, use_armor, ctx);
|
flags, plain, ciph, use_armor, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,11 +98,13 @@ gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,
|
|||||||
gpgme_ctx_t ctx /* FIXME */);
|
gpgme_ctx_t ctx /* FIXME */);
|
||||||
gpgme_error_t _gpgme_engine_op_encrypt (engine_t engine,
|
gpgme_error_t _gpgme_engine_op_encrypt (engine_t engine,
|
||||||
gpgme_key_t recp[],
|
gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t ciph,
|
gpgme_data_t plain, gpgme_data_t ciph,
|
||||||
int use_armor);
|
int use_armor);
|
||||||
gpgme_error_t _gpgme_engine_op_encrypt_sign (engine_t engine,
|
gpgme_error_t _gpgme_engine_op_encrypt_sign (engine_t engine,
|
||||||
gpgme_key_t recp[],
|
gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain,
|
gpgme_data_t plain,
|
||||||
gpgme_data_t ciph,
|
gpgme_data_t ciph,
|
||||||
|
@ -354,18 +354,19 @@ get_protocol (cjson_t json, gpgme_protocol_t *r_protocol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Extract the keys from the KEYS array in the JSON object. CTX is a
|
/* Extract the keys from the "keys" array in the JSON object. On
|
||||||
* GPGME context object. On success an array with the keys is stored
|
* success a string with the keys identifiers is stored at R_KEYS.
|
||||||
* at R_KEYS. In failure an error code is returned. */
|
* The keys in that string are LF delimited. On failure an error code
|
||||||
|
* is returned. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
|
get_keys (cjson_t json, char **r_keystring)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
|
||||||
cjson_t j_keys, j_item;
|
cjson_t j_keys, j_item;
|
||||||
int i, nkeys;
|
int i, nkeys;
|
||||||
gpgme_key_t *keys;
|
char *p;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
*r_keys = NULL;
|
*r_keystring = NULL;
|
||||||
|
|
||||||
j_keys = cJSON_GetObjectItem (json, "keys");
|
j_keys = cJSON_GetObjectItem (json, "keys");
|
||||||
if (!j_keys)
|
if (!j_keys)
|
||||||
@ -373,8 +374,15 @@ get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
|
|||||||
if (!cjson_is_array (j_keys) && !cjson_is_string (j_keys))
|
if (!cjson_is_array (j_keys) && !cjson_is_string (j_keys))
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
/* Fixme: We should better use a membuf like thing. */
|
||||||
|
length = 1; /* For the EOS. */
|
||||||
if (cjson_is_string (j_keys))
|
if (cjson_is_string (j_keys))
|
||||||
nkeys = 1;
|
{
|
||||||
|
nkeys = 1;
|
||||||
|
length += strlen (j_keys->valuestring);
|
||||||
|
if (strchr (j_keys->valuestring, '\n'))
|
||||||
|
return gpg_error (GPG_ERR_INV_USER_ID);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nkeys = cJSON_GetArraySize (j_keys);
|
nkeys = cJSON_GetArraySize (j_keys);
|
||||||
@ -385,43 +393,37 @@ get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
|
|||||||
j_item = cJSON_GetArrayItem (j_keys, i);
|
j_item = cJSON_GetArrayItem (j_keys, i);
|
||||||
if (!j_item || !cjson_is_string (j_item))
|
if (!j_item || !cjson_is_string (j_item))
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
if (i)
|
||||||
|
length++; /* Space for delimiter. */
|
||||||
|
length += strlen (j_item->valuestring);
|
||||||
|
if (strchr (j_item->valuestring, '\n'))
|
||||||
|
return gpg_error (GPG_ERR_INV_USER_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now allocate an array to store the gpgme key objects. */
|
p = *r_keystring = xtrymalloc (length);
|
||||||
keys = xcalloc (nkeys + 1, sizeof *keys);
|
if (!p)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
if (cjson_is_string (j_keys))
|
if (cjson_is_string (j_keys))
|
||||||
{
|
{
|
||||||
err = gpgme_get_key (ctx, j_keys->valuestring, &keys[0], 0);
|
strcpy (p, j_keys->valuestring);
|
||||||
if (err)
|
|
||||||
goto leave;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i=0; i < nkeys; i++)
|
for (i=0; i < nkeys; i++)
|
||||||
{
|
{
|
||||||
j_item = cJSON_GetArrayItem (j_keys, i);
|
j_item = cJSON_GetArrayItem (j_keys, i);
|
||||||
err = gpgme_get_key (ctx, j_item->valuestring, &keys[i], 0);
|
if (i)
|
||||||
if (err)
|
*p++ = '\n'; /* Add delimiter. */
|
||||||
goto leave;
|
p = stpcpy (p, j_item->valuestring);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = 0;
|
return 0;
|
||||||
*r_keys = keys;
|
|
||||||
keys = NULL;
|
|
||||||
|
|
||||||
leave:
|
|
||||||
if (keys)
|
|
||||||
{
|
|
||||||
for (i=0; keys[i]; i++)
|
|
||||||
gpgme_key_unref (keys[i]);
|
|
||||||
xfree (keys);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPGME support functions.
|
* GPGME support functions.
|
||||||
@ -582,11 +584,11 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
gpgme_ctx_t ctx = NULL;
|
gpgme_ctx_t ctx = NULL;
|
||||||
gpgme_protocol_t protocol;
|
gpgme_protocol_t protocol;
|
||||||
int opt_base64;
|
int opt_base64;
|
||||||
gpgme_key_t *keys = NULL;
|
char *keystring = NULL;
|
||||||
cjson_t j_input;
|
cjson_t j_input;
|
||||||
gpgme_data_t input = NULL;
|
gpgme_data_t input = NULL;
|
||||||
gpgme_data_t output = NULL;
|
gpgme_data_t output = NULL;
|
||||||
int abool, i;
|
int abool;
|
||||||
gpgme_encrypt_flags_t encrypt_flags = 0;
|
gpgme_encrypt_flags_t encrypt_flags = 0;
|
||||||
|
|
||||||
if ((err = get_protocol (request, &protocol)))
|
if ((err = get_protocol (request, &protocol)))
|
||||||
@ -622,7 +624,7 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
|
|
||||||
|
|
||||||
/* Get the keys. */
|
/* Get the keys. */
|
||||||
err = get_keys (ctx, request, &keys);
|
err = get_keys (request, &keystring);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
/* Provide a custom error response. */
|
/* Provide a custom error response. */
|
||||||
@ -674,7 +676,8 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Encrypt. */
|
/* Encrypt. */
|
||||||
err = gpgme_op_encrypt (ctx, keys, encrypt_flags, input, output);
|
err = gpgme_op_encrypt_ext (ctx, NULL, keystring, encrypt_flags,
|
||||||
|
input, output);
|
||||||
/* encrypt_result = gpgme_op_encrypt_result (ctx); */
|
/* encrypt_result = gpgme_op_encrypt_result (ctx); */
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -713,12 +716,7 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
if (keys)
|
xfree (keystring);
|
||||||
{
|
|
||||||
for (i=0; keys[i]; i++)
|
|
||||||
gpgme_key_unref (keys[i]);
|
|
||||||
xfree (keys);
|
|
||||||
}
|
|
||||||
release_context (ctx);
|
release_context (ctx);
|
||||||
gpgme_data_release (input);
|
gpgme_data_release (input);
|
||||||
return err;
|
return err;
|
||||||
|
@ -267,5 +267,10 @@ EXPORTS
|
|||||||
|
|
||||||
gpgme_op_conf_dir @199
|
gpgme_op_conf_dir @199
|
||||||
|
|
||||||
|
gpgme_op_encrypt_ext @200
|
||||||
|
gpgme_op_encrypt_ext_start @201
|
||||||
|
gpgme_op_encrypt_sign_ext @202
|
||||||
|
gpgme_op_encrypt_sign_ext_start @203
|
||||||
|
|
||||||
; END
|
; END
|
||||||
|
|
||||||
|
@ -1274,10 +1274,22 @@ gpgme_encrypt_flags_t;
|
|||||||
store the resulting ciphertext in CIPHER. */
|
store the resulting ciphertext in CIPHER. */
|
||||||
gpgme_error_t gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
gpgme_error_t gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher);
|
gpgme_data_t plain,
|
||||||
|
gpgme_data_t cipher);
|
||||||
gpgme_error_t gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
gpgme_error_t gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher);
|
gpgme_data_t plain,
|
||||||
|
gpgme_data_t cipher);
|
||||||
|
gpgme_error_t gpgme_op_encrypt_ext_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain,
|
||||||
|
gpgme_data_t cipher);
|
||||||
|
gpgme_error_t gpgme_op_encrypt_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain,
|
||||||
|
gpgme_data_t cipher);
|
||||||
|
|
||||||
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
||||||
store the resulting ciphertext in CIPHER. Also sign the ciphertext
|
store the resulting ciphertext in CIPHER. Also sign the ciphertext
|
||||||
@ -1289,7 +1301,19 @@ gpgme_error_t gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx,
|
|||||||
gpgme_data_t cipher);
|
gpgme_data_t cipher);
|
||||||
gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
gpgme_encrypt_flags_t flags,
|
gpgme_encrypt_flags_t flags,
|
||||||
gpgme_data_t plain, gpgme_data_t cipher);
|
gpgme_data_t plain,
|
||||||
|
gpgme_data_t cipher);
|
||||||
|
gpgme_error_t gpgme_op_encrypt_sign_ext_start (gpgme_ctx_t ctx,
|
||||||
|
gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain,
|
||||||
|
gpgme_data_t cipher);
|
||||||
|
gpgme_error_t gpgme_op_encrypt_sign_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
|
||||||
|
const char *recpstring,
|
||||||
|
gpgme_encrypt_flags_t flags,
|
||||||
|
gpgme_data_t plain,
|
||||||
|
gpgme_data_t cipher);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -215,10 +215,15 @@ GPGME_1.0 {
|
|||||||
gpgme_op_edit;
|
gpgme_op_edit;
|
||||||
gpgme_op_edit_start;
|
gpgme_op_edit_start;
|
||||||
gpgme_op_encrypt;
|
gpgme_op_encrypt;
|
||||||
gpgme_op_encrypt_result;
|
|
||||||
gpgme_op_encrypt_sign;
|
|
||||||
gpgme_op_encrypt_sign_start;
|
|
||||||
gpgme_op_encrypt_start;
|
gpgme_op_encrypt_start;
|
||||||
|
gpgme_op_encrypt_ext;
|
||||||
|
gpgme_op_encrypt_ext_start;
|
||||||
|
gpgme_op_encrypt_sign;
|
||||||
|
gpgme_op_encrypt_sign_ext;
|
||||||
|
gpgme_op_encrypt_sign_start;
|
||||||
|
gpgme_op_encrypt_sign_ext_start;
|
||||||
|
gpgme_op_encrypt_result;
|
||||||
|
|
||||||
gpgme_op_export;
|
gpgme_op_export;
|
||||||
gpgme_op_export_ext;
|
gpgme_op_export_ext;
|
||||||
gpgme_op_export_ext_start;
|
gpgme_op_export_ext_start;
|
||||||
|
@ -37,6 +37,19 @@
|
|||||||
static int verbose;
|
static int verbose;
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
xstrdup (const char *string)
|
||||||
|
{
|
||||||
|
char *p = strdup (string);
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "strdup failed\n");
|
||||||
|
exit (2);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
status_cb (void *opaque, const char *keyword, const char *value)
|
status_cb (void *opaque, const char *keyword, const char *value)
|
||||||
{
|
{
|
||||||
@ -88,6 +101,7 @@ show_usage (int ex)
|
|||||||
" --uiserver use the UI server\n"
|
" --uiserver use the UI server\n"
|
||||||
" --loopback use a loopback pinentry\n"
|
" --loopback use a loopback pinentry\n"
|
||||||
" --key NAME encrypt to key NAME\n"
|
" --key NAME encrypt to key NAME\n"
|
||||||
|
" --keystring NAMES encrypt to ';' delimited NAMES\n"
|
||||||
" --throw-keyids use this option\n"
|
" --throw-keyids use this option\n"
|
||||||
" --no-symkey-cache disable the use of that cache\n"
|
" --no-symkey-cache disable the use of that cache\n"
|
||||||
" --wrap assume input is valid OpenPGP message\n"
|
" --wrap assume input is valid OpenPGP message\n"
|
||||||
@ -103,7 +117,6 @@ main (int argc, char **argv)
|
|||||||
int last_argc = -1;
|
int last_argc = -1;
|
||||||
gpgme_error_t err;
|
gpgme_error_t err;
|
||||||
gpgme_ctx_t ctx;
|
gpgme_ctx_t ctx;
|
||||||
const char *key_string = NULL;
|
|
||||||
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
|
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
|
||||||
gpgme_data_t in, out;
|
gpgme_data_t in, out;
|
||||||
gpgme_encrypt_result_t result;
|
gpgme_encrypt_result_t result;
|
||||||
@ -113,6 +126,7 @@ main (int argc, char **argv)
|
|||||||
char *keyargs[10];
|
char *keyargs[10];
|
||||||
gpgme_key_t keys[10+1];
|
gpgme_key_t keys[10+1];
|
||||||
int keycount = 0;
|
int keycount = 0;
|
||||||
|
char *keystring = NULL;
|
||||||
int i;
|
int i;
|
||||||
gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
|
gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
|
||||||
gpgme_off_t offset;
|
gpgme_off_t offset;
|
||||||
@ -174,6 +188,17 @@ main (int argc, char **argv)
|
|||||||
keyargs[keycount++] = *argv;
|
keyargs[keycount++] = *argv;
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (*argv, "--keystring"))
|
||||||
|
{
|
||||||
|
argc--; argv++;
|
||||||
|
if (!argc)
|
||||||
|
show_usage (1);
|
||||||
|
keystring = xstrdup (*argv);
|
||||||
|
for (i=0; keystring[i]; i++)
|
||||||
|
if (keystring[i] == ';')
|
||||||
|
keystring[i] = '\n';
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
else if (!strcmp (*argv, "--throw-keyids"))
|
else if (!strcmp (*argv, "--throw-keyids"))
|
||||||
{
|
{
|
||||||
flags |= GPGME_ENCRYPT_THROW_KEYIDS;
|
flags |= GPGME_ENCRYPT_THROW_KEYIDS;
|
||||||
@ -207,15 +232,6 @@ main (int argc, char **argv)
|
|||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
show_usage (1);
|
show_usage (1);
|
||||||
|
|
||||||
if (key_string && protocol == GPGME_PROTOCOL_UISERVER)
|
|
||||||
{
|
|
||||||
fprintf (stderr, PGM ": ignoring --key in UI-server mode\n");
|
|
||||||
key_string = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key_string)
|
|
||||||
key_string = "test";
|
|
||||||
|
|
||||||
init_gpgme (protocol);
|
init_gpgme (protocol);
|
||||||
|
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
@ -298,7 +314,8 @@ main (int argc, char **argv)
|
|||||||
err = gpgme_data_new (&out);
|
err = gpgme_data_new (&out);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
err = gpgme_op_encrypt (ctx, keycount ? keys : NULL, flags, in, out);
|
err = gpgme_op_encrypt_ext (ctx, keycount ? keys : NULL, keystring,
|
||||||
|
flags, in, out);
|
||||||
result = gpgme_op_encrypt_result (ctx);
|
result = gpgme_op_encrypt_result (ctx);
|
||||||
if (result)
|
if (result)
|
||||||
print_result (result);
|
print_result (result);
|
||||||
@ -318,5 +335,6 @@ main (int argc, char **argv)
|
|||||||
for (i=0; i < keycount; i++)
|
for (i=0; i < keycount; i++)
|
||||||
gpgme_key_unref (keys[i]);
|
gpgme_key_unref (keys[i]);
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
|
free (keystring);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user