diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 53ce7281..f6f1692b 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -497,8 +497,8 @@ static inline void init_flags(struct sc_card *card) card->max_send_size = (255 - 12); /* manual says 255, but we need 12 extra bytes when encoding */ card->max_recv_size = 255; - algoflags = SC_ALGORITHM_RSA_RAW; /* RSA support */ - algoflags |= SC_ALGORITHM_RSA_HASH_NONE; + /* RSA Support with PKCS1.5 padding */ + algoflags = SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_PAD_PKCS1; _sc_card_add_rsa_alg(card, 1024, algoflags, 0); _sc_card_add_rsa_alg(card, 2048, algoflags, 0); } @@ -1356,8 +1356,6 @@ static int dnie_compute_signature(struct sc_card *card, { int result = SC_SUCCESS; struct sc_apdu apdu; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; /* to compose digest+hash data */ - size_t sbuflen = 0; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; /* to receive sign response */ /* some preliminar checks */ @@ -1391,20 +1389,6 @@ static int dnie_compute_signature(struct sc_card *card, sc_log(card->ctx, "Compute signature len: '%d' bytes:\n%s\n============================================================", datalen, sc_dump_hex(data, datalen)); - if (datalen != 256) { - sc_log(card->ctx, "Expected pkcs#1 v1.5 DigestInfo data"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); - } - - /* try to strip pkcs1 padding */ - sbuflen = sizeof(sbuf); - memset(sbuf, 0, sbuflen); - result = sc_pkcs1_strip_01_padding(card->ctx, data, datalen, sbuf, &sbuflen); - if (result != SC_SUCCESS) { - sc_log(card->ctx, "Provided data is not pkcs#1 padded"); - /* TODO: study what to do on plain data */ - LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_PADDING); - } /*INS: 0x2A PERFORM SECURITY OPERATION * P1: 0x9E Resp: Digital Signature @@ -1413,9 +1397,9 @@ static int dnie_compute_signature(struct sc_card *card, apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = 256; /* signature response size */ - apdu.data = sbuf; - apdu.lc = sbuflen; /* 15 SHA1 DigestInfo + 20 SHA1 computed Hash */ - apdu.datalen = sizeof(sbuf); + apdu.data = data; + apdu.lc = datalen; /* Caller determines the type of hash and its size */ + apdu.datalen = datalen; /* tell card to compute signature */ result = dnie_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, result, "compute_signature() failed"); diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index dc88ff7b..800ed6fc 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1489,6 +1489,7 @@ int cwa_encode_apdu(sc_card_t * card, /* reserve enougth space for apdulen+tlv bytes * to-be-crypted buffer and result apdu buffer */ + /* TODO DEE add 4 more bytes for testing.... */ apdubuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen), sizeof(u8)); @@ -1544,14 +1545,16 @@ int cwa_encode_apdu(sc_card_t * card, } /* if le byte is declared, compose and add Le TLV */ - /* TODO: study why original driver checks for le>=256? */ - if (from->le > 0) { - u8 le = 0xff & from->le; - res = cwa_compose_tlv(card, 0x97, 1, &le, &ccbuf, &cclen); - if (res != SC_SUCCESS) { - msg = "Encode APDU compose_tlv(0x97) failed"; - goto encode_end; - } + /* FIXME: For DNIe we must not send the le bytes + when le == 256 but this goes against the standard + and might break other cards reusing this code */ + if ((0xff & from->le) > 0) { + u8 le = 0xff & from->le; + res = cwa_compose_tlv(card, 0x97, 1, &le, &ccbuf, &cclen); + if (res != SC_SUCCESS) { + msg = "Encode APDU compose_tlv(0x97) failed"; + goto encode_end; + } } /* copy current data to apdu buffer (skip header and header padding) */ memcpy(apdubuf, ccbuf + 8, cclen - 8); diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index 94d7f4cb..c295c305 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -136,6 +136,7 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) sc_pkcs15_object_t *p15_obj; size_t len = sizeof(buf); int rv; + struct sc_pkcs15_cert_info *p15_info = NULL; sc_context_t *ctx = p15card->card->ctx; LOG_FUNC_CALLED(ctx); @@ -225,6 +226,15 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) && (p15_obj->auth_id.len == 0)) { p15_obj->auth_id.value[0] = 0x01; p15_obj->auth_id.len = 1; + }; + /* Set path count to -1 for public certificates, as they + will need to be decompressed and read_binary()'d, so + we make sure we end up reading the file->size and not the + path->count which is the compressed size on newer + DNIe versions */ + if ( p15_obj->df && (p15_obj->df->type == SC_PKCS15_CDF) ) { + p15_info = (struct sc_pkcs15_cert_info *) p15_obj ->data; + p15_info ->path.count = -1; } /* Remove found public keys as cannot be read_binary()'d */ if ( p15_obj->df && (p15_obj->df->type == SC_PKCS15_PUKDF) ) {