- decryption of sm apdu now working. verification of mac still missing.

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@71 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2010-04-12 21:22:39 +00:00
parent 535a2ea9f1
commit 985590c3a8
2 changed files with 38 additions and 14 deletions

View File

@@ -828,7 +828,7 @@ err:
int pace_test(sc_card_t *card)
{
__u8 in[16];
__u8 in[16], buf[SC_MAX_APDU_BUFFER_SIZE - 2];
__u8 *out = NULL;
size_t outlen;
struct sm_ctx sctx;
@@ -863,6 +863,8 @@ int pace_test(sc_card_t *card)
apdu.datalen = 2;
apdu.lc = apdu.datalen;
apdu.le = 0x00;
apdu.resp = buf;
apdu.resplen = sizeof buf;
apdu.cse = SC_APDU_CASE_4_SHORT;
SC_TEST_RET(card->ctx, pace_transmit_apdu(&sctx, card, &apdu),

View File

@@ -36,11 +36,11 @@ static const struct sc_asn1_entry c_sm_capdu[] = {
static const struct sc_asn1_entry c_sm_rapdu[] = {
{ "Padding-content indicator followed by cryptogram" ,
SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x07, SC_ASN1_OPTIONAL , NULL, NULL },
SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x07, SC_ASN1_OPTIONAL, NULL, NULL },
{ "Processing Status",
SC_ASN1_INTEGER , SC_ASN1_CTX|0x19, SC_ASN1_OPTIONAL|SC_ASN1_UNSIGNED, NULL, NULL },
SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x19, 0 , NULL, NULL },
{ "Cryptographic Checksum",
SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x0E, SC_ASN1_OPTIONAL , NULL, NULL },
SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x0E, SC_ASN1_OPTIONAL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
@@ -270,8 +270,6 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
sc_copy_asn1_entry(c_sm_capdu, sm_capdu);
sm_apdu->sensitive = 0;
sm_apdu->resp = apdu->resp;
sm_apdu->resplen = apdu->resplen;
sm_apdu->control = apdu->control;
sm_apdu->flags = apdu->flags;
sm_apdu->cla = 0x0C;
@@ -455,7 +453,7 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
int r;
struct sc_asn1_entry sm_rapdu[4];
struct sc_asn1_entry my_sm_rapdu[4];
u8 sw[2], mac[256], fdata[1024];
u8 sw[2], mac[8], fdata[SC_MAX_APDU_BUFFER_SIZE];
size_t sw_len = sizeof sw, mac_len = sizeof mac, fdata_len = sizeof fdata,
buf_len, asn1_len;
const u8 *buf;
@@ -466,7 +464,7 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
sc_format_asn1_entry(sm_rapdu + 1, sw, &sw_len, 0);
sc_format_asn1_entry(sm_rapdu + 2, mac, &mac_len, 0);
r = sc_asn1_decode(card->ctx, sm_rapdu, apdu->resp, apdu->resplen,
r = sc_asn1_decode(card->ctx, sm_rapdu, sm_apdu->resp, sm_apdu->resplen,
&buf, &buf_len);
if (r < 0)
goto err;
@@ -477,9 +475,10 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
if (sm_rapdu[2].flags & SC_ASN1_PRESENT) {
/* copy from sm_apdu to my_sm_apdu, but leave mac at default */
sc_copy_asn1_entry(sm_rapdu, my_sm_rapdu);
sc_copy_asn1_entry(&c_sm_rapdu[2], &my_sm_rapdu[2]);
sc_format_asn1_entry(my_sm_rapdu + 2, NULL, NULL, 0);
r = sc_asn1_encode(card->ctx, my_sm_rapdu, &asn1, &asn1_len);
if (r < 0)
goto err;
@@ -488,10 +487,16 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
goto err;
}
#if 0
/* XXX */
r = ctx->verify_authentication(card, ctx, mac, mac_len,
mac_data, r);
if (r < 0)
goto err;
#endif
} else {
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
goto err;
}
@@ -509,13 +514,30 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
if (r < 0)
goto err;
memcpy(apdu, sm_apdu, sizeof *apdu);
apdu->resp = data;
if (apdu->resplen < r) {
sc_error(card->ctx, "Response of SM APDU too long");
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
memcpy(apdu->resp, data, r);
apdu->resplen = r;
} else {
apdu->resplen = 0;
}
if (sm_rapdu[1].flags & SC_ASN1_PRESENT) {
if (sw_len != 2) {
sc_error(card->ctx, "Length of processing status bytes must be 2");
r = SC_ERROR_ASN1_END_OF_CONTENTS;
goto err;
}
apdu->sw1 = sw[0];
apdu->sw2 = sw[1];
} else {
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
goto err;
}
sc_debug(card->ctx, "Decrypted APDU sw1=%02x sw2=%02x",
apdu->sw1, apdu->sw2);
bin_log(card->ctx, "Decrypted APDU response data",
@@ -550,11 +572,11 @@ int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card,
SC_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, &sm_apdu),
"Could not encrypt APDU.");
SC_TEST_RET(card->ctx, my_transmit_apdu(card, &sm_apdu),
"Could not send SM APDU.");
SC_TEST_RET(card->ctx, sc_check_sw(card, sm_apdu.sw1, sm_apdu.sw2),
"Card returned error.");
"Could not transmit SM APDU.");
SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu),
"Could not decrypt APDU.");
SC_TEST_RET(card->ctx, sc_check_sw(card, apdu->sw1, apdu->sw2),
"Card returned error.");
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS);
}