Skip to content

Answer partial (RID) application selection - #49

Open
FlorianFranzen wants to merge 1 commit into
trussed-dev:mainfrom
FlorianFranzen:feat/rid-select
Open

FlorianFranzen wants to merge 1 commit into
trussed-dev:mainfrom
FlorianFranzen:feat/rid-select

Conversation

@FlorianFranzen

@FlorianFranzen FlorianFranzen commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Yubico ecosystem clients (ykman, yubico-piv-tool, piv-go, yubikey.rs) select PIV with only the 5 byte RID A0 00 00 03 08. The truncatable AID stopped at 9 bytes, so both the app's own SELECT parsing and the apdu-dispatch routing (which runs Aid::matches before the app parses anything) answered the RID select with 6A82. This showed up as soon as the app ran behind a real CCID interface.

With the stricter Aid::matches of iso7816 0.2.2 (a candidate must be a prefix of the full AID and at least the truncated length), truncating at the RID is all that is needed: a different PIX under the same RID is rejected by the matcher itself. This PR bumps iso7816 to 0.2.2, changes the truncation length and adds the tests (bare RID select, full AID select, other PIX refused).

It also fixes the existing SELECT test, which sent 00 A4 04 00 0C <AID> 00: Lc 0C with the Le byte folded into the data (SP 800-73-4 has Lc 0B and Le 00). The old matcher accepted the 12-byte candidate because it only compared a prefix; the new one correctly refuses it.

@robin-nitrokey robin-nitrokey left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not related to this PR, but I wonder why we have the Command::Select variant at all. SELECT should be handled by apdu-dispatch and never reach the normal command implementation in the app.

Anyway, in the PR description you mention the problem of AID prefix collisions and refer to trussed-dev/apdu-dispatch#17, but the issue describes a different problem. But I did not find a matching issue either. Can you clarify?

Besides the collision problem, I think the implementation of truncated AIDs is flawed in iso7816/apdu-dispatch (trussed-dev/iso7816#37). We should review that before merging this PR.

@FlorianFranzen

Copy link
Copy Markdown
Contributor Author

Sorry, added the reference to the wrong PR indeed. Please just ignore it.

And it is a valid point that the SELECT command is normally not run on real hardware. I did however hit this in my virtual tests.

Also good point to fix this in the upper layers first. Once the apdu dispatch fix lands, I will just keep the truncation changes and tests and drop the rest.

@robin-nitrokey

Copy link
Copy Markdown
Member

And it is a valid point that the SELECT command is normally not run on real hardware. I did however hit this in my virtual tests.

Interesting. How did you run the tests? Are you sure you hit Command::Select? My point is not about SELECT in general, just about this specific code path.

Comment thread src/commands.rs Resolved
@sosthene-nitrokey

sosthene-nitrokey commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Select does get sent to the application through apdu_app::App::select() here. It returns metadata to the host and resets volatile state. It is true that this could be done without involving the full command parsing machinery, but this would make it dependent on apdu_dispatch which is not required when using as a single app like in the VPICC case.

@robin-nitrokey

robin-nitrokey commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Select does get sent to the application through apdu_app::App::select() here. It returns metadata to the host and resets volatile state. It is true that this could be done without involving the full command parsing machinery, but this would make it dependent on apdu_dispatch which is not required when using as a single app like in the VPICC case.

Ah, I missed that path. Still Command::Select should never be constructed.

@robin-nitrokey

Copy link
Copy Markdown
Member

Nevermind, that’s the path I had in mind but it never triggers the AID handling in piv-authenticator. I still don’t see how it could be called over apdu-dispatch.

@FlorianFranzen
FlorianFranzen marked this pull request as draft October 8, 2026 20:22
@FlorianFranzen

Copy link
Copy Markdown
Contributor Author

It is constructed via the vpicc path: VpiccCard::handle feeds every APDU, SELECT included, into Authenticator::respond (dev-vpicc/src/vpicc.rs:42), which parses it as Command::Select(Select::try_from(data)?) (src/commands.rs:326) and runs the AID check there.

That is the path of examples/vpicc.rs and of the scard tests (aa_serial, opensc, pivy all go through VpiccCard), and the .ron harness calls respond as well (tests/command_response.rs:527).

To be sure I just replayed it: with examples/vpicc as the card behind pcscd and opensc-tool -s, a bare-RID SELECT answers 6A82 on main with iso7816#38 and 9000 on this branch, while a different PIX under the RID answers 6A82 on both, and the vpicc log shows parsed: Select(..) for each of them.

It also means the existing Select case in command_response.ron depends on that check, which is why it breaks with trussed-dev/iso7816#38: run_select sends 00 A4 04 00 0C <AID> 00, Lc 0C with the Le byte folded into the data, and the stricter matches rejects the 12-byte candidate. A fix for that is also included here for now.

If you want Command::Select gone, the natural place is dev-vpicc: Authenticator::select is public and needs no apdu-dispatch, so the virtual card can match the AID itself and call it the way the dispatcher does.

Happy to do that as a follow-up once 0.2.2 is in.

@robin-nitrokey

Copy link
Copy Markdown
Member

I see, thanks for the explanation. Probably it would make sense to mirror the adpu-dispatch behavior in vpicc, but let’s revisit that once we’ve updated apdu-dispatch.

@FlorianFranzen
FlorianFranzen marked this pull request as ready for review October 9, 2026 22:54
FlorianFranzen added a commit to FlorianFranzen/piv-authenticator that referenced this pull request Oct 16, 2026
- c7b2575 Answer partial (RID) application selection

This branch has not been deployed

No deployments
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.

3 participants