-
Notifications
You must be signed in to change notification settings - Fork 3
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
Conversion issue with maximum-length APDUs, serialization #6
Comments
Don't be sorry, it's interesting to update WSCT to address some new concrete needs. To sum up: From the standard:
From your use cases:
From my constraint:
Notation based on ISO/IEC 7816:
I'll have a look at your commit today and come back to you. |
Could you see this commit 3e7d3ee answers all your concerns? |
- unchanged: short C-APDU are automatically upgraded to extended when Nc or Ne is > FF - changed: extended C-APDU are never upgraded to short when both Nc and Ne are <= FF - new: short C-APDU can be enforced extended even when both Nc and Ne are <= FF (EnforceExtended() method) - new: when short CC2 or CC4 with Le='00' (Ne=FF+1) is upgraded to extended because Nc > FF, Le is set to FF+1
I’m traveling but will take a look after. |
Hi, |
Sorry to bring this up immediately after a release.
Automatic conversion between short and extended length APDUs is a bit tricky when Le is zero. Per ISO7816, the value has different meanings for short and extended APDUs.
For example, case 2:
This causes issues with automatic conversion of extended APDUs to non-extended APDUs, as well as intentional conversion from non-extended to extended. Changing an APDU with an Le encoding of zero from short to extended should change the encoded Le to a value of 0x0100, preserving the length. Otherwise, the meaning changes significantly instead of just the case.
An encoding of 0x00 meaning 256 also introduces an off-by one error in some of the testing (in terms of conversion). 0x0100 can be encoded in a single byte.
Additionally, automatic downconversion results in situations where valid APDUs (extended format, small Le) can't be represented, or a deserialized value ends up not serializing to the same value. The handling is a bit inconsistent, which is why the case 3 test didn't catch it, despite being an extended APDU with a short Lc.
I have a commit which demonstrates one possible approach to achieving consistency. It keeps extended APDUs as extended, ensures that all valid APDUs can be represented and encode and decode to the same value. It also properly converts between short and extended form while maintaining the semantic meaning. Additionally, exceptions have been added for conversions that can't be performed properly (Le > 0x0101).
https://github.com/mistial-dev/WSCT-Core/commit/16d485111f8b4b4a152f7caa8736b244ffd0875c
I have not put this as a pull request at this point because of one potentially breaking change, specifically in how Le is handled.
ISO7816-4 differentiates between the value of a field and its encoding. A value may be encoded in 0, 1, 2, or 3 bytes depending on the specifics. An Le with a value of zero is encoded as an absent encoded value, and a Le with an encoding of 0x00 has a value of 256. 0x0000 has a value of 65536.
By switching to using the actual value of Le, rather than the one-byte encoded value of Le, it's possible to switch back and forth between extended and non-extended without losing any meaning. This also ensures that a conversion from extended Le with encoded value 0x00 (65536) can fail when an attempt is made to convert it to short form. This also helps with consistency on the constructor, as Le = 0 means a case 1 APDU (which is the standards-compliant encoding for an APDU with no expected length) instead of a case 2 APDU.
The potentially breaking aspect of this approach is that software looking to use the one-byte encoded value in constructors or set commands will end up with a case they may not want. This is not an issue if they set Le explicitly, but is potentially breaking if they assume that setting Lc to 0 actually means maximum.
It's possible to work around this (for example, by automatically converting back and forth, and using flags to internally tell the difference), but it's a bit of a hack and isn't necessary on the extended APDU side, since nothing is using it yet. It doesn't really make sense with extended APDUs either, as a values are encoded multi-byte anyway. Unlike short APDUs, the encoded value and the numerical value will always differ by at least one byte.
The text was updated successfully, but these errors were encountered: