- Divided errors into different groups, added new ones
and renamed some - Moved sc_strerror() to errors.c - Added a 'sensitive' flag to struct sc_apdu git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@479 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
f781a14ae4
commit
6e0b7dea2c
|
@ -22,7 +22,7 @@ bin_SCRIPTS = opensc-config
|
||||||
|
|
||||||
lib_LTLIBRARIES = libopensc.la
|
lib_LTLIBRARIES = libopensc.la
|
||||||
libopensc_la_SOURCES = sc.c ctx.c module.c asn1.c log.c base64.c \
|
libopensc_la_SOURCES = sc.c ctx.c module.c asn1.c log.c base64.c \
|
||||||
sec.c card.c iso7816.c dir.c \
|
errors.c sec.c card.c iso7816.c dir.c \
|
||||||
pkcs15.c pkcs15-cert.c pkcs15-pin.c \
|
pkcs15.c pkcs15-cert.c pkcs15-pin.c \
|
||||||
pkcs15-prkey.c pkcs15-pubkey.c pkcs15-sec.c \
|
pkcs15-prkey.c pkcs15-pubkey.c pkcs15-sec.c \
|
||||||
pkcs15-cache.c $(PCSC_SRC) reader-ctapi.c \
|
pkcs15-cache.c $(PCSC_SRC) reader-ctapi.c \
|
||||||
|
|
|
@ -179,7 +179,7 @@ static int parse_flex_sf_reply(struct sc_context *ctx, const u8 *buf, int buflen
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error(ctx, "invalid file type: 0x%02X\n", *p);
|
error(ctx, "invalid file type: 0x%02X\n", *p);
|
||||||
return SC_ERROR_UNKNOWN_REPLY;
|
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
}
|
}
|
||||||
p += 2;
|
p += 2;
|
||||||
if (file->type == SC_FILE_TYPE_DF) {
|
if (file->type == SC_FILE_TYPE_DF) {
|
||||||
|
@ -334,10 +334,10 @@ static int select_file_id(struct sc_card *card, const u8 *buf, size_t buflen,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (apdu.resplen < 14)
|
if (apdu.resplen < 14)
|
||||||
return SC_ERROR_UNKNOWN_REPLY;
|
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
if (apdu.resp[0] == 0x6F) {
|
if (apdu.resp[0] == 0x6F) {
|
||||||
error(card->ctx, "unsupported: card returned FCI\n");
|
error(card->ctx, "unsupported: card returned FCI\n");
|
||||||
return SC_ERROR_UNKNOWN_REPLY; /* FIXME */
|
return SC_ERROR_UNKNOWN_DATA_RECEIVED; /* FIXME */
|
||||||
}
|
}
|
||||||
file = sc_file_new();
|
file = sc_file_new();
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
|
@ -430,7 +430,7 @@ static int flex_list_files(struct sc_card *card, u8 *buf, size_t buflen)
|
||||||
return r;
|
return r;
|
||||||
if (apdu.resplen != 4) {
|
if (apdu.resplen != 4) {
|
||||||
error(card->ctx, "expected 4 bytes, got %d.\n", apdu.resplen);
|
error(card->ctx, "expected 4 bytes, got %d.\n", apdu.resplen);
|
||||||
return SC_ERROR_ILLEGAL_RESPONSE;
|
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
}
|
}
|
||||||
memcpy(buf, rbuf + 2, 2);
|
memcpy(buf, rbuf + 2, 2);
|
||||||
buf += 2;
|
buf += 2;
|
||||||
|
@ -686,6 +686,7 @@ static int flex_compute_signature(struct sc_card *card, const u8 *data,
|
||||||
apdu.data = sbuf;
|
apdu.data = sbuf;
|
||||||
apdu.resplen = outlen > sizeof(sbuf) ? sizeof(sbuf) : outlen;
|
apdu.resplen = outlen > sizeof(sbuf) ? sizeof(sbuf) : outlen;
|
||||||
apdu.resp = sbuf;
|
apdu.resp = sbuf;
|
||||||
|
apdu.sensitive = 1;
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||||
|
@ -724,6 +725,7 @@ static int flex_verify(struct sc_card *card, unsigned int type, int ref,
|
||||||
apdu.datalen = buflen;
|
apdu.datalen = buflen;
|
||||||
apdu.data = sbuf;
|
apdu.data = sbuf;
|
||||||
apdu.resplen = 0;
|
apdu.resplen = 0;
|
||||||
|
apdu.sensitive = 1;
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
memset(sbuf, 0, buflen);
|
memset(sbuf, 0, buflen);
|
||||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
|
|
@ -217,7 +217,7 @@ gpk_check_sw(struct sc_card *card, u8 sw1, u8 sw2)
|
||||||
return SC_ERROR_OBJECT_NOT_VALID; /* XXX ??? */
|
return SC_ERROR_OBJECT_NOT_VALID; /* XXX ??? */
|
||||||
|
|
||||||
/* The following are handled by iso7816_check_sw
|
/* The following are handled by iso7816_check_sw
|
||||||
* but all return SC_ERROR_UNKNOWN_REPLY
|
* but all return SC_ERROR_UNKNOWN_DATA_RECEIVED
|
||||||
* XXX: fix in the iso driver? */
|
* XXX: fix in the iso driver? */
|
||||||
case 0x6983:
|
case 0x6983:
|
||||||
error(card->ctx, "PIN is blocked\n");
|
error(card->ctx, "PIN is blocked\n");
|
||||||
|
@ -744,7 +744,7 @@ gpk_verify_crycks(struct sc_card *card, struct sc_apdu *apdu, u8 *crycks)
|
||||||
|| memcmp(apdu->resp + apdu->resplen - 3, crycks, 3)) {
|
|| memcmp(apdu->resp + apdu->resplen - 3, crycks, 3)) {
|
||||||
if (card->ctx->debug)
|
if (card->ctx->debug)
|
||||||
debug(card->ctx, "Invalid secure messaging reply\n");
|
debug(card->ctx, "Invalid secure messaging reply\n");
|
||||||
return SC_ERROR_UNKNOWN_REPLY;
|
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
}
|
}
|
||||||
apdu->resplen -= 3;
|
apdu->resplen -= 3;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -905,6 +905,7 @@ gpk_select_key(struct sc_card *card, int key_sfi, const u8 *buf, size_t buflen)
|
||||||
apdu.resp = resp;
|
apdu.resp = resp;
|
||||||
apdu.resplen = sizeof(resp);
|
apdu.resplen = sizeof(resp);
|
||||||
apdu.le = 12;
|
apdu.le = 12;
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
@ -912,7 +913,7 @@ gpk_select_key(struct sc_card *card, int key_sfi, const u8 *buf, size_t buflen)
|
||||||
SC_TEST_RET(card->ctx, r, "Card returned error");
|
SC_TEST_RET(card->ctx, r, "Card returned error");
|
||||||
|
|
||||||
if (apdu.resplen != 12) {
|
if (apdu.resplen != 12) {
|
||||||
r = SC_ERROR_UNKNOWN_REPLY;
|
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
} else
|
} else
|
||||||
if ((r = gpk_set_filekey(buf, random, resp, priv->key)) == 0) {
|
if ((r = gpk_set_filekey(buf, random, resp, priv->key)) == 0) {
|
||||||
priv->key_set = 1;
|
priv->key_set = 1;
|
||||||
|
@ -956,6 +957,7 @@ gpk_verify_pin(struct sc_card *card, int ref,
|
||||||
apdu.lc = 8;
|
apdu.lc = 8;
|
||||||
apdu.datalen = 8;
|
apdu.datalen = 8;
|
||||||
apdu.data = buffer;
|
apdu.data = buffer;
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
@ -1023,6 +1025,7 @@ gpk_set_secret_code(struct sc_card *card, unsigned int mode,
|
||||||
apdu.lc = 8;
|
apdu.lc = 8;
|
||||||
apdu.data= data;
|
apdu.data= data;
|
||||||
apdu.datalen = 8;
|
apdu.datalen = 8;
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
memset(data, 0, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
for (n = 0; n < 8 && n < puklen; n += 2)
|
for (n = 0; n < 8 && n < puklen; n += 2)
|
||||||
|
@ -1396,6 +1399,7 @@ gpk_decipher(struct sc_card *card, const u8 *in, size_t inlen,
|
||||||
apdu.datalen = inlen;
|
apdu.datalen = inlen;
|
||||||
apdu.resp= buffer;
|
apdu.resp= buffer;
|
||||||
apdu.resplen = sizeof(buffer);
|
apdu.resplen = sizeof(buffer);
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
|
|
@ -143,26 +143,34 @@ static int sc_transceive_t0(struct sc_card *card, struct sc_apdu *apdu)
|
||||||
if (card->ctx->debug >= 5) {
|
if (card->ctx->debug >= 5) {
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
|
|
||||||
|
buf[0] = 0;
|
||||||
|
if (!apdu->sensitive || card->ctx->debug >= 6)
|
||||||
sc_hex_dump(card->ctx, sbuf, sendsize, buf, sizeof(buf));
|
sc_hex_dump(card->ctx, sbuf, sendsize, buf, sizeof(buf));
|
||||||
debug(card->ctx, "Sending %d bytes (resp. %d bytes):\n%s",
|
debug(card->ctx, "Sending %d bytes (resp. %d bytes%s):\n%s",
|
||||||
sendsize, recvsize, buf);
|
sendsize, recvsize,
|
||||||
|
apdu->sensitive ? ", sensitive" : "", buf);
|
||||||
}
|
}
|
||||||
r = card->reader->ops->transmit(card->reader, card->slot, sbuf,
|
r = card->reader->ops->transmit(card->reader, card->slot, sbuf,
|
||||||
sendsize, rbuf, &recvsize);
|
sendsize, rbuf, &recvsize);
|
||||||
|
if (apdu->sensitive)
|
||||||
memset(sbuf, 0, sendsize);
|
memset(sbuf, 0, sendsize);
|
||||||
SC_TEST_RET(card->ctx, r, "Unable to transmit");
|
SC_TEST_RET(card->ctx, r, "Unable to transmit");
|
||||||
|
|
||||||
assert(recvsize >= 2);
|
assert(recvsize >= 2);
|
||||||
apdu->sw1 = (unsigned int) rbuf[recvsize-2];
|
apdu->sw1 = (unsigned int) rbuf[recvsize-2];
|
||||||
apdu->sw2 = (unsigned int) rbuf[recvsize-1];
|
apdu->sw2 = (unsigned int) rbuf[recvsize-1];
|
||||||
|
if (apdu->sensitive)
|
||||||
|
rbuf[recvsize-2] = rbuf[recvsize-1] = 0;
|
||||||
recvsize -= 2;
|
recvsize -= 2;
|
||||||
if (recvsize > apdu->resplen)
|
if (recvsize > apdu->resplen)
|
||||||
recvsize = apdu->resplen;
|
data_bytes = apdu->resplen;
|
||||||
else
|
else
|
||||||
apdu->resplen = recvsize;
|
data_bytes = apdu->resplen = recvsize;
|
||||||
if (recvsize > 0)
|
if (recvsize > 0) {
|
||||||
memcpy(apdu->resp, rbuf, recvsize);
|
memcpy(apdu->resp, rbuf, recvsize);
|
||||||
|
if (apdu->sensitive)
|
||||||
|
memset(rbuf, 0, recvsize);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* errors.c: The textual representation of errors
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
|
#define DIM(v) (sizeof(v)/(sizeof((v)[0])))
|
||||||
|
|
||||||
|
const char *sc_strerror(int error)
|
||||||
|
{
|
||||||
|
const char *rdr_errors[] = {
|
||||||
|
"Generic reader error",
|
||||||
|
"No readers found",
|
||||||
|
"Slot not found",
|
||||||
|
"Slot already connected",
|
||||||
|
"Card not present",
|
||||||
|
"Card removed",
|
||||||
|
"Card reset",
|
||||||
|
"Transmit failed",
|
||||||
|
};
|
||||||
|
const int rdr_base = -SC_ERROR_READER;
|
||||||
|
const char *card_errors[] = {
|
||||||
|
"Card command failed",
|
||||||
|
"File not found",
|
||||||
|
"Record not found",
|
||||||
|
"Unsupported CLA byte in APDU",
|
||||||
|
"Unsupported INS byte in APDU",
|
||||||
|
"Incorrect parameters in APDU",
|
||||||
|
"Wrong length",
|
||||||
|
"Card memory failure",
|
||||||
|
"Card does not support the requested operation",
|
||||||
|
"Not allowed",
|
||||||
|
"Card is invalid or cannot be handled",
|
||||||
|
"Security status not satisfied",
|
||||||
|
"Authentication method blocked",
|
||||||
|
"Unknown data received from card",
|
||||||
|
"PIN code or key incorrect",
|
||||||
|
"File already exists",
|
||||||
|
};
|
||||||
|
const int card_base = -SC_ERROR_CARD_CMD_FAILED;
|
||||||
|
const char *arg_errors[] = {
|
||||||
|
"Invalid arguments",
|
||||||
|
"Command too short",
|
||||||
|
"Command too long",
|
||||||
|
"Buffer too small",
|
||||||
|
"Invalid PIN length",
|
||||||
|
};
|
||||||
|
const int arg_base = -SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
const char *int_errors[] = {
|
||||||
|
"Internal error",
|
||||||
|
"Invalid ASN.1 object",
|
||||||
|
"Required ASN.1 object not found",
|
||||||
|
"Premature end of ASN.1 stream",
|
||||||
|
"Out of memory",
|
||||||
|
"Object not valid",
|
||||||
|
"Too many objects",
|
||||||
|
"Object not valid",
|
||||||
|
"Requested object not found",
|
||||||
|
"Not supported",
|
||||||
|
};
|
||||||
|
const int int_base = -SC_ERROR_INTERNAL;
|
||||||
|
const char *p15i_errors[] = {
|
||||||
|
"Generic PKCS #15 initialization error",
|
||||||
|
"Syntax error",
|
||||||
|
"Inconsistent or incomplete pkcs15 profile",
|
||||||
|
};
|
||||||
|
const int p15i_base = -SC_ERROR_PKCS15INIT;
|
||||||
|
const char *misc_errors[] = {
|
||||||
|
"Unknown error",
|
||||||
|
"PKCS#15 compatible SmartCard not found",
|
||||||
|
};
|
||||||
|
const int misc_base = -SC_ERROR_UNKNOWN;
|
||||||
|
const char **errors;
|
||||||
|
int count = 0, err_base = 0;
|
||||||
|
|
||||||
|
if (error < 0)
|
||||||
|
error = -error;
|
||||||
|
if (error >= misc_base) {
|
||||||
|
errors = misc_errors;
|
||||||
|
count = DIM(misc_errors);
|
||||||
|
err_base = misc_base;
|
||||||
|
} else if (error >= p15i_base) {
|
||||||
|
errors = p15i_errors;
|
||||||
|
count = DIM(p15i_errors);
|
||||||
|
err_base = p15i_base;
|
||||||
|
} else if (error >= int_base) {
|
||||||
|
errors = int_errors;
|
||||||
|
count = DIM(int_errors);
|
||||||
|
err_base = int_base;
|
||||||
|
} else if (error >= arg_base) {
|
||||||
|
errors = arg_errors;
|
||||||
|
count = DIM(arg_errors);
|
||||||
|
err_base = arg_base;
|
||||||
|
} else if (error >= card_base) {
|
||||||
|
errors = card_errors;
|
||||||
|
count = DIM(card_errors);
|
||||||
|
err_base = card_base;
|
||||||
|
} else if (error >= rdr_base) {
|
||||||
|
errors = rdr_errors;
|
||||||
|
count = DIM(rdr_errors);
|
||||||
|
err_base = rdr_base;
|
||||||
|
}
|
||||||
|
error -= err_base;
|
||||||
|
if (error >= count || count == 0)
|
||||||
|
return misc_errors[0];
|
||||||
|
return errors[error];
|
||||||
|
}
|
|
@ -24,46 +24,59 @@
|
||||||
#define SC_SUCCESS 0
|
#define SC_SUCCESS 0
|
||||||
#define SC_NO_ERROR 0
|
#define SC_NO_ERROR 0
|
||||||
|
|
||||||
#define SC_ERROR_MIN -1000
|
/* Errors related to reader operation */
|
||||||
#define SC_ERROR_UNKNOWN -1000
|
#define SC_ERROR_READER -1100
|
||||||
#define SC_ERROR_CMD_TOO_SHORT -1001
|
#define SC_ERROR_NO_READERS_FOUND -1101
|
||||||
#define SC_ERROR_CMD_TOO_LONG -1002
|
#define SC_ERROR_SLOT_NOT_FOUND -1102
|
||||||
#define SC_ERROR_NOT_SUPPORTED -1003
|
#define SC_ERROR_SLOT_ALREADY_CONNECTED -1103
|
||||||
#define SC_ERROR_TRANSMIT_FAILED -1004
|
#define SC_ERROR_CARD_NOT_PRESENT -1104
|
||||||
#define SC_ERROR_FILE_NOT_FOUND -1005
|
#define SC_ERROR_CARD_REMOVED -1105
|
||||||
#define SC_ERROR_INVALID_ARGUMENTS -1006
|
#define SC_ERROR_CARD_RESET -1106
|
||||||
#define SC_ERROR_PKCS15_APP_NOT_FOUND -1007
|
#define SC_ERROR_TRANSMIT_FAILED -1107
|
||||||
#define SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND -1008
|
|
||||||
#define SC_ERROR_OUT_OF_MEMORY -1009
|
/* Resulting from a card command or related to the card*/
|
||||||
#define SC_ERROR_NO_READERS_FOUND -1010
|
#define SC_ERROR_CARD_CMD_FAILED -1200
|
||||||
#define SC_ERROR_OBJECT_NOT_VALID -1011
|
#define SC_ERROR_FILE_NOT_FOUND -1201
|
||||||
#define SC_ERROR_ILLEGAL_RESPONSE -1012
|
#define SC_ERROR_RECORD_NOT_FOUND -1202
|
||||||
#define SC_ERROR_PIN_CODE_INCORRECT -1013
|
#define SC_ERROR_CLASS_NOT_SUPPORTED -1203
|
||||||
#define SC_ERROR_SECURITY_STATUS_NOT_SATISFIED -1014
|
#define SC_ERROR_INS_NOT_SUPPORTED -1204
|
||||||
#define SC_ERROR_CONNECTING_TO_RES_MGR -1015
|
#define SC_ERROR_INCORRECT_PARAMETERS -1205
|
||||||
#define SC_ERROR_INVALID_ASN1_OBJECT -1016
|
#define SC_ERROR_WRONG_LENGTH -1206
|
||||||
#define SC_ERROR_BUFFER_TOO_SMALL -1017
|
#define SC_ERROR_MEMORY_FAILURE -1207
|
||||||
#define SC_ERROR_CARD_NOT_PRESENT -1018
|
#define SC_ERROR_NO_CARD_SUPPORT -1208
|
||||||
#define SC_ERROR_RESOURCE_MANAGER -1019
|
#define SC_ERROR_NOT_ALLOWED -1209
|
||||||
#define SC_ERROR_CARD_REMOVED -1020
|
#define SC_ERROR_INVALID_CARD -1210
|
||||||
#define SC_ERROR_INVALID_PIN_LENGTH -1021
|
#define SC_ERROR_SECURITY_STATUS_NOT_SATISFIED -1211
|
||||||
#define SC_ERROR_UNKNOWN_SMARTCARD -1022
|
#define SC_ERROR_AUTH_METHOD_BLOCKED -1212
|
||||||
#define SC_ERROR_UNKNOWN_REPLY -1023
|
#define SC_ERROR_UNKNOWN_DATA_RECEIVED -1213
|
||||||
#define SC_ERROR_OBJECT_NOT_FOUND -1024
|
#define SC_ERROR_PIN_CODE_INCORRECT -1214
|
||||||
#define SC_ERROR_CARD_RESET -1025
|
#define SC_ERROR_FILE_ALREADY_EXISTS -1215
|
||||||
#define SC_ERROR_ASN1_OBJECT_NOT_FOUND -1026
|
|
||||||
#define SC_ERROR_ASN1_END_OF_CONTENTS -1027
|
/* Returned by OpenSC library when called with invalid arguments */
|
||||||
#define SC_ERROR_TOO_MANY_OBJECTS -1028
|
#define SC_ERROR_INVALID_ARGUMENTS -1300
|
||||||
#define SC_ERROR_INVALID_CARD -1029
|
#define SC_ERROR_CMD_TOO_SHORT -1301
|
||||||
#define SC_ERROR_WRONG_LENGTH -1030
|
#define SC_ERROR_CMD_TOO_LONG -1302
|
||||||
#define SC_ERROR_RECORD_NOT_FOUND -1031
|
#define SC_ERROR_BUFFER_TOO_SMALL -1303
|
||||||
#define SC_ERROR_INTERNAL -1032
|
#define SC_ERROR_INVALID_PIN_LENGTH -1304
|
||||||
#define SC_ERROR_CLASS_NOT_SUPPORTED -1033
|
|
||||||
#define SC_ERROR_SLOT_NOT_FOUND -1034
|
/* Resulting from OpenSC internal operation */
|
||||||
#define SC_ERROR_SLOT_ALREADY_CONNECTED -1035
|
#define SC_ERROR_INTERNAL -1400
|
||||||
#define SC_ERROR_AUTH_METHOD_BLOCKED -1036
|
#define SC_ERROR_INVALID_ASN1_OBJECT -1401
|
||||||
#define SC_ERROR_SYNTAX_ERROR -1037
|
#define SC_ERROR_ASN1_OBJECT_NOT_FOUND -1402
|
||||||
#define SC_ERROR_INCONSISTENT_PROFILE -1038
|
#define SC_ERROR_ASN1_END_OF_CONTENTS -1403
|
||||||
#define SC_ERROR_FILE_ALREADY_EXISTS -1039
|
#define SC_ERROR_OUT_OF_MEMORY -1404
|
||||||
|
#define SC_ERROR_TOO_MANY_OBJECTS -1405
|
||||||
|
#define SC_ERROR_OBJECT_NOT_VALID -1406
|
||||||
|
#define SC_ERROR_OBJECT_NOT_FOUND -1407
|
||||||
|
#define SC_ERROR_NOT_SUPPORTED -1408
|
||||||
|
|
||||||
|
/* Relating to PKCS #15 init stuff */
|
||||||
|
#define SC_ERROR_PKCS15INIT -1500
|
||||||
|
#define SC_ERROR_SYNTAX_ERROR -1501
|
||||||
|
#define SC_ERROR_INCONSISTENT_PROFILE -1502
|
||||||
|
|
||||||
|
/* Errors that do not fit the categories above */
|
||||||
|
#define SC_ERROR_UNKNOWN -1900
|
||||||
|
#define SC_ERROR_PKCS15_APP_NOT_FOUND -1901
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,48 +27,48 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
const static struct sc_card_error iso7816_errors[] = {
|
const static struct sc_card_error iso7816_errors[] = {
|
||||||
{ 0x6200, SC_ERROR_UNKNOWN_REPLY, "State of non-volatile memory unchanged" },
|
{ 0x6200, SC_ERROR_MEMORY_FAILURE, "State of non-volatile memory unchanged" },
|
||||||
{ 0x6281, SC_ERROR_UNKNOWN_REPLY, "Part of returned data may be corrupted" },
|
{ 0x6281, SC_ERROR_MEMORY_FAILURE, "Part of returned data may be corrupted" },
|
||||||
{ 0x6282, SC_ERROR_UNKNOWN_REPLY, "End of file/record reached before reading Le bytes" },
|
{ 0x6282, SC_ERROR_CARD_CMD_FAILED, "End of file/record reached before reading Le bytes" },
|
||||||
{ 0x6283, SC_ERROR_UNKNOWN_REPLY, "Selected file invalidated" },
|
{ 0x6283, SC_ERROR_CARD_CMD_FAILED, "Selected file invalidated" },
|
||||||
{ 0x6284, SC_ERROR_UNKNOWN_REPLY, "FCI not formatted according to 5.1.5" },
|
{ 0x6284, SC_ERROR_CARD_CMD_FAILED, "FCI not formatted according to ISO 7816-4" },
|
||||||
|
|
||||||
{ 0x6300, SC_ERROR_UNKNOWN_REPLY, "State of non-volatile memory changed" },
|
{ 0x6300, SC_ERROR_MEMORY_FAILURE, "State of non-volatile memory changed" },
|
||||||
{ 0x6381, SC_ERROR_UNKNOWN_REPLY, "File filled up by last write" },
|
{ 0x6381, SC_ERROR_CARD_CMD_FAILED, "File filled up by last write" },
|
||||||
|
|
||||||
{ 0x6581, SC_ERROR_UNKNOWN_REPLY, "Memory failure" },
|
{ 0x6581, SC_ERROR_MEMORY_FAILURE, "Memory failure" },
|
||||||
|
|
||||||
{ 0x6700, SC_ERROR_WRONG_LENGTH, "Wrong length" },
|
{ 0x6700, SC_ERROR_WRONG_LENGTH, "Wrong length" },
|
||||||
|
|
||||||
{ 0x6800, SC_ERROR_UNKNOWN_REPLY, "Functions in CLA not supported" },
|
{ 0x6800, SC_ERROR_NO_CARD_SUPPORT, "Functions in CLA not supported" },
|
||||||
{ 0x6881, SC_ERROR_UNKNOWN_REPLY, "Logical channel not supported" },
|
{ 0x6881, SC_ERROR_NO_CARD_SUPPORT, "Logical channel not supported" },
|
||||||
{ 0x6882, SC_ERROR_UNKNOWN_REPLY, "Secure messaging not supported" },
|
{ 0x6882, SC_ERROR_NO_CARD_SUPPORT, "Secure messaging not supported" },
|
||||||
|
|
||||||
{ 0x6900, SC_ERROR_UNKNOWN_REPLY, "Command not allowed" },
|
{ 0x6900, SC_ERROR_NOT_ALLOWED, "Command not allowed" },
|
||||||
{ 0x6981, SC_ERROR_UNKNOWN_REPLY, "Command incompatible with file structure" },
|
{ 0x6981, SC_ERROR_CARD_CMD_FAILED, "Command incompatible with file structure" },
|
||||||
{ 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" },
|
{ 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" },
|
||||||
{ 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "Authentication method blocked" },
|
{ 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "Authentication method blocked" },
|
||||||
{ 0x6984, SC_ERROR_UNKNOWN_REPLY, "Referenced data invalidated" },
|
{ 0x6984, SC_ERROR_CARD_CMD_FAILED, "Referenced data invalidated" },
|
||||||
{ 0x6985, SC_ERROR_UNKNOWN_REPLY, "Conditions of use not satisfied" },
|
{ 0x6985, SC_ERROR_NOT_ALLOWED, "Conditions of use not satisfied" },
|
||||||
{ 0x6986, SC_ERROR_UNKNOWN_REPLY, "Command not allowed (no current EF)" },
|
{ 0x6986, SC_ERROR_NOT_ALLOWED, "Command not allowed (no current EF)" },
|
||||||
{ 0x6987, SC_ERROR_UNKNOWN_REPLY, "Expected SM data objects missing" },
|
{ 0x6987, SC_ERROR_INCORRECT_PARAMETERS,"Expected SM data objects missing" },
|
||||||
{ 0x6988, SC_ERROR_UNKNOWN_REPLY, "SM data objects incorrect" },
|
{ 0x6988, SC_ERROR_INCORRECT_PARAMETERS,"SM data objects incorrect" },
|
||||||
|
|
||||||
{ 0x6A00, SC_ERROR_UNKNOWN_REPLY, "Wrong parameter(s) P1-P2" },
|
{ 0x6A00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
|
||||||
{ 0x6A80, SC_ERROR_UNKNOWN_REPLY, "Incorrect parameters in the data field" },
|
{ 0x6A80, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters in the data field" },
|
||||||
{ 0x6A81, SC_ERROR_NOT_SUPPORTED, "Function not supported" },
|
{ 0x6A81, SC_ERROR_NOT_SUPPORTED, "Function not supported" },
|
||||||
{ 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File not found" },
|
{ 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File not found" },
|
||||||
{ 0x6A83, SC_ERROR_RECORD_NOT_FOUND, "Record not found" },
|
{ 0x6A83, SC_ERROR_RECORD_NOT_FOUND, "Record not found" },
|
||||||
{ 0x6A84, SC_ERROR_UNKNOWN_REPLY, "Not enough memory space in the file" },
|
{ 0x6A84, SC_ERROR_CARD_CMD_FAILED, "Not enough memory space in the file" },
|
||||||
{ 0x6A85, SC_ERROR_INVALID_ARGUMENTS, "Lc inconsistent with TLV structure" },
|
{ 0x6A85, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with TLV structure" },
|
||||||
{ 0x6A86, SC_ERROR_INVALID_ARGUMENTS, "Incorrect parameters P1-P2" },
|
{ 0x6A86, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters P1-P2" },
|
||||||
{ 0x6A87, SC_ERROR_INVALID_ARGUMENTS, "Lc inconsistent with P1-P2" },
|
{ 0x6A87, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with P1-P2" },
|
||||||
{ 0x6A88, SC_ERROR_UNKNOWN_REPLY, "Referenced data not found" },
|
{ 0x6A88, SC_ERROR_CARD_CMD_FAILED, "Referenced data not found" },
|
||||||
|
|
||||||
{ 0x6B00, SC_ERROR_UNKNOWN_REPLY, "Wrong parameter(s) P1-P2" },
|
{ 0x6B00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
|
||||||
{ 0x6D00, SC_ERROR_NOT_SUPPORTED, "Instruction code not supported or invalid" },
|
{ 0x6D00, SC_ERROR_INS_NOT_SUPPORTED, "Instruction code not supported or invalid" },
|
||||||
{ 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" },
|
{ 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" },
|
||||||
{ 0x6F00, SC_ERROR_UNKNOWN_REPLY, "No precise diagnosis" }
|
{ 0x6F00, SC_ERROR_CARD_CMD_FAILED, "No precise diagnosis" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int iso7816_check_sw(struct sc_card *card, int sw1, int sw2)
|
static int iso7816_check_sw(struct sc_card *card, int sw1, int sw2)
|
||||||
|
@ -89,7 +89,7 @@ static int iso7816_check_sw(struct sc_card *card, int sw1, int sw2)
|
||||||
return iso7816_errors[i].errorno;
|
return iso7816_errors[i].errorno;
|
||||||
}
|
}
|
||||||
error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
|
error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
|
||||||
return SC_ERROR_UNKNOWN_REPLY;
|
return SC_ERROR_CARD_CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iso7816_read_binary(struct sc_card *card,
|
static int iso7816_read_binary(struct sc_card *card,
|
||||||
|
@ -447,9 +447,9 @@ static int iso7816_select_file(struct sc_card *card,
|
||||||
*file_out = file;
|
*file_out = file;
|
||||||
break;
|
break;
|
||||||
case 0x00: /* proprietary coding */
|
case 0x00: /* proprietary coding */
|
||||||
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_REPLY);
|
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
default:
|
default:
|
||||||
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_REPLY);
|
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -589,6 +589,7 @@ static int iso7816_verify(struct sc_card *card, unsigned int type, int ref,
|
||||||
apdu.datalen = pinlen;
|
apdu.datalen = pinlen;
|
||||||
apdu.data = sbuf;
|
apdu.data = sbuf;
|
||||||
apdu.resplen = 0;
|
apdu.resplen = 0;
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
memset(sbuf, 0, pinlen);
|
memset(sbuf, 0, pinlen);
|
||||||
|
@ -722,6 +723,7 @@ static int iso7816_compute_signature(struct sc_card *card,
|
||||||
apdu.data = sbuf;
|
apdu.data = sbuf;
|
||||||
apdu.lc = datalen;
|
apdu.lc = datalen;
|
||||||
apdu.datalen = datalen;
|
apdu.datalen = datalen;
|
||||||
|
apdu.sensitive = 1;
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||||
|
@ -733,9 +735,9 @@ static int iso7816_compute_signature(struct sc_card *card,
|
||||||
SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int iso7816_decipher(struct sc_card *card,
|
||||||
iso7816_decipher(struct sc_card *card,
|
const u8 * crgram, size_t crgram_len,
|
||||||
const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen)
|
u8 * out, size_t outlen)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct sc_apdu apdu;
|
struct sc_apdu apdu;
|
||||||
|
@ -753,6 +755,7 @@ iso7816_decipher(struct sc_card *card,
|
||||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x80, 0x86);
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x80, 0x86);
|
||||||
apdu.resp = rbuf;
|
apdu.resp = rbuf;
|
||||||
apdu.resplen = sizeof(rbuf); /* FIXME */
|
apdu.resplen = sizeof(rbuf); /* FIXME */
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
|
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
|
||||||
memcpy(sbuf + 1, crgram, crgram_len);
|
memcpy(sbuf + 1, crgram, crgram_len);
|
||||||
|
@ -796,6 +799,7 @@ static int iso7816_change_reference_data(struct sc_card *card, unsigned int type
|
||||||
apdu.datalen = len;
|
apdu.datalen = len;
|
||||||
apdu.data = sbuf;
|
apdu.data = sbuf;
|
||||||
apdu.resplen = 0;
|
apdu.resplen = 0;
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
memset(sbuf, 0, len);
|
memset(sbuf, 0, len);
|
||||||
|
@ -842,6 +846,7 @@ static int iso7816_reset_retry_counter(struct sc_card *card, unsigned int type,
|
||||||
apdu.datalen = len;
|
apdu.datalen = len;
|
||||||
apdu.data = sbuf;
|
apdu.data = sbuf;
|
||||||
apdu.resplen = 0;
|
apdu.resplen = 0;
|
||||||
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
memset(sbuf, 0, len);
|
memset(sbuf, 0, len);
|
||||||
|
|
|
@ -137,7 +137,7 @@ static int pcsc_transmit(struct sc_reader *reader, struct sc_slot_info *slot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dwRecvLength < 2)
|
if (dwRecvLength < 2)
|
||||||
return SC_ERROR_ILLEGAL_RESPONSE;
|
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
*recvsize = dwRecvLength;
|
*recvsize = dwRecvLength;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -170,61 +170,6 @@ int sc_append_path_id(struct sc_path *dest, const u8 *id, size_t idlen)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *sc_strerror(int error)
|
|
||||||
{
|
|
||||||
const char *errors[] = {
|
|
||||||
"Unknown error",
|
|
||||||
"Command too short",
|
|
||||||
"Command too long",
|
|
||||||
"Not supported",
|
|
||||||
"Transmit failed",
|
|
||||||
"File not found",
|
|
||||||
"Invalid arguments",
|
|
||||||
"PKCS#15 compatible SmartCard not found",
|
|
||||||
"Required parameter not found on SmartCard",
|
|
||||||
"Out of memory",
|
|
||||||
"No readers found",
|
|
||||||
"Object not valid",
|
|
||||||
"Unknown response",
|
|
||||||
"PIN code incorrect",
|
|
||||||
"Security status not satisfied",
|
|
||||||
"Error connecting to Resource Manager",
|
|
||||||
"Invalid ASN.1 object",
|
|
||||||
"Buffer too small",
|
|
||||||
"Card not present",
|
|
||||||
"Error with Resource Manager",
|
|
||||||
"Card removed",
|
|
||||||
"Invalid PIN length",
|
|
||||||
"Unknown SmartCard",
|
|
||||||
"Unknown reply from SmartCard",
|
|
||||||
"Requested object not found",
|
|
||||||
"Card reset",
|
|
||||||
"Required ASN.1 object not found",
|
|
||||||
"Premature end of ASN.1 stream",
|
|
||||||
"Too many objects",
|
|
||||||
"Card is invalid or cannot be handled",
|
|
||||||
"Wrong length",
|
|
||||||
"Record not found",
|
|
||||||
"Internal error",
|
|
||||||
"Invalid CLA byte in APDU",
|
|
||||||
"Slot not found",
|
|
||||||
"Slot already connected",
|
|
||||||
"Authentication method blocked",
|
|
||||||
"Syntax error",
|
|
||||||
"Inconsistent or incomplete pkcs15 profile",
|
|
||||||
"File already exists",
|
|
||||||
};
|
|
||||||
int nr_errors = sizeof(errors) / sizeof(errors[0]);
|
|
||||||
|
|
||||||
error -= SC_ERROR_MIN;
|
|
||||||
if (error < 0)
|
|
||||||
error = -error;
|
|
||||||
|
|
||||||
if (error >= nr_errors)
|
|
||||||
return errors[0];
|
|
||||||
return errors[error];
|
|
||||||
}
|
|
||||||
|
|
||||||
int sc_file_add_acl_entry(struct sc_file *file, unsigned int operation,
|
int sc_file_add_acl_entry(struct sc_file *file, unsigned int operation,
|
||||||
unsigned int method, unsigned long key_ref)
|
unsigned int method, unsigned long key_ref)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,6 +82,9 @@ typedef struct sc_apdu {
|
||||||
u8 *resp; /* R-APDU data buffer */
|
u8 *resp; /* R-APDU data buffer */
|
||||||
size_t resplen; /* in: size of R-APDU buffer,
|
size_t resplen; /* in: size of R-APDU buffer,
|
||||||
* out: length of data returned in R-APDU */
|
* out: length of data returned in R-APDU */
|
||||||
|
u8 sensitive; /* Set if the either the command or
|
||||||
|
* the response contains secrets,
|
||||||
|
* e.g. a PIN. */
|
||||||
|
|
||||||
unsigned int sw1, sw2; /* Status words returned in R-APDU */
|
unsigned int sw1, sw2; /* Status words returned in R-APDU */
|
||||||
} sc_apdu_t;
|
} sc_apdu_t;
|
||||||
|
|
|
@ -50,7 +50,6 @@ CK_RV sc_to_cryptoki_error(int rc, int reader)
|
||||||
case SC_ERROR_CARD_NOT_PRESENT:
|
case SC_ERROR_CARD_NOT_PRESENT:
|
||||||
card_removed(reader);
|
card_removed(reader);
|
||||||
return CKR_TOKEN_NOT_PRESENT;
|
return CKR_TOKEN_NOT_PRESENT;
|
||||||
case SC_ERROR_UNKNOWN_SMARTCARD:
|
|
||||||
case SC_ERROR_INVALID_CARD:
|
case SC_ERROR_INVALID_CARD:
|
||||||
return CKR_TOKEN_NOT_RECOGNIZED;
|
return CKR_TOKEN_NOT_RECOGNIZED;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue