1 /* passwd.c - Passphrase changing function
2 Copyright (C) 2010 g10 Code GmbH
4 This file is part of GPGME.
6 GPGME is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of
9 the License, or (at your option) any later version.
11 GPGME is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this program; if not, see <http://www.gnu.org/licenses/>.
39 /* Parse an error status line and return the error code. */
41 parse_error (char *args)
44 char *where = strchr (args, ' ');
52 where = strchr (which, ' ');
59 return gpg_error (GPG_ERR_INV_ENGINE);
63 if (!strcmp (where, "keyedit.passwd"))
71 passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
73 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
78 err = _gpgme_op_data_lookup (ctx, OPDATA_PASSWD, &hook, -1, NULL);
85 case GPGME_STATUS_ERROR:
86 err = parse_error (args);
91 case GPGME_STATUS_SUCCESS:
92 opd->success_seen = 1;
95 case GPGME_STATUS_EOF:
96 /* In case the OpenPGP engine does not properly implement the
97 passwd command we won't get a success status back and thus we
98 conclude that this operation is not supported. This is for
99 example the case for GnuPG < 2.0.16. Note that this test is
100 obsolete for assuan based engines because they will properly
101 return an error for an unknown command. */
102 if (ctx->protocol == GPGME_PROTOCOL_OpenPGP
103 && !opd->error_seen && !opd->success_seen)
104 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
116 passwd_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
124 return gpg_error (GPG_ERR_INV_VALUE);
126 return gpg_error (GPG_ERR_INV_FLAG);
128 err = _gpgme_op_reset (ctx, synchronous);
132 err = _gpgme_op_data_lookup (ctx, OPDATA_PASSWD, &hook, sizeof (*opd), NULL);
137 opd->success_seen = 0;
140 _gpgme_engine_set_status_handler (ctx->engine, passwd_status_handler, ctx);
142 return _gpgme_engine_op_passwd (ctx->engine, key, flags);
147 /* Change the passphrase for KEY. FLAGS is reserved for future use
148 and must be passed as 0. The engine is expected to present a user
149 interface to enter the old and the new passphrase. This is the
150 asynchronous variant.
152 Note that if ever the need arises to supply a passphrase we can do
153 this with a flag value and the passphrase callback feature. */
155 gpgme_op_passwd_start (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags)
158 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_passwd_start", ctx,
159 "key=%p, flags=0x%x", key, flags);
162 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
164 err = passwd_start (ctx, 0, key, flags);
165 return TRACE_ERR (err);
169 /* Change the passphrase for KEY. FLAGS is reserved for future use
170 and must be passed as 0. This is the synchronous variant. */
172 gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags)
176 TRACE_BEG2 (DEBUG_CTX, "gpgme_op_passwd", ctx,
177 "key=%p, flags=0x%x", key, flags);
180 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
182 err = passwd_start (ctx, 1, key, flags);
184 err = _gpgme_wait_one (ctx);
185 return TRACE_ERR (err);