From ec9e8e0d6a1fe47dbf42652c4246e1c34fdf0288 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 25 Nov 2020 15:27:21 +0100 Subject: [PATCH] scd: Extend ISO binary and record reading functions. * scd/iso7816.c (iso7816_read_binary_ext): Add optional arg r_sw and change callers. (iso7816_read_record): Factor all code out to ... (iso7816_read_record_ext): New. Signed-off-by: Werner Koch --- scd/app-p15.c | 2 +- scd/iso7816.c | 39 +++++++++++++++++++++++++++++++-------- scd/iso7816.h | 7 ++++++- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 53e122206..21f7726cd 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -2917,7 +2917,7 @@ readcert_by_cdf (app_t app, cdf_object_t cdf, goto leave; err = iso7816_read_binary_ext (app_get_slot (app), 1, cdf->off, cdf->len, - &buffer, &buflen); + &buffer, &buflen, NULL); if (!err && (!buflen || *buffer == 0xff)) err = gpg_error (GPG_ERR_NOT_FOUND); if (err) diff --git a/scd/iso7816.c b/scd/iso7816.c index 20706706c..d996eef39 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -786,13 +786,15 @@ iso7816_get_challenge (int slot, int length, unsigned char *buffer) } /* Perform a READ BINARY command requesting a maximum of NMAX bytes - from OFFSET. With NMAX = 0 the entire file is read. The result is - stored in a newly allocated buffer at the address passed by RESULT. - Returns the length of this data at the address of RESULTLEN. */ + * from OFFSET. With NMAX = 0 the entire file is read. The result is + * stored in a newly allocated buffer at the address passed by RESULT. + * Returns the length of this data at the address of RESULTLEN. If + * R_SW is not NULL the last status word is stored there. */ gpg_error_t iso7816_read_binary_ext (int slot, int extended_mode, size_t offset, size_t nmax, - unsigned char **result, size_t *resultlen) + unsigned char **result, size_t *resultlen, + int *r_sw) { int sw; unsigned char *buffer; @@ -800,6 +802,9 @@ iso7816_read_binary_ext (int slot, int extended_mode, int read_all = !nmax; size_t n; + if (r_sw) + *r_sw = 0; + if (!result || !resultlen) return gpg_error (GPG_ERR_INV_VALUE); *result = NULL; @@ -825,6 +830,8 @@ iso7816_read_binary_ext (int slot, int extended_mode, ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL, n, &buffer, &bufferlen); } + if (r_sw) + *r_sw = sw; if (*result && sw == SW_BAD_P0_P1) { @@ -885,7 +892,8 @@ gpg_error_t iso7816_read_binary (int slot, size_t offset, size_t nmax, unsigned char **result, size_t *resultlen) { - return iso7816_read_binary_ext (slot, 0, offset, nmax, result, resultlen); + return iso7816_read_binary_ext (slot, 0, offset, nmax, + result, resultlen, NULL); } @@ -895,15 +903,20 @@ iso7816_read_binary (int slot, size_t offset, size_t nmax, should be 0 to read the current EF or contain a short EF. The result is stored in a newly allocated buffer at the address passed by RESULT. Returns the length of this data at the address of - RESULTLEN. */ + RESULTLEN. If R_SW is not NULL the last status word is stored + there. */ gpg_error_t -iso7816_read_record (int slot, int recno, int reccount, int short_ef, - unsigned char **result, size_t *resultlen) +iso7816_read_record_ext (int slot, int recno, int reccount, int short_ef, + unsigned char **result, size_t *resultlen, + int *r_sw) { int sw; unsigned char *buffer; size_t bufferlen; + if (r_sw) + *r_sw = 0; + if (!result || !resultlen) return gpg_error (GPG_ERR_INV_VALUE); *result = NULL; @@ -922,6 +935,8 @@ iso7816_read_record (int slot, int recno, int reccount, int short_ef, short_ef? short_ef : 0x04, -1, NULL, 0, &buffer, &bufferlen); + if (r_sw) + *r_sw = sw; if (sw != SW_SUCCESS && sw != SW_EOF_REACHED) { @@ -937,3 +952,11 @@ iso7816_read_record (int slot, int recno, int reccount, int short_ef, return 0; } + +gpg_error_t +iso7816_read_record (int slot, int recno, int reccount, int short_ef, + unsigned char **result, size_t *resultlen) +{ + return iso7816_read_record_ext (slot, recno, reccount, short_ef, + result, resultlen, NULL); +} diff --git a/scd/iso7816.h b/scd/iso7816.h index bad558d0a..2cbfe6185 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -135,9 +135,14 @@ gpg_error_t iso7816_get_challenge (int slot, gpg_error_t iso7816_read_binary_ext (int slot, int extended_mode, size_t offset, size_t nmax, - unsigned char **result, size_t *resultlen); + unsigned char **result, size_t *resultlen, + int *r_sw); gpg_error_t iso7816_read_binary (int slot, size_t offset, size_t nmax, unsigned char **result, size_t *resultlen); +gpg_error_t iso7816_read_record_ext (int slot, int recno, int reccount, + int short_ef, + unsigned char **result, size_t *resultlen, + int *r_sw); gpg_error_t iso7816_read_record (int slot, int recno, int reccount, int short_ef, unsigned char **result, size_t *resultlen);