mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-07 17:33:02 +01:00
scd: Parse "Algorithm Information" data object in scdaemon.
* scd/app-openpgp.c (data_objects): 0x00FA for binary data. (do_getattr): Parse the data and send it in status lines. (get_algorithm_attribute_string): New. -- Signed-off-by: NIIBE Yutaka <gniibe@fsij.org> Backported-from-master: eba2563dabbb4f61537900289fbe3ae113904733 Backported-from-master: 43bbc25b0f57dec24412886ff46041e0b1f3de26
This commit is contained in:
parent
1915b95ffd
commit
d6aa8bcbbb
14
doc/DETAILS
14
doc/DETAILS
@ -1174,6 +1174,20 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
|
|||||||
name of the manufacturer is also given as <string>; spaces are not
|
name of the manufacturer is also given as <string>; spaces are not
|
||||||
escaped. For PKCS#15 cards <string> is TokenInfo.manufactorerID.
|
escaped. For PKCS#15 cards <string> is TokenInfo.manufactorerID.
|
||||||
|
|
||||||
|
*** KEY-STATUS <keyref> <status>
|
||||||
|
This is the response from scdaemon on GETATTR KEY-STATUS for
|
||||||
|
OpenPGP cards. <keyref> is the usual keyref (e.g. OPENPGP.1 or
|
||||||
|
OPENPGP.129) and <status> is an integer describing the status of
|
||||||
|
the key: 0 = key is not present, 1 = key generated on card, 2 =
|
||||||
|
key imported. See section 4.4.3.8 of the OpenPGP Smart Card
|
||||||
|
Application V3.4.
|
||||||
|
|
||||||
|
*** KEY-ATTR-INFO <keyref> <string>
|
||||||
|
This is the response from scdaemon on GETATTR KEY-ATTR-INFO for
|
||||||
|
OpenPGP cards. <keyref> is the usual keyref (e.g. OPENPGP.1 or
|
||||||
|
OPENPGP.129) and <string> is the algoritm or curve name, which
|
||||||
|
is available for the key.
|
||||||
|
|
||||||
* Format of the --attribute-fd output
|
* Format of the --attribute-fd output
|
||||||
|
|
||||||
When --attribute-fd is set, during key listings (--list-keys,
|
When --attribute-fd is set, during key listings (--list-keys,
|
||||||
|
@ -115,6 +115,7 @@ static struct {
|
|||||||
{ 0x7F74, 0, 0, 1, 0, 0, 0, 0, "General Feature Management"},
|
{ 0x7F74, 0, 0, 1, 0, 0, 0, 0, "General Feature Management"},
|
||||||
{ 0x00D5, 0, 0, 1, 0, 0, 0, 0, "AES key data"},
|
{ 0x00D5, 0, 0, 1, 0, 0, 0, 0, "AES key data"},
|
||||||
{ 0x00F9, 0, 0, 1, 0, 0, 0, 0, "KDF data object"},
|
{ 0x00F9, 0, 0, 1, 0, 0, 0, 0, "KDF data object"},
|
||||||
|
{ 0x00FA, 0, 0, 1, 0, 0, 0, 2, "Algorithm Information"},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -253,6 +254,8 @@ static gpg_error_t do_auth (app_t app, ctrl_t ctrl, const char *keyidstr,
|
|||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen);
|
unsigned char **outdata, size_t *outdatalen);
|
||||||
|
static const char *get_algorithm_attribute_string (const unsigned char *buffer,
|
||||||
|
size_t buflen);
|
||||||
static gpg_error_t parse_algorithm_attribute (app_t app, int keyno);
|
static gpg_error_t parse_algorithm_attribute (app_t app, int keyno);
|
||||||
static gpg_error_t change_keyattr_from_string
|
static gpg_error_t change_keyattr_from_string
|
||||||
(app_t app,
|
(app_t app,
|
||||||
@ -1169,6 +1172,86 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
|
|||||||
|
|
||||||
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
|
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
|
||||||
}
|
}
|
||||||
|
else if (table[idx].special == 6)
|
||||||
|
{
|
||||||
|
for (i=0,rc=0; !rc && i+1 < valuelen; i += 2)
|
||||||
|
rc = send_status_printf (ctrl, table[idx].name, "OPENPGP.%u %u",
|
||||||
|
value[i], value[i+1]);
|
||||||
|
if (gpg_err_code (rc) == GPG_ERR_NO_OBJ)
|
||||||
|
rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
else if (table[idx].special == 7)
|
||||||
|
{
|
||||||
|
const unsigned char *p = value;
|
||||||
|
int tag;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (valuelen < 2)
|
||||||
|
return gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
|
||||||
|
tag = *p++;
|
||||||
|
len = *p++;
|
||||||
|
|
||||||
|
/* Does it comes tag+len at the head? */
|
||||||
|
if (tag == 0x00FA)
|
||||||
|
{
|
||||||
|
p += 2;
|
||||||
|
|
||||||
|
if (len == 0x81)
|
||||||
|
{
|
||||||
|
if (valuelen < 3)
|
||||||
|
return gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
len = *p++;
|
||||||
|
}
|
||||||
|
else if (len == 0x82)
|
||||||
|
{
|
||||||
|
if (valuelen < 4)
|
||||||
|
return gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
len = *p++;
|
||||||
|
len = (len << 8) | *p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
valuelen -= (p - value);
|
||||||
|
value = (unsigned char *)p;
|
||||||
|
|
||||||
|
if (valuelen != len)
|
||||||
|
{
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info ("Yubikey bug: length %zu != %zu", valuelen, len);
|
||||||
|
|
||||||
|
if (APP_CARD(app)->cardtype != CARDTYPE_YUBIKEY)
|
||||||
|
return gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; p < value + valuelen; p += len)
|
||||||
|
{
|
||||||
|
const char *key_algo_str;
|
||||||
|
int keyrefno;
|
||||||
|
|
||||||
|
if (p + 2 > value + valuelen)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tag = *p++;
|
||||||
|
len = *p++;
|
||||||
|
|
||||||
|
if (tag < 0xc1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tag == 0xda)
|
||||||
|
keyrefno = 0x81;
|
||||||
|
else
|
||||||
|
keyrefno = tag - 0xc1 + 1;
|
||||||
|
|
||||||
|
if (p + len > value + valuelen)
|
||||||
|
break;
|
||||||
|
|
||||||
|
key_algo_str = get_algorithm_attribute_string (p, len);
|
||||||
|
|
||||||
|
send_status_printf (ctrl, table[idx].name, "OPENPGP.%u %s",
|
||||||
|
keyrefno, key_algo_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
|
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
|
||||||
|
|
||||||
@ -5289,7 +5372,7 @@ parse_historical (struct app_local_s *apploc,
|
|||||||
* The constant string is not allocated dynamically, never free it.
|
* The constant string is not allocated dynamically, never free it.
|
||||||
*/
|
*/
|
||||||
static const char *
|
static const char *
|
||||||
ecc_curve (unsigned char *buf, size_t buflen)
|
ecc_curve (const unsigned char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
gcry_mpi_t oid;
|
gcry_mpi_t oid;
|
||||||
char *oidstr;
|
char *oidstr;
|
||||||
@ -5320,6 +5403,39 @@ ecc_curve (unsigned char *buf, size_t buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_algorithm_attribute_string (const unsigned char *buffer,
|
||||||
|
size_t buflen)
|
||||||
|
{
|
||||||
|
enum gcry_pk_algos galgo;
|
||||||
|
const char *curve;
|
||||||
|
unsigned int nbits = 0;
|
||||||
|
|
||||||
|
galgo = map_openpgp_pk_to_gcry (*buffer);
|
||||||
|
nbits = 0;
|
||||||
|
curve = NULL;
|
||||||
|
|
||||||
|
if (*buffer == PUBKEY_ALGO_RSA && (buflen == 5 || buflen == 6))
|
||||||
|
nbits = (buffer[1]<<8 | buffer[2]);
|
||||||
|
else if (*buffer == PUBKEY_ALGO_ECDH || *buffer == PUBKEY_ALGO_ECDSA
|
||||||
|
|| *buffer == PUBKEY_ALGO_EDDSA)
|
||||||
|
{
|
||||||
|
int oidlen = buflen - 1;
|
||||||
|
|
||||||
|
if (buffer[buflen-1] == 0x00 || buffer[buflen-1] == 0xff)
|
||||||
|
{ /* Found "pubkey required"-byte for private key template. */
|
||||||
|
oidlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
curve = ecc_curve (buffer + 1, oidlen);
|
||||||
|
}
|
||||||
|
else if (opt.verbose)
|
||||||
|
log_printhex (buffer, buflen, "");
|
||||||
|
|
||||||
|
return get_keyalgo_string (galgo, nbits, curve);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse and optionally show the algorithm attributes for KEYNO.
|
/* Parse and optionally show the algorithm attributes for KEYNO.
|
||||||
KEYNO must be in the range 0..2. */
|
KEYNO must be in the range 0..2. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user