* 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.
This commit is contained in:
Werner Koch 2002-08-14 14:01:09 +00:00
parent c79fa94260
commit a8782e4ed7
7 changed files with 78 additions and 24 deletions

View File

@ -1,3 +1,23 @@
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> 2002-07-29 Marcus Brinkmann <marcus@g10code.de>
* rungpg.c (_gpgme_gpg_op_edit): Use --with-colons. * rungpg.c (_gpgme_gpg_op_edit): Use --with-colons.

View File

@ -130,11 +130,17 @@ struct gpgme_data_s {
char *private_buffer; 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 {
struct user_id_s *next; struct user_id_s *next;
unsigned int revoked:1; unsigned int revoked:1;
unsigned int invalid:1; unsigned int invalid:1;
GpgmeValidity validity; GpgmeValidity validity;
struct certsig_s *certsigs;
const char *name_part; /* all 3 point into strings behind name */ const char *name_part; /* all 3 point into strings behind name */
const char *email_part; /* or to read-only strings */ const char *email_part; /* or to read-only strings */
const char *comment_part; const char *comment_part;

View File

@ -302,14 +302,14 @@ typedef enum {
GPGME_STATUS_EXPSIG , GPGME_STATUS_EXPSIG ,
GPGME_STATUS_EXPKEYSIG , GPGME_STATUS_EXPKEYSIG ,
GPGME_STATUS_TRUNCATED , GPGME_STATUS_TRUNCATED ,
GPGME_STATUS_ERROR , GPGME_STATUS_ERROR
} GpgmeStatusCode; } GpgmeStatusCode;
/* The available keylist mode flags. */ /* 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_EXTERN 2
#define GPGME_KEYLIST_MODE_SIGS 4
/* Types for callback functions. */ /* Types for callback functions. */

View File

@ -392,6 +392,7 @@ _gpgme_key_add_secret_subkey (GpgmeKey key)
void void
gpgme_key_release (GpgmeKey key) gpgme_key_release (GpgmeKey key)
{ {
struct certsig_s *c, *c2;
struct user_id_s *u, *u2; struct user_id_s *u, *u2;
struct subkey_s *k, *k2; struct subkey_s *k, *k2;
@ -417,6 +418,11 @@ gpgme_key_release (GpgmeKey key)
for (u = key->uids; u; u = u2) for (u = key->uids; u; u = u2)
{ {
u2 = u->next; u2 = u->next;
for (c = u->certsigs; c; c = c2)
{
c2 = c->next;
xfree (c);
}
xfree (u); xfree (u);
} }
xfree (key->issuer_serial); xfree (key->issuer_serial);
@ -580,16 +586,10 @@ _gpgme_key_append_name (GpgmeKey key, const char *s)
/* We can malloc a buffer of the same length, because the converted /* We can malloc a buffer of the same length, because the converted
string will never be larger. Actually we allocate it twice the string will never be larger. Actually we allocate it twice the
size, so that we are able to store the parsed stuff there too. */ 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) if (!uid)
return mk_error (Out_Of_Core); return mk_error (Out_Of_Core);
uid->revoked = 0; memset (uid, 0, sizeof *uid);
uid->invalid = 0;
uid->validity = 0;
uid->name_part = NULL;
uid->email_part = NULL;
uid->comment_part = NULL;
uid->next = NULL;
d = uid->name; d = uid->name;
while (*s) while (*s)
@ -897,6 +897,9 @@ gpgme_key_get_string_attr (GpgmeKey key, GpgmeAttr what,
if (k) if (k)
val = pkalgo_to_string (k->key_algo); val = pkalgo_to_string (k->key_algo);
break; break;
case GPGME_ATTR_TYPE:
val = key->x509? "X.509":"PGP";
break;
case GPGME_ATTR_LEN: case GPGME_ATTR_LEN:
case GPGME_ATTR_CREATED: case GPGME_ATTR_CREATED:
case GPGME_ATTR_EXPIRE: case GPGME_ATTR_EXPIRE:
@ -961,7 +964,6 @@ gpgme_key_get_string_attr (GpgmeKey key, GpgmeAttr what,
} }
break; break;
case GPGME_ATTR_LEVEL: case GPGME_ATTR_LEVEL:
case GPGME_ATTR_TYPE:
case GPGME_ATTR_KEY_REVOKED: case GPGME_ATTR_KEY_REVOKED:
case GPGME_ATTR_KEY_INVALID: case GPGME_ATTR_KEY_INVALID:
case GPGME_ATTR_KEY_EXPIRED: case GPGME_ATTR_KEY_EXPIRED:
@ -1047,6 +1049,9 @@ gpgme_key_get_ulong_attr (GpgmeKey key, GpgmeAttr what,
if (k) if (k)
val = (unsigned long) k->key_len; val = (unsigned long) k->key_len;
break; break;
case GPGME_ATTR_TYPE:
val = key->x509? 1:0;
break;
case GPGME_ATTR_CREATED: case GPGME_ATTR_CREATED:
for (k = &key->keys; k && idx; k = k->next, idx--) for (k = &key->keys; k && idx; k = k->next, idx--)
; ;
@ -1121,3 +1126,4 @@ gpgme_key_get_ulong_attr (GpgmeKey key, GpgmeAttr what,
} }
return val; return val;
} }

