add support for signature generation with a decryption key; patch supplied by Peter Koch <pk_opensc@web.de>
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2491 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
9a49854fdc
commit
b143ac5637
|
@ -48,6 +48,7 @@ static const struct sc_card_operations *iso_ops = NULL;
|
|||
|
||||
typedef struct tcos_data_st {
|
||||
unsigned int pad_flags;
|
||||
unsigned int default_sec_env;
|
||||
} tcos_data;
|
||||
|
||||
static int tcos_finish(sc_card_t *card)
|
||||
|
@ -610,15 +611,17 @@ static int tcos_set_security_env(sc_card_t *card,
|
|||
if (se_num)
|
||||
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if (env->operation == SC_SEC_OPERATION_SIGN) {
|
||||
/* There is only a default security environment for
|
||||
signature creation. */
|
||||
/* for signature-computation with local key 0 the default security environment
|
||||
will be used automatically, so we return immediately. */
|
||||
if (env->operation == SC_SEC_OPERATION_SIGN && env->key_ref_len==1 && *env->key_ref==0x80 ) {
|
||||
((tcos_data *)card->drv_data)->default_sec_env = 1;
|
||||
return 0;
|
||||
}
|
||||
} else ((tcos_data *)card->drv_data)->default_sec_env = 0;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0);
|
||||
switch (env->operation) {
|
||||
case SC_SEC_OPERATION_DECIPHER:
|
||||
case SC_SEC_OPERATION_SIGN:
|
||||
apdu.p1 = 0xC1;
|
||||
apdu.p2 = 0xB8;
|
||||
/* save padding flags */
|
||||
|
@ -627,6 +630,7 @@ static int tcos_set_security_env(sc_card_t *card,
|
|||
default:
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
apdu.le = 0;
|
||||
p = sbuf;
|
||||
if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
|
||||
|
@ -683,6 +687,52 @@ static int tcos_restore_security_env(sc_card_t *card, int se_num)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* TCOS compute_signature command. As TCOS can compute signatures
|
||||
* with the default security environment only, signatures with other
|
||||
* security environments are computed by encrypting the pkcs1-padded data
|
||||
*/
|
||||
static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, u8 * out, size_t outlen)
|
||||
{
|
||||
int r;
|
||||
sc_apdu_t apdu;
|
||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
|
||||
assert(card != NULL && data != NULL && out != NULL);
|
||||
|
||||
if (datalen > 255) SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if(((tcos_data *)card->drv_data)->default_sec_env){
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A);
|
||||
memcpy(sbuf, data, datalen);
|
||||
} else {
|
||||
unsigned int keylen=128; /* FIXME: use correct key-size */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x84);
|
||||
for(r=0;r<sizeof(sbuf);++r) sbuf[r]=0xff;
|
||||
sbuf[0]=0x00; sbuf[1]=0x01; sbuf[keylen-datalen-1]=0x00;
|
||||
memcpy(sbuf+keylen-datalen, data, datalen);
|
||||
datalen=keylen;
|
||||
}
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
apdu.le = 256;
|
||||
|
||||
apdu.data = sbuf;
|
||||
apdu.lc = datalen;
|
||||
apdu.datalen = datalen;
|
||||
apdu.sensitive = 1;
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||
size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
|
||||
|
||||
memcpy(out, apdu.resp, len);
|
||||
SC_FUNC_RETURN(card->ctx, 4, len);
|
||||
}
|
||||
SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
}
|
||||
|
||||
/**
|
||||
* TCOS decipher command (same as iso7816_decipher besides setting
|
||||
* the padding byte).
|
||||
|
@ -826,6 +876,7 @@ static struct sc_card_driver * sc_get_driver(void)
|
|||
tcos_ops.list_files = tcos_list_files;
|
||||
tcos_ops.delete_file = tcos_delete_file;
|
||||
tcos_ops.set_security_env = tcos_set_security_env;
|
||||
tcos_ops.compute_signature = tcos_compute_signature;
|
||||
tcos_ops.decipher = tcos_decipher;
|
||||
tcos_ops.restore_security_env = tcos_restore_security_env;
|
||||
tcos_ops.card_ctl = tcos_card_ctl;
|
||||
|
|
Loading…
Reference in New Issue