diff options
author | Werner Koch <wk@gnupg.org> | 2019-01-20 11:41:23 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2019-01-20 11:41:23 +0100 |
commit | 70bb5c7931598590b1acfae90bf4657f5911d2d3 (patch) | |
tree | 2528e900b7df2c1af710afb3a5bccc0e8e926e96 /scd/iso7816.c | |
parent | ssh: Simplify the curve name lookup. (diff) | |
download | gnupg2-70bb5c7931598590b1acfae90bf4657f5911d2d3.tar.xz gnupg2-70bb5c7931598590b1acfae90bf4657f5911d2d3.zip |
scd: One new and one improved 7816 function.
* scd/apdu.c (apdu_send_direct): New arg R_SW.
* scd/command.c (cmd_apdu): Ditto.
* scd/iso7816.c (iso7816_apdu_direct): New arg R_SW.
(iso7816_general_authenticate): New.
* scd/app-nks.c (get_chv_status, get_nks_version): Pass NULL for new
arg.
--
iso7816_general_authenticate will be used for the PIV card support.
The new arg to iso7816_apdu_direct and apdu_send_direct allows to get
the raw status word back without the need to handle an output buffer.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'scd/iso7816.c')
-rw-r--r-- | scd/iso7816.c | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/scd/iso7816.c b/scd/iso7816.c index 43c0bcd8e..c8a2138cb 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -50,6 +50,7 @@ #define CMD_PUT_DATA 0xDA #define CMD_MSE 0x22 #define CMD_PSO 0x2A +#define CMD_GENERAL_AUTHENTICATE 0x87 #define CMD_INTERNAL_AUTHENTICATE 0x88 #define CMD_GENERATE_KEYPAIR 0x47 #define CMD_GET_CHALLENGE 0x84 @@ -225,24 +226,28 @@ iso7816_list_directory (int slot, int list_dirs, internally. The return value is a gpg error code (i.e. a mapped status word). This is basically the same as apdu_send_direct but it maps the status word and does not return it in the result - buffer. */ + buffer. However, it R_SW is not NULL the status word is stored + R_SW for closer inspection. */ gpg_error_t iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen, - int handle_more, + int handle_more, unsigned int *r_sw, unsigned char **result, size_t *resultlen) { - int sw; + int sw, sw2; - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; + if (result) + { + *result = NULL; + *resultlen = 0; + } sw = apdu_send_direct (slot, 0, apdudata, apdudatalen, handle_more, - result, resultlen); + &sw2, result, resultlen); if (!sw) { - if (*resultlen < 2) + if (!result) + sw = sw2; + else if (*resultlen < 2) sw = SW_HOST_GENERAL_ERROR; else { @@ -251,13 +256,15 @@ iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen, (*resultlen)--; } } - if (sw != SW_SUCCESS) + if (sw != SW_SUCCESS && result) { /* Make sure that pending buffers are released. */ xfree (*result); *result = NULL; *resultlen = 0; } + if (r_sw) + *r_sw = sw; return map_sw (sw); } @@ -621,7 +628,7 @@ iso7816_decipher (int slot, int extended_mode, } -/* For LE see do_generate_keypair. */ +/* For LE see do_generate_keypair. */ gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode, const unsigned char *data, size_t datalen, @@ -658,6 +665,44 @@ iso7816_internal_authenticate (int slot, int extended_mode, } +/* For LE see do_generate_keypair. */ +gpg_error_t +iso7816_general_authenticate (int slot, int extended_mode, + int algoref, int keyref, + const unsigned char *data, size_t datalen, + int le, + unsigned char **result, size_t *resultlen) +{ + int sw; + + if (!data || !datalen || !result || !resultlen) + return gpg_error (GPG_ERR_INV_VALUE); + *result = NULL; + *resultlen = 0; + + if (!extended_mode) + le = 256; /* Ignore provided Le and use what apdu_send uses. */ + else if (le >= 0 && le < 256) + le = 256; + + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_GENERAL_AUTHENTICATE, algoref, keyref, + datalen, (const char*)data, + le, + result, resultlen); + if (sw != SW_SUCCESS) + { + /* Make sure that pending buffers are released. */ + xfree (*result); + *result = NULL; + *resultlen = 0; + return map_sw (sw); + } + + return 0; +} + + /* LE is the expected return length. This is usually 0 except if extended length mode is used and more than 256 byte will be returned. In that case a value of -1 uses a large default |