mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02:00
Add readcert command.
fix reading large certificates.
This commit is contained in:
parent
bdbeb0ac2b
commit
5f8acaccc0
@ -575,7 +575,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||||||
/* (int) pi.dwProcessId, (int) pi.dwThreadId); */
|
/* (int) pi.dwProcessId, (int) pi.dwThreadId); */
|
||||||
|
|
||||||
/* Fixme: For unknown reasons AllowSetForegroundWindow returns an
|
/* Fixme: For unknown reasons AllowSetForegroundWindow returns an
|
||||||
invalid argument error if we pass the the correct processID to
|
invalid argument error if we pass the correct processID to
|
||||||
it. As a workaround we use -1 (ASFW_ANY). */
|
it. As a workaround we use -1 (ASFW_ANY). */
|
||||||
if ( (flags & 64) )
|
if ( (flags & 64) )
|
||||||
gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/);
|
gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/);
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
2009-06-17 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* card-util.c (put_data_to_file, read_cert): New.
|
||||||
|
(card_edit): Add command "readcert".
|
||||||
|
(fetch_url): Allow code also for this gnupg major version 2.
|
||||||
|
* call-agent.c (agent_scd_readcert): New.
|
||||||
|
|
||||||
|
2009-06-15 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* keyserver.c (keyserver_search_prompt): No prompt in batch+colons
|
||||||
|
mode.
|
||||||
|
|
||||||
2009-06-09 Werner Koch <wk@g10code.com>
|
2009-06-09 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* card-util.c (write_sc_op_status): New.
|
* card-util.c (write_sc_op_status): New.
|
||||||
|
@ -488,7 +488,6 @@ agent_scd_writecert (const char *certidstr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle a KEYDATA inquiry. Note, we only send the data,
|
/* Handle a KEYDATA inquiry. Note, we only send the data,
|
||||||
assuan_transact takes care of flushing and writing the end */
|
assuan_transact takes care of flushing and writing the end */
|
||||||
@ -539,7 +538,6 @@ agent_scd_writekey (int keyno, const char *serialno,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Status callback for the SCD GENKEY command. */
|
/* Status callback for the SCD GENKEY command. */
|
||||||
static int
|
static int
|
||||||
@ -765,6 +763,43 @@ agent_scd_pkdecrypt (const char *serialno,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Send a READCERT command to the SCdaemon. */
|
||||||
|
int
|
||||||
|
agent_scd_readcert (const char *certidstr,
|
||||||
|
void **r_buf, size_t *r_buflen)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
membuf_t data;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
*r_buf = NULL;
|
||||||
|
rc = start_agent ();
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
init_membuf (&data, 2048);
|
||||||
|
|
||||||
|
snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
|
||||||
|
line[DIM(line)-1] = 0;
|
||||||
|
rc = assuan_transact (agent_ctx, line,
|
||||||
|
membuf_data_cb, &data,
|
||||||
|
default_inq_cb, NULL, NULL, NULL);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
xfree (get_membuf (&data, &len));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
*r_buf = get_membuf (&data, r_buflen);
|
||||||
|
if (!*r_buf)
|
||||||
|
return gpg_error (GPG_ERR_ENOMEM);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Change the PIN of an OpenPGP card or reset the retry counter.
|
/* Change the PIN of an OpenPGP card or reset the retry counter.
|
||||||
CHVNO 1: Change the PIN
|
CHVNO 1: Change the PIN
|
||||||
2: For v1 cards: Same as 1.
|
2: For v1 cards: Same as 1.
|
||||||
|
@ -104,6 +104,10 @@ int agent_scd_pkdecrypt (const char *serialno,
|
|||||||
const unsigned char *indata, size_t indatalen,
|
const unsigned char *indata, size_t indatalen,
|
||||||
unsigned char **r_buf, size_t *r_buflen);
|
unsigned char **r_buf, size_t *r_buflen);
|
||||||
|
|
||||||
|
/* Send a READKEY command to the SCdaemon. */
|
||||||
|
int agent_scd_readcert (const char *certidstr,
|
||||||
|
void **r_buf, size_t *r_buflen);
|
||||||
|
|
||||||
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
||||||
int agent_scd_change_pin (int chvno, const char *serialno);
|
int agent_scd_change_pin (int chvno, const char *serialno);
|
||||||
|
|
||||||
|
@ -715,7 +715,6 @@ change_url (void)
|
|||||||
static int
|
static int
|
||||||
fetch_url(void)
|
fetch_url(void)
|
||||||
{
|
{
|
||||||
#if GNUPG_MAJOR_VERSION == 1
|
|
||||||
int rc;
|
int rc;
|
||||||
struct agent_card_info_s info;
|
struct agent_card_info_s info;
|
||||||
|
|
||||||
@ -755,15 +754,11 @@ fetch_url(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
#else
|
|
||||||
#warning need to implemented fucntion
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read data from file FNAME up to MAXLEN characters. On error return
|
/* Read data from file FNAME up to MAXLEN characters. On error return
|
||||||
-1 and store NULl at R_BUFFER; on success return the number of
|
-1 and store NULL at R_BUFFER; on success return the number of
|
||||||
bytes read and store the address of a newly allocated buffer at
|
bytes read and store the address of a newly allocated buffer at
|
||||||
R_BUFFER. */
|
R_BUFFER. */
|
||||||
static int
|
static int
|
||||||
@ -814,6 +809,39 @@ get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Write LENGTH bytes from BUFFER to file FNAME. Return 0 on
|
||||||
|
success. */
|
||||||
|
static int
|
||||||
|
put_data_to_file (const char *fname, const void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen (fname, "wb");
|
||||||
|
#if GNUPG_MAJOR_VERSION == 1
|
||||||
|
if (fp && is_secured_file (fileno (fp)))
|
||||||
|
{
|
||||||
|
fclose (fp);
|
||||||
|
fp = NULL;
|
||||||
|
errno = EPERM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
tty_printf (_("can't create `%s': %s\n"), fname, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length && fwrite (buffer, length, 1, fp) != 1)
|
||||||
|
{
|
||||||
|
tty_printf (_("error writing `%s': %s\n"), fname, strerror (errno));
|
||||||
|
fclose (fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fclose (fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
change_login (const char *args)
|
change_login (const char *args)
|
||||||
{
|
{
|
||||||
@ -933,6 +961,37 @@ change_cert (const char *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_cert (const char *args)
|
||||||
|
{
|
||||||
|
const char *fname;
|
||||||
|
void *buffer;
|
||||||
|
size_t length;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (args && *args == '>') /* Write it to a file */
|
||||||
|
{
|
||||||
|
for (args++; spacep (args); args++)
|
||||||
|
;
|
||||||
|
fname = args;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tty_printf ("usage error: redirectrion to file required\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = agent_scd_readcert ("OPENPGP.3", &buffer, &length);
|
||||||
|
if (rc)
|
||||||
|
log_error ("error reading certificate from card: %s\n", gpg_strerror (rc));
|
||||||
|
else
|
||||||
|
rc = put_data_to_file (fname, buffer, length);
|
||||||
|
xfree (buffer);
|
||||||
|
write_sc_op_status (rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
change_lang (void)
|
change_lang (void)
|
||||||
{
|
{
|
||||||
@ -1447,7 +1506,7 @@ enum cmdids
|
|||||||
cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
|
cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
|
||||||
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
|
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
|
||||||
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
|
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
|
||||||
cmdUNBLOCK,
|
cmdREADCERT, cmdUNBLOCK,
|
||||||
cmdINVCMD
|
cmdINVCMD
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1481,6 +1540,7 @@ static struct
|
|||||||
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
|
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
|
||||||
/* Note, that we do not announce these command yet. */
|
/* Note, that we do not announce these command yet. */
|
||||||
{ "privatedo", cmdPRIVATEDO, 0, NULL },
|
{ "privatedo", cmdPRIVATEDO, 0, NULL },
|
||||||
|
{ "readcert", cmdREADCERT, 0, NULL },
|
||||||
{ "writecert", cmdWRITECERT, 1, NULL },
|
{ "writecert", cmdWRITECERT, 1, NULL },
|
||||||
{ NULL, cmdINVCMD, 0, NULL }
|
{ NULL, cmdINVCMD, 0, NULL }
|
||||||
};
|
};
|
||||||
@ -1735,6 +1795,13 @@ card_edit (strlist_t commands)
|
|||||||
change_cert (arg_rest);
|
change_cert (arg_rest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmdREADCERT:
|
||||||
|
if ( arg_number != 3 )
|
||||||
|
tty_printf ("usage: readcert 3 > FILE\n");
|
||||||
|
else
|
||||||
|
read_cert (arg_rest);
|
||||||
|
break;
|
||||||
|
|
||||||
case cmdFORCESIG:
|
case cmdFORCESIG:
|
||||||
toggle_forcesig ();
|
toggle_forcesig ();
|
||||||
break;
|
break;
|
||||||
|
@ -862,6 +862,9 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr)
|
|||||||
if(i!=count)
|
if(i!=count)
|
||||||
validcount=0;
|
validcount=0;
|
||||||
|
|
||||||
|
if (opt.with_colons && opt.batch)
|
||||||
|
break;
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if(show_prompt(desc,i,validcount?count:0,localstr))
|
if(show_prompt(desc,i,validcount?count:0,localstr))
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
2009-06-17 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* iso7816.c (iso7816_get_data): Add arg EXTENDED_MODE. Change all
|
||||||
|
callers.
|
||||||
|
* app-openpgp.c (data_objects): Use bit flags. Add flag
|
||||||
|
TRY_EXTLENGTH.
|
||||||
|
(get_cached_data): Add arg TRY_EXTLEN and use it for iso7816_get_data.
|
||||||
|
(get_one_do): Use extended length APDU if necessary.
|
||||||
|
|
||||||
|
2009-06-10 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* app-openpgp.c (store_fpr): Change first arg to app_t; adjust
|
||||||
|
callers. Flush the cache.
|
||||||
|
|
||||||
2009-06-09 Werner Koch <wk@g10code.com>
|
2009-06-09 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* app-openpgp.c (do_readcert): Return NOT_FOUND if the retrieved
|
* app-openpgp.c (do_readcert): Return NOT_FOUND if the retrieved
|
||||||
|
@ -75,43 +75,45 @@ static struct {
|
|||||||
int tag;
|
int tag;
|
||||||
int constructed;
|
int constructed;
|
||||||
int get_from; /* Constructed DO with this DO or 0 for direct access. */
|
int get_from; /* Constructed DO with this DO or 0 for direct access. */
|
||||||
int binary;
|
int binary:1;
|
||||||
int dont_cache;
|
int dont_cache:1;
|
||||||
int flush_on_error;
|
int flush_on_error:1;
|
||||||
int get_immediate_in_v11; /* Enable a hack to bypass the cache of
|
int get_immediate_in_v11:1; /* Enable a hack to bypass the cache of
|
||||||
this data object if it is used in 1.1
|
this data object if it is used in 1.1
|
||||||
and later versions of the card. This
|
and later versions of the card. This
|
||||||
does not work with composite DO and is
|
does not work with composite DO and
|
||||||
currently only useful for the CHV
|
is currently only useful for the CHV
|
||||||
status bytes. */
|
status bytes. */
|
||||||
|
int try_extlen:1; /* Large object; try to use an extended
|
||||||
|
length APDU. */
|
||||||
char *desc;
|
char *desc;
|
||||||
} data_objects[] = {
|
} data_objects[] = {
|
||||||
{ 0x005E, 0, 0, 1, 0, 0, 0, "Login Data" },
|
{ 0x005E, 0, 0, 1, 0, 0, 0, 0, "Login Data" },
|
||||||
{ 0x5F50, 0, 0, 0, 0, 0, 0, "URL" },
|
{ 0x5F50, 0, 0, 0, 0, 0, 0, 0, "URL" },
|
||||||
{ 0x5F52, 0, 0, 1, 0, 0, 0, "Historical Bytes" },
|
{ 0x5F52, 0, 0, 1, 0, 0, 0, 0, "Historical Bytes" },
|
||||||
{ 0x0065, 1, 0, 1, 0, 0, 0, "Cardholder Related Data"},
|
{ 0x0065, 1, 0, 1, 0, 0, 0, 0, "Cardholder Related Data"},
|
||||||
{ 0x005B, 0, 0x65, 0, 0, 0, 0, "Name" },
|
{ 0x005B, 0, 0x65, 0, 0, 0, 0, 0, "Name" },
|
||||||
{ 0x5F2D, 0, 0x65, 0, 0, 0, 0, "Language preferences" },
|
{ 0x5F2D, 0, 0x65, 0, 0, 0, 0, 0, "Language preferences" },
|
||||||
{ 0x5F35, 0, 0x65, 0, 0, 0, 0, "Sex" },
|
{ 0x5F35, 0, 0x65, 0, 0, 0, 0, 0, "Sex" },
|
||||||
{ 0x006E, 1, 0, 1, 0, 0, 0, "Application Related Data" },
|
{ 0x006E, 1, 0, 1, 0, 0, 0, 0, "Application Related Data" },
|
||||||
{ 0x004F, 0, 0x6E, 1, 0, 0, 0, "AID" },
|
{ 0x004F, 0, 0x6E, 1, 0, 0, 0, 0, "AID" },
|
||||||
{ 0x0073, 1, 0, 1, 0, 0, 0, "Discretionary Data Objects" },
|
{ 0x0073, 1, 0, 1, 0, 0, 0, 0, "Discretionary Data Objects" },
|
||||||
{ 0x0047, 0, 0x6E, 1, 1, 0, 0, "Card Capabilities" },
|
{ 0x0047, 0, 0x6E, 1, 1, 0, 0, 0, "Card Capabilities" },
|
||||||
{ 0x00C0, 0, 0x6E, 1, 1, 0, 0, "Extended Card Capabilities" },
|
{ 0x00C0, 0, 0x6E, 1, 1, 0, 0, 0, "Extended Card Capabilities" },
|
||||||
{ 0x00C1, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Signature" },
|
{ 0x00C1, 0, 0x6E, 1, 1, 0, 0, 0, "Algorithm Attributes Signature" },
|
||||||
{ 0x00C2, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Decryption" },
|
{ 0x00C2, 0, 0x6E, 1, 1, 0, 0, 0, "Algorithm Attributes Decryption" },
|
||||||
{ 0x00C3, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Authentication" },
|
{ 0x00C3, 0, 0x6E, 1, 1, 0, 0, 0, "Algorithm Attributes Authentication" },
|
||||||
{ 0x00C4, 0, 0x6E, 1, 0, 1, 1, "CHV Status Bytes" },
|
{ 0x00C4, 0, 0x6E, 1, 0, 1, 1, 0, "CHV Status Bytes" },
|
||||||
{ 0x00C5, 0, 0x6E, 1, 0, 0, 0, "Fingerprints" },
|
{ 0x00C5, 0, 0x6E, 1, 0, 0, 0, 0, "Fingerprints" },
|
||||||
{ 0x00C6, 0, 0x6E, 1, 0, 0, 0, "CA Fingerprints" },
|
{ 0x00C6, 0, 0x6E, 1, 0, 0, 0, 0, "CA Fingerprints" },
|
||||||
{ 0x00CD, 0, 0x6E, 1, 0, 0, 0, "Generation time" },
|
{ 0x00CD, 0, 0x6E, 1, 0, 0, 0, 0, "Generation time" },
|
||||||
{ 0x007A, 1, 0, 1, 0, 0, 0, "Security Support Template" },
|
{ 0x007A, 1, 0, 1, 0, 0, 0, 0, "Security Support Template" },
|
||||||
{ 0x0093, 0, 0x7A, 1, 1, 0, 0, "Digital Signature Counter" },
|
{ 0x0093, 0, 0x7A, 1, 1, 0, 0, 0, "Digital Signature Counter" },
|
||||||
{ 0x0101, 0, 0, 0, 0, 0, 0, "Private DO 1"},
|
{ 0x0101, 0, 0, 0, 0, 0, 0, 0, "Private DO 1"},
|
||||||
{ 0x0102, 0, 0, 0, 0, 0, 0, "Private DO 2"},
|
{ 0x0102, 0, 0, 0, 0, 0, 0, 0, "Private DO 2"},
|
||||||
{ 0x0103, 0, 0, 0, 0, 0, 0, "Private DO 3"},
|
{ 0x0103, 0, 0, 0, 0, 0, 0, 0, "Private DO 3"},
|
||||||
{ 0x0104, 0, 0, 0, 0, 0, 0, "Private DO 4"},
|
{ 0x0104, 0, 0, 0, 0, 0, 0, 0, "Private DO 4"},
|
||||||
{ 0x7F21, 1, 0, 1, 0, 0, 0, "Cardholder certificate"},
|
{ 0x7F21, 1, 0, 1, 0, 0, 0, 1, "Cardholder certificate"},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -244,17 +246,19 @@ do_deinit (app_t app)
|
|||||||
|
|
||||||
/* Wrapper around iso7816_get_data which first tries to get the data
|
/* Wrapper around iso7816_get_data which first tries to get the data
|
||||||
from the cache. With GET_IMMEDIATE passed as true, the cache is
|
from the cache. With GET_IMMEDIATE passed as true, the cache is
|
||||||
bypassed. */
|
bypassed. With TRY_EXTLEN extended lengths APDUs are use if
|
||||||
|
supported by the card. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
get_cached_data (app_t app, int tag,
|
get_cached_data (app_t app, int tag,
|
||||||
unsigned char **result, size_t *resultlen,
|
unsigned char **result, size_t *resultlen,
|
||||||
int get_immediate)
|
int get_immediate, int try_extlen)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int i;
|
int i;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
size_t len;
|
size_t len;
|
||||||
struct cache_s *c;
|
struct cache_s *c;
|
||||||
|
int exmode;
|
||||||
|
|
||||||
*result = NULL;
|
*result = NULL;
|
||||||
*resultlen = 0;
|
*resultlen = 0;
|
||||||
@ -279,7 +283,12 @@ get_cached_data (app_t app, int tag,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = iso7816_get_data (app->slot, tag, &p, &len);
|
if (try_extlen && app->app_local->cardcap.ext_lc_le)
|
||||||
|
exmode = app->app_local->extcap.max_rsp_data;
|
||||||
|
else
|
||||||
|
exmode = 0;
|
||||||
|
|
||||||
|
err = iso7816_get_data (app->slot, exmode, tag, &p, &len);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
*result = p;
|
*result = p;
|
||||||
@ -392,6 +401,7 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
|
|||||||
unsigned char *value;
|
unsigned char *value;
|
||||||
size_t valuelen;
|
size_t valuelen;
|
||||||
int dummyrc;
|
int dummyrc;
|
||||||
|
int exmode;
|
||||||
|
|
||||||
if (!r_rc)
|
if (!r_rc)
|
||||||
r_rc = &dummyrc;
|
r_rc = &dummyrc;
|
||||||
@ -404,7 +414,11 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
|
|||||||
|
|
||||||
if (app->card_version > 0x0100 && data_objects[i].get_immediate_in_v11)
|
if (app->card_version > 0x0100 && data_objects[i].get_immediate_in_v11)
|
||||||
{
|
{
|
||||||
rc = iso7816_get_data (app->slot, tag, &buffer, &buflen);
|
if (data_objects[i].try_extlen && app->app_local->cardcap.ext_lc_le)
|
||||||
|
exmode = app->app_local->extcap.max_rsp_data;
|
||||||
|
else
|
||||||
|
exmode = 0;
|
||||||
|
rc = iso7816_get_data (app->slot, exmode, tag, &buffer, &buflen);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
*r_rc = rc;
|
*r_rc = rc;
|
||||||
@ -422,7 +436,8 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
|
|||||||
rc = get_cached_data (app, data_objects[i].get_from,
|
rc = get_cached_data (app, data_objects[i].get_from,
|
||||||
&buffer, &buflen,
|
&buffer, &buflen,
|
||||||
(data_objects[i].dont_cache
|
(data_objects[i].dont_cache
|
||||||
|| data_objects[i].get_immediate_in_v11));
|
|| data_objects[i].get_immediate_in_v11),
|
||||||
|
data_objects[i].try_extlen);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
const unsigned char *s;
|
const unsigned char *s;
|
||||||
@ -445,7 +460,8 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
|
|||||||
{
|
{
|
||||||
rc = get_cached_data (app, tag, &buffer, &buflen,
|
rc = get_cached_data (app, tag, &buffer, &buflen,
|
||||||
(data_objects[i].dont_cache
|
(data_objects[i].dont_cache
|
||||||
|| data_objects[i].get_immediate_in_v11));
|
|| data_objects[i].get_immediate_in_v11),
|
||||||
|
data_objects[i].try_extlen);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
value = buffer;
|
value = buffer;
|
||||||
@ -476,7 +492,9 @@ dump_all_do (int slot)
|
|||||||
if (data_objects[i].get_from)
|
if (data_objects[i].get_from)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rc = iso7816_get_data (slot, data_objects[i].tag, &buffer, &buflen);
|
/* We don't try extended length APDU because such large DO would
|
||||||
|
be pretty useless in a log file. */
|
||||||
|
rc = iso7816_get_data (slot, 0, data_objects[i].tag, &buffer, &buflen);
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NO_OBJ)
|
if (gpg_err_code (rc) == GPG_ERR_NO_OBJ)
|
||||||
;
|
;
|
||||||
else if (rc)
|
else if (rc)
|
||||||
@ -621,13 +639,14 @@ parse_login_data (app_t app)
|
|||||||
|
|
||||||
/* Note, that FPR must be at least 20 bytes. */
|
/* Note, that FPR must be at least 20 bytes. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
store_fpr (int slot, int keynumber, u32 timestamp,
|
store_fpr (app_t app, int keynumber, u32 timestamp,
|
||||||
const unsigned char *m, size_t mlen,
|
const unsigned char *m, size_t mlen,
|
||||||
const unsigned char *e, size_t elen,
|
const unsigned char *e, size_t elen,
|
||||||
unsigned char *fpr, unsigned int card_version)
|
unsigned char *fpr, unsigned int card_version)
|
||||||
{
|
{
|
||||||
unsigned int n, nbits;
|
unsigned int n, nbits;
|
||||||
unsigned char *buffer, *p;
|
unsigned char *buffer, *p;
|
||||||
|
int tag, tag2;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */
|
for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */
|
||||||
@ -662,9 +681,12 @@ store_fpr (int slot, int keynumber, u32 timestamp,
|
|||||||
|
|
||||||
xfree (buffer);
|
xfree (buffer);
|
||||||
|
|
||||||
rc = iso7816_put_data (slot, 0,
|
tag = (card_version > 0x0007? 0xC7 : 0xC6) + keynumber;
|
||||||
(card_version > 0x0007? 0xC7 : 0xC6)
|
flush_cache_item (app, tag);
|
||||||
+ keynumber, fpr, 20);
|
tag2 = 0xCE + keynumber;
|
||||||
|
flush_cache_item (app, tag2);
|
||||||
|
|
||||||
|
rc = iso7816_put_data (app->slot, 0, tag, fpr, 20);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error (_("failed to store the fingerprint: %s\n"),gpg_strerror (rc));
|
log_error (_("failed to store the fingerprint: %s\n"),gpg_strerror (rc));
|
||||||
|
|
||||||
@ -677,7 +699,7 @@ store_fpr (int slot, int keynumber, u32 timestamp,
|
|||||||
buf[2] = timestamp >> 8;
|
buf[2] = timestamp >> 8;
|
||||||
buf[3] = timestamp;
|
buf[3] = timestamp;
|
||||||
|
|
||||||
rc = iso7816_put_data (slot, 0, 0xCE + keynumber, buf, 4);
|
rc = iso7816_put_data (app->slot, 0, tag2, buf, 4);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error (_("failed to store the creation date: %s\n"),
|
log_error (_("failed to store the creation date: %s\n"),
|
||||||
gpg_strerror (rc));
|
gpg_strerror (rc));
|
||||||
@ -2131,7 +2153,7 @@ does_key_exist (app_t app, int keyidx, int force)
|
|||||||
|
|
||||||
assert (keyidx >=0 && keyidx <= 2);
|
assert (keyidx >=0 && keyidx <= 2);
|
||||||
|
|
||||||
if (iso7816_get_data (app->slot, 0x006E, &buffer, &buflen))
|
if (iso7816_get_data (app->slot, 0, 0x006E, &buffer, &buflen))
|
||||||
{
|
{
|
||||||
log_error (_("error reading application data\n"));
|
log_error (_("error reading application data\n"));
|
||||||
return gpg_error (GPG_ERR_GENERAL);
|
return gpg_error (GPG_ERR_GENERAL);
|
||||||
@ -2623,7 +2645,7 @@ do_writekey (app_t app, ctrl_t ctrl,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = store_fpr (app->slot, keyno, created_at,
|
err = store_fpr (app, keyno, created_at,
|
||||||
rsa_n, rsa_n_len, rsa_e, rsa_e_len,
|
rsa_n, rsa_n_len, rsa_e, rsa_e_len,
|
||||||
fprbuf, app->card_version);
|
fprbuf, app->card_version);
|
||||||
if (err)
|
if (err)
|
||||||
@ -2757,7 +2779,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
|||||||
send_status_info (ctrl, "KEY-CREATED-AT",
|
send_status_info (ctrl, "KEY-CREATED-AT",
|
||||||
numbuf, (size_t)strlen(numbuf), NULL, 0);
|
numbuf, (size_t)strlen(numbuf), NULL, 0);
|
||||||
|
|
||||||
rc = store_fpr (app->slot, keyno, (u32)created_at,
|
rc = store_fpr (app, keyno, (u32)created_at,
|
||||||
m, mlen, e, elen, fprbuf, app->card_version);
|
m, mlen, e, elen, fprbuf, app->card_version);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -2811,7 +2833,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
|
|||||||
|
|
||||||
assert (keyno >= 1 && keyno <= 3);
|
assert (keyno >= 1 && keyno <= 3);
|
||||||
|
|
||||||
rc = get_cached_data (app, 0x006E, &buffer, &buflen, 0);
|
rc = get_cached_data (app, 0x006E, &buffer, &buflen, 0, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error (_("error reading application data\n"));
|
log_error (_("error reading application data\n"));
|
||||||
@ -3502,7 +3524,7 @@ app_select_openpgp (app_t app)
|
|||||||
replace a possibly already set one from a EF.GDO with this
|
replace a possibly already set one from a EF.GDO with this
|
||||||
one. Note, that for current OpenPGP cards, no EF.GDO exists
|
one. Note, that for current OpenPGP cards, no EF.GDO exists
|
||||||
and thus it won't matter at all. */
|
and thus it won't matter at all. */
|
||||||
rc = iso7816_get_data (slot, 0x004F, &buffer, &buflen);
|
rc = iso7816_get_data (slot, 0, 0x004F, &buffer, &buflen);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
|
@ -420,19 +420,27 @@ iso7816_reset_retry_counter (int slot, int chvno,
|
|||||||
a newly allocated buffer at the address passed by RESULT. Return
|
a newly allocated buffer at the address passed by RESULT. Return
|
||||||
the length of this data at the address of RESULTLEN. */
|
the length of this data at the address of RESULTLEN. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
iso7816_get_data (int slot, int tag,
|
iso7816_get_data (int slot, int extended_mode, int tag,
|
||||||
unsigned char **result, size_t *resultlen)
|
unsigned char **result, size_t *resultlen)
|
||||||
{
|
{
|
||||||
int sw;
|
int sw;
|
||||||
|
int le;
|
||||||
|
|
||||||
if (!result || !resultlen)
|
if (!result || !resultlen)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
*result = NULL;
|
*result = NULL;
|
||||||
*resultlen = 0;
|
*resultlen = 0;
|
||||||
|
|
||||||
sw = apdu_send (slot, 0, 0x00, CMD_GET_DATA,
|
if (extended_mode > 0 && extended_mode < 256)
|
||||||
((tag >> 8) & 0xff), (tag & 0xff), -1, NULL,
|
le = 65534; /* Not 65535 in case it is used as some special flag. */
|
||||||
result, resultlen);
|
else if (extended_mode > 0)
|
||||||
|
le = extended_mode;
|
||||||
|
else
|
||||||
|
le = 256;
|
||||||
|
|
||||||
|
sw = apdu_send_le (slot, extended_mode, 0x00, CMD_GET_DATA,
|
||||||
|
((tag >> 8) & 0xff), (tag & 0xff), -1, NULL, le,
|
||||||
|
result, resultlen);
|
||||||
if (sw != SW_SUCCESS)
|
if (sw != SW_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Make sure that pending buffers are released. */
|
/* Make sure that pending buffers are released. */
|
||||||
|
@ -84,7 +84,7 @@ gpg_error_t iso7816_reset_retry_counter_kp (int slot, int chvno,
|
|||||||
gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno,
|
gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno,
|
||||||
const char *data,
|
const char *data,
|
||||||
size_t datalen);
|
size_t datalen);
|
||||||
gpg_error_t iso7816_get_data (int slot, int tag,
|
gpg_error_t iso7816_get_data (int slot, int extended_mode, int tag,
|
||||||
unsigned char **result, size_t *resultlen);
|
unsigned char **result, size_t *resultlen);
|
||||||
gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag,
|
gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag,
|
||||||
const unsigned char *data, size_t datalen);
|
const unsigned char *data, size_t datalen);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user