Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

card-rtecp: Fix rtecp_change_reference_data (resolves #931) #958

Merged
merged 3 commits into from
Feb 20, 2017

Conversation

konstantinpersidskiy
Copy link
Contributor

@konstantinpersidskiy konstantinpersidskiy commented Feb 3, 2017

Hello

This branch resolves the issue #931 . I inspected some code and probably found out the cause of the trouble. The problem seemed to appear in OpenSC of version 0.14.0 and higher and it was caused by rtecp-dependent code relying on previous implementation of function asn1_put_tag. So when asn1_put_tag was changed to treat long data more accurate, some of rtecp-dependent code became invalid in some cases. I rewrote that rtecp code and now it seems to work properly when it comes to importing long pieces of data (like RSA keys) to rtecp (tested on Rutoken ECP 2.0).

Regards,
Konstantin Persidskiy

@dengert
Copy link
Member

dengert commented Feb 3, 2017

The comment in line 450 to 453 is hard to read, and not clear if this is code or not. Can you use:

/*
 * comment
 * comment
 */

You comment that the card in one case does not support sc_asn1_put_tag properly, but you also use sc_asn1_put_tag in another place. The card may be expecting SIMPLE-TLV not BER-TLV a form of ASN.1.
In SIMPLE-TLV the length is either 1 or 3 bytes, the single length byte can be between 0-254.
ISO 7816-4 "5.4.4 Data field bytes"

abf8f36 has a version of simpletlv.c and simpletlv.c but its is not in master.

Does the card really support chaining (SC_APDU_FLAGS_CHAINING)?

If it did, I would not expect each each segment to have to start with the A5 Len.
The point in chaining is is to send large blocks in smaller segments, without having to add
extra fields for each segment.

What you might be seeing is the OpenSC code sees the chaining bit set, and sends multiple APDUs
to the card each with the A5 Len as you reconstructed the buffer to have the A5 len in the right places. But the card is ignoring the chaining bit. So in effect you are using the OpenSC chaining code to loop for you.

@konstantinpersidskiy
Copy link
Contributor Author

Comment at 450-453 should really be a bit more neat - thanks for noticing

TLV-format used in rtecp is not SIMPLE-TLV and not BER-TLV - that's why we have to put A5 tags in a special loop, not with any of implemented in OpenSC functions. But when TLV length is less than 128, the output of asn1_put_tag() matches the expected format, and for putting TLV with small length asn1_put_tag() is used - to fit into general OpenSC codestyle

Rtecp supports chaining, but it's a bit 'special' either. The card doesn't ignore the chaining bit - it is needed to ensure the consistency of chaining APDU, but card also expects each transmit not to cut TLVs in parts, that's why it may look a little confusing.

Copy link
Member

@frankmorgner frankmorgner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change the comments, I'd merge this commit. If possible please don't use assert.

* buf_length <= apdu_num * max_transmit_length;
* 2 + sizeof(rsf_length) + newlen + 2 * apdu_num <= apdu_num * max_transmit_length;
* apdu_num >= (2 + sizeof(rsf_length) + newlen) / (max_transmit_length -2)
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clearify the comments. If nobody knows what you're talking about you might as well remove the comments...

val_length = max_transmit_length - (p - buf) % max_transmit_length - 2;
else
val_length = newlen;
assert(val_length <= newlen);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please replace assert with proper error handling.

@konstantinpersidskiy
Copy link
Contributor Author

konstantinpersidskiy commented Feb 16, 2017

@frankmorgner , thanks for reviewing the code!

The assert you mentioned won't be triggered in any situation in this version of file - that is guaranteed by the if-else block (lines 471-474), but it'll help future developers to control violating of input data borders (if he change code between if-else and assert). Also asserts are used evwerywhere in this particular file, so I decided to follow the style and use them either.

I also changed the comment to be more informative and clear.

If you change the comments, I'd merge this commit.

I'm looking forward to it!

@frankmorgner
Copy link
Member

Indeed, we could do much better with the error handling, but that shouldn't keep us from starting somewhere.

@frankmorgner frankmorgner merged commit a087082 into OpenSC:master Feb 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants