myeid: added card capabilities check to ...
... correctly determine which algorithms and key sizes are supported.
This commit is contained in:
parent
27c9daeede
commit
7598c822ed
|
@ -46,9 +46,17 @@
|
||||||
#define MYEID_STATE_CREATION 0x01
|
#define MYEID_STATE_CREATION 0x01
|
||||||
#define MYEID_STATE_ACTIVATED 0x07
|
#define MYEID_STATE_ACTIVATED 0x07
|
||||||
|
|
||||||
#define MYEID_INFINEON_CHIP_ATR 0x04
|
|
||||||
#define MYEID_CARD_NAME_MAX_LEN 100
|
#define MYEID_CARD_NAME_MAX_LEN 100
|
||||||
|
|
||||||
|
/* The following flags define the features supported by the card currently in use.
|
||||||
|
They are used in 'card_supported_features' field in myeid_card_caps struct */
|
||||||
|
#define MYEID_CARD_CAP_RSA 0x01
|
||||||
|
#define MYEID_CARD_CAP_3DES 0x02
|
||||||
|
#define MYEID_CARD_CAP_AES 0x04
|
||||||
|
#define MYEID_CARD_CAP_ECC 0x08
|
||||||
|
#define MYEID_CARD_CAP_GRIDPIN 0x10
|
||||||
|
#define MYEID_CARD_CAP_PIV_EMU 0x20
|
||||||
|
|
||||||
static const char *myeid_card_name = "MyEID";
|
static const char *myeid_card_name = "MyEID";
|
||||||
static char card_name_buf[MYEID_CARD_NAME_MAX_LEN];
|
static char card_name_buf[MYEID_CARD_NAME_MAX_LEN];
|
||||||
|
|
||||||
|
@ -83,6 +91,15 @@ typedef struct myeid_private_data {
|
||||||
const struct sc_security_env* sec_env;
|
const struct sc_security_env* sec_env;
|
||||||
} myeid_private_data_t;
|
} myeid_private_data_t;
|
||||||
|
|
||||||
|
typedef struct myeid_card_caps {
|
||||||
|
unsigned char card_caps_ver;
|
||||||
|
unsigned short card_supported_features;
|
||||||
|
unsigned short max_rsa_key_length;
|
||||||
|
unsigned short max_des_key_length;
|
||||||
|
unsigned short max_aes_key_length;
|
||||||
|
unsigned short max_ecc_key_length;
|
||||||
|
} myeid_card_caps_t;
|
||||||
|
|
||||||
static struct myeid_supported_ec_curves {
|
static struct myeid_supported_ec_curves {
|
||||||
char *curve_name;
|
char *curve_name;
|
||||||
struct sc_object_id curve_oid;
|
struct sc_object_id curve_oid;
|
||||||
|
@ -97,6 +114,7 @@ static struct myeid_supported_ec_curves {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int myeid_get_info(struct sc_card *card, u8 *rbuf, size_t buflen);
|
static int myeid_get_info(struct sc_card *card, u8 *rbuf, size_t buflen);
|
||||||
|
static int myeid_get_card_caps(struct sc_card *card, myeid_card_caps_t* card_caps);
|
||||||
|
|
||||||
static int myeid_match_card(struct sc_card *card)
|
static int myeid_match_card(struct sc_card *card)
|
||||||
{
|
{
|
||||||
|
@ -130,10 +148,8 @@ static int myeid_init(struct sc_card *card)
|
||||||
u8 appletInfo[20];
|
u8 appletInfo[20];
|
||||||
size_t appletInfoLen;
|
size_t appletInfoLen;
|
||||||
int r;
|
int r;
|
||||||
int largeEccKeys = 0;
|
unsigned short max_ecc_key_length = 256;
|
||||||
u8 defatr[SC_MAX_ATR_SIZE];
|
myeid_card_caps_t card_caps;
|
||||||
size_t len = sizeof(defatr);
|
|
||||||
const char *atrp = myeid_atrs[MYEID_INFINEON_CHIP_ATR];
|
|
||||||
|
|
||||||
LOG_FUNC_CALLED(card->ctx);
|
LOG_FUNC_CALLED(card->ctx);
|
||||||
|
|
||||||
|
@ -166,15 +182,23 @@ static int myeid_init(struct sc_card *card)
|
||||||
_sc_card_add_rsa_alg(card, 1536, flags, 0);
|
_sc_card_add_rsa_alg(card, 1536, flags, 0);
|
||||||
_sc_card_add_rsa_alg(card, 2048, flags, 0);
|
_sc_card_add_rsa_alg(card, 2048, flags, 0);
|
||||||
|
|
||||||
if (sc_hex_to_bin(atrp, defatr, &len) == 0
|
memset(&card_caps, 0, sizeof(myeid_card_caps_t));
|
||||||
&& (len == card->atr.len) &&
|
|
||||||
memcmp(card->atr.value, defatr, len) == 0) {
|
if (card->version.fw_major >= 40) {
|
||||||
largeEccKeys = 1;
|
/* Since 4.0, we can query available algorithms and key sizes.
|
||||||
|
* Since 3.5.0 RSA up to 2048 and ECC up to 256 are always supported, so we check only max ECC key length. */
|
||||||
|
r = myeid_get_card_caps(card, &card_caps);
|
||||||
|
|
||||||
|
if (r == SC_SUCCESS) {
|
||||||
|
max_ecc_key_length = card_caps.max_ecc_key_length;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sc_log(card->ctx, "Failed to get card capabilities. Using default max ECC key length 256.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* show ECC algorithms if the applet version of the inserted card supports them */
|
/* show ECC algorithms if the applet version of the inserted card supports them */
|
||||||
if ((card->version.fw_major == 3 && card->version.fw_minor > 5) ||
|
if (card->version.fw_major >= 35) {
|
||||||
card->version.fw_major >= 4) {
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN;
|
flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN;
|
||||||
|
@ -182,10 +206,12 @@ static int myeid_init(struct sc_card *card)
|
||||||
ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
|
ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
|
||||||
|
|
||||||
for (i=0; ec_curves[i].curve_name != NULL; i++) {
|
for (i=0; ec_curves[i].curve_name != NULL; i++) {
|
||||||
if (i >= 2 && !largeEccKeys)
|
if (i == 2 && max_ecc_key_length < 384)
|
||||||
continue;
|
continue;
|
||||||
else
|
else if (i == 3 && max_ecc_key_length < 521)
|
||||||
_sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].curve_oid);
|
continue;
|
||||||
|
else
|
||||||
|
_sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].curve_oid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1387,6 +1413,45 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
|
||||||
LOG_FUNC_RETURN(card->ctx, r);
|
LOG_FUNC_RETURN(card->ctx, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get information of features that the card supports. MyEID 4.x cards are available on different
|
||||||
|
hardware and maximum key sizes cannot be determined simply from the version number anymore.
|
||||||
|
*/
|
||||||
|
static int myeid_get_card_caps(struct sc_card *card, myeid_card_caps_t* card_caps)
|
||||||
|
{
|
||||||
|
sc_apdu_t apdu;
|
||||||
|
int r;
|
||||||
|
unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(card->ctx);
|
||||||
|
|
||||||
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0xAA);
|
||||||
|
apdu.resp = rbuf;
|
||||||
|
apdu.resplen = sizeof(myeid_card_caps_t);
|
||||||
|
apdu.le = sizeof(myeid_card_caps_t);
|
||||||
|
|
||||||
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
|
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
|
||||||
|
if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
|
||||||
|
return SC_ERROR_INTERNAL;
|
||||||
|
|
||||||
|
if (apdu.resplen < 11) {
|
||||||
|
sc_log(card->ctx, "Unexpected response to GET DATA (MyEIC card capabilities)");
|
||||||
|
return SC_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
card_caps->card_caps_ver = rbuf[0];
|
||||||
|
/* the card returns big endian values */
|
||||||
|
card_caps->card_supported_features = (unsigned short) rbuf[1] << 8 | rbuf[2];
|
||||||
|
card_caps->max_rsa_key_length = (unsigned short) rbuf[3] << 8 | rbuf[4];
|
||||||
|
card_caps->max_des_key_length = (unsigned short) rbuf[5] << 8 | rbuf[6];
|
||||||
|
card_caps->max_aes_key_length = (unsigned short) rbuf[7] << 8 | rbuf[8];
|
||||||
|
card_caps->max_ecc_key_length = (unsigned short) rbuf[9] << 8 | rbuf[10];
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(card->ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
|
static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
|
||||||
{
|
{
|
||||||
int r = SC_ERROR_NOT_SUPPORTED;
|
int r = SC_ERROR_NOT_SUPPORTED;
|
||||||
|
|
Loading…
Reference in New Issue