mirror of
git://git.gnupg.org/gnupg.git
synced 2024-06-20 01:02:44 +02:00
card: New command 'authenticate'.
* tools/card-tool-misc.c (hex_to_buffer): New. * tools/gpg-card-tool.c (get_data_from_file): Change to allow returning a string. (cmd_authenticate): New. (cmds): Add command "authenticate". Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
1d57450f3e
commit
da38325740
|
@ -42,3 +42,38 @@ find_kinfo (card_info_t info, const char *keyref)
|
||||||
return kinfo;
|
return kinfo;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert STRING into a newly allocated buffer while translating the
|
||||||
|
* hex numbers. Blanks and colons are allowed to separate pairs of
|
||||||
|
* hex digits. Returns NULL on error or a newly malloced buffer and
|
||||||
|
* its length in LENGTH. */
|
||||||
|
void *
|
||||||
|
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 (ascii_isspace (*s) || *s == ':')
|
||||||
|
continue;
|
||||||
|
if (hexdigitp (s) && hexdigitp (s+1))
|
||||||
|
{
|
||||||
|
buffer[n++] = xtoi_2 (s);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xfree (buffer);
|
||||||
|
gpg_err_set_errno (EINVAL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*r_length = n;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
|
@ -189,6 +189,7 @@ gpg_error_t test_get_matching_keys (const char *hexgrip);
|
||||||
|
|
||||||
/*-- card-tool-misc.c --*/
|
/*-- card-tool-misc.c --*/
|
||||||
key_info_t find_kinfo (card_info_t info, const char *keyref);
|
key_info_t find_kinfo (card_info_t info, const char *keyref);
|
||||||
|
void *hex_to_buffer (const char *string, size_t *r_length);
|
||||||
|
|
||||||
|
|
||||||
/*-- card-call-scd.c --*/
|
/*-- card-call-scd.c --*/
|
||||||
|
|
|
@ -326,8 +326,11 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
/* Read data from file FNAME up to MAX_GET_DATA_FROM_FILE characters.
|
/* Read data from file FNAME up to MAX_GET_DATA_FROM_FILE characters.
|
||||||
* On error return an error code and stores NULL at R_BUFFER; on
|
* On error return an error code and stores NULL at R_BUFFER; on
|
||||||
* success returns 0, stpres the number of bytes read at R_BUFLEN and
|
* success returns 0 and stores the number of bytes read at R_BUFLEN
|
||||||
* the address of a newly allocated buffer at R_BUFFER. */
|
* and the address of a newly allocated buffer at R_BUFFER. A
|
||||||
|
* complementary nul byte is always appended to the data but not
|
||||||
|
* counted; this allows to pass NULL for R-BUFFER and consider the
|
||||||
|
* returned data as a string. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
get_data_from_file (const char *fname, char **r_buffer, size_t *r_buflen)
|
get_data_from_file (const char *fname, char **r_buffer, size_t *r_buflen)
|
||||||
{
|
{
|
||||||
|
@ -337,7 +340,8 @@ get_data_from_file (const char *fname, char **r_buffer, size_t *r_buflen)
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
*r_buffer = NULL;
|
*r_buffer = NULL;
|
||||||
*r_buflen = 0;
|
if (r_buflen)
|
||||||
|
*r_buflen = 0;
|
||||||
|
|
||||||
fp = es_fopen (fname, "rb");
|
fp = es_fopen (fname, "rb");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
|
@ -356,7 +360,7 @@ get_data_from_file (const char *fname, char **r_buffer, size_t *r_buflen)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = es_fread (data, 1, MAX_GET_DATA_FROM_FILE, fp);
|
n = es_fread (data, 1, MAX_GET_DATA_FROM_FILE - 1, fp);
|
||||||
es_fclose (fp);
|
es_fclose (fp);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
{
|
{
|
||||||
|
@ -365,8 +369,11 @@ get_data_from_file (const char *fname, char **r_buffer, size_t *r_buflen)
|
||||||
xfree (data);
|
xfree (data);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
data[n] = 0;
|
||||||
|
|
||||||
*r_buffer = data;
|
*r_buffer = data;
|
||||||
*r_buflen = n;
|
if (r_buflen)
|
||||||
|
*r_buflen = n;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,6 +958,73 @@ cmd_verify (card_info_t info, char *argstr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gpg_error_t
|
||||||
|
cmd_authenticate (card_info_t info, char *argstr)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
int opt_setkey;
|
||||||
|
int opt_raw;
|
||||||
|
char *string = NULL;
|
||||||
|
char *key = NULL;
|
||||||
|
size_t keylen;
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
return print_help
|
||||||
|
("AUTHENTICATE [--setkey] [--raw] [< FILE]|KEY\n\n"
|
||||||
|
"Perform a mutual autentication either by reading the key\n"
|
||||||
|
"from FILE or by taking it from the command line. Without\n"
|
||||||
|
"the option --raw the key is expected to be hex encoded.\n"
|
||||||
|
"To install a new administration key --setkey is used; this\n"
|
||||||
|
"requires a prior authentication with the old key.",
|
||||||
|
APP_TYPE_PIV, 0);
|
||||||
|
|
||||||
|
if (info->apptype != APP_TYPE_PIV)
|
||||||
|
{
|
||||||
|
log_info ("Note: This is a PIV only command.\n");
|
||||||
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_setkey = has_leading_option (argstr, "--setkey");
|
||||||
|
opt_raw = has_leading_option (argstr, "--raw");
|
||||||
|
argstr = skip_options (argstr);
|
||||||
|
|
||||||
|
if (*argstr == '<') /* Read key from a file. */
|
||||||
|
{
|
||||||
|
for (argstr++; spacep (argstr); argstr++)
|
||||||
|
;
|
||||||
|
err = get_data_from_file (argstr, &string, NULL);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_raw)
|
||||||
|
{
|
||||||
|
key = string? string : xstrdup (argstr);
|
||||||
|
string = NULL;
|
||||||
|
keylen = strlen (key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key = hex_to_buffer (string? string: argstr, &keylen);
|
||||||
|
if (!key)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = scd_setattr (opt_setkey? "SET-ADM-KEY":"AUTH-ADM-KEY", key, keylen);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if (key)
|
||||||
|
{
|
||||||
|
wipememory (key, keylen);
|
||||||
|
xfree (key);
|
||||||
|
}
|
||||||
|
xfree (string);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Helper for cmd_name to qyery a part of name. */
|
/* Helper for cmd_name to qyery a part of name. */
|
||||||
static char *
|
static char *
|
||||||
ask_one_name (const char *prompt)
|
ask_one_name (const char *prompt)
|
||||||
|
@ -2610,7 +2684,7 @@ enum cmdids
|
||||||
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSALUT, cmdCAFPR,
|
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSALUT, cmdCAFPR,
|
||||||
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
|
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
|
||||||
cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, cmdKDFSETUP,
|
cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, cmdKDFSETUP,
|
||||||
cmdKEYATTR, cmdUIF,
|
cmdKEYATTR, cmdUIF, cmdAUTHENTICATE,
|
||||||
cmdINVCMD
|
cmdINVCMD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2641,6 +2715,7 @@ static struct
|
||||||
{ "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
|
{ "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
|
||||||
{ "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
|
{ "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
|
||||||
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code")},
|
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code")},
|
||||||
|
{ "authenticate",cmdAUTHENTICATE, 0,N_("authenticate to the card")},
|
||||||
{ "reset" , cmdRESET, 0, N_("send a reset to the card daemon")},
|
{ "reset" , cmdRESET, 0, N_("send a reset to the card daemon")},
|
||||||
{ "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
|
{ "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
|
||||||
{ "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")},
|
{ "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")},
|
||||||
|
@ -2871,6 +2946,7 @@ interactive_loop (void)
|
||||||
if (!err)
|
if (!err)
|
||||||
redisplay = 1;
|
redisplay = 1;
|
||||||
break;
|
break;
|
||||||
|
case cmdAUTHENTICATE: err = cmd_authenticate (info, argstr); break;
|
||||||
case cmdNAME: err = cmd_name (info, argstr); break;
|
case cmdNAME: err = cmd_name (info, argstr); break;
|
||||||
case cmdURL: err = cmd_url (info, argstr); break;
|
case cmdURL: err = cmd_url (info, argstr); break;
|
||||||
case cmdFETCH: err = cmd_fetch (info); break;
|
case cmdFETCH: err = cmd_fetch (info); break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user