From 410cdf0dcc2dce62f0d4bac00619ddd77920b279 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 23 Jan 2018 13:53:23 +0100 Subject: [PATCH] refactored sc_get_challenge Let sc_get_challenge() do sc_lock() and loop through the card driver's get_challenge() until enough bytes were collected. The card driver's get_challenge() now returns the number of bytes collected (less or equal than requested) or an error code. - Allow more code re-use. - PIV driver now uses ASN.1 parser for reading the random bytes --- src/libopensc/card-authentic.c | 37 ++++++------------ src/libopensc/card-cac.c | 38 +++++-------------- src/libopensc/card-coolkey.c | 39 ++++--------------- src/libopensc/card-dnie.c | 56 ++++++++------------------- src/libopensc/card-epass2003.c | 38 ++++++++----------- src/libopensc/card-isoApplet.c | 8 ++-- src/libopensc/card-muscle.c | 8 +++- src/libopensc/card-openpgp.c | 5 ++- src/libopensc/card-piv.c | 69 ++++++++++++++-------------------- src/libopensc/card-rutoken.c | 38 ++++++++----------- src/libopensc/card.c | 28 ++++++++++++-- src/libopensc/iasecc-sm.c | 27 +------------ src/libopensc/iso7816.c | 20 ++++------ src/minidriver/minidriver.c | 2 +- src/tools/opensc-explorer.c | 3 +- 15 files changed, 151 insertions(+), 265 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 45e8632b..9ef4b05c 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1664,40 +1664,27 @@ authentic_get_serialnr(struct sc_card *card, struct sc_serial_number *serial) } -/* 'GET CHALLENGE' returns always 24 bytes */ static int authentic_get_challenge(struct sc_card *card, unsigned char *rnd, size_t len) { - struct sc_context *ctx = card->ctx; - struct sc_apdu apdu; + /* 'GET CHALLENGE' returns always 24 bytes */ unsigned char rbuf[0x18]; - int rv, nn; + size_t out_len; + int r; - LOG_FUNC_CALLED(ctx); - if (!rnd && len) - return SC_ERROR_INVALID_ARGUMENTS; + LOG_FUNC_CALLED(card->ctx); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = sizeof(rbuf); + r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); - while (len > 0) { - rv = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(ctx, rv, "PIN cmd failed"); - - if (apdu.resplen != sizeof(rbuf)) - return sc_check_sw(card, apdu.sw1, apdu.sw2); - - nn = len > apdu.resplen ? apdu.resplen : len; - memcpy(rnd, apdu.resp, nn); - len -= nn; - rnd += nn; + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; } + memcpy(rnd, rbuf, out_len); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, out_len); } diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index d8762b03..b509136e 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -849,42 +849,22 @@ static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int cac_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { + /* CAC requires 8 byte response */ u8 rbuf[8]; - u8 *rbufp = NULL; - size_t rbuflen = 0; + size_t out_len = sizeof rbuf; int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + LOG_FUNC_CALLED(card->ctx); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "challenge len=%"SC_FORMAT_LEN_SIZE_T"u", len); + r = cac_apdu_io(card, 0x84, 0x00, 0x00, NULL, 0, (u8 **) &rbuf, &out_len); + LOG_TEST_RET(card->ctx, r, "Could not get challenge"); - r = sc_lock(card); - if (r != SC_SUCCESS) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - - - /* CAC requires 8 byte response */ - while (len > 0) { - size_t n; - - rbufp = &rbuf[0]; - rbuflen = sizeof(rbuf); - r = cac_apdu_io(card, 0x84, 0x00, 0x00, NULL, 0, &rbufp, &rbuflen); - if (r < 0) { - sc_unlock(card); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - } - n = len > rbuflen ? rbuflen : len; - memcpy(rnd, rbufp, n); - len -= n; - rnd += n; + if (len < out_len) { + out_len = len; } + memcpy(rnd, rbuf, out_len); - r = sc_unlock(card); - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, (int) out_len); } static int cac_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 768ff22e..4db84464 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1610,40 +1610,17 @@ static int coolkey_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int coolkey_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - size_t rbuflen = 0; - int r; + LOG_FUNC_CALLED(card->ctx); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + if (len > COOLKEY_MAX_CHUNK_SIZE) + len = COOLKEY_MAX_CHUNK_SIZE; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "challenge len=%"SC_FORMAT_LEN_SIZE_T"u", len); - - r = sc_lock(card); - if (r != SC_SUCCESS) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - - for(; len >= COOLKEY_MAX_CHUNK_SIZE; len -= COOLKEY_MAX_CHUNK_SIZE, - rnd += COOLKEY_MAX_CHUNK_SIZE) { - rbuflen = COOLKEY_MAX_CHUNK_SIZE; - r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_RANDOM, - 0, 0, NULL, 0, &rnd, &rbuflen, NULL, 0); - if (r != COOLKEY_MAX_CHUNK_SIZE) { - len = 0; - break; - } - } - if (len) { - r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_RANDOM, - 0, 0, NULL, 0, &rnd, &len, NULL, 0); - } - sc_unlock(card); - - if (r > 0) { - r= SC_SUCCESS; - } - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_TEST_RET(card->ctx, + coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_RANDOM, 0, 0, + NULL, 0, &rnd, &len, NULL, 0), + "Could not get challenge"); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, (int) len); } static int coolkey_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 6ba0eba5..cefe0788 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1340,51 +1340,27 @@ static int dnie_select_file(struct sc_card *card, * @param len requested challenge length * @return SC_SUCCESS if OK; else error code */ -#define BUFFER_SIZE 8 static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len) { - sc_apdu_t apdu; - u8 buf[MAX_RESP_BUFFER_SIZE]; - int result = SC_SUCCESS; - if ((card == NULL) || (card->ctx == NULL)) - return SC_ERROR_INVALID_ARGUMENTS; - LOG_FUNC_CALLED(card->ctx); - /* just a copy of iso7816::get_challenge() but call dnie_check_sw to - * look for extra error codes */ - if ( (rnd==NULL) || (len==0) ) { - /* no valid buffer provided */ - result = SC_ERROR_INVALID_ARGUMENTS; - goto dnie_get_challenge_error; - } - dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00, BUFFER_SIZE, 0, - buf, MAX_RESP_BUFFER_SIZE, NULL, 0); + /* As DNIe cannot handle other data length than 0x08 and 0x14 */ + u8 rbuf[8]; + size_t out_len; + int r; - /* - * As DNIe cannot handle other data length than 0x08 and 0x14, - * perform consecutive reads of 8 bytes until retrieve requested length - */ - while (len > 0) { - size_t n = len > BUFFER_SIZE ? BUFFER_SIZE : len; - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = BUFFER_SIZE; - apdu.resp = buf; - apdu.resplen = MAX_RESP_BUFFER_SIZE; /* include SW's */ - result = sc_transmit_apdu(card, &apdu); - if (result != SC_SUCCESS) { - LOG_TEST_RET(card->ctx, result, "APDU transmit failed"); - } - if (apdu.resplen != BUFFER_SIZE) { - result = sc_check_sw(card, apdu.sw1, apdu.sw2); - goto dnie_get_challenge_error; - } - memcpy(rnd, apdu.resp, n); - len -= n; - rnd += n; + LOG_FUNC_CALLED(card->ctx); + + r = iso_ops->get_challenge(card, rbuf, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); + + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; } - result = SC_SUCCESS; - dnie_get_challenge_error: - LOG_FUNC_RETURN(card->ctx, result); + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, (int) out_len); } /* diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 4de750bf..4594e366 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -2573,34 +2573,26 @@ get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char return r; } - static int -epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t count) +static int +epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - sc_apdu_t apdu; u8 rbuf[16]; - size_t n; - int ret = SC_SUCCESS; /* if count == 0 */ + size_t out_len; + int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = sizeof(rbuf); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); + LOG_FUNC_CALLED(card->ctx); - while (count > 0) - { - ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); - ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Get challenge failed"); - if (apdu.resplen != sizeof(rbuf)) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN); - n = count < sizeof(rbuf) ? count : sizeof(rbuf); - memcpy(rnd, rbuf, n); - count -= n; - rnd += n; + r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); + + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, (int) out_len); } diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 1ef35e2e..c323d922 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1211,17 +1211,17 @@ isoApplet_compute_signature(struct sc_card *card, static int isoApplet_get_challenge(struct sc_card *card, u8 *rnd, size_t len) { - struct sc_context *ctx = card->ctx; int r; - LOG_FUNC_CALLED(ctx); + LOG_FUNC_CALLED(card->ctx); - if(card->caps & SC_CARD_CAP_RNG) { + if(card->caps & SC_CARD_CAP_RNG) { r = iso_ops->get_challenge(card, rnd, len); } else { r = SC_ERROR_NOT_SUPPORTED; } - LOG_FUNC_RETURN(ctx, r); + + LOG_FUNC_RETURN(card->ctx, r); } static int isoApplet_card_reader_lock_obtained(sc_card_t *card, int was_reset) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 9aa6766f..fd148e30 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -775,8 +775,12 @@ static int muscle_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { if (len == 0) return SC_SUCCESS; - else - return msc_get_challenge(card, len, 0, NULL, rnd); + else { + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + msc_get_challenge(card, len, 0, NULL, rnd), + "GET CHALLENGE cmd failed"); + return (int) len; + } } static int muscle_check_sw(sc_card_t * card, unsigned int sw1, unsigned int sw2) { diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 1f903231..fe6e6e63 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1222,16 +1222,17 @@ pgp_list_files(sc_card_t *card, u8 *buf, size_t buflen) static int pgp_get_challenge(struct sc_card *card, u8 *rnd, size_t len) { - struct pgp_priv_data *priv = DRVDATA(card); + struct pgp_priv_data *priv; LOG_FUNC_CALLED(card->ctx); + priv = DRVDATA(card); if (0 == (priv->ext_caps & EXT_CAP_GET_CHALLENGE)) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } if (priv->max_challenge_size > 0 && len > priv->max_challenge_size) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); + len = priv->max_challenge_size; } LOG_FUNC_RETURN(card->ctx, iso_ops->get_challenge(card, rnd, len)); diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 722315bf..8525eede 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2229,54 +2229,41 @@ static int piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - u8 sbuf[16]; + /* Dynamic Authentication Template (Challenge) */ + u8 sbuf[] = {0x7c, 0x02, 0x81, 0x00}; u8 *rbuf = NULL; - size_t rbuflen = 0; - u8 *p, *q; + const u8 *p; + size_t rbuf_len = 0, out_len = 0; int r; + unsigned int tag, cla; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + LOG_FUNC_CALLED(card->ctx); - sc_log(card->ctx, "challenge len=%"SC_FORMAT_LEN_SIZE_T"u", len); + /* NIST 800-73-3 says use 9B, previous verisons used 00 */ + r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len); + LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed"); - r = sc_lock(card); - if (r != SC_SUCCESS) - LOG_FUNC_RETURN(card->ctx, r); - - p = sbuf; - *p++ = 0x7c; - *p++ = 0x02; - *p++ = 0x81; - *p++ = 0x00; - - /* assuming 8 byte response ? */ - /* should take what the card returns */ - while (len > 0) { - size_t n = len > 8 ? 8 : len; - - /* NIST 800-73-3 says use 9B, previous versions used 00 */ - r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, p - sbuf, &rbuf, &rbuflen); - if (r < 0) { - sc_unlock(card); - LOG_FUNC_RETURN(card->ctx, r); - } - q = rbuf; - if ( (*q++ != 0x7C) - || (*q++ != rbuflen - 2) - || (*q++ != 0x81) - || (*q++ != rbuflen - 4)) { - r = SC_ERROR_INVALID_DATA; - sc_unlock(card); - LOG_FUNC_RETURN(card->ctx, r); - } - memcpy(rnd, q, n); - len -= n; - rnd += n; - free(rbuf); - rbuf = NULL; + p = rbuf; + r = sc_asn1_read_tag(&p, rbuf_len, &cla, &tag, &out_len); + if (r < 0 || (cla|tag) != 0x7C) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Dynamic Authentication Template"); } - r = sc_unlock(card); + rbuf_len = out_len; + r = sc_asn1_read_tag(&p, rbuf_len, &cla, &tag, &out_len); + if (r < 0 || (cla|tag) != 0x81) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Challenge"); + } + + if (len < out_len) { + out_len = len; + } + memcpy(rnd, p, out_len); + + r = (int) out_len; + +err: + free(rbuf); LOG_FUNC_RETURN(card->ctx, r); diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 86f8e034..6658a360 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -1137,33 +1137,25 @@ static int rutoken_compute_signature(struct sc_card *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); } -static int rutoken_get_challenge(sc_card_t *card, u8 *rnd, size_t count) +static int rutoken_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - sc_apdu_t apdu; - u8 rbuf[32]; - size_t n; - int ret = SC_SUCCESS; /* if count == 0 */ + unsigned char rbuf[32]; + size_t out_len; + int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = sizeof(rbuf); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); + LOG_FUNC_CALLED(card->ctx); - while (count > 0) - { - ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); - ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Get challenge failed"); - if (apdu.resplen != sizeof(rbuf)) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN); - n = count < sizeof(rbuf) ? count : sizeof(rbuf); - memcpy(rnd, rbuf, n); - count -= n; - rnd += n; + r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); + + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, out_len); } static int rutoken_get_serial(sc_card_t *card, sc_serial_number_t *serial) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 724e73b8..5968b0bd 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -805,16 +805,36 @@ int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { int r; - if (card == NULL) { + if (len == 0) + return SC_SUCCESS; + + if (card == NULL || rnd == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } + LOG_FUNC_CALLED(card->ctx); - if (card->ops->get_challenge == NULL) + if (card->ops == NULL || card->ops->get_challenge == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - r = card->ops->get_challenge(card, rnd, len); - LOG_FUNC_RETURN(card->ctx, r); + r = sc_lock(card); + if (r != SC_SUCCESS) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + + while (len > 0) { + r = card->ops->get_challenge(card, rnd, len); + if (r < 0) { + sc_unlock(card); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + } + + rnd += (size_t) r; + len -= (size_t) r; + } + + sc_unlock(card); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int sc_read_record(sc_card_t *card, unsigned int rec_nr, u8 *buf, diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index eed7c59b..45870650 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -260,31 +260,6 @@ iasecc_sm_se_mutual_authentication(struct sc_card *card, unsigned se_num) LOG_FUNC_RETURN(ctx, rv); } - - -static int -iasecc_sm_get_challenge(struct sc_card *card, unsigned char *out, size_t len) -{ - struct sc_context *ctx = card->ctx; - struct sc_apdu apdu; - unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE]; - int rv; - - sc_log(ctx, "SM get challenge: length %"SC_FORMAT_LEN_SIZE_T"u", len); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0, 0); - apdu.le = len; - apdu.resplen = len; - apdu.resp = rbuf; - - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(ctx, rv, "Command failed"); - - memcpy(out, rbuf, apdu.resplen); - - LOG_FUNC_RETURN(ctx, apdu.resplen); -} #endif @@ -309,7 +284,7 @@ iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd) rv = iasecc_sm_se_mutual_authentication(card, se_num); LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() MUTUAL AUTHENTICATION failed"); - rv = iasecc_sm_get_challenge(card, cwa_session->card_challenge, SM_SMALL_CHALLENGE_LEN); + rv = sc_get_challenge(card, cwa_session->card_challenge, SM_SMALL_CHALLENGE_LEN); LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() GET CHALLENGE failed"); sc_remote_data_init(&rdata); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 1e889ad4..ba0680ee 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -621,12 +621,6 @@ iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len) int r; struct sc_apdu apdu; - if (len == 0) - return SC_SUCCESS; - - if (!rnd) - return SC_ERROR_INVALID_ARGUMENTS; - sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00); apdu.le = len; apdu.resp = rnd; @@ -635,14 +629,14 @@ iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.resplen != len) { - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r == SC_SUCCESS) { - r = SC_ERROR_WRONG_LENGTH; - } - } + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed"); - return r; + if (len < apdu.resplen) { + return (int) len; + } + + return (int) apdu.resplen; } diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 206273fe..82ce1980 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -3665,7 +3665,7 @@ DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData, } rv = sc_get_challenge(vs->p15card->card, *ppbChallengeData, 8); - if (rv) { + if (rv < 0) { logprintf(pCardData, 1, "Get challenge failed: %s\n", sc_strerror(rv)); pCardData->pfnCspFree(*ppbChallengeData); *ppbChallengeData = NULL; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 298293a4..152b6a42 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1609,7 +1609,8 @@ static int do_random(int argc, char **argv) count = atoi(argv[0]); if (count < 0 || (size_t) count > sizeof buffer) { - printf("Number must be in range 0..256\n"); + printf("Number must be in range 0..%"SC_FORMAT_LEN_SIZE_T"u\n", + sizeof buffer); return -1; }