diff options
| -rw-r--r-- | NEWS | 2 | ||||
| -rw-r--r-- | src/engine-gpg.c | 24 | ||||
| -rw-r--r-- | src/genkey.c | 110 | ||||
| -rw-r--r-- | src/gpgme.def | 2 | ||||
| -rw-r--r-- | src/gpgme.h.in | 13 | ||||
| -rw-r--r-- | src/libgpgme.vers | 2 | ||||
| -rw-r--r-- | tests/run-genkey.c | 72 | 
7 files changed, 192 insertions, 33 deletions
| @@ -19,6 +19,8 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]   gpgme_op_createkey_start       NEW.   gpgme_op_createsubkey          NEW.   gpgme_op_createsubkey_start    NEW. + gpgme_op_adduid_start          NEW. + gpgme_op_adduid                NEW.   gpgme_genkey_result_t          EXTENDED: New fields pubkey and seckey.   gpgme_signature_t              EXTENDED: New field key.   gpgme_key_t                    EXTENDED: New field fpr. diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 5a16f805..d2b6dd34 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2114,11 +2114,25 @@ gpg_addkey (engine_gpg_t gpg,  static gpgme_error_t  gpg_adduid (engine_gpg_t gpg, -            const char *userid, -            unsigned int flags, -            int use_armor) +            gpgme_key_t key, +            const char *userid)  { -  return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +  gpgme_error_t err; + +  if (!key || !key->fpr || !userid) +    return gpg_error (GPG_ERR_INV_ARG); + +  err = add_arg (gpg, "--quick-adduid"); +  if (!err) +    err = add_arg (gpg, "--"); +  if (!err) +    err = add_arg (gpg, key->fpr); +  if (!err) +    err = add_arg (gpg, userid); + +  if (!err) +    err = start (gpg); +  return err;  } @@ -2170,7 +2184,7 @@ gpg_genkey (void *engine,    else if (!userid && key)      err = gpg_addkey (gpg, algo, expires, key, flags, use_armor);    else if (userid && key && !algo) -    err = gpg_adduid (gpg, userid, flags, use_armor); +    err = gpg_adduid (gpg, key, userid);    else      err = gpg_error (GPG_ERR_INV_VALUE); diff --git a/src/genkey.c b/src/genkey.c index 26bcca6e..b93abb80 100644 --- a/src/genkey.c +++ b/src/genkey.c @@ -42,6 +42,9 @@ typedef struct    /* The error code from certain ERROR status lines or 0.  */    gpg_error_t error_code; +  /* Flag to indicate that a UID is to be added.  */ +  gpg_error_t uidmode; +    /* The key parameters passed to the crypto engine.  */    gpgme_data_t key_parameter;  } *op_data_t; @@ -142,7 +145,10 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)        if (args && *args)  	{  	  if (*args == 'B' || *args == 'P') -	    opd->result.primary = 1; +            { +              opd->result.primary = 1; +              opd->result.uid = 1; +            }  	  if (*args == 'B' || *args == 'S')  	    opd->result.sub = 1;  	  if (args[1] == ' ') @@ -171,10 +177,12 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)      case GPGME_STATUS_EOF:        if (opd->error_code)          return opd->error_code; -      else if (!opd->result.primary && !opd->result.sub) +      else if (!opd->uidmode && !opd->result.primary && !opd->result.sub)  	return gpg_error (GPG_ERR_GENERAL);        else if (opd->failure_code)          return opd->failure_code; +      else if (opd->uidmode) +        opd->result.uid = 1;  /* We have no status line, thus this hack.  */        break;      case GPGME_STATUS_INQUIRE_MAXLEN: @@ -277,7 +285,7 @@ gpgme_op_genkey_start (gpgme_ctx_t ctx, const char *parms,    TRACE_LOGBUF (parms, strlen (parms));    if (!ctx) -    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));    err = genkey_start (ctx, 0, parms, pubkey, seckey);    return TRACE_ERR (err); @@ -298,7 +306,7 @@ gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms, gpgme_data_t pubkey,    TRACE_LOGBUF (parms, strlen (parms));    if (!ctx) -    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));    err = genkey_start (ctx, 1, parms, pubkey, seckey);    if (!err) @@ -323,7 +331,7 @@ createkey_start (gpgme_ctx_t ctx, int synchronous,      return err;    if (reserved || anchorkey || !userid) -    return gpg_error (GPG_ERR_INV_VALUE); +    return gpg_error (GPG_ERR_INV_ARG);    err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,  			       sizeof (*opd), release_op_data); @@ -360,7 +368,7 @@ gpgme_op_createkey_start (gpgme_ctx_t ctx, const char *userid, const char *algo,  	      "userid='%s', algo='%s' flags=0x%x", userid, algo, flags);    if (!ctx) -    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));    err = createkey_start (ctx, 0,                           userid, algo, reserved, expires, anchorkey, flags); @@ -379,7 +387,7 @@ gpgme_op_createkey (gpgme_ctx_t ctx, const char *userid, const char *algo,  	      "userid='%s', algo='%s' flags=0x%x", userid, algo, flags);    if (!ctx) -    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));    err = createkey_start (ctx, 1,                           userid, algo, reserved, expires, anchorkey, flags); @@ -409,7 +417,7 @@ createsubkey_start (gpgme_ctx_t ctx, int synchronous,      return err;    if (reserved || !key) -    return gpg_error (GPG_ERR_INV_VALUE); +    return gpg_error (GPG_ERR_INV_ARG);    err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,  			       sizeof (*opd), release_op_data); @@ -447,7 +455,7 @@ gpgme_op_createsubkey_start (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,  	      "key=%p, algo='%s' flags=0x%x", key, algo, flags);    if (!ctx) -    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));    err = createsubkey_start (ctx, 0, key, algo, reserved, expires, flags);    return TRACE_ERR (err); @@ -465,10 +473,92 @@ gpgme_op_createsubkey (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,  	      "key=%p, algo='%s' flags=0x%x", key, algo, flags);    if (!ctx) -    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));    err = createsubkey_start (ctx, 1, key, algo, reserved, expires, flags);    if (!err)      err = _gpgme_wait_one (ctx);    return TRACE_ERR (err);  } + + + +static gpgme_error_t +adduid_start (gpgme_ctx_t ctx, int synchronous, +              gpgme_key_t key, const char *userid, unsigned int flags) +{ +  gpgme_error_t err; +  void *hook; +  op_data_t opd; + +  if (ctx->protocol != GPGME_PROTOCOL_OPENPGP) +    return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL); + +  if (!key || !userid) +    return gpg_error (GPG_ERR_INV_ARG); + +  err = _gpgme_op_reset (ctx, synchronous); +  if (err) +    return err; + +  err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook, +			       sizeof (*opd), release_op_data); +  opd = hook; +  if (err) +    return err; + +  opd->uidmode = 1; + +  _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, NULL, 0, 0, +                                  key, flags, +                                  NULL, ctx->use_armor, NULL, NULL); + +} + + +/* Add USERID to an existing KEY.  */ +gpgme_error_t +gpgme_op_adduid_start (gpgme_ctx_t ctx, +                       gpgme_key_t key, const char *userid, unsigned int flags) +{ +  gpgme_error_t err; + +  TRACE_BEG2 (DEBUG_CTX, "gpgme_op_adduid_start", ctx, +	      "uid='%s' flags=0x%x", userid, flags); + +  if (!ctx) +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG)); + +  err = adduid_start (ctx, 0, key, userid, flags); +  return TRACE_ERR (err); +} + + +gpgme_error_t +gpgme_op_adduid (gpgme_ctx_t ctx, +                 gpgme_key_t key, const char *userid, unsigned int flags) +{ +  gpgme_error_t err; + +  TRACE_BEG2 (DEBUG_CTX, "gpgme_op_adduid", ctx, +	      "uid='%s' flags=0x%x", userid, flags); + +  if (!ctx) +    return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG)); + +  err = adduid_start (ctx, 1, key, userid, flags); +  if (!err) +    err = _gpgme_wait_one (ctx); +  return TRACE_ERR (err); +} diff --git a/src/gpgme.def b/src/gpgme.def index 7b7b1f20..54b04e04 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -233,6 +233,8 @@ EXPORTS      gpgme_op_createkey                    @173      gpgme_op_createsubkey_start           @174      gpgme_op_createsubkey                 @175 +    gpgme_op_adduid_start                 @176 +    gpgme_op_adduid                       @177  ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 0fdc9276..ec436c80 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1835,8 +1835,11 @@ struct _gpgme_op_genkey_result    /* A sub key was generated.  */    unsigned int sub : 1; +  /* A user id was generated.  */ +  unsigned int uid : 1; +    /* Internal to GPGME, do not use.  */ -  unsigned int _unused : 30; +  unsigned int _unused : 29;    /* The fingerprint of the generated key.  */    char *fpr; @@ -1888,6 +1891,14 @@ gpgme_error_t gpgme_op_createsubkey       (gpgme_ctx_t ctx,                                             unsigned long expires,                                             unsigned int flags); +/* Add USERID to an existing KEY.  */ +gpgme_error_t gpgme_op_adduid_start (gpgme_ctx_t ctx, +                                     gpgme_key_t key, const char *userid, +                                     unsigned int flags); +gpgme_error_t gpgme_op_adduid       (gpgme_ctx_t ctx, +                                     gpgme_key_t key, const char *userid, +                                     unsigned int flags); +  /* Retrieve a pointer to the result of a genkey, createkey, or diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 2a3e9fc3..0cef9e0b 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -107,6 +107,8 @@ GPGME_1.1 {      gpgme_op_createkey;      gpgme_op_createsubkey_start;      gpgme_op_createsubkey; +    gpgme_op_adduid_start; +    gpgme_op_adduid;  }; diff --git a/tests/run-genkey.c b/tests/run-genkey.c index 3b645025..959e2ea1 100644 --- a/tests/run-genkey.c +++ b/tests/run-genkey.c @@ -199,9 +199,13 @@ parse_usage_string (const char *string)  static int  show_usage (int ex)  { -  fputs ("usage: " PGM " [options] USERID [ALGO [USAGE [EXPIRESECONDS]]]\n\n" +  fputs ("usage: " PGM " [options] ARGS\n" +         "         args: USERID [ALGO [USAGE [EXPIRESECONDS]]]\n" +         "   for addkey: FPR    [ALGO [USAGE [EXPIRESECONDS]]]\n" +         "   for adduid: FPR    USERID\n"           "Options:\n" -         "  --addkey         add a subkey to the key with USERID\n" +         "  --addkey         add a subkey to the key with FPR\n" +         "  --adduid         add a user id to the key with FPR\n"           "  --verbose        run in verbose mode\n"           "  --status         print status lines from the backend\n"           "  --progress       print progress info\n" @@ -226,8 +230,10 @@ main (int argc, char **argv)    int print_progress = 0;    int use_loopback = 0;    int addkey = 0; +  int adduid = 0;    const char *userid;    const char *algo = NULL; +  const char *newuserid = NULL;    unsigned int flags = 0;    unsigned long expire = 0;    gpgme_genkey_result_t result; @@ -248,6 +254,13 @@ main (int argc, char **argv)        else if (!strcmp (*argv, "--addkey"))          {            addkey = 1; +          adduid = 0; +          argc--; argv++; +        } +      else if (!strcmp (*argv, "--adduid")) +        { +          addkey = 0; +          adduid = 1;            argc--; argv++;          }        else if (!strcmp (*argv, "--verbose")) @@ -294,15 +307,25 @@ main (int argc, char **argv)          show_usage (1);      } -  if (!argc || argc > 4) -    show_usage (1); -  userid = argv[0]; -  if (argc > 1) -    algo = argv[1]; -  if (argc > 2) -    flags |= parse_usage_string (argv[2]); -  if (argc > 3) -    expire = parse_expire_string (argv[3]); +  if (adduid) +    { +      if (argc != 2) +        show_usage (1); +      userid = argv[0]; +      newuserid = argv[1]; +    } +  else +    { +      if (!argc || argc > 4) +        show_usage (1); +      userid = argv[0]; +      if (argc > 1) +        algo = argv[1]; +      if (argc > 2) +        flags |= parse_usage_string (argv[2]); +      if (argc > 3) +        expire = parse_expire_string (argv[3]); +    }    init_gpgme (protocol); @@ -323,7 +346,7 @@ main (int argc, char **argv)        gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);      } -  if (addkey) +  if (addkey || adduid)      {        gpgme_key_t akey; @@ -335,12 +358,25 @@ main (int argc, char **argv)            exit (1);          } -      err = gpgme_op_createsubkey (ctx, akey, algo, 0, expire, flags); -      if (err) +      if (addkey)          { -          fprintf (stderr, PGM ": gpgme_op_createsubkey failed: %s\n", -                   gpg_strerror (err)); -          exit (1); +          err = gpgme_op_createsubkey (ctx, akey, algo, 0, expire, flags); +          if (err) +            { +              fprintf (stderr, PGM ": gpgme_op_createsubkey failed: %s\n", +                       gpg_strerror (err)); +              exit (1); +            } +        } +      else if (adduid) +        { +          err = gpgme_op_adduid (ctx, akey, newuserid, flags); +          if (err) +            { +              fprintf (stderr, PGM ": gpgme_op_adduid failed: %s\n", +                       gpg_strerror (err)); +              exit (1); +            }          }        gpgme_key_unref (akey);      } @@ -373,6 +409,8 @@ main (int argc, char **argv)      fprintf (stderr, PGM": primary key was not generated\n");    if (!result->sub)      fprintf (stderr, PGM": sub key was not generated\n"); +  if (!result->uid) +    fprintf (stderr, PGM": uid was not generated\n");    gpgme_release (ctx);    return 0; | 
