
* src/gpgme.c (gpgme_set_export_session_keys): New function. (gpgme_get_export_session_keys): New function. * src/gpgme.h.in (struct _gpgme_op_decrypt_result): Add session_key member. (gpgme_{set,get}_export_session_keys): Declare new functions. * src/libgpgme.vers, src/gpgme.def: Export new functions in shared object. * src/engine.h: (_gpgme_engine_op_decrypt) Add export_session_key parameter. (_gpgme_engine_op_decrypt_verify): Add export_session_key parameter. * src/engine-backend.h: (struct engine_ops): Change function pointer declarations to match. * src/context.h (struct gpgme_context): Add export_session_keys member. * src/decrypt.c (release_op_data): Free result.session_key. (_gpgme_decrypt_status_handler): Store a copy of the exported session key. (decrypt_start): Pass export_session_keys from the context. * src/decrypt-verify.c (decrypt_verify_start): Pass export_session_keys from context. * src/engine.c (_gpgme_engine_op_decrypt): Pass through export_session_key flag. (_gpgme_engine_op_decrypt_verify): Pass through export_session_key flag. * src/engine-gpg.c (gpg_decrypt): If export_session_key is set, add --export-session-key to argument list. * src/engine-gpgsm.c (gpgsm_decrypt): Ignore export_session_key for now, since gpgsm offers no such mechanism. * src/engine-uiserver.c (_uiserver_decrypt): If export_session_key is set, add --export-session-key flag to cmd. * doc/gpgme.texi: Document new functions and session_key member of decrypt_result_t. * doc/uiserver.texi: Add --export-session-key flag to DECRYPT command. -- gpg(1) documents session key export as useful for key escrow, and is rightly dubious of that use case. However, session key export is also useful in other use cases. Two examples from MUA development (where this functionality would be specifically useful to me right now): * If the MUA stores a local copy of the session key upon decrypting the message, it can re-decrypt the message without expensive asymmetric operations. When rendering a thread with dozens of encrypted messages, this can represent a significant speedup. * A user may have expired encryption-capable secret key material, along with many messages encrypted to that material. If she stores the session keys for those messages she wants to keep, she can destroy her secret key material and make any messages she has deleted completely unrecoverable, even to an attacker who gets her remaining secret keys in the future. This patchset makes a two specific implementation decisions that could have gone in different ways. I welcome feedback on preferred outcomes. 0) session key representation: we currently represent the session key as an opaque textual string, rather than trying to provide any sort of in-memory structure. While it wouldn't be hard to parse the data produced by gpg's --export-session-key, I chose to use the opaque string rather than lock in a particular data format. 1) API/ABI: i've added a member to gpgme_op_decrypt_result_t. This has the potential to cause an out-of-bound memory access if someone uses code compiled against the newer verision, but linked at runtime against an older version. I've attempted to limit that risk by documenting that users must verify gpgme_get_export_session_keys() before accessing this new struct member -- this means that code expecting this capability will require the symbol at link-time, and will refuse to link against older versions. Another approach to solving this problem would be to avoid modifying gpgme_op_decrypt_result_t, and to introduce instead a new function gpgme_op_session_key(), which could be called in the same places as gpgme_op_decrypt_result(). Depending on the representation of the session key, this might introduce new memory-management burdens on the user of the library, and the session key is certainly part of a decryption result, so it seemed simpler to go with what i have here. If anyone has strong preferences that these choices should be solved in a different way, i'm happy to hear them. Additionally, I note that i'm also still pretty unclear about how the "UI Server" fits into this whole ecosystem. In particular, I don't know whether it's kosher to just add an --export-session-key flag to the DECRYPT operation without actually having implemented it anywhere, but i don't see where i would actually implement it either :/ If this patch (or some variant) is adopted, i will supply another patch that permits offering a session key during decryption (e.g. "gpg --override-session-key"), but I wanted to get these implementation choices ironed out first. Gnupg-Bug-Id: 2754 Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net> On the concern of adding a new field to a structure: It may not be clearly documented but we don't expect that a user ever allocates such a structure - those result structure may only be created bu gpgme and are read-only for the user. Adding a new member constitutes a compatible ABI change and thus an older SO may not be used by code compiled with a header for the newer API. Unless someone tinkers with the build system, this should never happen. We have added new fields to result structure may times and I can't remember any problems. - wk
211 lines
8.5 KiB
C
211 lines
8.5 KiB
C
/* engine.h - GPGME engine interface.
|
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
|
Copyright (C) 2001, 2002, 2003, 2004, 2010 g10 Code GmbH
|
|
|
|
This file is part of GPGME.
|
|
|
|
GPGME is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Lesser General Public License as
|
|
published by the Free Software Foundation; either version 2.1 of
|
|
the License, or (at your option) any later version.
|
|
|
|
GPGME 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
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser 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. */
|
|
|
|
#ifndef ENGINE_H
|
|
#define ENGINE_H
|
|
|
|
#include "gpgme.h"
|
|
|
|
/* Flags used by the EXTRAFLAGS arg of _gpgme_engine_op_genkey. */
|
|
#define GENKEY_EXTRAFLAG_ARMOR 1
|
|
#define GENKEY_EXTRAFLAG_REVOKE 2
|
|
|
|
|
|
struct engine;
|
|
typedef struct engine *engine_t;
|
|
|
|
typedef gpgme_error_t (*engine_status_handler_t) (void *priv,
|
|
gpgme_status_code_t code,
|
|
char *args);
|
|
typedef gpgme_error_t (*engine_colon_line_handler_t) (void *priv, char *line);
|
|
typedef gpgme_error_t (*engine_command_handler_t) (void *priv,
|
|
gpgme_status_code_t code,
|
|
const char *keyword,
|
|
int fd, int *processed);
|
|
typedef gpgme_error_t (*engine_assuan_result_cb_t) (void *priv,
|
|
gpgme_error_t result);
|
|
|
|
/* Helper for gpgme_set_global_flag. */
|
|
int _gpgme_set_engine_minimal_version (const char *value);
|
|
|
|
/* Get a deep copy of the engine info and return it in INFO. */
|
|
gpgme_error_t _gpgme_engine_info_copy (gpgme_engine_info_t *r_info);
|
|
|
|
/* Release the engine info INFO. */
|
|
void _gpgme_engine_info_release (gpgme_engine_info_t info);
|
|
|
|
/* Set the engine info for the info list INFO, protocol PROTO, to the
|
|
file name FILE_NAME and the home directory HOME_DIR. */
|
|
gpgme_error_t _gpgme_set_engine_info (gpgme_engine_info_t info,
|
|
gpgme_protocol_t praoto,
|
|
const char *file_name,
|
|
const char *home_dir);
|
|
|
|
|
|
gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info,
|
|
engine_t *r_engine);
|
|
gpgme_error_t _gpgme_engine_reset (engine_t engine);
|
|
|
|
gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
|
|
const char *value);
|
|
gpgme_error_t _gpgme_engine_set_protocol (engine_t engine,
|
|
gpgme_protocol_t protocol);
|
|
void _gpgme_engine_release (engine_t engine);
|
|
void _gpgme_engine_set_status_cb (engine_t engine,
|
|
gpgme_status_cb_t cb, void *cb_value);
|
|
void _gpgme_engine_set_status_handler (engine_t engine,
|
|
engine_status_handler_t fnc,
|
|
void *fnc_value);
|
|
gpgme_error_t _gpgme_engine_set_command_handler (engine_t engine,
|
|
engine_command_handler_t fnc,
|
|
void *fnc_value,
|
|
gpgme_data_t data);
|
|
gpgme_error_t
|
|
_gpgme_engine_set_colon_line_handler (engine_t engine,
|
|
engine_colon_line_handler_t fnc,
|
|
void *fnc_value);
|
|
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
|
|
gpgme_data_t plain,
|
|
int export_session_key);
|
|
gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine,
|
|
gpgme_data_t ciph,
|
|
gpgme_data_t plain,
|
|
int export_session_key);
|
|
gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
|
|
int allow_secret);
|
|
gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,
|
|
gpgme_key_t key, gpgme_data_t out,
|
|
gpgme_ctx_t ctx /* FIXME */);
|
|
gpgme_error_t _gpgme_engine_op_encrypt (engine_t engine,
|
|
gpgme_key_t recp[],
|
|
gpgme_encrypt_flags_t flags,
|
|
gpgme_data_t plain, gpgme_data_t ciph,
|
|
int use_armor);
|
|
gpgme_error_t _gpgme_engine_op_encrypt_sign (engine_t engine,
|
|
gpgme_key_t recp[],
|
|
gpgme_encrypt_flags_t flags,
|
|
gpgme_data_t plain,
|
|
gpgme_data_t ciph,
|
|
int use_armor,
|
|
gpgme_ctx_t ctx /* FIXME */);
|
|
gpgme_error_t _gpgme_engine_op_export (engine_t engine, const char *pattern,
|
|
gpgme_export_mode_t mode,
|
|
gpgme_data_t keydata, int use_armor);
|
|
gpgme_error_t _gpgme_engine_op_export_ext (engine_t engine,
|
|
const char *pattern[],
|
|
gpgme_export_mode_t mode,
|
|
gpgme_data_t keydata,
|
|
int use_armor);
|
|
gpgme_error_t _gpgme_engine_op_genkey (engine_t engine,
|
|
const char *userid, const char *algo,
|
|
unsigned long reserved,
|
|
unsigned long expires,
|
|
gpgme_key_t key, unsigned int flags,
|
|
gpgme_data_t help_data,
|
|
unsigned int extraflags,
|
|
gpgme_data_t pubkey,
|
|
gpgme_data_t seckey);
|
|
gpgme_error_t _gpgme_engine_op_keysign (engine_t engine,
|
|
gpgme_key_t key, const char *userid,
|
|
unsigned long expires,
|
|
unsigned int flags,
|
|
gpgme_ctx_t ctx);
|
|
gpgme_error_t _gpgme_engine_op_tofu_policy (engine_t engine,
|
|
gpgme_key_t key,
|
|
gpgme_tofu_policy_t policy);
|
|
gpgme_error_t _gpgme_engine_op_import (engine_t engine,
|
|
gpgme_data_t keydata,
|
|
gpgme_key_t *keyarray);
|
|
gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,
|
|
const char *pattern,
|
|
int secret_only,
|
|
gpgme_keylist_mode_t mode,
|
|
int engine_flags);
|
|
gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine,
|
|
const char *pattern[],
|
|
int secret_only,
|
|
int reserved,
|
|
gpgme_keylist_mode_t mode,
|
|
int engine_flags);
|
|
gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in,
|
|
gpgme_data_t out, gpgme_sig_mode_t mode,
|
|
int use_armor, int use_textmode,
|
|
int include_certs,
|
|
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_data_t signed_text,
|
|
gpgme_data_t plaintext,
|
|
gpgme_ctx_t ctx);
|
|
|
|
gpgme_error_t _gpgme_engine_op_getauditlog (engine_t engine,
|
|
gpgme_data_t output,
|
|
unsigned int flags);
|
|
gpgme_error_t _gpgme_engine_op_assuan_transact
|
|
(engine_t engine,
|
|
const char *command,
|
|
gpgme_assuan_data_cb_t data_cb,
|
|
void *data_cb_value,
|
|
gpgme_assuan_inquire_cb_t inq_cb,
|
|
void *inq_cb_value,
|
|
gpgme_assuan_status_cb_t status_cb,
|
|
void *status_cb_value);
|
|
|
|
gpgme_error_t _gpgme_engine_op_conf_load (engine_t engine,
|
|
gpgme_conf_comp_t *conf_p);
|
|
gpgme_error_t _gpgme_engine_op_conf_save (engine_t engine,
|
|
gpgme_conf_comp_t conf);
|
|
|
|
gpgme_error_t _gpgme_engine_op_query_swdb (engine_t engine,
|
|
const char *name,
|
|
const char *iversion,
|
|
gpgme_query_swdb_result_t result);
|
|
|
|
|
|
void _gpgme_engine_set_io_cbs (engine_t engine,
|
|
gpgme_io_cbs_t io_cbs);
|
|
void _gpgme_engine_io_event (engine_t engine,
|
|
gpgme_event_io_t type, void *type_data);
|
|
|
|
gpgme_error_t _gpgme_engine_cancel (engine_t engine);
|
|
|
|
gpgme_error_t _gpgme_engine_cancel_op (engine_t engine);
|
|
|
|
gpgme_error_t _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
|
|
unsigned int flags);
|
|
|
|
gpgme_error_t _gpgme_engine_set_pinentry_mode (engine_t engine,
|
|
gpgme_pinentry_mode_t mode);
|
|
|
|
gpgme_error_t _gpgme_engine_op_spawn (engine_t engine,
|
|
const char *file, const char *argv[],
|
|
gpgme_data_t datain,
|
|
gpgme_data_t dataout,
|
|
gpgme_data_t dataerr,
|
|
unsigned int flags);
|
|
|
|
/* The available engine option flags. */
|
|
#define GPGME_ENGINE_FLAG_OFFLINE 1
|
|
|
|
|
|
#endif /* ENGINE_H */
|