aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS6
-rw-r--r--doc/gpgme.texi22
-rw-r--r--src/engine-gpg.c2
-rw-r--r--src/engine-gpgsm.c12
-rw-r--r--src/gpgme-tool.c10
-rw-r--r--src/gpgme.h.in1
-rw-r--r--src/keylist.c24
7 files changed, 64 insertions, 13 deletions
diff --git a/NEWS b/NEWS
index b7a6227d..c6a8f52e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,12 @@
Noteworthy changes in version 1.5.1 (unreleased) [C__/A__/R_]
-------------------------------------------------------------
+ * Add support for GnuPG 2.1's --with-secret option.
+
+ * Interface changes relative to the 1.5.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GPGME_KEYLIST_MODE_WITH_SECRET NEW.
+
Noteworthy changes in version 1.5.0 (2014-05-21) [C23/A12/R0]
-------------------------------------------------------------
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index e3265740..1f4a9e1d 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -2472,6 +2472,13 @@ signature notations on key signatures should be included in the listed
keys. This only works if @code{GPGME_KEYLIST_MODE_SIGS} is also
enabled.
+@item GPGME_KEYLIST_MODE_WITH_SECRET
+The @code{GPGME_KEYLIST_MODE_WITH_SECRET} returns information about
+the presence of a corresponding secret key in a public key listing. A
+public key listing with this mode is slower than a standard listing
+but can be used instead of a second run to list the secret keys. This
+is only supported for GnuPG versions >= 2.1.
+
@item GPGME_KEYLIST_MODE_EPHEMERAL
The @code{GPGME_KEYLIST_MODE_EPHEMERAL} symbol specifies that keys
flagged as ephemeral are included in the listing.
@@ -2712,9 +2719,11 @@ This is true if the subkey can be used for qualified signatures
according to local government regulations.
@item unsigned int secret : 1
-This is true if the subkey is a secret key. Note that it will be false
-if the key is actually a stub key; i.e. a secret key operation is
-currently not possible (offline-key).
+This is true if the subkey is a secret key. Note that it will be
+false if the key is actually a stub key; i.e. a secret key operation
+is currently not possible (offline-key). This is only set if a
+listing of secret keys has been requested or if
+@code{GPGME_KEYLIST_MODE_WITH_SECRET} is active.
@item gpgme_pubkey_algo_t pubkey_algo
This is the public key algorithm supported by this subkey.
@@ -2905,9 +2914,10 @@ This is true if the key can be used for qualified signatures according
to local government regulations.
@item unsigned int secret : 1
-This is true if the key is a secret key. Note, that this will always be
-true even if the corresponding subkey flag may be false (offline/stub
-keys).
+This is true if the key is a secret key. Note, that this will always
+be true even if the corresponding subkey flag may be false
+(offline/stub keys). This is only set if a listing of secret keys has
+been requested or if @code{GPGME_KEYLIST_MODE_WITH_SECRET} is active.
@item gpgme_protocol_t protocol
This is the protocol supported by this key.
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index ede098ef..4df0f3e4 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -2194,6 +2194,8 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
err = add_arg (gpg, "--with-fingerprint");
if (!err)
err = add_arg (gpg, "--with-fingerprint");
+ if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
+ err = add_arg (gpg, "--with-secret");
if (!err
&& (mode & GPGME_KEYLIST_MODE_SIGS)
&& (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 710bf14a..8ec15985 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -1551,7 +1551,7 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
the agent. However on a fresh installation no public keys are
available and thus there is no need for gpgsm to ask the agent
whether a secret key exists for the public key. */
- if (secret_only)
+ if (secret_only || (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "GETINFO agent-check",
NULL, NULL);
@@ -1580,6 +1580,11 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
"OPTION with-ephemeral-keys=1":
"OPTION with-ephemeral-keys=0" ,
NULL, NULL);
+ gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+ (mode & GPGME_KEYLIST_MODE_WITH_SECRET)?
+ "OPTION with-secret=1":
+ "OPTION with-secret=0" ,
+ NULL, NULL);
/* Length is "LISTSECRETKEYS " + p + '\0'. */
@@ -1645,6 +1650,11 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
"OPTION with-validation=1":
"OPTION with-validation=0" ,
NULL, NULL);
+ gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+ (mode & GPGME_KEYLIST_MODE_WITH_SECRET)?
+ "OPTION with-secret=1":
+ "OPTION with-secret=0" ,
+ NULL, NULL);
if (pattern && *pattern)
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
index be8ed078..f02fffa7 100644
--- a/src/gpgme-tool.c
+++ b/src/gpgme-tool.c
@@ -1861,6 +1861,8 @@ gt_get_keylist_mode (gpgme_tool_t gt)
modes[idx++] = "sigs";
if (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS)
modes[idx++] = "sig_notations";
+ if (mode & GPGME_KEYLIST_MODE_WITH_SECRET)
+ modes[idx++] = "with_secret";
if (mode & GPGME_KEYLIST_MODE_EPHEMERAL)
modes[idx++] = "ephemeral";
if (mode & GPGME_KEYLIST_MODE_VALIDATE)
@@ -2591,6 +2593,8 @@ cmd_keylist_mode (assuan_context_t ctx, char *line)
mode |= GPGME_KEYLIST_MODE_SIGS;
if (strstr (line, "sig_notations"))
mode |= GPGME_KEYLIST_MODE_SIG_NOTATIONS;
+ if (strstr (line, "with_secret"))
+ mode |= GPGME_KEYLIST_MODE_WITH_SECRET;
if (strstr (line, "ephemeral"))
mode |= GPGME_KEYLIST_MODE_EPHEMERAL;
if (strstr (line, "validate"))
@@ -3299,6 +3303,12 @@ cmd_keylist (assuan_context_t ctx, char *line)
result_xml_tag_start (&state, "subkey", NULL);
/* FIXME: more data */
result_add_fpr (&state, "fpr", subkey->fpr);
+ result_add_value (&state, "secret", subkey->secret);
+ result_add_value (&state, "is_cardkey", subkey->is_cardkey);
+ if (subkey->card_number)
+ result_add_string (&state, "card_number", subkey->card_number);
+ if (subkey->curve)
+ result_add_string (&state, "curve", subkey->curve);
result_xml_tag_end (&state); /* subkey */
subkey = subkey->next;
}
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index d47f4ba9..15ed8037 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -370,6 +370,7 @@ gpgme_protocol_t;
#define GPGME_KEYLIST_MODE_EXTERN 2
#define GPGME_KEYLIST_MODE_SIGS 4
#define GPGME_KEYLIST_MODE_SIG_NOTATIONS 8
+#define GPGME_KEYLIST_MODE_WITH_SECRET 16
#define GPGME_KEYLIST_MODE_EPHEMERAL 128
#define GPGME_KEYLIST_MODE_VALIDATE 256
diff --git a/src/keylist.c b/src/keylist.c
index 582b241b..36ee3eaa 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -367,7 +367,7 @@ set_ownertrust (gpgme_key_t key, const char *src)
reference to smartcards. FIELD is the content of the field and we
are allowed to modify it. */
static gpg_error_t
-parse_sec_field15 (gpgme_subkey_t subkey, char *field)
+parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)
{
if (!*field)
; /* Empty. */
@@ -375,17 +375,25 @@ parse_sec_field15 (gpgme_subkey_t subkey, char *field)
{
/* This is a stub for an offline key. We reset the SECRET flag
of the subkey here. Note that the secret flag of the entire
- key will be true even then. */
+ key will be true even then. We even explicitly set
+ key->secret to make it works for GPGME_KEYLIST_MODE_WITH_SECRET. */
subkey->secret = 0;
+ key->secret = 1;
}
else if (strchr ("01234567890ABCDEFabcdef", *field))
{
/* Fields starts with a hex digit; thus it is a serial number. */
+ key->secret = 1;
subkey->is_cardkey = 1;
subkey->card_number = strdup (field);
if (!subkey->card_number)
return gpg_error_from_syserror ();
}
+ else if (*field == '+')
+ {
+ key->secret = 1;
+ subkey->secret = 1;
+ }
else
{
/* RFU. */
@@ -578,9 +586,11 @@ keylist_colon_handler (void *priv, char *line)
set_mainkey_capability (key, field[11]);
/* Field 15 carries special flags of a secret key. */
- if (fields >= 15 && key->secret)
+ if (fields >= 15
+ && (key->secret
+ || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
{
- err = parse_sec_field15 (subkey, field[14]);
+ err = parse_sec_field15 (key, subkey, field[14]);
if (err)
return err;
}
@@ -649,9 +659,11 @@ keylist_colon_handler (void *priv, char *line)
set_subkey_capability (subkey, field[11]);
/* Field 15 carries special flags of a secret key. */
- if (fields >= 15 && key->secret)
+ if (fields >= 15
+ && (key->secret
+ || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
{
- err = parse_sec_field15 (subkey, field[14]);
+ err = parse_sec_field15 (key, subkey, field[14]);
if (err)
return err;
}