aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-01-05 17:36:53 +0000
committerWerner Koch <[email protected]>2010-01-05 17:36:53 +0000
commit97c5d4d312dbb6d6f70d1d8ea88ab6a03f4e2f2a (patch)
treec2152eeed6bd99594e4208c1d1e8b73cc38ecb68
parent2009-12-22 Marcus Brinkmann <[email protected]> (diff)
downloadgpgme-97c5d4d312dbb6d6f70d1d8ea88ab6a03f4e2f2a.tar.gz
gpgme-97c5d4d312dbb6d6f70d1d8ea88ab6a03f4e2f2a.zip
Add an API to change passphrases. Currently only implemented for
GPGSM. Requires GnuPG 2.1
-rw-r--r--NEWS26
-rw-r--r--README2
-rw-r--r--configure.ac5
-rw-r--r--doc/ChangeLog4
-rw-r--r--doc/gpgme.texi48
-rw-r--r--src/ChangeLog18
-rw-r--r--src/Makefile.am2
-rw-r--r--src/engine-backend.h3
-rw-r--r--src/engine-gpgsm.c43
-rw-r--r--src/engine.c18
-rw-r--r--src/engine.h6
-rw-r--r--src/gpgme-tool.c44
-rw-r--r--src/gpgme.c6
-rw-r--r--src/gpgme.def3
-rw-r--r--src/gpgme.h.in15
-rw-r--r--src/libgpgme.vers3
-rw-r--r--src/passwd.c95
17 files changed, 312 insertions, 29 deletions
diff --git a/NEWS b/NEWS
index 3fcc8dee..a2bc80ff 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Noteworthy changes in version 1.2.1 (unreleased)
+Noteworthy changes in version 1.3.0 (unreleased)
------------------------------------------------
* GPGME does not come with an internal libassuan version anymore.
@@ -10,14 +10,21 @@ Noteworthy changes in version 1.2.1 (unreleased)
* New engine GPGME_PROTOCOL_UISERVER to support UI Servers.
+ * New API to change the passpgrase of a key.
+
* Interface changes relative to the 1.2.0 release:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-GPGME_STATUS_INV_SGNR NEW
-GPGME_STATUS_NO_SGNR NEW
-GPGME_PROTOCOL_G13 NEW
-gpgme_op_g13_mount NEW
-gpgme_g13_result_t NEW
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GPGME_STATUS_INV_SGNR NEW.
+ GPGME_STATUS_NO_SGNR NEW.
+ GPGME_PROTOCOL_G13 NEW.
+ gpgme_op_g13_mount NEW.
+ gpgme_g13_result_t NEW.
+ GPGME_PK_ECDSA NEW.
+ GPGME_PK_ECDH NEW.
+ gpgme_op_passwd_start NEW.
+ gpgme_op_passwd NEW.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
Noteworthy changes in version 1.2.0 (2009-06-18)
------------------------------------------------
@@ -1321,7 +1328,8 @@ Noteworthy changes in version 0.2.1 (2001-04-02)
* Made the W32 support more robust.
- Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008 g10 Code GmbH
+ Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009,
+ 2010 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
diff --git a/README b/README
index 7594bda7..01d7d3ac 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
GPGME - GnuPG Made Easy
---------------------------
- Copyright 2004, 2006 g10 Code GmbH
+ Copyright 2004, 2006, 2010 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
diff --git a/configure.ac b/configure.ac
index 90df95f8..c1e28fd2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,7 @@
# configure.ac for GPGME
# Copyright (C) 2000 Werner Koch (dd9jn)
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 g10 Code GmbH
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+# 2009, 2010 g10 Code GmbH
#
# This file is part of GPGME.
#
@@ -31,7 +32,7 @@ min_automake_version="1.10"
# specific feature can already be done under the assumption that the
# SVN version is the most recent one in a branch. To disable the SVN
# version for the real release, set the my_issvn macro to no.
-m4_define(my_version, [1.2.1])
+m4_define(my_version, [1.3.0])
m4_define(my_issvn, [yes])
m4_define([svn_revision], m4_esyscmd([printf "%d" $( (svn info 2>/dev/null \
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 34f30bd0..d1ea9439 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,7 @@
+2010-01-05 Werner Koch <[email protected]>
+
+ * gpgme.texi (Changing Passphrases): New.
+
2009-07-21 Werner Koch <[email protected]>
* uiserver.texi (UI Server Encrypt): Add --expect-sign option to
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 8cf7c4bf..b98db55d 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -13,7 +13,8 @@
@syncodeindex pg fn
@copying
-Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007, 2008 g10 Code GmbH.
+Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007,
+2008, 2010 g10 Code GmbH.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -1014,6 +1015,18 @@ This value indicates ElGamal.
@item GPGME_PK_ELG_E
This value also indicates ElGamal and is used specifically in GnuPG.
+
+@item GPGME_PK_ELG_E
+This value also indicates ElGamal and is used specifically in GnuPG.
+
+@item GPGME_PK_ECDSA
+This value indicates ECDSA, the Elliptic Curve Digital Signature
+Algorithm as defined by FIPS 186-2.
+
+@item GPGME_PK_ECDH
+This value indicates ECDH, the Eliptic Curve Diffie-Hellmann encryption
+algorithm as defined by the ECC in OpenPGP draft.
+
@end table
@end deftp
@@ -2737,6 +2750,7 @@ in the list is the main (or primary) user ID.
* Exporting Keys:: Retrieving key data from the key ring.
* Importing Keys:: Adding keys to the key ring.
* Deleting Keys:: Removing keys from the key ring.
+* Changing Passphrases:: Change the passphrase of a key.
* Advanced Key Editing:: Advanced key edit operation.
@end menu
@@ -3715,6 +3729,38 @@ operation was started successfully, and @code{GPG_ERR_INV_VALUE} if
@end deftypefun
+@node Changing Passphrases
+@subsection Changing Passphrases
+@cindex passphrase, change
+
+@deftypefun gpgme_error_t gpgme_op_passwd @
+ (@w{gpgme_ctx_t @var{ctx}}, @
+ @w{const gpgme_key_t @var{key}}, @
+ @w{unsigned int @var{flags}})
+
+The function @code{gpgme_op_passwd} changes the passphrase of the
+private key associated with @var{key}. The only allowed value for
+@var{flags} is @code{0}. The backend engine will usually popup a window
+to ask for the old and the new passphrase. Thus this function is not
+useful in a server application (where passphrases are not required
+anyway).
+@end deftypefun
+
+@deftypefun gpgme_error_t gpgme_op_passwd_start @
+ (@w{gpgme_ctx_t @var{ctx}}, @
+ @w{const gpgme_key_t @var{key}}, @
+ @w{unsigned int @var{flags}})
+
+The function @code{gpgme_op_passwd_start} initiates a
+@code{gpgme_op_passwd} operation. It can be completed by calling
+@code{gpgme_wait} on the context. @xref{Waiting For Completion}.
+
+The function returns @code{0} if the operation was started successfully,
+and an error code if one of the arguments is not valid or the oepration
+could not be started.
+@end deftypefun
+
+
@node Advanced Key Editing
@subsection Advanced Key Editing
@cindex key, edit
diff --git a/src/ChangeLog b/src/ChangeLog
index 4a83b93c..929bbc5f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,21 @@
+2010-01-05 Werner Koch <[email protected]>
+
+ * gpgme-tool.c (gt_passwd, cmd_passwd): New.
+ (register_commands): Register.
+
+ * gpgme.h.in (gpgme_op_passwd_start, gpgme_op_passwd): New.
+ * libgpgme.vers, gpgme.def: Add new functions.
+ * passwd.c: New.
+ * Makefile.am (main_sources): Add passwd.c
+ * engine.c, engine.h (_gpgme_engine_op_passwd): New.
+ * engine-backend.h (struct engine_ops): Add PASSWD.
+ * engine-gpgsm.c (gpgsm_passwd): New.
+ (_gpgme_engine_ops_gpgsm): Register.
+ (gpgsm_reset): Reset only if we have a conenction.
+
+ * gpgme.h.in (GPGME_PK_ECDSA, GPGME_PK_ECDH): New.
+ * gpgme.c (gpgme_pubkey_algo_name): Add them.
+
2009-12-22 Marcus Brinkmann <[email protected]>
* debug.c: Test for TLS, not __GNUC__
diff --git a/src/Makefile.am b/src/Makefile.am
index 41ab762e..1ecb7610 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -115,7 +115,7 @@ main_sources = \
sign.c passphrase.c progress.c \
key.c keylist.c trust-item.c trustlist.c \
import.c export.c genkey.c delete.c edit.c getauditlog.c \
- opassuan.c \
+ opassuan.c passwd.c \
engine.h engine-backend.h engine.c engine-gpg.c status-table.h \
$(gpgsm_components) $(assuan_components) $(gpgconf_components) \
$(uiserver_components) \
diff --git a/src/engine-backend.h b/src/engine-backend.h
index fa0b4392..e540acb9 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -118,6 +118,9 @@ struct engine_ops
/* Cancel only the current operation, not the whole session. */
gpgme_error_t (*cancel_op) (void *engine);
+
+ /* Change the passphrase for KEY. */
+ gpgme_error_t (*passwd) (void *engine, gpgme_key_t key, unsigned int flags);
};
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 32294b0b..2dda7339 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -1,6 +1,7 @@
/* engine-gpgsm.c - GpgSM engine.
Copyright (C) 2000 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 g10 Code GmbH
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009,
+ 2010 g10 Code GmbH
This file is part of GPGME.
@@ -1053,13 +1054,18 @@ gpgsm_reset (void *engine)
{
engine_gpgsm_t gpgsm = engine;
- /* We must send a reset because we need to reset the list of
- signers. Note that RESET does not reset OPTION commands. */
- return gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET", NULL, NULL);
+ /* IF we have an active connection we must send a reset because we
+ need to reset the list of signers. Note that RESET does not
+ reset OPTION commands. */
+ return (gpgsm->assuan_ctx
+ ? gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET",
+ NULL, NULL)
+ : 0);
}
#endif
+
static gpgme_error_t
gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
{
@@ -1894,6 +1900,32 @@ gpgsm_io_event (void *engine, gpgme_event_io_t type, void *type_data)
}
+static gpgme_error_t
+gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags)
+{
+ engine_gpgsm_t gpgsm = engine;
+ gpgme_error_t err;
+ char *line;
+
+ if (!key || !key->subkeys || !key->subkeys->fpr)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ if (asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0)
+ return gpg_error_from_syserror ();
+
+ gpgsm_clear_fd (gpgsm, OUTPUT_FD);
+ gpgsm_clear_fd (gpgsm, INPUT_FD);
+ gpgsm_clear_fd (gpgsm, MESSAGE_FD);
+ gpgsm->inline_data = NULL;
+
+ err = start (gpgsm, line);
+ free (line);
+
+ return err;
+}
+
+
+
struct engine_ops _gpgme_engine_ops_gpgsm =
{
/* Static functions. */
@@ -1937,5 +1969,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_set_io_cbs,
gpgsm_io_event,
gpgsm_cancel,
- NULL /* cancel_op */
+ NULL, /* cancel_op */
+ gpgsm_passwd
};
diff --git a/src/engine.c b/src/engine.c
index ecf23047..71f0c9c6 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1,6 +1,6 @@
/* engine.c - GPGME engine support.
Copyright (C) 2000 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009 g10 Code GmbH
+ Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009, 2010 g10 Code GmbH
This file is part of GPGME.
@@ -906,3 +906,19 @@ _gpgme_engine_cancel_op (engine_t engine)
return (*engine->ops->cancel_op) (engine->engine);
}
+
+
+/* Change the passphrase for KEY. */
+gpgme_error_t
+_gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
+ unsigned int flags)
+{
+ if (!engine)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ if (!engine->ops->passwd)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+ return (*engine->ops->passwd) (engine->engine, key, flags);
+}
+
diff --git a/src/engine.h b/src/engine.h
index d9119391..dfc73acc 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -1,6 +1,6 @@
/* engine.h - GPGME engine interface.
Copyright (C) 2000 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
+ Copyright (C) 2001, 2002, 2003, 2004, 2010 g10 Code GmbH
This file is part of GPGME.
@@ -157,4 +157,8 @@ 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);
+
+
#endif /* ENGINE_H */
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
index 0af65c32..ad647fc9 100644
--- a/src/gpgme-tool.c
+++ b/src/gpgme-tool.c
@@ -1,6 +1,5 @@
/* gpgme-tool.c - GnuPG Made Easy.
- Copyright (C) 2000 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH
+ Copyright (C) 2009, 2010 g10 Code GmbH
This file is part of GPGME.
@@ -15,9 +14,8 @@
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. */
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
#if HAVE_CONFIG_H
#include <config.h>
@@ -1119,7 +1117,30 @@ gt_vfs_create (gpgme_tool_t gt, const char *container_file, int flags)
}
-// TODO
+static const char hlp_passwd[] =
+ "PASSWD <user-id>\n"
+ "\n"
+ "Ask the backend to change the passphrase for the key\n"
+ "specified by USER-ID.";
+gpg_error_t
+gt_passwd (gpgme_tool_t gt, char *fpr)
+{
+ gpg_error_t err;
+ gpgme_key_t key;
+
+ err = gpgme_get_key (gt->ctx, fpr, &key, 0);
+ if (err)
+ return err;
+
+ err = gpgme_op_passwd (gt->ctx, key, 0);
+ gpgme_key_unref (key);
+ return err;
+}
+
+
+
+
+/* TODO */
#define GT_RESULT_ENCRYPT 0x1
#define GT_RESULT_DECRYPT 0x2
#define GT_RESULT_SIGN 0x4
@@ -1975,6 +1996,16 @@ cmd_vfs_create (assuan_context_t ctx, char *line)
static gpg_error_t
+cmd_passwd (assuan_context_t ctx, char *line)
+{
+ struct server *server = assuan_get_pointer (ctx);
+
+ return gt_passwd (server->gt, line);
+}
+
+
+
+static gpg_error_t
cmd_result (assuan_context_t ctx, char *line)
{
struct server *server = assuan_get_pointer (ctx);
@@ -2076,6 +2107,7 @@ register_commands (assuan_context_t ctx)
{ "STRERROR", cmd_strerror },
{ "PUBKEY_ALGO_NAME", cmd_pubkey_algo_name },
{ "HASH_ALGO_NAME", cmd_hash_algo_name },
+ { "PASSWD", cmd_passwd, hlp_passwd },
{ NULL }
};
int idx;
diff --git a/src/gpgme.c b/src/gpgme.c
index 2d709e40..fe601a09 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -792,6 +792,12 @@ gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
case GPGME_PK_ELG:
return "ELG";
+ case GPGME_PK_ECDSA:
+ return "ECDSA";
+
+ case GPGME_PK_ECDH:
+ return "ECDH";
+
default:
return NULL;
}
diff --git a/src/gpgme.def b/src/gpgme.def
index eee25311..1a685ffe 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -196,5 +196,8 @@ EXPORTS
gpgme_set_sub_protocol @150
gpgme_get_sub_protocol @151
+ gpgme_op_passwd_start @152
+ gpgme_op_passwd @153
+
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 13a33992..68ebd1a4 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1,6 +1,7 @@
/* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*-
Copyright (C) 2000 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 g10 Code GmbH
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009
+ 2010 g10 Code GmbH
This file is part of GPGME.
@@ -209,7 +210,9 @@ typedef enum
GPGME_PK_RSA_S = 3,
GPGME_PK_ELG_E = 16,
GPGME_PK_DSA = 17,
- GPGME_PK_ELG = 20
+ GPGME_PK_ELG = 20,
+ GPGME_PK_ECDSA = 301,
+ GPGME_PK_ECDH = 302
}
gpgme_pubkey_algo_t;
@@ -1664,6 +1667,14 @@ gpgme_error_t gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key);
/* Terminate a pending keylist operation within CTX. */
gpgme_error_t gpgme_op_keylist_end (gpgme_ctx_t ctx);
+/* Change the passphrase for KEY. FLAGS is reserved for future use
+ and must be passed as 0. */
+gpgme_error_t gpgme_op_passwd_start (gpgme_ctx_t ctx, gpgme_key_t key,
+ unsigned int flags);
+gpgme_error_t gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key,
+ unsigned int flags);
+
+
/* Trust items and operations. */
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index a9ddfb3c..9d927cef 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -76,6 +76,9 @@ GPGME_1.1 {
gpgme_key_from_uid;
gpgme_set_sub_protocol;
gpgme_get_sub_protocol;
+
+ gpgme_op_passwd_start;
+ gpgme_op_passwd;
};
diff --git a/src/passwd.c b/src/passwd.c
new file mode 100644
index 00000000..d189814d
--- /dev/null
+++ b/src/passwd.c
@@ -0,0 +1,95 @@
+/* passwd.c - Passphrase changing function
+ Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gpgme.h"
+#include "debug.h"
+#include "context.h"
+#include "ops.h"
+
+
+static gpgme_error_t
+passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
+{
+ (void)priv;
+ (void)code;
+ (void)args;
+ return 0;
+}
+
+
+static gpgme_error_t
+passwd_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
+ unsigned int flags)
+{
+ gpgme_error_t err;
+
+ if (!key)
+ return gpg_error (GPG_ERR_INV_VALUE);
+ if (flags)
+ return gpg_error (GPG_ERR_INV_FLAG);
+
+ err = _gpgme_op_reset (ctx, synchronous);
+ if (err)
+ return err;
+
+ _gpgme_engine_set_status_handler (ctx->engine, passwd_status_handler, ctx);
+
+ return _gpgme_engine_op_passwd (ctx->engine, key, flags);
+}
+
+
+
+/* Change the passphrase for KEY. FLAGS is reserved for future use
+ and must be passed as 0. The engine is expected to present a user
+ interface to enter the old and the new passphrase. This is the
+ asynchronous variant.
+
+ Note that if ever the need arises to supply a passphrase we can do
+ this with a flag value and the passphrase callback feature. */
+gpgme_error_t
+gpgme_op_passwd_start (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags)
+{
+ gpg_error_t err;
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_passwd_start", ctx,
+ "key=%p, flags=0x%x", key, flags);
+ err = passwd_start (ctx, 0, key, flags);
+ return TRACE_ERR (err);
+}
+
+
+/* Change the passphrase for KEY. FLAGS is reserved for future use
+ and must be passed as 0. This is the synchronous variant. */
+gpgme_error_t
+gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_passwd", ctx,
+ "key=%p, flags=0x%x", key, flags);
+
+ err = passwd_start (ctx, 1, key, flags);
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
+