+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * key.h (struct certsig_s): New. Use it in gpgme_key_s.
+ * key.c (gpgme_key_release): Release it. We need to add more code
+ of course.
+ (_gpgme_key_append_name): Use memset to intialize the struct.
+ * gpgme.h (GPGME_KEYLIST_MODE_SIGS): New.
+ * rungpg.c (_gpgme_gpg_op_keylist): Include sigs in listing depending
+ non the list mode.
+
+ * key.c (gpgme_key_get_string_attr): Use GPGME_ATTR_TYPE to return
+ information about the key type (PGP or X.509).
+ (gpgme_key_get_ulong_attr): Likewise.
+
+ * keylist.c (keylist_colon_handler): Include 1 in the check for
+ valid algorithms so that RSA is usable. Store the issuer name and
+ serial number also for "crs" records. Parse the expire date for
+ subkeys.
+ (set_userid_flags): Put them onto the last appended key.
+
2002-07-29 Marcus Brinkmann <marcus@g10code.de>
* rungpg.c (_gpgme_gpg_op_edit): Use --with-colons.
char *private_buffer;
};
+/* Forward declaration of a structure to store certification
+ signatures. */
+struct certsig_s;
+
+/* Structure to store user IDs. */
struct user_id_s {
struct user_id_s *next;
unsigned int revoked:1;
unsigned int invalid:1;
GpgmeValidity validity;
+ struct certsig_s *certsigs;
const char *name_part; /* all 3 point into strings behind name */
const char *email_part; /* or to read-only strings */
const char *comment_part;
GPGME_STATUS_EXPSIG ,
GPGME_STATUS_EXPKEYSIG ,
GPGME_STATUS_TRUNCATED ,
- GPGME_STATUS_ERROR ,
+ GPGME_STATUS_ERROR
} GpgmeStatusCode;
/* The available keylist mode flags. */
-#define GPGME_KEYLIST_MODE_LOCAL 1
+#define GPGME_KEYLIST_MODE_LOCAL 1
#define GPGME_KEYLIST_MODE_EXTERN 2
-
+#define GPGME_KEYLIST_MODE_SIGS 4
/* Types for callback functions. */
void
gpgme_key_release (GpgmeKey key)
{
+ struct certsig_s *c, *c2;
struct user_id_s *u, *u2;
struct subkey_s *k, *k2;
for (u = key->uids; u; u = u2)
{
u2 = u->next;
+ for (c = u->certsigs; c; c = c2)
+ {
+ c2 = c->next;
+ xfree (c);
+ }
xfree (u);
}
xfree (key->issuer_serial);
/* We can malloc a buffer of the same length, because the converted
string will never be larger. Actually we allocate it twice the
size, so that we are able to store the parsed stuff there too. */
- uid = xtrymalloc ( sizeof *uid + 2*strlen (s)+3);
+ uid = xtrymalloc (sizeof *uid + 2*strlen (s)+3);
if (!uid)
return mk_error (Out_Of_Core);
- uid->revoked = 0;
- uid->invalid = 0;
- uid->validity = 0;
- uid->name_part = NULL;
- uid->email_part = NULL;
- uid->comment_part = NULL;
- uid->next = NULL;
+ memset (uid, 0, sizeof *uid);
d = uid->name;
while (*s)
if (k)
val = pkalgo_to_string (k->key_algo);
break;
+ case GPGME_ATTR_TYPE:
+ val = key->x509? "X.509":"PGP";
+ break;
case GPGME_ATTR_LEN:
case GPGME_ATTR_CREATED:
case GPGME_ATTR_EXPIRE:
}
break;
case GPGME_ATTR_LEVEL:
- case GPGME_ATTR_TYPE:
case GPGME_ATTR_KEY_REVOKED:
case GPGME_ATTR_KEY_INVALID:
case GPGME_ATTR_KEY_EXPIRED:
if (k)
val = (unsigned long) k->key_len;
break;
+ case GPGME_ATTR_TYPE:
+ val = key->x509? 1:0;
+ break;
case GPGME_ATTR_CREATED:
for (k = &key->keys; k && idx; k = k->next, idx--)
;
}
return val;
}
+
#include "types.h"
#include "context.h"
+struct certsig_s {
+ struct certsig_s *next;
+ struct {
+ unsigned int revoked:1 ;
+ unsigned int expired:1 ;
+ unsigned int invalid:1 ;
+ } flags;
+ char keyid[16+1];
+ time_t timestamp; /* -1 for invalid, 0 for not available */
+ time_t expires_at; /* 0 for does not expires */
+};
+
struct subkey_s {
struct subkey_s *next;
unsigned int secret:1;
static void
set_userid_flags (GpgmeKey key, const char *s)
{
+ struct user_id_s *u = key->uids;
+
+ assert (u);
+ while (u->next)
+ u = u->next;
+
/* Look at letters and stop at the first digit. */
for (; *s && !my_isdigit (*s); s++)
{
switch (*s)
{
- case 'r': key->uids->revoked = 1; break;
- case 'i': key->uids->invalid = 1; break;
+ case 'r': u->revoked = 1; break;
+ case 'i': u->invalid = 1; break;
- case 'n': key->uids->validity = GPGME_VALIDITY_NEVER; break;
- case 'm': key->uids->validity = GPGME_VALIDITY_MARGINAL; break;
- case 'f': key->uids->validity = GPGME_VALIDITY_FULL; break;
- case 'u': key->uids->validity = GPGME_VALIDITY_ULTIMATE; break;
+ case 'n': u->validity = GPGME_VALIDITY_NEVER; break;
+ case 'm': u->validity = GPGME_VALIDITY_MARGINAL; break;
+ case 'f': u->validity = GPGME_VALIDITY_FULL; break;
+ case 'u': u->validity = GPGME_VALIDITY_ULTIMATE; break;
}
}
}
break;
case 4: /* pubkey algo */
i = atoi (p);
- if (i > 1 && i < 128)
+ if (i >= 1 && i < 128)
key->keys.key_algo = i;
break;
case 5: /* long keyid */
key->keys.expires_at = parse_timestamp (p);
break;
case 8: /* X.509 serial number */
- if (rectype == RT_CRT)
+ if (rectype == RT_CRT || rectype == RT_CRS)
{
key->issuer_serial = xtrystrdup (p);
if (!key->issuer_serial)
break;
case 10: /* not used for gpg due to --fixed-list-mode option
but gpgsm stores the issuer name */
- if (rectype == RT_CRT)
+ if (rectype == RT_CRT || rectype == RT_CRS)
{
key->issuer_name = xtrystrdup (p);
if (!key->issuer_name)
break;
case 4: /* pubkey algo */
i = atoi (p);
- if (i > 1 && i < 128)
+ if (i >= 1 && i < 128)
sk->key_algo = i;
break;
case 5: /* long keyid */
sk->timestamp = parse_timestamp (p);
break;
case 7: /* expiration time (seconds) */
+ sk->expires_at = parse_timestamp (p);
break;
case 8: /* reserved (LID) */
break;
else
{
if (trust_info)
- set_userid_flags (key, trust_info);
+ set_userid_flags (key, trust_info);
}
pend = NULL; /* we can stop here */
break;
if (!err)
err = _gpgme_gpg_add_arg (gpg, "--with-fingerprint");
if (!err)
- err = _gpgme_gpg_add_arg (gpg, secret_only ? "--list-secret-keys"
+ err = _gpgme_gpg_add_arg (gpg,
+ (keylist_mode & GPGME_KEYLIST_MODE_SIGS)?
+ "--check-sigs" :
+ secret_only ? "--list-secret-keys"
: "--list-keys");
/* Tell the gpg object about the data */