gpgme/gpgme/genkey.c
Marcus Brinkmann 2c543f6a86 doc/
2003-01-29  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (I/O Callback Interface): Document new even
	GPGME_EVENT_START.
	(Waiting For Completion): Document new possible return values.
	(I/O Callback Interface): Document return type of GpgmeIOCb.

gpgme/
2003-01-29  Marcus Brinkmann  <marcus@g10code.de>

	* context.h (gpgme_context_s): Remove member ERROR.
	* types.h (GpgmeStatusHandler): Change return type to GpgmeError.
	(GpgmeCommandHandler): Change return type to GpgmeError and add
	new argument RESULT.
	* gpgme.h (GpgmeIOCb): Change return type to GpgmeError.
	(GpgmeEventIO): New event GPGME_EVENT_START.
	(GpgmeIdleFunc): Remove type.
	(gpgme_register_idle): Remove prototype.
	* data.c: Include <assert.h>.
	(_gpgme_data_inbound_handler): Change return type to GpgmeError.
	Return any error instead ignoring it, don't close file descriptor
	on error.
	(_gpgme_data_outbound_handler): Likewise.
	* decrypt.c: Do not include <stdio.h>, <string.h> and <assert.h>.
	(_gpgme_decrypt_status_handler): Change return type to GpgmeError.
	Return error instead setting ctx->error.  Return success at end of
	function.
	(gpgme_op_decrypt): Don't work around the old kludge anymore.
	* decrypt-verify.c (decrypt_verify_status_handler): Change return
	type to GpgmeError.  Return possible errors.
	* delete.c: Do not include <stdio.h>, <string.h>, <time.h> and
	<assert.h>.
	(delete_status_handler): Change return type to GpgmeError.  Return
	error instead setting ctx->error.  Return success at end of
	function.
	* edit.c: Do not include <stdio.h> and <string.h>.
	(_gpgme_edit_status_handler): Change type to GpgmeError,
	make static and rename to ...
	(edit_status_handler): ... this.  Return error directly.
	(command_handler): Change return type to GpgmeError, add result
	argument.  Return error directly.
	* encrypt.c (status_handler_finish): Remove function.
	(_gpgme_encrypt_status_handler): Change return type to GpgmeError.
	Return error directly.
	(_gpgme_encrypt_sym_status_handler): Likewise.
	* encrypt-sign.c (encrypt_sign_status_handler): Likewise.
	* engine-gpgsm.c (close_notify_handler): Do not signal done event
	anymore.
	(status_handler): Change return type to GpgmeError.  Diddle things
	around a bit to return errors directly.
	(start): Send start event.
	* export.c: Do not include <stdio.h>, <string.h> and <assert.h>.
	(export_status_handler): Change return type to GpgmeError.  Don't
	check ctx->error.
	* genkey.c: Do not include <stdio.h> and <assert.h>.
	(genkey_status_handler): Change return type to GpgmeError.  Don't
	check ctx->error.  Return errors directly.
	* gpgme.c (_gpgme_release_result): Do not initialize ctx->error.
	(_gpgme_op_event_cb): Function removed.
	(_gpgme_op_event_cb_user): Likewise.
	* import.c: Do not include <stdio.h>, <string.h> and <assert.h>.
	(import_status_handler): Change return type to GpgmeError.  Don't
	check ctx->error.
	* keylist.c (keylist_colon_handler, keylist_status_handler, finish_key):
	Change return type to GpgmeError, return error directly.
	* Makefile (libgpgme_la_SOURCES): Add wait-global.c,
	wait-private.c and wait-user.c
	* ops.h (test_and_allocate_result): Return error instead setting
	ctx->error.
	(_gpgme_data_inbound_handler, _gpgme_data_outbound_handler,
	_gpgme_verify_status_handler, _gpgme_decrypt_status_handler,
	_gpgme_sign_status_handler, _gpgme_encrypt_staus_handler,
	_gpgme_passphrase_status_handler, _gpgme_progress_status_handler):
	Change return type to GpgmeError.
	(_gpgme_passphease_command_handler): Change return type to
	GpgmeError and add new argument RESULT.
	* op-support.c: Use new callback functions, and change private
	data to ctx everywhere.
	* passphrase.c (_gpgme_passphrase_status_handler): Change return
	type to GpgmeError, return error directly.
	(_gpgme_passphrase_command_handler): Change return type to
	GpgmeError, add result argument.  Return results accordingly.
	* progress.c (_gpgme_progress_status_handler): Change return type
	to GpgmeError, return errors directly.
	* rungpg.c (status_handler): Change return type to GpgmeError.
	Return error directly.
	(close_notify_handler): Don't send done event.
	(colon_line_handler): Change return type to GpgmeError, return
	errors directly.
	* rungpg.c (start): Send start event.
	* sign.c (_gpgme_sign_status_handler): Change return type to
	GpgmeError, return errors directly.
	* trustlist.c (trustlist_status_handler): Change return type to
	GpgmeError.  Return 0.
	(trustlist_colon_handler): Change return type GpgmeError.  Return
	errors directly.
	* verify.c (add_notation): Change return type to GpgmeError,
	return errors directly.
	(_gpgme_verify_status_handler): Likewise.
	* wait.h (struct fd_table): Remove lock member.
	(struct wait_item_s): Moved here from wait.c.
	(struct tag): New structure.
	(_gpgme_wait_event_cb): Remove prototype.
	(_gpgme_wait_private_event_cb, _gpgme_wait_global_event_cb,
	_gpgme_wait_user_add_io_cb, _gpgme_wait_user_remove_io_cb,
	_gpgme_wait_user_event_io_cb): New prototypes.
	* wait.c: Don't include <stdio.h>.
	(ftd_global, ctx_done_list, ctx_done_list_size,
	ctx_done_list_length, ctx_done_list_lock, idle_function): Remove
	global variable.
	(gpgme_register_idle, do_select, _gpgme_wait_event_cb): Remove
	function.
	(gpgme_wait): Move to file wait-global.c.
	(_gpgme_add_io_cb): Take ctx as private argument, initialize ctx
	member in wait item and tag.
	(_gpgme_remove_io_cb): Take ctx from tag.  Don't use FDT lock.
	(_gpgme_wait_one, _gpgme_wait_on_condition): Move to
	wait-private.c.
	(gpgme_fd_table_init): Don't initialize FDT->lock.
	(gpgme_fd_table_deinit): Don't destroy FDT->lock.
	(_gpgme_fd_table_put): Make static and rename to ...
	(fd_table_put): ... this function.  Don't use FDT->lock.
	(struct wait_item_s): Move to wait.h.
	* wait-global.c: New file.
	* wait-private.c: New file.
	* wait-user.c: New file.
