Provide inforation about smartcards.

This commit is contained in:
Werner Koch 2009-02-04 09:51:43 +00:00
parent d951cb713f
commit 259cbefd5c
7 changed files with 87 additions and 9 deletions

1
NEWS
View File

@ -11,6 +11,7 @@ Noteworthy changes in version 1.1.9
gpgme_op_assuan_transact_start NEW. gpgme_op_assuan_transact_start NEW.
gpgme_op_assuan_transact NEW. gpgme_op_assuan_transact NEW.
gpgme_op_assuan_result NEW. gpgme_op_assuan_result NEW.
gpgme_subkey_t EXTENDED: New fields is_cardkey, card_number.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,3 +1,11 @@
2009-02-03 Werner Koch <wk@g10code.com>
* gpgme.h.in (struct _gpgme_subkey): Add fields IS_CARDKEY and
CARD_NUMBER..
* key.c (gpgme_key_unref): Release field CARD_NUMBER.
* keylist.c (keylist_colon_handler): Factor common code out to ...
(parse_sec_field15): New. Set card number.
2009-01-26 Werner Koch <wk@g10code.com> 2009-01-26 Werner Koch <wk@g10code.com>
* opassuan.c, dirinfo.c, engine-assuan.c: New. * opassuan.c, dirinfo.c, engine-assuan.c: New.

View File

@ -519,8 +519,11 @@ struct _gpgme_subkey
/* True if subkey is qualified for signatures according to German law. */ /* True if subkey is qualified for signatures according to German law. */
unsigned int is_qualified : 1; unsigned int is_qualified : 1;
/* True if the secret key is stored on a smart card. */
unsigned int is_cardkey : 1;
/* Internal to GPGME, do not use. */ /* Internal to GPGME, do not use. */
unsigned int _unused : 22; unsigned int _unused : 21;
/* Public key algorithm supported by this subkey. */ /* Public key algorithm supported by this subkey. */
gpgme_pubkey_algo_t pubkey_algo; gpgme_pubkey_algo_t pubkey_algo;
@ -542,6 +545,9 @@ struct _gpgme_subkey
/* The expiration timestamp, 0 if the subkey does not expire. */ /* The expiration timestamp, 0 if the subkey does not expire. */
long int expires; long int expires;
/* The serial number of a smart card holding this key or NULL. */
char *card_number;
}; };
typedef struct _gpgme_subkey *gpgme_subkey_t; typedef struct _gpgme_subkey *gpgme_subkey_t;

View File

@ -327,6 +327,8 @@ gpgme_key_unref (gpgme_key_t key)
gpgme_subkey_t next = subkey->next; gpgme_subkey_t next = subkey->next;
if (subkey->fpr) if (subkey->fpr)
free (subkey->fpr); free (subkey->fpr);
if (subkey->card_number)
free (subkey->card_number);
free (subkey); free (subkey);
subkey = next; subkey = next;
} }

View File

@ -1,7 +1,7 @@
/* keylist.c - Listing keys. /* keylist.c - Listing keys.
Copyright (C) 2000 Werner Koch (dd9jn) Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007, Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007,
2008 g10 Code GmbH 2008, 2009 g10 Code GmbH
This file is part of GPGME. This file is part of GPGME.
@ -351,6 +351,38 @@ set_ownertrust (gpgme_key_t key, const char *src)
} }
/* Parse field 15 of a secret key or subkey. This fields holds a
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)
{
if (!*field)
; /* Empty. */
else if (*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. */
subkey->secret = 0;
}
else if (strchr ("01234567890ABCDEFabcdef", *field))
{
/* Fields starts with a hex digit; thus it is a serial number. */
subkey->is_cardkey = 1;
subkey->card_number = strdup (field);
if (!subkey->card_number)
return gpg_error_from_syserror ();
}
else
{
/* RFU. */
}
return 0;
}
/* We have read an entire key into tmp_key and should now finish it. /* We have read an entire key into tmp_key and should now finish it.
It is assumed that this releases tmp_key. */ It is assumed that this releases tmp_key. */
static void static void
@ -533,12 +565,13 @@ keylist_colon_handler (void *priv, char *line)
if (fields >= 12) if (fields >= 12)
set_mainkey_capability (key, field[11]); set_mainkey_capability (key, field[11]);
/* Field 15 carries special flags of a secret key. We reset the /* Field 15 carries special flags of a secret key. */
SECRET flag of a subkey here if the key is actually only a
stub. The SECRET flag of the key will be true even then. */
if (fields >= 15 && key->secret) if (fields >= 15 && key->secret)
if (*field[14] == '#') {
subkey->secret = 0; err = parse_sec_field15 (subkey, field[14]);
if (err)
return err;
}
break; break;
case RT_SUB: case RT_SUB:
@ -596,8 +629,11 @@ keylist_colon_handler (void *priv, char *line)
/* Field 15 carries special flags of a secret key. */ /* Field 15 carries special flags of a secret key. */
if (fields >= 15 && key->secret) if (fields >= 15 && key->secret)
if (*field[14] == '#') {
subkey->secret = 0; err = parse_sec_field15 (subkey, field[14]);
if (err)
return err;
}
break; break;
case RT_UID: case RT_UID:

View File

@ -1,3 +1,8 @@
2009-02-03 Werner Koch <wk@g10code.com>
* gpg/t-keylist.c (main): Check that new fields is_cardkey and
card_number are not set.
2009-01-26 Werner Koch <wk@g10code.com> 2009-01-26 Werner Koch <wk@g10code.com>
* opassuan/: New. * opassuan/: New.

View File

@ -270,6 +270,16 @@ main (int argc, char **argv)
fprintf (stderr, "Primary key unexpectedly secret\n"); fprintf (stderr, "Primary key unexpectedly secret\n");
exit (1); exit (1);
} }
if (key->subkeys->is_cardkey)
{
fprintf (stderr, "Public key marked as card key\n");
exit (1);
}
if (key->subkeys->card_number)
{
fprintf (stderr, "Public key with card number set\n");
exit (1);
}
if (key->subkeys->pubkey_algo != GPGME_PK_DSA) if (key->subkeys->pubkey_algo != GPGME_PK_DSA)
{ {
fprintf (stderr, "Primary key has unexpected public key algo: %s\n", fprintf (stderr, "Primary key has unexpected public key algo: %s\n",
@ -342,6 +352,16 @@ main (int argc, char **argv)
fprintf (stderr, "Secondary key unexpectedly secret\n"); fprintf (stderr, "Secondary key unexpectedly secret\n");
exit (1); exit (1);
} }
if (key->subkeys->next->is_cardkey)
{
fprintf (stderr, "Secondary public key marked as card key\n");
exit (1);
}
if (key->subkeys->next->card_number)
{
fprintf (stderr, "Secondary public key with card number set\n");
exit (1);
}
if (key->subkeys->next->pubkey_algo != GPGME_PK_ELG_E) if (key->subkeys->next->pubkey_algo != GPGME_PK_ELG_E)
{ {
fprintf (stderr, "Secondary key has unexpected public key algo: %s\n", fprintf (stderr, "Secondary key has unexpected public key algo: %s\n",