add support for d-trust cards.

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2927 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
aj 2006-05-01 10:12:36 +00:00
parent 8fe04d5a86
commit b507ee68e4
4 changed files with 133 additions and 19 deletions

1
NEWS
View File

@ -9,6 +9,7 @@ or doc/ChangeLog.
New in 0.11.1; ????-??-??; ? ?
* Improved TCOS driver for Uni Giesen Card
* handle size_t printf with "%lu" and (unsigned long) cast
* add support for d-trust cards / improve micardo 2.1 driver
New in 0.11.0; 2006-05-01; Andreas Jellinghaus
* compile fixes/improvements for windows

View File

@ -232,6 +232,16 @@ app default {
force_protocol = t0;
}
# D-Trust cards are also based on micardo and need T=0 for some reason
card_atr 3b:fe:94:00:ff:80:b1:fa:45:1f:03:45:73:74:45:49:44:20:76:65:72:20:31:2e:30:43 {
force_protocol = t0;
}
card_atr 3b:ff:94:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:23 {
force_protocol = t0;
}
card_atr 3b:ff:11:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:a6 {
force_protocol = t0;
}
# Below are the framework specific configuration blocks.

View File

@ -31,10 +31,15 @@
#include "esteid.h"
static struct sc_atr_table mcrd_atrs[] = {
{"3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", NULL, "German BMI", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL},
{"3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", NULL,
"Micardo 2.1/German BMI/D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL},
{"3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20:76:65:72:20:31:2E:30:43", NULL, "EstEID (cold)", SC_CARD_TYPE_MCRD_ESTEID, 0, NULL},
{"3B:6E:00:FF:45:73:74:45:49:44:20:76:65:72:20:31:2E:30", NULL,
"EstEID (warm)", SC_CARD_TYPE_MCRD_ESTEID, 0, NULL},
{"3b:6f:00:ff:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00", NULL,
"D-Trust", SC_CARD_TYPE_MCRD_DTRUST, 0, NULL},
{"3b:ff:11:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:a6", NULL,
"D-Trust", SC_CARD_TYPE_MCRD_DTRUST, 0, NULL},
{NULL, NULL, NULL, 0, 0, NULL}
};
@ -968,10 +973,35 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file)
pathptr[n >> 1] =
(path->value[n] << 8) | path->value[n + 1];
pathlen = path->len >> 1;
if (path->type == SC_PATH_TYPE_PATH)
r = select_file_by_path(card, pathptr, pathlen, file);
else { /* SC_PATH_TYPE_FILEID */
r = select_file_by_fid(card, pathptr, pathlen, file);
int samepath = 1;
if (pathlen == priv->curpathlen && priv->is_ef != 2) {
for (n = 0; n < pathlen; n++) {
if (priv->curpath[n] != pathptr[n]) {
samepath = 0;
break;
}
}
} else if (priv->curpathlen < pathlen && priv->is_ef != 2) {
for (n = 0; n < priv->curpathlen; n++) {
if (priv->curpath[n] != pathptr[n]) {
samepath = 0;
break;
}
}
pathptr = pathptr + n;
pathlen = pathlen - n;
}
if (samepath != 1 || priv->is_ef == 0 || priv->is_ef == 1) {
if (path->type == SC_PATH_TYPE_PATH)
r = select_file_by_path(card, pathptr, pathlen,
file);
else { /* SC_PATH_TYPE_FILEID */
r = select_file_by_fid(card, pathptr, pathlen,
file);
}
}
}
@ -1003,6 +1033,29 @@ static int mcrd_restore_se(sc_card_t * card, int se_num)
return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
int select_key_df(sc_card_t * card)
{
int r, i;
char tmpstr[16] = "";
char currpathpart[10];
struct mcrd_priv_data *priv = DRVDATA(card);
memset(tmpstr, 0, 16);
i = 0;
while (i < priv->curpathlen - 1) {
sprintf(currpathpart, "%04x", (unsigned short)priv->curpath[i]);
strcat(tmpstr, currpathpart);
i++;
}
sc_path_t tmppath;
sc_format_path(tmpstr, &tmppath);
tmppath.type = SC_PATH_TYPE_PATH;
r = sc_select_file(card, &tmppath, NULL);
SC_TEST_RET(card->ctx, r, "Micardo select DF failed");
return r;
}
/* It seems that MICARDO does not fully comply with ISO, so I use
values gathered from peeking actual signing opeations using a
different system.
@ -1055,6 +1108,37 @@ static int mcrd_set_security_env(sc_card_t * card,
return 0;
}
if (card->type == SC_CARD_TYPE_MCRD_DTRUST
|| card->type == SC_CARD_TYPE_MCRD_GENERIC) {
sc_debug(card->ctx, "Using SC_CARD_TYPE_MCRD_DTRUST\n");
/* some sanity checks */
if (env->flags & SC_SEC_ENV_ALG_PRESENT) {
if (env->algorithm != SC_ALGORITHM_RSA)
return SC_ERROR_INVALID_ARGUMENTS;
}
if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)
|| env->key_ref_len != 1)
return SC_ERROR_INVALID_ARGUMENTS;
switch (env->operation) {
case SC_SEC_OPERATION_DECIPHER:
sc_debug(card->ctx,
"Using keyref %d to dechiper\n",
env->key_ref[0]);
mcrd_delete_ref_to_authkey(card);
mcrd_delete_ref_to_signkey(card);
mcrd_set_decipher_key_ref(card, env->key_ref[0]);
break;
case SC_SEC_OPERATION_SIGN:
sc_debug(card->ctx, "Using keyref %d to sign\n",
env->key_ref[0]);
break;
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
priv->sec_env = *env;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0);
apdu.le = 0;
p = sbuf;
@ -1073,22 +1157,34 @@ static int mcrd_set_security_env(sc_card_t * card,
*p++ = 0x83;
*p++ = 0x03;
*p++ = 0x80;
if ((env->flags & SC_SEC_ENV_FILE_REF_PRESENT)
&& env->file_ref.len > 1) {
unsigned short fid;
int num;
fid = env->file_ref.value[env->file_ref.len - 2] << 8;
fid |= env->file_ref.value[env->file_ref.len - 1];
num = get_se_num_from_keyd(card, fid, p);
if (num != -1) {
/* Need to restore the security environmnet. */
if (num) {
r = mcrd_restore_se(card, num);
SC_TEST_RET(card->ctx, r,
"mcrd_enable_se failed");
if (card->type == SC_CARD_TYPE_MCRD_DTRUST
|| card->type == SC_CARD_TYPE_MCRD_GENERIC) {
unsigned short fid;
fid = env->key_ref[0];
*p = fid;
p++;
*p = 0;
p++;
} else if (card->type == SC_CARD_TYPE_MCRD_ESTEID) {
if ((env->flags & SC_SEC_ENV_FILE_REF_PRESENT)
&& env->file_ref.len > 1) {
unsigned short fid;
int num;
fid = env->file_ref.value[env->file_ref.len - 2] << 8;
fid |= env->file_ref.value[env->file_ref.len - 1];
num = get_se_num_from_keyd(card, fid, p);
if (num != -1) {
/* Need to restore the security environmnet. */
if (num) {
r = mcrd_restore_se(card, num);
SC_TEST_RET(card->ctx, r,
"mcrd_enable_se failed");
}
p += 2;
}
p += 2;
}
} else {
return SC_ERROR_INVALID_ARGUMENTS;
@ -1229,6 +1325,12 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data,
data->pin1.length_offset = 4;
data->pin2.offset = 5;
data->pin2.length_offset = 4;
if (card->type == SC_CARD_TYPE_MCRD_DTRUST
|| card->type == SC_CARD_TYPE_MCRD_GENERIC) {
sc_debug(card->ctx, "modify pin reference for D-Trust\n");
if (data->pin_reference == 0x02)
data->pin_reference = data->pin_reference | 0x80;
}
SC_FUNC_RETURN(card->ctx, 4, iso_ops->pin_cmd(card, data, tries_left));
}

View File

@ -69,6 +69,7 @@ enum {
SC_CARD_TYPE_MCRD_BASE = 5000,
SC_CARD_TYPE_MCRD_GENERIC,
SC_CARD_TYPE_MCRD_ESTEID,
SC_CARD_TYPE_MCRD_DTRUST,
/* setcos driver */
SC_CARD_TYPE_SETCOS_BASE = 6000,