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 <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-11-25 15:27:21 +01:00
parent 1303b0ed84
commit ec9e8e0d6a
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 38 additions and 10 deletions

View File

@ -2917,7 +2917,7 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
goto leave; goto leave;
err = iso7816_read_binary_ext (app_get_slot (app), 1, cdf->off, cdf->len, err = iso7816_read_binary_ext (app_get_slot (app), 1, cdf->off, cdf->len,
&buffer, &buflen); &buffer, &buflen, NULL);
if (!err && (!buflen || *buffer == 0xff)) if (!err && (!buflen || *buffer == 0xff))
err = gpg_error (GPG_ERR_NOT_FOUND); err = gpg_error (GPG_ERR_NOT_FOUND);
if (err) if (err)

View File

@ -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 /* Perform a READ BINARY command requesting a maximum of NMAX bytes
from OFFSET. With NMAX = 0 the entire file is read. The result is * 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. * stored in a newly allocated buffer at the address passed by RESULT.
Returns the length of this data at the address of RESULTLEN. */ * 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 gpg_error_t
iso7816_read_binary_ext (int slot, int extended_mode, iso7816_read_binary_ext (int slot, int extended_mode,
size_t offset, size_t nmax, size_t offset, size_t nmax,
unsigned char **result, size_t *resultlen) unsigned char **result, size_t *resultlen,
int *r_sw)
{ {
int sw; int sw;
unsigned char *buffer; unsigned char *buffer;
@ -800,6 +802,9 @@ iso7816_read_binary_ext (int slot, int extended_mode,
int read_all = !nmax; int read_all = !nmax;
size_t n; size_t n;
if (r_sw)
*r_sw = 0;
if (!result || !resultlen) if (!result || !resultlen)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
*result = NULL; *result = NULL;
@ -825,6 +830,8 @@ iso7816_read_binary_ext (int slot, int extended_mode,
((offset>>8) & 0xff), (offset & 0xff) , -1, NULL, ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
n, &buffer, &bufferlen); n, &buffer, &bufferlen);
} }
if (r_sw)
*r_sw = sw;
if (*result && sw == SW_BAD_P0_P1) 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, iso7816_read_binary (int slot, size_t offset, size_t nmax,
unsigned char **result, size_t *resultlen) 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 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 result is stored in a newly allocated buffer at the address passed
by RESULT. Returns the length of this data at the address of 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 gpg_error_t
iso7816_read_record (int slot, int recno, int reccount, int short_ef, iso7816_read_record_ext (int slot, int recno, int reccount, int short_ef,
unsigned char **result, size_t *resultlen) unsigned char **result, size_t *resultlen,
int *r_sw)
{ {
int sw; int sw;
unsigned char *buffer; unsigned char *buffer;
size_t bufferlen; size_t bufferlen;
if (r_sw)
*r_sw = 0;
if (!result || !resultlen) if (!result || !resultlen)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
*result = NULL; *result = NULL;
@ -922,6 +935,8 @@ iso7816_read_record (int slot, int recno, int reccount, int short_ef,
short_ef? short_ef : 0x04, short_ef? short_ef : 0x04,
-1, NULL, -1, NULL,
0, &buffer, &bufferlen); 0, &buffer, &bufferlen);
if (r_sw)
*r_sw = sw;
if (sw != SW_SUCCESS && sw != SW_EOF_REACHED) 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; 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);
}

View File

@ -135,9 +135,14 @@ gpg_error_t iso7816_get_challenge (int slot,
gpg_error_t iso7816_read_binary_ext (int slot, int extended_mode, gpg_error_t iso7816_read_binary_ext (int slot, int extended_mode,
size_t offset, size_t nmax, 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, gpg_error_t iso7816_read_binary (int slot, size_t offset, size_t nmax,
unsigned char **result, size_t *resultlen); 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, gpg_error_t iso7816_read_record (int slot, int recno, int reccount,
int short_ef, int short_ef,
unsigned char **result, size_t *resultlen); unsigned char **result, size_t *resultlen);