diff options
-rw-r--r-- | doc/gpgme.texi | 9 | ||||
-rw-r--r-- | lang/cpp/src/context.cpp | 10 | ||||
-rw-r--r-- | lang/cpp/src/context.h | 3 | ||||
-rw-r--r-- | lang/qt/src/qgpgmequickjob.cpp | 11 | ||||
-rw-r--r-- | lang/qt/src/qgpgmequickjob.h | 1 | ||||
-rw-r--r-- | lang/qt/src/quickjob.h | 3 | ||||
-rw-r--r-- | src/engine-gpg.c | 33 | ||||
-rw-r--r-- | src/genkey.c | 8 | ||||
-rw-r--r-- | src/gpgme.h.in | 1 | ||||
-rw-r--r-- | tests/run-genkey.c | 41 |
10 files changed, 116 insertions, 4 deletions
diff --git a/doc/gpgme.texi b/doc/gpgme.texi index aaa2ab3f..48cca032 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -4390,6 +4390,11 @@ override this check. Request generation of keys that do not expire. +@item GPGME_CREATE_ADSK +@since{1.24.0} + +Add an ADSK to the key. + @end table After the operation completed successfully, information about the @@ -4465,6 +4470,10 @@ values for timestamps and thus can only encode dates up to the year @var{flags} takes the same values as described above for @code{gpgme_op_createkey}. +If the @code{GPGME_CREATE_ADSK} flag is set, the subkey fingerprint +given in the @code{algo} parameter is added as an ADSK +to the key. + After the operation completed successfully, information about the created key can be retrieved with @code{gpgme_op_genkey_result}. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 7d04e9cc..57f92394 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1799,6 +1799,16 @@ Error Context::startRevokeSignature(const Key &key, const Key &signingKey, key.impl(), signingKey.impl(), uids.c_str(), flags)); } +Error Context::addAdsk(const Key &k, const char *adsk) +{ + return Error(d->lasterr = gpgme_op_createsubkey(d->ctx, k.impl(), adsk, 0, 0, GPGME_CREATE_ADSK)); +} + +Error Context::startAddAdsk(const Key &k, const char *adsk) +{ + return Error(d->lasterr = gpgme_op_createsubkey_start(d->ctx, k.impl(), adsk, 0, 0, GPGME_CREATE_ADSK)); +} + Error Context::setFlag(const char *name, const char *value) { return Error(d->lasterr = gpgme_set_ctx_flag(d->ctx, name, value)); diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index 4d7fedf0..c4f968f4 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -324,6 +324,9 @@ public: Error startRevokeSignature(const Key &key, const Key &signingKey, const std::vector<UserID> &userIds = std::vector<UserID>()); + Error addAdsk(const Key &k, const char *adsk); + Error startAddAdsk(const Key &k, const char *adsk); + // using TofuInfo::Policy Error setTofuPolicy(const Key &k, unsigned int policy); Error setTofuPolicyStart(const Key &k, unsigned int policy); diff --git a/lang/qt/src/qgpgmequickjob.cpp b/lang/qt/src/qgpgmequickjob.cpp index 33f1178a..1c6023a4 100644 --- a/lang/qt/src/qgpgmequickjob.cpp +++ b/lang/qt/src/qgpgmequickjob.cpp @@ -109,6 +109,12 @@ static QGpgMEQuickJob::result_type revokeSignatureWorker(Context *ctx, return std::make_tuple(err, QString(), Error()); } +static QGpgMEQuickJob::result_type addAdskWorker(Context *ctx, const Key &key, const char *adsk) +{ + const auto err = ctx->addAdsk(key, adsk); + return std::make_tuple(err, QString(), Error()); +} + void QGpgMEQuickJob::startCreate(const QString &uid, const char *algo, const QDateTime &expires, @@ -142,4 +148,9 @@ void QGpgMEQuickJob::startRevokeSignature(const Key &key, const Key &signingKey, run(std::bind(&revokeSignatureWorker, std::placeholders::_1, key, signingKey, userIds)); } +void QGpgMEQuickJob::startAddAdsk(const GpgME::Key &key, const char *adsk) +{ + run(std::bind(&addAdskWorker, std::placeholders::_1, key, adsk)); +} + #include "qgpgmequickjob.moc" diff --git a/lang/qt/src/qgpgmequickjob.h b/lang/qt/src/qgpgmequickjob.h index 2f59d8d4..07b89e18 100644 --- a/lang/qt/src/qgpgmequickjob.h +++ b/lang/qt/src/qgpgmequickjob.h @@ -71,6 +71,7 @@ public: unsigned int flags = 0) override; void startRevokeSignature(const GpgME::Key &key, const GpgME::Key &signingKey, const std::vector<GpgME::UserID> &userIds = std::vector<GpgME::UserID>()) override; + void startAddAdsk(const GpgME::Key &key, const char *adsk) override; }; } diff --git a/lang/qt/src/quickjob.h b/lang/qt/src/quickjob.h index 612a53d0..2d159bbe 100644 --- a/lang/qt/src/quickjob.h +++ b/lang/qt/src/quickjob.h @@ -85,6 +85,9 @@ public: virtual void startRevokeSignature(const GpgME::Key &key, const GpgME::Key &signingKey, const std::vector<GpgME::UserID> &userIds = std::vector<GpgME::UserID>()) = 0; + /** Start --quick-add-adsk */ + virtual void startAddAdsk(const GpgME::Key &key, const char *adsk) = 0; + Q_SIGNALS: void result(const GpgME::Error &error, const QString &auditLogAsHtml = QString(), const GpgME::Error &auditLogError = GpgME::Error()); diff --git a/src/engine-gpg.c b/src/engine-gpg.c index d5b2ab71..e212f1f8 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2856,6 +2856,33 @@ gpg_adduid (engine_gpg_t gpg, static gpgme_error_t +gpg_addadsk (engine_gpg_t gpg, gpgme_key_t key, const char *adskfpr) +{ + gpgme_error_t err; + + if (!key || !key->fpr) + return gpg_error (GPG_ERR_INV_ARG); + + if (!adskfpr || !*adskfpr) + return gpg_error (GPG_ERR_INV_ARG); + + if (!have_gpg_version (gpg, "2.4.1")) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + err = add_arg (gpg, "--quick-add-adsk"); + if (!err) + err = add_arg (gpg, "--"); + if (!err) + err = add_arg (gpg, key->fpr); + if (!err) + err = add_arg (gpg, adskfpr); + if (!err) + err = start (gpg); + return err; +} + + +static gpgme_error_t gpg_genkey (void *engine, const char *userid, const char *algo, unsigned long reserved, unsigned long expires, @@ -2878,6 +2905,8 @@ gpg_genkey (void *engine, * !USERID && KEY - Add a new subkey to KEY (gpg >= 2.1.14) * USERID && KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14). * or set a flag on a user id. + * !USERID && KEY && ALGO + * && GPGME_CREATE_ADSK - Add ALGO as an ADSK to KEY. */ if (help_data) { @@ -2894,10 +2923,12 @@ gpg_genkey (void *engine, err = gpg_error (GPG_ERR_NOT_SUPPORTED); else if (userid && !key) err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags); - else if (!userid && key) + else if (!userid && key && !(flags & GPGME_CREATE_ADSK)) err = gpg_addkey (gpg, algo, expires, key, flags, extraflags); else if (userid && key && !algo) err = gpg_adduid (gpg, key, userid, extraflags); + else if (!userid && key && algo && (flags & GPGME_CREATE_ADSK)) + err = gpg_addadsk (gpg, key, algo); else err = gpg_error (GPG_ERR_INV_VALUE); diff --git a/src/genkey.c b/src/genkey.c index 89e1d985..11ca5cbe 100644 --- a/src/genkey.c +++ b/src/genkey.c @@ -48,6 +48,9 @@ typedef struct /* The key parameters passed to the crypto engine. */ gpgme_data_t key_parameter; + + /* Flag to indicate that an ADSK is to be added. */ + unsigned int adskmode : 1; } *op_data_t; @@ -180,7 +183,7 @@ 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->uidmode && !opd->result.primary && !opd->result.sub) + else if (!opd->uidmode && !opd->adskmode && !opd->result.primary && !opd->result.sub) return gpg_error (GPG_ERR_GENERAL); else if (opd->failure_code) return opd->failure_code; @@ -445,6 +448,9 @@ createsubkey_start (gpgme_ctx_t ctx, int synchronous, return err; } + if (flags & GPGME_CREATE_ADSK) + opd->adskmode = 1; + return _gpgme_engine_op_genkey (ctx->engine, NULL, algo, reserved, expires, key, flags, diff --git a/src/gpgme.h.in b/src/gpgme.h.in index eaeb22aa..0ee3e088 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1866,6 +1866,7 @@ gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx, #define GPGME_CREATE_WANTSEC (1 << 11) /* Return the secret key. */ #define GPGME_CREATE_FORCE (1 << 12) /* Force creation. */ #define GPGME_CREATE_NOEXPIRE (1 << 13) /* Create w/o expiration. */ +#define GPGME_CREATE_ADSK (1 << 14) /* Add an ADSK */ /* An object to return result from a key generation. diff --git a/tests/run-genkey.c b/tests/run-genkey.c index 8572db26..56404dd3 100644 --- a/tests/run-genkey.c +++ b/tests/run-genkey.c @@ -215,6 +215,7 @@ show_usage (int ex) " for revuid: FPR USERID\n" " for setexpire: FPR EXPIRE [SUBFPRS]\n" " for set-primary: FPR USERID\n" + " for addadsk: FPR ADSKFPR\n" "Options:\n" " --addkey add a subkey to the key with FPR\n" " --adduid add a user id to the key with FPR\n" @@ -222,6 +223,7 @@ show_usage (int ex) " --set-primary set the primary key flag on USERID\n" " --setexpire set the expiration time of the key FPR\n" " or of its subkeys SUBFPRS\n" + " --addadsk add the subkey with ADSKFPR to the key FPR\n" " --verbose run in verbose mode\n" " --status print status lines from the backend\n" " --progress print progress info\n" @@ -250,6 +252,7 @@ main (int argc, char **argv) int revuid = 0; int setpri = 0; int setexpire = 0; + int addadsk = 0; const char *userid; const char *algo = NULL; const char *newuserid = NULL; @@ -260,6 +263,7 @@ main (int argc, char **argv) int i; size_t n; char *subfprs_buffer = NULL; + char *adskfpr = NULL; if (argc) { argc--; argv++; } @@ -281,6 +285,7 @@ main (int argc, char **argv) revuid = 0; setpri = 0; setexpire = 0; + addadsk = 0; argc--; argv++; } else if (!strcmp (*argv, "--adduid")) @@ -290,6 +295,7 @@ main (int argc, char **argv) revuid = 0; setpri = 0; setexpire = 0; + addadsk = 0; argc--; argv++; } else if (!strcmp (*argv, "--revuid")) @@ -299,6 +305,7 @@ main (int argc, char **argv) revuid = 1; setpri = 0; setexpire = 0; + addadsk = 0; argc--; argv++; } else if (!strcmp (*argv, "--set-primary")) @@ -308,6 +315,7 @@ main (int argc, char **argv) revuid = 0; setpri = 1; setexpire = 0; + addadsk = 0; argc--; argv++; } else if (!strcmp (*argv, "--setexpire")) @@ -317,6 +325,17 @@ main (int argc, char **argv) revuid = 0; setpri = 0; setexpire = 1; + addadsk = 0; + argc--; argv++; + } + else if (!strcmp (*argv, "--addadsk")) + { + addkey = 0; + adduid = 0; + revuid = 0; + setpri = 0; + setexpire = 0; + addadsk = 1; argc--; argv++; } else if (!strcmp (*argv, "--verbose")) @@ -412,6 +431,13 @@ main (int argc, char **argv) subfprs = NULL; } } + else if (addadsk) + { + if (argc != 2) + show_usage(1); + userid = argv[0]; + adskfpr = argv[1]; + } else { if (!argc || argc > 4) @@ -445,7 +471,7 @@ main (int argc, char **argv) } - if (addkey || adduid || revuid || setpri || setexpire) + if (addkey || adduid || revuid || setpri || setexpire || addadsk) { gpgme_key_t akey; @@ -507,6 +533,17 @@ main (int argc, char **argv) exit (1); } } + else if (addadsk) + { + err = gpgme_op_createsubkey(ctx, akey, adskfpr, 0, 0, + GPGME_CREATE_ADSK); + if (err) + { + fprintf (stderr, PGM ": gpgme_op_createsubkey failed: %s\n", + gpg_strerror (err)); + exit (1); + } + } gpgme_key_unref (akey); } @@ -521,7 +558,7 @@ main (int argc, char **argv) } } - if (!setpri && !setexpire) + if (!setpri && !setexpire && !addadsk) { result = gpgme_op_genkey_result (ctx); if (!result) |