Skip to content

Conversation

@jurajsarinay
Copy link
Contributor

@jurajsarinay jurajsarinay commented Dec 31, 2022

Checklist
  • New files have a LGPL 2.1 license statement
  • PKCS#11 module is tested
  • Windows minidriver is tested
  • macOS tokend is tested

Please see #208 (comment).

I propose to add a new driver to handle eID cards issued by Slovakia from mid-2021 until November 2022.

Driver

The card runs CardOS 5.4, the new driver is therefore a stripped-down version of card-cardos.c The only place where I have to diverge from the original driver is set_security_env, because the card expects MSE RESTORE instead of MSE SET. I abuse key_ref to store the corresponding seIdentifier, as our pkcs#15 structures do not include the entry.

Because the card shares the ATR with other CardOS 5.4 cards, the new driver precedes cardos-driver within internal_card_drivers[].

PKCS#15 emulation

Within EF.DIR there are 5 applications. The last two carry (apparently not entirely usable) PKCS#15 structures.

pkcs15-skeid.c binds the fourth application in the list. Otherwise sc_pkcs15_bind_internal would get called and create an unusable token. In the case of the fifth application this is prevented by SC_PKCS11_FRAMEWORK_DATA_MAX_NUM = 4.

Because there is no point in calling sc_pkcs15_bind_internal for this card, I added it to sc_pkcs15_is_emulation_only. This does not prevent sc_pkcs15_bind_internal from getting called though (if synthetic binding was unsuccessful).

I consider this behaviour a bit counterintuitive. I mention it here to report on and justify what I have done, it has no noticeable effect on my driver (any more). Let me know if sc_pkcs15_is_emulation_only warrants a separate GitHub issue.

PINs

There is a global User PIN labeled BOK. The qualified certificate (key) requires user consent and a separate (local) Signature PIN labeled KEP. The "official" proprietary PKCS#11 module requires both the codes for every signature. Fortunately, the card is happy with the Signature PIN only, as there seems to be no convenient way to have multiple PIN codes per slot.

I considered emulating (parts of) the "official" behaviour wihtin a custom pin_cmd that contained the following:

    if (data->pin_reference == 0x87 && data->cmd != SC_PIN_CMD_CHANGE && data->pin_type != SC_AC_CONTEXT_SPECIFIC)
        {
               sc_log(card->ctx, "Non-specific KEP PIN encountered, handling it as BOK instead.");
               data->pin_reference = 0x03;
       }

I ultimately decided against the idea. It adds complexity (or confusion) and provides little benefit. I mention the issue because it is connected to a failure in pkcs11-tool --test --slot 1 --login: log.

Because the local Signature PIN is used for the session, test_verify() fails here.

The card enforces CKA_ALWAYS_AUTHENTICATE and therefore reports that the Signature PIN is (no longer) verified, apparently because signatures have been computed during test_signature(). The only effect of this is that the built-in test fails even though the token works (reasonably) well.

The above pin_cmd hack would result in a passed pkcs11-tool --test --slot 1 --login.

I include this information mainly to justify a PR with a failed test attached. If the behaviour of pkcs11-tool --test in the context of a local Signature PIN and user_consent warrants a separate GitHub issue, do please let me know.

For completeness, here is the output of pkcs11-tool --test --slot 0 --login.

@jurajsarinay jurajsarinay marked this pull request as draft December 31, 2022 02:41
@jurajsarinay jurajsarinay marked this pull request as ready for review December 31, 2022 08:40
@martinpaljak
Copy link
Member

@jurajsarinay don't take the tests at gold standard value, if it can be fixed in a generalized way to take into account "always authenticate" behavior, would be a lovely addition together with this PR.

}

key_id = env->key_ref[0];
r = sc_restore_security_env(card, key_id);
Copy link
Member

Choose a reason for hiding this comment

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

This is at least weird. I would be probably for reimplementing the iso7816_restore_security_env (its just one APDU) with some comments, instead of reusing it for setting the security environment (with the key id instead of security environment number). The restore of security environment is completely different operation and that it works is probably pure coincidence.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pure coincidence

... of design & luck.

I need to bolt this on top of OpenSC in one way or another. Because of use_key() there needs to be a meaningful sc_set_security_env() for the card.

r = sc_set_security_env(p15card->card, senv, 0);

MSE RESTORE is what the proprietary module does. The operation is simply a shorthand for MSE SET, that's why I hoped this would not be viewed as utter heresy.

Copy link
Member

Choose a reason for hiding this comment

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

If others dont have issue with this. I am ok with keeping this as long as it will contain some comment in the code that this is what the official driver does. Without comment it still looks like an error (and comments on github are not guaranteed to be accessible forever).

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.

Please add your card's ATR to the Windows installation so that it will be supported via Windows' Minidriver via https://github.com/OpenSC/OpenSC/blob/master/win32/customactions.cpp

@frankmorgner
Copy link
Member

I wonder if card-skeid.c is needed at if the difference from card-cardos.c is so small. card-cardos.c is written in a generic way, which the slowak card doesn't need. I think it should be better to use skeid_known_url() in cardos_init to get the card type and later to use the card type in cardos_set_security_env to implement the workaround for the slowak card.

@Jakuje , since you are familiar with the cardos specification, do you know where the use of MSE RESTORE originates and if it could be integrated in a general way into card-cardos.c?

@jurajsarinay
Copy link
Contributor Author

I wonder if card-skeid.c is needed at if the difference from card-cardos.c is so small.

That was my original plan. I went for a separate driver, because I did not feel comfortable touching (old) code in the CardOS driver(s).

Apart from using a specific sc_set_security_env() I also simply use iso7816_compute_signature() and iso7816_decipher() instead of the CardOS-specific functions.

@frankmorgner
Copy link
Member

Apart from using a specific sc_set_security_env() I also simply use iso7816_compute_signature() and iso7816_decipher() instead of the CardOS-specific functions.

OK, fair enough, card-skeid.c is simple enough to be maintained seperately.

@jurajsarinay jurajsarinay requested a review from Jakuje January 28, 2023 09:45
@andrewshadura
Copy link

@jurajsarinay, you should probably rebase your commits on top of the current master instead of merging it in.

@jurajsarinay
Copy link
Contributor Author

@jurajsarinay, you should probably rebase your commits on top of the current master instead of merging it in.

This is a result of clicking "Sync fork" within GitHub, I should probably have refrained from that :-)
I would very much prefer to avoid GitHub altogether, yet when in Rome, do as the Romans do.

@andrewshadura
Copy link

Oh, I never used that button, I always rebase and force-push manually 🙂

Copy link
Member

@Jakuje Jakuje left a comment

Choose a reason for hiding this comment

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

minor whitespace nits, but otherwise looks good

}

key_id = env->key_ref[0];
r = sc_restore_security_env(card, key_id);
Copy link
Member

Choose a reason for hiding this comment

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

If others dont have issue with this. I am ok with keeping this as long as it will contain some comment in the code that this is what the official driver does. Without comment it still looks like an error (and comments on github are not guaranteed to be accessible forever).

@jurajsarinay
Copy link
Contributor Author

minor whitespace nits

Thank you, @Jakuje!

@nervous-inhuman
Copy link

@frankmorgner Any updates as to when this could possibly be merged?

@frankmorgner frankmorgner merged commit d952a9f into OpenSC:master Mar 22, 2023
@frankmorgner
Copy link
Member

done, thank you

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.

6 participants