View File

@ -26,6 +26,18 @@
#include "types.h" #include "types.h"
#include "context.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 {
struct subkey_s *next; struct subkey_s *next;
unsigned int secret:1; unsigned int secret:1;

View File

@ -149,18 +149,24 @@ set_mainkey_trust_info (GpgmeKey key, const char *s)
static void static void
set_userid_flags (GpgmeKey key, const char *s) 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. */ /* Look at letters and stop at the first digit. */
for (; *s && !my_isdigit (*s); s++) for (; *s && !my_isdigit (*s); s++)
{ {
switch (*s) switch (*s)
{ {
case 'r': key->uids->revoked = 1; break; case 'r': u->revoked = 1; break;
case 'i': key->uids->invalid = 1; break; case 'i': u->invalid = 1; break;
case 'n': key->uids->validity = GPGME_VALIDITY_NEVER; break; case 'n': u->validity = GPGME_VALIDITY_NEVER; break;
case 'm': key->uids->validity = GPGME_VALIDITY_MARGINAL; break; case 'm': u->validity = GPGME_VALIDITY_MARGINAL; break;
case 'f': key->uids->validity = GPGME_VALIDITY_FULL; break; case 'f': u->validity = GPGME_VALIDITY_FULL; break;
case 'u': key->uids->validity = GPGME_VALIDITY_ULTIMATE; break; case 'u': u->validity = GPGME_VALIDITY_ULTIMATE; break;
} }
} }
} }
@ -374,7 +380,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
break; break;
case 4: /* pubkey algo */ case 4: /* pubkey algo */
i = atoi (p); i = atoi (p);
if (i > 1 && i < 128) if (i >= 1 && i < 128)
key->keys.key_algo = i; key->keys.key_algo = i;
break; break;
case 5: /* long keyid */ case 5: /* long keyid */
@ -388,7 +394,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
key->keys.expires_at = parse_timestamp (p); key->keys.expires_at = parse_timestamp (p);
break; break;
case 8: /* X.509 serial number */ case 8: /* X.509 serial number */
if (rectype == RT_CRT) if (rectype == RT_CRT || rectype == RT_CRS)
{ {
key->issuer_serial = xtrystrdup (p); key->issuer_serial = xtrystrdup (p);
if (!key->issuer_serial) if (!key->issuer_serial)
@ -400,7 +406,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
break; break;
case 10: /* not used for gpg due to --fixed-list-mode option case 10: /* not used for gpg due to --fixed-list-mode option
but gpgsm stores the issuer name */ but gpgsm stores the issuer name */
if (rectype == RT_CRT) if (rectype == RT_CRT || rectype == RT_CRS)
{ {
key->issuer_name = xtrystrdup (p); key->issuer_name = xtrystrdup (p);
if (!key->issuer_name) if (!key->issuer_name)
@ -431,7 +437,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
break; break;
case 4: /* pubkey algo */ case 4: /* pubkey algo */
i = atoi (p); i = atoi (p);
if (i > 1 && i < 128) if (i >= 1 && i < 128)
sk->key_algo = i; sk->key_algo = i;
break; break;
case 5: /* long keyid */ case 5: /* long keyid */
@ -442,6 +448,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
sk->timestamp = parse_timestamp (p); sk->timestamp = parse_timestamp (p);
break; break;
case 7: /* expiration time (seconds) */ case 7: /* expiration time (seconds) */
sk->expires_at = parse_timestamp (p);
break; break;
case 8: /* reserved (LID) */ case 8: /* reserved (LID) */
break; break;
@ -473,7 +480,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
else else
{ {
if (trust_info) if (trust_info)
set_userid_flags (key, trust_info); set_userid_flags (key, trust_info);
} }
pend = NULL; /* we can stop here */ pend = NULL; /* we can stop here */
break; break;

View File

@ -1674,7 +1674,10 @@ _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,
if (!err) if (!err)
err = _gpgme_gpg_add_arg (gpg, "--with-fingerprint"); err = _gpgme_gpg_add_arg (gpg, "--with-fingerprint");
if (!err) 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"); : "--list-keys");
/* Tell the gpg object about the data */ /* Tell the gpg object about the data */