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
This commit is contained in:
parent
91812cf40f
commit
410cdf0dcc
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue