aboutsummaryrefslogtreecommitdiffstats
path: root/src/genkey.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2016-09-13 16:57:38 +0000
committerWerner Koch <[email protected]>2016-09-13 16:59:10 +0000
commit00c501d296da287bec2fd6a0e3912abfbde90a98 (patch)
tree496dbb635f8062aaec7978e7f64719d0e1528481 /src/genkey.c
parentpython: Handle slight differences between Python 2 and 3. (diff)
downloadgpgme-00c501d296da287bec2fd6a0e3912abfbde90a98.tar.gz
gpgme-00c501d296da287bec2fd6a0e3912abfbde90a98.zip
core: New function gpgme_op_create_key.
* src/engine-backend.h (engine_ops): Change prototype of genkey. * src/engine-gpgsm.c (gpgsm_genkey): Change accordingly. * src/engine-gpg.c (gpg_genkey): Change it to a dispatcher. (gpg_createkey_from_param): New for the old functionality. (gpg_createkey_legacy): New. Stub for now. (gpg_createkey): New. (gpg_addkey): New. Stub for now. (gpg_adduid): New. Stub for now. * src/engine.c (_gpgme_engine_op_genkey): Add new args. * src/genkey.c (op_data_t): Add field ERROR_CODE. (parse_error): New. (genkey_status_handler): Parse ERROR status line. (genkey_start): Use NULL/0 for the new args. (createkey_start): New. (gpgme_op_createkey_start, gpgme_op_createkey): New. * src/gpgme.def, src/libgpgme.vers: Add gpgme_op_createkey_start and gpgme_op_createkey. * src/gpgme.h.in (_gpgme_op_genkey_result): Add fields PUBKEY and SECKEY. (GPGME_CREATE_SIGN): New. (GPGME_CREATE_ENCR): New. (GPGME_CREATE_CERT): New. (GPGME_CREATE_AUTH): New. (GPGME_CREATE_NOPASSWD): New. (GPGME_CREATE_SELFSIGNED): New. (GPGME_CREATE_NOSTORE): New. (GPGME_CREATE_WANTPUB): New. (GPGME_CREATE_WANTSEC): New. (GPGME_CREATE_FORCE): New. * tests/run-genkey.c: New. * tests/Makefile.am (noinst_PROGRAMS): Add it. -- This function uses the new --quick-gen-key API of gpg. A limited compatibility mode to use older gpg versions and gpgsm will eventually be provided. Not all flags are currently implemented. ./run-genkey --unprotected --force [email protected] Create a new standard key with the given user id. --force is used to allow creating more than one key with that user id in the keyring. ./run-genkey --unprotected --force \ [email protected] default default 2145826800 Creates a new standard key with an expiration date of 2037-12-31. ./run-genkey --unprotected --force \ [email protected] future-default default 2145826800 Create a standard key using the fugure default algorithms. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'src/genkey.c')
-rw-r--r--src/genkey.c172
1 files changed, 150 insertions, 22 deletions
diff --git a/src/genkey.c b/src/genkey.c
index 34cc5af4..0b795f43 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -1,23 +1,22 @@
/* genkey.c - Key generation.
- Copyright (C) 2000 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004 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. */
+ * Copyright (C) 2000 Werner Koch (dd9jn)
+ * Copyright (C) 2001, 2002, 2003, 2004, 2016 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>
@@ -40,6 +39,9 @@ typedef struct
/* The error code from a FAILURE status line or 0. */
gpg_error_t failure_code;
+ /* The error code from certain ERROR status lines or 0. */
+ gpg_error_t error_code;
+
/* The key parameters passed to the crypto engine. */
gpgme_data_t key_parameter;
} *op_data_t;
@@ -82,7 +84,39 @@ gpgme_op_genkey_result (gpgme_ctx_t ctx)
return &opd->result;
}
+
+/* Parse an error status line. Return the error location and the
+ error code. The function may modify ARGS. */
+static char *
+parse_error (char *args, gpg_error_t *r_err)
+{
+ char *where = strchr (args, ' ');
+ char *which;
+
+ if (where)
+ {
+ *where = '\0';
+ which = where + 1;
+
+ where = strchr (which, ' ');
+ if (where)
+ *where = '\0';
+
+ where = args;
+ }
+ else
+ {
+ *r_err = trace_gpg_error (GPG_ERR_INV_ENGINE);
+ return NULL;
+ }
+
+ *r_err = atoi (which);
+
+ return where;
+}
+
+
static gpgme_error_t
genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
@@ -90,6 +124,7 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
gpgme_error_t err;
void *hook;
op_data_t opd;
+ char *loc;
/* Pipe the status code through the progress status handler. */
err = _gpgme_progress_status_handler (ctx, code, args);
@@ -121,13 +156,22 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
}
break;
+ case GPGME_STATUS_ERROR:
+ loc = parse_error (args, &err);
+ if (!loc)
+ return err;
+ if (!opd->error_code)
+ opd->error_code = err;
+ break;
+
case GPGME_STATUS_FAILURE:
opd->failure_code = _gpgme_parse_failure (args);
break;
case GPGME_STATUS_EOF:
- /* FIXME: Should return some more useful error value. */
- if (!opd->result.primary && !opd->result.sub)
+ if (opd->error_code)
+ return opd->error_code;
+ else if (!opd->result.primary && !opd->result.sub)
return gpg_error (GPG_ERR_GENERAL);
else if (opd->failure_code)
return opd->failure_code;
@@ -212,7 +256,9 @@ genkey_start (gpgme_ctx_t ctx, int synchronous, const char *parms,
return err;
}
- return _gpgme_engine_op_genkey (ctx->engine, opd->key_parameter,
+ return _gpgme_engine_op_genkey (ctx->engine,
+ NULL, NULL, 0, 0, NULL, 0,
+ opd->key_parameter,
ctx->use_armor, pubkey, seckey);
}
@@ -259,3 +305,85 @@ gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms, gpgme_data_t pubkey,
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
}
+
+
+
+static gpgme_error_t
+createkey_start (gpgme_ctx_t ctx, int synchronous,
+ const char *userid, const char *algo,
+ unsigned long reserved, unsigned long expires,
+ gpgme_key_t anchorkey, unsigned int flags)
+{
+ gpgme_error_t err;
+ void *hook;
+ op_data_t opd;
+
+ err = _gpgme_op_reset (ctx, synchronous);
+ if (err)
+ return err;
+
+ if (reserved || anchorkey || !userid)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,
+ sizeof (*opd), release_op_data);
+ opd = hook;
+ if (err)
+ return err;
+
+ _gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
+
+ if (ctx->passphrase_cb)
+ {
+ err = _gpgme_engine_set_command_handler
+ (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
+ if (err)
+ return err;
+ }
+
+ return _gpgme_engine_op_genkey (ctx->engine,
+ userid, algo, reserved, expires,
+ anchorkey, flags,
+ NULL, ctx->use_armor, NULL, NULL);
+
+}
+
+
+gpgme_error_t
+gpgme_op_createkey_start (gpgme_ctx_t ctx, const char *userid, const char *algo,
+ unsigned long reserved, unsigned long expires,
+ gpgme_key_t anchorkey, unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG3 (DEBUG_CTX, "gpgme_op_createkey_start", ctx,
+ "userid='%s', algo='%s' flags=0x%x", userid, algo, flags);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ err = createkey_start (ctx, 0,
+ userid, algo, reserved, expires, anchorkey, flags);
+ return TRACE_ERR (err);
+}
+
+
+gpgme_error_t
+gpgme_op_createkey (gpgme_ctx_t ctx, const char *userid, const char *algo,
+ unsigned long reserved, unsigned long expires,
+ gpgme_key_t anchorkey, unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG3 (DEBUG_CTX, "gpgme_op_createkey", ctx,
+ "userid='%s', algo='%s' flags=0x%x", userid, algo, flags);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ err = createkey_start (ctx, 1,
+ userid, algo, reserved, expires, anchorkey, flags);
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}