diff options
Diffstat (limited to 'src/genkey.c')
| -rw-r--r-- | src/genkey.c | 172 | 
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); +}  | 