2003-01-29 15:20:58 +00:00

226 lines
5.6 KiB
C

/* genkey.c - Key generation.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002 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 General Public License as published by
the Free Software Foundation; either version 2 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GPGME; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct genkey_result_s
{
int created_primary : 1;
int created_sub : 1;
char *fpr;
};
void
_gpgme_release_genkey_result (GenKeyResult result)
{
if (!result)
return;
if (result->fpr)
free (result->fpr);
free (result);
}
static GpgmeError
genkey_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
GpgmeError err = _gpgme_progress_status_handler (ctx, code, args);
if (err)
return err;
test_and_allocate_result (ctx, genkey);
switch (code)
{
case GPGME_STATUS_KEY_CREATED:
if (args && *args)
{
if (*args == 'B' || *args == 'P')
ctx->result.genkey->created_primary = 1;
if (*args == 'B' || *args == 'S')
ctx->result.genkey->created_sub = 1;
if (args[1] == ' ')
{
if (ctx->result.genkey->fpr)
free (ctx->result.genkey->fpr);
ctx->result.genkey->fpr = strdup (&args[2]);
if (!ctx->result.genkey->fpr)
return mk_error (Out_Of_Core);
}
}
break;
case GPGME_STATUS_EOF:
/* FIXME: Should return some more useful error value. */
if (!ctx->result.genkey->created_primary
&& !ctx->result.genkey->created_sub)
return mk_error (General_Error);
break;
default:
break;
}
return 0;
}
static GpgmeError
_gpgme_op_genkey_start (GpgmeCtx ctx, int synchronous, const char *parms,
GpgmeData pubkey, GpgmeData seckey)
{
int err = 0;
const char *s, *s2, *sx;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
goto leave;
gpgme_data_release (ctx->help_data_1);
ctx->help_data_1 = NULL;
if ((parms = strstr (parms, "<GnupgKeyParms "))
&& (s = strchr (parms, '>'))
&& (sx = strstr (parms, "format=\"internal\""))
&& sx < s
&& (s2 = strstr (s+1, "</GnupgKeyParms>")))
{
/* FIXME: Check that there are no control statements inside. */
s++; /* Skip '>'. */
while (*s == '\n')
s++;
err = gpgme_data_new_from_mem (&ctx->help_data_1, s, s2-s, 1);
}
else
err = mk_error (Invalid_Value);
if (err)
goto leave;
_gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
err = _gpgme_engine_op_genkey (ctx->engine, ctx->help_data_1, ctx->use_armor,
pubkey, seckey);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
/**
* gpgme_op_genkey:
* @c: the context
* @parms: XML string with the key parameters
* @pubkey: Returns the public key
* @seckey: Returns the secret key
*
* Generate a new key and store the key in the default keyrings if
* both @pubkey and @seckey are NULL. If @pubkey and @seckey are
* given, the newly created key will be returned in these data
* objects. This function just starts the gheneration and does not
* wait for completion.
*
* Here is an example on how @parms should be formatted; for deatils
* see the file doc/DETAILS from the GnuPG distribution.
*
* <literal>
* <![CDATA[
* <GnupgKeyParms format="internal">
* Key-Type: DSA
* Key-Length: 1024
* Subkey-Type: ELG-E
* Subkey-Length: 1024
* Name-Real: Joe Tester
* Name-Comment: with stupid passphrase
* Name-Email: joe@foo.bar
* Expire-Date: 0
* Passphrase: abc
* </GnupgKeyParms>
* ]]>
* </literal>
*
* Strings should be given in UTF-8 encoding. The format we support
* for now is only "internal". The content of the
* &lt;GnupgKeyParms&gt; container is passed verbatim to GnuPG.
* Control statements are not allowed.
*
* Return value: 0 for success or an error code
**/
GpgmeError
gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms,
GpgmeData pubkey, GpgmeData seckey)
{
return _gpgme_op_genkey_start (ctx, 0, parms, pubkey, seckey);
}
/**
* gpgme_op_genkey:
* @c: the context
* @parms: XML string with the key parameters
* @pubkey: Returns the public key
* @seckey: Returns the secret key
* @fpr: Returns the fingerprint of the key.
*
* Generate a new key and store the key in the default keyrings if both
* @pubkey and @seckey are NULL. If @pubkey and @seckey are given, the newly
* created key will be returned in these data objects.
* See gpgme_op_genkey_start() for a description of @parms.
*
* Return value: 0 for success or an error code
**/
GpgmeError
gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
GpgmeData pubkey, GpgmeData seckey,
char **fpr)
{
GpgmeError err = _gpgme_op_genkey_start (ctx, 1, parms, pubkey, seckey);
if (!err)
err = _gpgme_wait_one (ctx);
if (!err && fpr)
{
if (ctx->result.genkey->fpr)
{
*fpr = strdup (ctx->result.genkey->fpr);
if (!*fpr)
return mk_error (Out_Of_Core);
}
else
*fpr = NULL;
}
return err;
}