-
Notifications
You must be signed in to change notification settings - Fork 712
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
CAC regression? #1533
Comments
Try adding Just a hunch, and is easy to try. |
I have more than one token inserted - a CAC, a Yubikey, a YubiHSM2. When I added When everything works, it prompts me for a PIN for each token, and then offers a certificate that matches what the server asked for (CAC in this case). So I'd enter a PIN for each token once. Before trying your suggestion, Firefox would enter an infinite loop, asking for the CAC PIN. Now it enters infinite loop asking for the Yubikey PIN - but once I cancel that, it proceeds to the DOD web site correctly. My conclusion/guess is - something in the CAC detection mechanism of the new driver is screwed up. Update
Update 2 |
Problem could be in card.c line 252: I don't know if we test forcing a driver very well. A debug log would help. You can start firefox from a script and have |
Try to isolate the problem:
Generate logs with |
Are you using p11-kit? Or just opensc-pkcs11.so. Prior to the regression Firefox would preset a list of certificates to use. Do there certificates have the same subjectName? Are they signed by the same CA? Firefox might get mixed up if same subjectName. Prior to the regression it all worked, and your card was recognized as a CAC card. Do you have a log of that to compare to current logs. As Frank said, can you get pkcs11-tool to fail to select the CAC card without the card_atr ? before and after regression. |
AFAIK, only
No to both. Different DN's with different chain of trust and different CAs.
I think the card is still recognized as a CAC card (and the "cac" driver was forced in
Alas, I don't.
I'll try - but I don't think it's the problem of selecting the card - every time I enter the PIN, the appropriate card reader blinks, so apparently they are in communication (i.e., the card is selected and being talked to). |
First, I rebuilt OpenSC with the current (as of last night) master. I started with
This is what happens when the driver is not selected by ATR:
BTW, note how crazy it got regarding "context-specific PIN", asking for it every time even when it's clearly unnecessary (e.g., for Then I tried
To my surprise, it worked as expected: I guess I could/should close this issue... |
As for the "crazy" part: There was a mod added on behalf of Yubico users who wanted to use different key attributes then defined in NIST 800-73. It only allied to a non government cards, (FASC-N in CHUID not present or starts with 9999) For a non government card pkcs15-piv.c to use the certificates keyUsage attribute to map to the SC_PKCS15_PRKEY_USAGE_* bits. For the retired keys pkcs15-piv.c would set user_consent, not the first 4 keys.
These lines all show the 4 keys have the 0x02 SC_X509_NON_REPUDIATION bit set. But this should not be a problem with the 4 main certificates, as If these are signed by your CA you may want to reevaluate what keyUsage bits you are setting.
|
Disregard the above. looking closer at your:
Looks correct. pkcs11-tool tests the "key 1 (SIGN key)" with RSA-X-509 and RSA-PKCS. So two sign operations are done, each prompts for the context specific pin, does the crypto and write "OK" pkcs11-test then goes on to test "key 2 (KEY MAN key)" with RSA-X-509 and RSA-PKCS but does not prompt because user is still logged into card. |
I still want to revert this to being prompted as needed instead of when the OpenSC software thinks the card may want to re-authenticate (and being wrong most of the time, at least for single-run invocations). |
Live with it. We have had these discussions before. You can always go with the `ignore_user_consent" and "use_pin_caching". |
Alas, that setting appears to be ignored, as you could observe in the above screen log. |
What is missing is What is missing is an This could be implemented in framework-pkcs15.c for all cards, or after pkcs15-piv.c line 1196 as the last operation in the loop to test if override_user_consent is set, and do prkey_obj.user_consent = 0; You could test this by adding the one line (and make sure use_pin_caching is set):
|
The patch should have been: |
Should the above force P.S. I have both |
Tested. It became worse:
|
The above patch is just to test if this would do what you want. i.e. does the pin caching then take effect if the sign operation fails and reissue the command, and it it fails a second time, return to the user as not logged in. In the offline discussion you said: "The driver has the control over what to report to the app, upon which the app decides whether to prompt the user or not." This is not always true. With PKCS#11 the application may query for the CKA_ALWAYS_AUTHENTICATE once and assume the value does not change. This is not a dynamic request of the attribute. It is a statement of a policy that the card and/or issuer wants the user to follow, i.e. the user will provide the PIN each time. There is no restriction placed on when the application can ask for the attribute, or what the application can do between the query for CKA_ALWAYS_AUTHENTICATE and a C_Sign operation. With PKCS#15 user_consent is the number of times the PIN can be used before the user has to login again. PKCS#11 does not have this concept, just the CKA_ALWAYS_AUTHENTICATE. In you statement, for the app to decide whether to prompt the user or not could involve commands to the card which could then change the state of the card. Just returning USER_NOT_LOGGED_IN may not cause the application to do another login. Some applications use C_GetTokenInfo (or some such call) to test if the user is logged it. They do this expecting the state will not change while doing a Sign operation, and there are really 2 states, the login state and the CKA_ALWAYS_AUTHENTICATE state. This may differ for different cards. The PIV driver goes to great lengths to avoid any interference to the card between a CKU_CONEXT_SPECIFIC login and a crypto operation. so as to satisfy the card's PIN_Always requirements. It does not do that for a normal login. We do not have much control over the applications and much of what you want to do requires the applications to do things they do not do today. So my approach to this is to let users set options in opensc.conf to not only ignore_user_consent, (And don't forget about the PIN PAD readers which are designed to enforce policy. ) |
Do you have an opensc.debug.log to show why it did not work? It may need some additional locking. |
Sorry, the patch is in the wrong spot. Needs to be in 2 spots. RSA and ECC. I get usng NIST demo card 1:
|
I see, thanks.
The sane thing for an app to do upon such a return code would be to either attempt another login, or abort.
I'm not sure I understand the above - but if I do, I disagree. There is no "ALWAYS_AUTHENTICATE state". The card will tell you if it needs another login, when it needs another login. The potential problem is somebody else interfering between
Which IMHO is the consequence of the (IMHO unfortunate) decision to always re-authenticate by software whim, instead of relying on the card itself to tell you whether it needs a re-auth or not. (Assuming that by "override the policies" you mean "the user has a choice between suffering the software prompting for the PIN always regardless of whether it's needed or not - and 'overriding' when it won't prompt at all, except for the first time".)
I don't know enough to agree or disagree with the above. I don't think I've observed apps conforming to what you described, but I may be missing something.
The policy IMHO is adequately enforced by the card hardware/firmware itself. It doesn't need an OpenSC software cop to ride shotgun over it. IMHO, PIN PAD readers' main purpose is to avoid exposing the PIN to the computer at all, thus eliminating the potential for malware to steal it like it steals passwords.
Sure: |
I should've spotted that. No worries. I've applied the patch in the RSA place, and it worked excellent, exhibiting the behavior I like and can accept. Although I'd prefer to use the "override" as the last resort (like, for Java that cannot deal with tokens correctly without it), and in "normal" cases rely on the card: if for whatever reasons the login state was lost and re-login is needed - ask for it, otherwise proceed without bothering the user. That doesn't incur the risk of caching the PIN, and doesn't inconvenience the user needlessly. |
You said: "There is no "ALWAYS_AUTHENTICATE state". I would disagree. For the PIV, the state exists after a verify until the next APDU. This is the only time a key with the "PIN Always" can do a crypto operation General Authenticate with INS=87 Have a look at #1529. It causes pkcs15-crypt to do only one verify and signals the PIV driver to do an extra PCSC lock which start a PCSC transaction. The transaction will not end until the piv driver finishes the next APDU what ever it is. In the case of pkcs15-crypt this is the crypto operation. Putting both the verify and crypto commands in the same transaction then locks out other applications from sending any APDUs to the card for the PIV applet, other applet like OpenPGP or testing APDU like those use to match a driver to a card. Because of all the problems with the multiple applets on a card, and other applications looking at cards between transactions, the PIV driver at the start of every transaction, checks for the active AID and the So it might be possible to treat the verify from the original C_Login such that it does the extra PCSC lock, Or for the first C_Login at least tell the PIV driver to not check the state of the card until after the next command is sent. But this allows interference from other applications. |
If I understand you correctly, you are saying that enforcing "VERIFY" by the software/middleware for a key marked "ALWAYS_AUTHENTICATE" is necessary to accommodate the possibility that multiple apps are accessing the token (this applet, or other/multiple applets)?
It seemed to me that the software doesn't even need to know whether the key has the ALWAYS_AUTHENTICATE attribute or not, let alone query for it. If |
"Enforcing "VERIFY" by the software/middleware for a key marked "ALWAYS_AUTHENTICATE" does 3 things.
Unfortunately just returning "NOT_LOGGED_IN" to an application is not good enough. We have seen applications that may do more then just redoo the verify. They may backup further and do other commands between the VERIFY and the crypto operation again. We have also seen applications do a C_GetSessionInfo to test the login state just before the crypto operation and don't expect the crypto to return NOT_LOGGED_IN. We do not have control over these applications. There are some trade offs being made between avoiding any interference, using two applets at the same time, not caching the pin, and trying to use use the initial verify of a PIN to satisfy the "PIN Always". Right now the circumvention is to use pin caching. Will continue discussion of Dual CAC/PIV with next comment... |
The PIV driver has to deal with Dual CAC/PIV cards and PIV/OpenPGP cards. And it has to deal with PIV applets which do not follow NIST specifications especially dealing the login state. I would like to add better detection of Dual PIV/CAC cards to the PIV driver. My problem is I don't have and CAC or Dual CAC/PIV cards. There have been a number of recent issues dealing with what look like Dual CAC/PIV cards. On way to solve some of these was in: #1460 (comment) I would like the assistance of: @mouse07410, @Jakuje or anyone else who has a CAC or Dual CAC/PIV card to sent the ATR and the output of the CCC. (See below.) Both PIV and CAC define a CCC. NIST 800-73-4 says: "The Card Capability Container (CCC) is a mandatory data object whose purpose is to facilitate compatibility of Government Smart Card Interoperability Specification (GSC-IS) applications with PIV Cards." ref1.c.i-CAC_End-Point_Implementation_Guide_v1-22.pdf The PIV driver can return the CCC to the application, (but has not needed to use it internally.) For example reading the CCC of the NIST Demo card 1:
or
I am especially interested in the F3 and F5 tags. Thanks. |
It looks like we diverged a bit from the original subject that the issue started with. Can we start a new clean issue with just discusison about the CAC/PIV detection? I would be happy to help. I have two CAC cards (from 2012 or so) at hand, from which one of them should be dual, but it is not detected by the PIV driver and the other should be plain CAC. The CCC in the CAC driver is not exposed as an object in PKCS#11 interface, but used internally to detect the objects on the card. If I see right what you ask for, it is F3 tag (ApplicationsCardURL) and F5 (Registered Data Model). For the cards I have, I get the following cardURLs:
The second card (non-PIV compliant) I have is missing the AID The data mode number for the dual card is
And
Collected using master + #1535 |
The reason for the divergence is I expect to find that Dual CAC/PIV cards have a problem with one or more of the PIV card_issues. It might be possible to back off on commands used at the start of every PIV transaction for Dual CAC/PIV, as these commands were added mostly for the Dual PIV and OpenPGP applets on the same card. I don't think there would ever be CAC, PIV and OpenPGP applets on the same card. The PIV CCC is mandatory for a true PIV card, (But not needed by OpenSC PIV driver). So if present it can be used to see if any of the F3 or F5 indicate it is also CAC. So would expect it to be there for any Dual CAC/PIV as (I believe) these are all government issued cards, And it is not clear if on a Dual mode card, that the "PIN Always" in enforced on the PIV SIGN key. Or if the PIV driver could use the CAC commands to use the CAC "CAC Email Signature" key, that appears to be the same certificate and key and I believe that the CAC applet does not enforce "PIN Always" on the card. If any of above are true, it might avoid the "CKA_ALWAYS_AUTHENTICATE" for the PIV SIGN Key on these Dual CAC/PIV cards. A lot of testing would be needed. |
@mouse07410 and send results. Can you try adding to opensc.conf with your ATR:
|
But the ATR you provided above is not for CAC:
For Yubikey 4 the ATR is As far as I can tell, the ATR you gave does nothing (observable). For the CAC (new issue):
Having both tokens inserted:
Replacing the ATR you gave with the proper one for my CAC (i.e., forcing it to be a PIV):
So, the object doesn't appear to be there. |
Well Thanks for trying to see if the PIV applet has a CCC. The hex output above is a prompt to login that was sent to stdout, and the util_getpass had an error, Most likely because no pssword was entered. Since the driver being used was the CAC driver, Based on the #1533 (comment) it sounded like this was a request to look at some of the CKA_ALWAYS_AUTHENTICATE issues. Bu I think I may have lead you and Jakub down the wrong path as the original problem sounds like some driver cross talk, when more then one card is inserted. I guess I should have stopped when you said in: #1533 (comment) |
The password certainly was not entered, because there was no prompt for it. Some stdin/stdout redirection screw-up, I think.
As you saw above, the PIV applet response with
It certainly was on my side. And your test-patch addressed it. What's missing is extending that patch into checking for whether
I concur: either CAC+PIV, or PIV+OpenPGP. |
Sounds like the regression and crazy behavior was solved by building from master. The issue of The test patch was in the PIV driver to not set I would like to ask @frankmorgner and others to comment on how should the user express their desire to override this possible policy of the card issuer:
I for one, consider this an overriding of a policy of the card issuer and the user or site should understand that they are overriding a policy and the override should not be the default. |
There is no card that I know of, that would set ALWAYS_AUTHENTICATE but not enforce it in hardware. In fact, I claim that such a card is not compliant. Therefore I re-state my opinion that OpenSC shouldn't play a cop for such cards (whose existence, BTW, is unclear). Yes, if this "enforcement" is going to continue - of course user's desire to override must be respected for all the cases. No, there's no need for a different parameter. Yes it should apply to all cards, but in addition to that the ability of the user to constrain it to some cards only, via, e.g., ATR, would be great. I agree that if the decision is to keep the enforcement in place, override should not be the default setting. |
If it can be avoided, we should try not to add more options. Keep in mind, that it's the vendor's intended behavior and there's no need to make it comfortable to avoid.
A per-card-configuration would be useful, yes. But since it won't be used very often, I personally will not put too much effort into this.
Yes. It should reflect a behavior that's enforced in hardware (I agree with @mouse07410 ). We should, however, treat it correctly by default at the PKCS#15 level to avoid unexpected failures at the lower level.
To answer these, we need to look at the original intention of this setting given in ISO7816-15 (previously PKCS#15):
So actually it tells us how many times we can use the private key before we need to ask the PIN again. However, in OpenSC we only use this flag to check whether we are allowed to cache the PIN or not. So before adding new options here and there, we need to question whether we have a good understanding of this setting. |
... and back to the original question. Am I getting this right that there isn't any problem with CAC/PIV/OpenPGP left? Identification and functionality of the cards are as expected (i.e. OK)? |
Give me a day to confirm. It's been somewhat unstable, and I couldn't determine the cause yet. |
I agree that we don't have a good understanding of the PKCS#15 Note PKCS$15 says about user_consent: "the card may enforce this value". I read this as saying the card issuer by setting user_consent expects the middleware to enforce this even if the card does not. That is why I am in favor of "override" and "policy" in option name. (I disagree with Mouse's comment: "It doesn't need an OpenSC software cop to ride shotgun over it.") Here is some sample code that can implement a pin_cache_override_user_consent_policy.diff.txt The override is actually implemented in 2 places as examples of what we could do:
PKCS#15 cards set For emulated cards, the code in So the sample patch still needs work to add or remove some code. I tested patch using |
Since you've been in the field longer than I have - could you name one card you know of that "expects the middleware to enforce..."? Not to mention that from security point of view "delegating" the responsibilities (that I might point out are the primary reason to use hardware tokens!) to software that may or may not care, would not be a good policy for a card manufacturer that wishes to stay in business. And probably not many of commercial (or government) purchasers would be eager to buy such a card. So, I think the "may enforce" piece is technically valid, but 100% impractical and unreasonable. |
No I can not name one. I got into Kerberos in the late 80's so passwords would not be sent over the internet, then in the late 90's got in to smartcards so one would not need a password but instead use a smartcard with Microsoft AD (as the Kerberos KDC) and even pushed for pin pad readers so even the PIN was not exposed. I have concentrated on the PIV since HSPD-12 was released in 2004. It was obvious that the DOE Lab where I retired from would eventually be using PIV cards. OpenSC was originally designed to support PKCS#15 cards and there may be cards where keys have user_consent set, but I don't have much interest in PKCS#15 cards and don't have any. I leave it up to the PKCS#15 developers to answer your question. |
Back then I added SecureNetKey hardware token support to Kerberos-IV, and then ported it to -V. ;-)
No argument here - but my point is: if a card supports that kind of a flag, it invariably enforces it in hardware by itself. It would not rely on software to do it. |
OK. It looks like we diverged a little from the main line of this issue. I confirm that the current master worked OK with the current Firefox (Dev Edition) and the current (reasonably "fresh") CAC. Thank you for your help! |
So the original issue is resolved. We started discussion about ignoring the always authenticate few comments back with a new option (sigh ...) and with some working patch from @dengert. Should we follow up on this with new issue or PR? Anyway, from what I remember, neither of the NIST PIV Test cards enforces the always authenticate policy (the coolkey driver ignored this and worked as a charm). But that is not an excuse and I think OpenSC does the right thing enforcing this policy, while we should indeed provide a working solution to overwrite it if needed. |
@Jakuje are you saying that your test NIST PIV cards allow other operations between login and, e.g., signing with an ALWAYS_AUTHENTICATE key? Please forgive me if I don't believe it. Or do you mean that when you perform signatures with those cards/keys, since there's no "flow interruption" between token login and requested crypto - it knows it doesn't need to bug you with an extra PIN request, so it doesn't? Also, does your test setup user PIN caching? (which would silently feed the PIN to the card without asking you)? |
This goes a bit off topic, but as you are talking about userConsent... I've noticed that OpenSC maps PKCS#15 userConsent to CKA_ALWAYS_AUTHENTICATE when reading cards and parsing PKCS#15, but seems to ignore this attribute when creating keys via PKCS#11. I would like to add handling of CKA_ALWAYS_AUTHENTICATE to functions pkcs15_create_private_key() and pkcs15_create_secret_key() and map it to userConsent=1. Card drivers could then set their own card specific flags when creating keys, to enforce re-authentication for each use of a specific key. At least in MyEID it can be set separately for each key object. Authentication state of a selected PIN is reset after using the key, if set. |
As I understand, OpenSC usually prefers that vendor-provided tools are used to generate keys. |
CAC driver keeps giving me trouble once in a while (on access to DOD sites that want SIGN cert), starting to prompt incessantly for a PIN. When I change
everything becomes normal. I have I guess I shouldn't waste mine and everybody else's time trying to get CAC driver to work, when PIV does the job fine enough. |
Problem Description
When I specify in
opensc.conf
the driver to use for the CAC asI am unable to login to remote Web sites via Firefox: it keeps prompting for a PIN forever.
Proposed Resolution
My workaround was to comment out the
driver = "cac";
, letting the PIV driver to take over. Then I can login fine.This problem started occuring after CAC1 (the old model) support was re-integrated. Before that CAC driver worked just fine.
Steps to reproduce
/Library/OpenSC/lib/opensc-pkcs11.dylib
.Logs
Not sure how to capture a log from Firefox.
The text was updated successfully, but these errors were encountered: