mirror of
git://git.gnupg.org/gnupg.git
synced 2024-06-14 00:19:50 +02:00
Added command APDU
This commit is contained in:
parent
76cb368202
commit
c664309a0a
|
@ -347,6 +347,8 @@ syncronizing access to a token between sessions.
|
||||||
* Scdaemon RANDOM:: Return random bytes generate on-card.
|
* Scdaemon RANDOM:: Return random bytes generate on-card.
|
||||||
* Scdaemon PASSWD:: Change PINs.
|
* Scdaemon PASSWD:: Change PINs.
|
||||||
* Scdaemon CHECKPIN:: Perform a VERIFY operation.
|
* Scdaemon CHECKPIN:: Perform a VERIFY operation.
|
||||||
|
* Scdaemon RESTART:: Restart connection
|
||||||
|
* Scdaemon APDU:: Send a verbatim APDU to the card
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Scdaemon SERIALNO
|
@node Scdaemon SERIALNO
|
||||||
|
@ -553,3 +555,47 @@ and only if the retry counter is still at 3.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@node Scdaemon RESTART
|
||||||
|
@subsection Perform a RESTART operation.
|
||||||
|
|
||||||
|
@example
|
||||||
|
RESTART
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Restart the current connection; this is a kind of warm reset. It
|
||||||
|
deletes the context used by this connection but does not actually
|
||||||
|
reset the card.
|
||||||
|
|
||||||
|
This is used by gpg-agent to reuse a primary pipe connection and
|
||||||
|
may be used by clients to backup from a conflict in the serial
|
||||||
|
command; i.e. to select another application.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@node Scdaemon APDU
|
||||||
|
@subsection Send a verbatim APDU to the card.
|
||||||
|
|
||||||
|
@example
|
||||||
|
APDU [--atr] [--more] [@var{hexstring}]
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
|
Send an APDU to the current reader. This command bypasses the high
|
||||||
|
level functions and sends the data directly to the card.
|
||||||
|
@var{hexstring} is expected to be a proper APDU. If @var{hexstring} is
|
||||||
|
not given no commands are send to the card; However the command will
|
||||||
|
implictly check whether the card is ready for use.
|
||||||
|
|
||||||
|
Using the option @code{--atr} returns the ATR of the card as a status
|
||||||
|
message before any data like this:
|
||||||
|
@example
|
||||||
|
S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Using the option @code{--more} handles the card status word MORE_DATA
|
||||||
|
(61xx) and concatenate all reponses to one block.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
2006-04-11 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* command.c (hex_to_buffer): New.
|
||||||
|
(cmd_apdu): New.
|
||||||
|
|
||||||
|
2006-04-03 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* scdaemon.c [__GLIBC__]: Default to libpcsclite.so.1.
|
||||||
|
|
||||||
2006-03-21 Werner Koch <wk@g10code.com>
|
2006-03-21 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* command.c (cmd_pksign): Add --hash option.
|
* command.c (cmd_pksign): Add --hash option.
|
||||||
|
|
|
@ -2848,8 +2848,8 @@ apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1,
|
||||||
HANDLE_MORE set to true this function will handle the MORE DATA
|
HANDLE_MORE set to true this function will handle the MORE DATA
|
||||||
status and return all APDUs concatenated with one status word at
|
status and return all APDUs concatenated with one status word at
|
||||||
the end. The function does not return a regular status word but 0
|
the end. The function does not return a regular status word but 0
|
||||||
on success. If the slot is locked, the fucntion returns
|
on success. If the slot is locked, the function returns
|
||||||
immediately.*/
|
immediately with an error. */
|
||||||
int
|
int
|
||||||
apdu_send_direct (int slot, const unsigned char *apdudata, size_t apdudatalen,
|
apdu_send_direct (int slot, const unsigned char *apdudata, size_t apdudatalen,
|
||||||
int handle_more,
|
int handle_more,
|
||||||
|
|
|
@ -112,8 +112,8 @@ struct app_local_s {
|
||||||
encoded S-expression encoding a public
|
encoded S-expression encoding a public
|
||||||
key. Might be NULL if key is not
|
key. Might be NULL if key is not
|
||||||
available. */
|
available. */
|
||||||
size_t keylen; /* The length of the above S-expression. Thsi
|
size_t keylen; /* The length of the above S-expression. This
|
||||||
is usullay only required for corss checks
|
is usullay only required for cross checks
|
||||||
because the length of an S-expression is
|
because the length of an S-expression is
|
||||||
implicitly available. */
|
implicitly available. */
|
||||||
} pk[3];
|
} pk[3];
|
||||||
|
|
128
scd/command.c
128
scd/command.c
|
@ -156,6 +156,38 @@ has_option (const char *line, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert the STRING into a newly allocated buffer while translating
|
||||||
|
the hex numbers. Stops at the first invalid character. Blanks and
|
||||||
|
colons are allowed to separate the hex digits. Returns NULL on
|
||||||
|
error or a newly malloced buffer and its length in LENGTH. */
|
||||||
|
static unsigned char *
|
||||||
|
hex_to_buffer (const char *string, size_t *r_length)
|
||||||
|
{
|
||||||
|
unsigned char *buffer;
|
||||||
|
const char *s;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
buffer = xtrymalloc (strlen (string)+1);
|
||||||
|
if (!buffer)
|
||||||
|
return NULL;
|
||||||
|
for (s=string, n=0; *s; s++)
|
||||||
|
{
|
||||||
|
if (spacep (s) || *s == ':')
|
||||||
|
continue;
|
||||||
|
if (hexdigitp (s) && hexdigitp (s+1))
|
||||||
|
{
|
||||||
|
buffer[n++] = xtoi_2 (s);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*r_length = n;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Reset the card and free the application context. With SEND_RESET
|
/* Reset the card and free the application context. With SEND_RESET
|
||||||
set to true actually send a RESET to the reader. */
|
set to true actually send a RESET to the reader. */
|
||||||
static void
|
static void
|
||||||
|
@ -1372,6 +1404,101 @@ cmd_restart (assuan_context_t ctx, char *line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* APDU [--atr] [--more] [hexstring]
|
||||||
|
|
||||||
|
Send an APDU to the current reader. This command bypasses the high
|
||||||
|
level functions and sends the data directly to the card. HEXSTRING
|
||||||
|
is expected to be a proper APDU. If HEXSTRING is not given no
|
||||||
|
commands are set to the card but the command will implictly check
|
||||||
|
whether the card is ready for use.
|
||||||
|
|
||||||
|
Using the option "--atr" returns the ATR of the card as a status
|
||||||
|
message before any data like this:
|
||||||
|
S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
|
||||||
|
|
||||||
|
Using the option --more handles the card status word MORE_DATA
|
||||||
|
(61xx) and concatenate all reponses to one block.
|
||||||
|
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cmd_apdu (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
int rc;
|
||||||
|
int rc_is_assuan = 0;
|
||||||
|
unsigned char *apdu;
|
||||||
|
size_t apdulen;
|
||||||
|
int with_atr;
|
||||||
|
int handle_more;
|
||||||
|
|
||||||
|
with_atr = has_option (line, "--atr");
|
||||||
|
handle_more = has_option (line, "--more");
|
||||||
|
|
||||||
|
/* Skip over options. */
|
||||||
|
while ( *line == '-' && line[1] == '-' )
|
||||||
|
{
|
||||||
|
while (*line && !spacep (line))
|
||||||
|
line++;
|
||||||
|
while (spacep (line))
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IS_LOCKED (ctrl) )
|
||||||
|
return gpg_error (GPG_ERR_LOCKED);
|
||||||
|
|
||||||
|
if ((rc = open_card (ctrl, NULL)))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (with_atr)
|
||||||
|
{
|
||||||
|
unsigned char *atr;
|
||||||
|
size_t atrlen;
|
||||||
|
int i;
|
||||||
|
char hexbuf[400];
|
||||||
|
|
||||||
|
atr = apdu_get_atr (ctrl->reader_slot, &atrlen);
|
||||||
|
if (!atr || atrlen > sizeof hexbuf - 2 )
|
||||||
|
{
|
||||||
|
rc = gpg_error (GPG_ERR_INV_CARD);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
for (i=0; i < atrlen; i++)
|
||||||
|
sprintf (hexbuf+2*i, "%02X", atr[i]);
|
||||||
|
xfree (atr);
|
||||||
|
send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
apdu = hex_to_buffer (line, &apdulen);
|
||||||
|
if (!apdu)
|
||||||
|
{
|
||||||
|
rc = gpg_error_from_errno (errno);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (apdulen)
|
||||||
|
{
|
||||||
|
unsigned char *result = NULL;
|
||||||
|
size_t resultlen;
|
||||||
|
|
||||||
|
rc = apdu_send_direct (ctrl->reader_slot, apdu, apdulen, handle_more,
|
||||||
|
&result, &resultlen);
|
||||||
|
if (rc)
|
||||||
|
log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc_is_assuan = 1;
|
||||||
|
rc = assuan_send_data (ctx, result, resultlen);
|
||||||
|
xfree (result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xfree (apdu);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
TEST_CARD_REMOVAL (ctrl, rc);
|
||||||
|
return rc_is_assuan? rc : map_to_assuan_status (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Tell the assuan library about our commands */
|
/* Tell the assuan library about our commands */
|
||||||
|
@ -1403,6 +1530,7 @@ register_commands (assuan_context_t ctx)
|
||||||
{ "UNLOCK", cmd_unlock },
|
{ "UNLOCK", cmd_unlock },
|
||||||
{ "GETINFO", cmd_getinfo },
|
{ "GETINFO", cmd_getinfo },
|
||||||
{ "RESTART", cmd_restart },
|
{ "RESTART", cmd_restart },
|
||||||
|
{ "APDU", cmd_apdu },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
|
@ -139,6 +139,8 @@ static ARGPARSE_OPTS opts[] = {
|
||||||
/* The card dirver we use by default for PC/SC. */
|
/* The card dirver we use by default for PC/SC. */
|
||||||
#if defined(HAVE_W32_SYSTEM) || defined(__CYGWIN__)
|
#if defined(HAVE_W32_SYSTEM) || defined(__CYGWIN__)
|
||||||
#define DEFAULT_PCSC_DRIVER "winscard.dll"
|
#define DEFAULT_PCSC_DRIVER "winscard.dll"
|
||||||
|
#elif defined(__GLIBC__)
|
||||||
|
#define DEFAULT_PCSC_DRIVER "libpcsclite.so.1"
|
||||||
#else
|
#else
|
||||||
#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
|
#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user