Hello Andre, (and a Cc to the list as you requested)
I know what you are trying to explain. Let me describe it from another POV: I have a card (the Estonian ID-card to be precise) with an authentication key and a non-repudiation key and with two PIN codes, PIN1 and PIN2. The authentication key can be used as long as PIN1 is verified once and until the card is reset. The signature key requires PIN2 verification before every operation. The fact that the authentication key can be used by other applications once I've verified PIN1 and until I have not removed the card from the reader (if the reader is not locked or in exclusive mode), is actually a usability feature for me. If I want the key to become inactive, I remove the card from the reader. Yes, it means that an adversary could abuse the authentication key if my host computer would be compromised. If you allow other users to be logged in to your personal computer, you're compromised by design. If you're not using a standard desktop system, you can tweak opensc.conf to match your requirements. The code below will, in fact, demonstrate the possible abuse with the authentication key. But the card takes measures to protect the signature key by requiring a PIN2 verification before every operation with the key, so your demo below will have no effect. Requiring a PIN before every operation does not really protect against a compromised computer either - if the computer is under the control of the adversary, you can't even be sure that the data sent to the card is not tampered with, not even at PKCS#11/PCSC level (what C_Login locking would help against) but on a lower level, for example with a "fixed" libpcsclite or a rootkit module or something similar. Possible solutions to the problem require support from the card (and card driver and PKCS#11 applications) or sacrificing usability for better "security". Some options: * lock the card at C_Login time and loose the ability to use multiple applications simultaneously. That means very bad or zero usability for people who want to read e-mail and browse the web with Mozillas at the same time for example. Would be even worse if they used VPN for network access. * make all your keys require user consent before use and be forced to enter the PIN for every operation. This will result in a PIN entry dialog for every SSL handshake for example. PIN caching can be used to prevent this, but this will a) be not very secure as the adversary could scan your memory and find out the PIN code b) will not work for pinpads, that *will* require a PIN entry on the pinpad for every operation. Not very convenient. And OpenSC does not cache PINs that protect objects that require user consent before use, as that would break the original idea. * make OpenSC reset the card after every transaction (transaction_reset = true in opensc.conf) and guarantee that after every logical transaction (for example, C_SignInit->C_Sign) the card will be reset and keys will be de-authorized and will require re-authentication of the PIN code. This will result in behavior like in the previous point, with the difference that PIN caching could trigger a transparent re-authentication. Again, this involves caching the PIN, which, by nature, is not the best thing to do. This will actually not work as there are two different transactions, one for C_Login and one for C_Sign, and C_Sign would result in sec_error_token_not_logged_in from Firefox for example. Nor would work de-authenticating the key after a successful sign/decrypt, see below. * but you could use cards that support "authentication cookies" that can be cached by the application and re-used for operations that might require PIN verification. That would work with pinpads for example, and keep the PIN safe, but would not protect an adversay inside your computer from tampering with the communication between host and card or sniffing the authentication cookie. * fix common applications (for example Firefox and Thunderbird) to use C_Login only when needed and issue a C_Logout when the token is not used any longer. Locking the card for a single application makes sense if the granularity of operations allows other apps to use the card as well. * implement a "PKCS#11 daemon" that controls access to the card and multiplexes it to applications. That's something that Gnome keyring apparently wants to do (or what Tokend on OS X is supposed to do). Tokend by default also would want to lock the card for Tokend use only, which would mean that OpenSC PKCS#11 module would not work. Not very usable and not done by OpenSC.tokend So, to really be sure that your PIN is safe from the adversary in your computer and to take steps against unaothorized key use, you need to: - only use a pinpad reader for PIN entry - use cards that support requiring user consent before every key operation and enable it for your keys - pray that your computer is not under the control of the bad guys so that you can actually be sure that the data you think you're signing is the data you actually send to the card Right now, the balance is between locking the card to a single application or requiring many PIN entries (always with a pinpad) or rely on pin caching by OpenSC. Here are bits and pieces from the PKCS#11 v2.20 spec that should be taken into account when dealing with the problem: * Page 13, 6.2 Design goals: "A secondary goal was resource-sharing. As desktop multi-tasking operating systems become more popular, a single device should be shared between more than one application. In addition, an application should be able to interface to more than one device at a given time." (Locking the device on C_Login is against this principle) * Page 83, 10.9 Private key objects: The CKA_ALWAYS_AUTHENTICATE attribute can be used to force re- authentication (i.e. force the user to provide a PIN) for each use of a private key. “Use” in this case means a cryptographic operation such as sign or decrypt. This attribute may only be set to CK_TRUE when CKA_PRIVATE is also CK_TRUE. (this must of course be enforced by the card, not just as an attribute of the PKCS#11 module) * Page 126, 11.6 Session management functions: C_Login may be called repeatedly, without intervening C_Logout calls, if (and only if) a key with the CKA_ALWAYS_AUTHENTICATE attribute set to CK_TRUE exists, and the user needs to do cryptographic operation on this key. See further Section 10.9. (which means that arbitrarily de-authenticating keys after C_Login without CKA_ALWAYS_AUTHENTICATE is actually not a nice thing to do) Conclusion: if you allow "unknown actors" to operate on your host machine, the "inherent security of smart cards" will become negligible with or without locking the reader at C_Login. If your usage scenario depends on end user machines being knowingly compromised, there's nothing you can do. For an informed and motivated adversary the contents of OpenSC configuration makes no difference. The risk of a random intruder attacking the smart card communication (instead of installing a spambot or website defacement) depends, but is not as huge. Eventually it is the task of the smart card to protect what's inside and thus the responsibility of the card initializer to set the values that are sufficient for the application or usage scenario in question. If there's a risk that damage can be done by unauthorized key use, the card must take measures to protect it from misuse. And require user consent. For your specific case, I would suggest trying out SELinux before anything else. Cheers, Martin On Aug 17, 2010, at 6:30 PM, Andre Zepezauer wrote: > Hello, > > obviously not even you know the difference. Execute the following steps: > > 1. insert your smart card > 2. verify your pin via one of the mozilla applications > 3. log into your system as a different user via ssh or another terminal > 4. check out opensc trunk at revision 4508 > 5. apply the following patch and build the whole thing > 6. run "pkcs11-tool -t" > > (Debian, Ubuntu, MacOSX are confirmed to work) > > Do you want to tell me any longer, that this has something to do with > security? Will you post this to the mailing list too? > > Index: src/pkcs11/framework-pkcs15.c > =================================================================== > --- src/pkcs11/framework-pkcs15.c (revision 4508) > +++ src/pkcs11/framework-pkcs15.c (working copy) > @@ -736,7 +736,7 @@ > } else { > snprintf(tmp, sizeof(tmp), "%s", p15card->label); > } > - slot->token_info.flags |= CKF_LOGIN_REQUIRED; > +// slot->token_info.flags |= CKF_LOGIN_REQUIRED; > /* FIXME: update this information during runtime */ > if (pin_info->tries_left >= 0) { > if (pin_info->tries_left == 1) > Index: src/libopensc/reader-pcsc.c > =================================================================== > --- src/libopensc/reader-pcsc.c (revision 4508) > +++ src/libopensc/reader-pcsc.c (working copy) > @@ -452,6 +452,8 @@ > > static int pcsc_disconnect(sc_reader_t * reader) > { > + return SC_SUCCESS; > + > struct pcsc_private_data *priv = GET_PRIV_DATA(reader); > > SC_FUNC_CALLED(reader->ctx, SC_LOG_DEBUG_NORMAL); > > -- Martin Paljak @martinpaljak.net +3725156495 _______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel