philipWendland / IsoApplet

A Java Card PKI Applet aiming to be ISO 7816 compliant
GNU General Public License v3.0
165 stars 72 forks source link

Support for RSA-PSS / RSA-X-509 #18

Closed gesteur closed 4 years ago

gesteur commented 5 years ago

OpenVPN currently seems to use the RSA no padding signature algorithm, making it not compatible with a smartcard using IsoApplet. Debugging openVPN, the call to pkcs11-helper invokes the following padding alg: CKM_RSA_X_509 which is not supported by IsoApplet. Pkcs11-helper has been patched to support this recently.

I patched the IsoApplet code on my local PC, to add the signature use case for ALG_RSA_NOPAD and modified the openSC driver card-isoApplet.c to include this new option. This has been tested on a JCOP 41 card (javacard 2.2.1) card, and I now can sucessfully connect to my VPN server.
(since my card is 2.2.1 I also had to remove the apdu extended stuff for this to work with my card.)

Was wondering if it would make sense to add the no padding code to your official repository?

philipWendland commented 5 years ago

Hi, thank you for reporting this. Do you happen to know why OpenVpn prefers raw RSA over padded RSA? If the token and applet would (theoretically) support OAEP padding, would OpenVpn use this instead?

Raw/textbook RSA has many weaknesses, and by exposing it as function of the token, the responsibility to add padding is transferred to the application or middleware. I think it would be better to enforce that there is at least PKCS#1 padding - at the token - to prevent weaknesses resulting from improper configuration or use. But I would be happy to hear other opinions about it.

Kind regards, Philip

gesteur commented 5 years ago

Hi, I would not know why OpenVPN doens't use PKCS#1 anymore in the handshake, it could be as well that it's OpenSSL forcing it, I stumbled across different forum posts where users couldn't use their smartcards anymore. I debugged the code for the algorithm mechanism selection, and the padding passed to OpenSC and PKCS11-helper is no_padding (CKM_RSA_X_509) , I dont think I have a way of influencing this via OpenVPN configuration. To avoid misunderstandings: The algorithm is no padding, but the data is pre-padded by OpenSSL so it should be secure, cant see a reason why they would go for a less secure option.

e.g of a post where the same issue is described. http://openssl.6102.n7.nabble.com/Issue-with-smartcard-authentication-for-openvpn-td76415.html

Reading on other forums some suggest to use an earlier version of TLS which would use PKCS#1, but that 's not really an option, why would I use old protocols and install an older version of OpenVPN + OpenSSL?!

I'm aware that RSA with no padding is not as secure if the data is not passed pre-padded, but that is in my opinion the responsability of the software, not the token to ensure that the message is properly padded. Blocking such algorithm at the token level will result in an incompatibility with OpenVPN and possibly other softwares, which is really a pity.

as for me, I just started using smartcards for authentication, not really an expert at all, took me some days to figure out concept of smartcards, different javacard version, which applet can be used for PKI, OpenSC, ecc ecc, which software to patch. This triggered to post here an enhancement request and share some insights with whoever might face the same issues I had to get IsoApplet working with OpenVPN.

I might create a repository based on IsoApplet with javacard version 2.2.1 if you dont mind, where the extended apdu is not supported.

Grüsse Gesteur

edgecase14 commented 4 years ago

I have a similar issue when using TLS1.3 with Client Certificate authentication, in connection with IsoApplet.

With Firefox on 76 on Ubuntu 20.04, I can downgrade to TLS1.2 and authenticate successfully. While TLS1.2 in general is considered "secure" as of today, there is a known issue when using Client Certificates, in that tracking is possible:

DOI 10.1515/popets-2018-0031

I see that newer JavaCards support RSA-PSS, would it make more sense for IsoApplet to add support for that?

I realize that it would be desirable to support older cards, but I myself have found it more cost effective to just buy newer cards rather than develop backwards compatibility. There is also the added benefit of other enhancements that come with newer cards.

As for OpenVPN, I suspect there is an option to downgrade to TLS1.2 and remain secure, although I am not aware of the implications for user tracing in that case when using Client Certificates. Perhaps that is an acceptable compromise until support for RSA-PSS is available.

gesteur commented 4 years ago

I have a similar issue when using TLS1.3 with Client Certificate authentication, in connection with IsoApplet.

With Firefox on 76 on Ubuntu 20.04, I can downgrade to TLS1.2 and authenticate successfully. While TLS1.2 in general is considered "secure" as of today, there is a known issue when using Client Certificates, in that tracking is possible:

DOI 10.1515/popets-2018-0031

I see that newer JavaCards support RSA-PSS, would it make more sense for IsoApplet to add support for that?

I realize that it would be desirable to support older cards, but I myself have found it more cost effective to just buy newer cards rather than develop backwards compatibility. There is also the added benefit of other enhancements that come with newer cards.

As for OpenVPN, I suspect there is an option to downgrade to TLS1.2 and remain secure, although I am not aware of the implications for user tracing in that case when using Client Certificates. Perhaps that is an acceptable compromise until support for RSA-PSS is available.

I think people will be switching to other applets, like PIV applet, where RSA-PSS is supported in software. Since as you correctly say OpenSSL is using no padding (RSA-PSS) algorithm which they pre-pad before sending it to the card.

If you want to use isoapplet, i have patched it so it works with RSA-PSS, you can find it on my repository, including opensc driver.

philipWendland commented 4 years ago

I have a similar issue when using TLS1.3 with Client Certificate authentication, in connection with IsoApplet.

With Firefox on 76 on Ubuntu 20.04, I can downgrade to TLS1.2 and authenticate successfully. While TLS1.2 in general is considered "secure" as of today, there is a known issue when using Client Certificates, in that tracking is possible:

DOI 10.1515/popets-2018-0031

I see that newer JavaCards support RSA-PSS, would it make more sense for IsoApplet to add support for that?

I realize that it would be desirable to support older cards, but I myself have found it more cost effective to just buy newer cards rather than develop backwards compatibility. There is also the added benefit of other enhancements that come with newer cards.

As for OpenVPN, I suspect there is an option to downgrade to TLS1.2 and remain secure, although I am not aware of the implications for user tracing in that case when using Client Certificates. Perhaps that is an acceptable compromise until support for RSA-PSS is available.

I totally agree with this approach - this should be done using the JavaCard API. The ABI at OpenSC can easily be backwards compatible (i.e. new OpenSC can support older applet versions).

I think IsoApplet should move towards 3.0+ cards soon (at the main branch). Older 2.2.2 cards can be supported with necessary patches for some time.

I plan on investigating this next week - I don't have access to my smartcards earlier.

edgecase14 commented 4 years ago

I think people will be switching to other applets, like PIV applet, where RSA-PSS is supported in software. Since as you correctly say OpenSSL is using no padding (RSA-PSS) algorithm which they pre-pad before sending it to the card.

I just looked at PIVapplet, and it does not support RSA-PSS, even on JC3.0.5 cards (even though it could support it on most JC3.0.1 cards). It allows RSA-X509 (RAW) signatures directly on data from outside the card, which exposes risk of improper use to a larger surface, as Philip has mentioned.

It is more accurate to say PIVapplet enables RSA-PSS emulation in OpenSC. This can be useful for testing TLS1.3 with applications such at Firefox and OpenVPN in combination with OpenSC, but I don't see it as a long term solution, since PSS has been developed to enhance (provability) of security.

That is likely why TLS1.3 removed support for the older RSA-PKCS1 signatures, which are supported by both IsoApplet and PIVapplet. This article explains: RSA-PSS

So, each person can choose for themself, which compromise to use in the short term: TLS1.2 or RSA-X509(RAW). Long term, JC3.0.1 support of RSA-PSS provides enhanced security following industry best practices and mathematical proofs.

To be clear, TLS1.2 compromises by allowing tracking when using Client Certificate authentication. OpenSC + PIVapplet compromise by allowing a larger vulnerability field (more software that can have mistakes). Both are tradeoffs. When RSA-PSS support comes to an opensource applet (either one), then no tradeoffs will be required (except waiting!).

If you want to use isoapplet, i have patched it so it works with RSA-PSS, you can find it on my repository, including opensc driver.

Technically, what you have done is enabled RSA RAW in IsoApplet. It is OpenSC (available starting in release 0.20) which is "emulating" RSA-PSS to provide support to pkcs11 using applications such as OpenVPN and OpenSSL(engine_pkcs11).

gesteur commented 4 years ago

you are fully right, I meant that RSA-PSS is done in software and then sent to the token which uses RAW RSA to sign, but this doesn't seem to happen in OpenVPN. With TLSv1.2 and TLSv1.3 OpenVPN seems to ask for a no padding algorithm, according to the below link and debug statements when i launch OpenVPN, i get the same results. If I lower to TLS1.1 then OpenVPN will use: Control Channel: TLSv1.1, cipher TLSv1.0 ECDHE-RSA-AES256-SHA, which in turn will ask the token to use pkcs1 padding.

http://openssl.6102.n7.nabble.com/Issue-with-smartcard-authentication-for-openvpn-td76415.html

"padding = 3 means "no padding" indicating that the data for signature is already padded. That's why the data size (flen) is 256 (hashed data padded to the rsa key size of 2048 bits, I guess). If you are using OpenSSL 1.1.1, this could be due to PSS padding in which case current implementation passes pre-padded data for raw signature to the callback. AFAIK, pkcs11-helper only handles PKCS1 padding (CKM_RSA_PKCS) though pkcs11 standard does support raw signatures. "

so i'm a little bit lost, also if the applet will support native PSS padding, this will not solve the issue right since OpenVPN is requesting no padding?

I think I'm missing something...

edit: I should say OpenSSL decides which padding algorithm to use

edit2: Please check out this issue. https://github.com/openssl/openssl/issues/7968#issuecomment-450742204 This is exactly what has been happening with the upgrade of OpenSSL to 1.1.1. This obviously has a drawback with SmartCards that don't expose RAW RSA, which I of course understand is a risk.

gesteur commented 4 years ago

to summarize a bit, at the beginning I wasn't really clear what the issue was and confused some things, hopefully this will clarify for other people who are also stumbling on the same issue without spending hours of debugging, researching on the internet, etc etc.

my issue was that after upgrading to OpenSSL 1.1.1, I couldn't use IsoApplet in combination with OpenVPN anymore.

To solve this issue one has 2 choices:

problem description:

in short: if you use OpenSSL 1.1.1 the padding schema is not RSA_PKCS1_PADDING anymore so the smart token won't be able to do the signing any longer if it doesn't expose raw RSA padding algorithm.

long version: With OpenSSL 1.1.1, TLSv.1.3 is being released which changes the RSA padding to use RSASSA-PSS (let's call it RSA-PSS). see chapter 1.2 https://tools.ietf.org/html/rfc8446

As a consequence OpenSSL does the pre-padding, it's not OpenVPN, OpenSC or other programs but it's OpenSSL itself which choses the padding algorithm. OpenSSL uses RSA-PSS and will pre-pad the data, then call the RSA encryption function specifying RSA_NO_PADDING for the padding (see post above). Hence when we get the request to sign or encrypt data on the smart token this will fail, since most smart tokens don't support that padding algo.

That said, I'm not sure that supporting the token with native RSA-PSS signature will change anything, until OpenSSL changes their code not to select RSA_NO_PADDING.

As for me, i don't see it as a risk if the token exposes raw RSA (RSA_NO_PADDING), it won't expose the private key. if the token is used for signing then the risks are far less (signed data is not secret) if compared to using TLSv1.0. Considering that a serious software like OpenSSL is doing the padding, i have no concerns that the padding is done correctly.

As everyone says, using raw RSA is insecure if padded incorrectly, it could reveal the cipher text with brute force attacks.

philipWendland commented 4 years ago

I am not quite sure yet whether supporting RSA-PSS at the token would solve this issue at once. If not, OpenVPN or OpenSSL code should be looked at.

After some digging, ALG_RSA_SHA_256_PKCS1_PSS is supported since 3.0.1. But it is optional and not supported by many smart cards. I found a G&D SmartCafe 7.0 card at home that should suffice for testing. I think 3.0.1 should be the next JC version that IsoApplet supports.

I started work at https://github.com/philipWendland/IsoApplet/tree/jc301 and https://github.com/philipWendland/OpenSC/tree/jc301. Will take some time though, as I want to make some clean-ups while I'm at it.

philipWendland commented 4 years ago

My G&D SmartCafe 7.0 crashes at https://github.com/philipWendland/IsoApplet/blob/jc304/src/net/pwendland/javacard/pki/isoapplet/IsoApplet.java#L1412

No Exception, just 6F00. Maybe I did something wrong, don't know for sure yet. Strangely enough, my card is listed as "c22" here, Signature.ALG_RSA_SHA_256_PKCS1_PSS should actually work...

@edgecase14

I see that newer JavaCards support RSA-PSS, would it make more sense for IsoApplet to add support for that?

Do you happen to have a card that supports Signature.ALG_RSA_SHA_256_PKCS1_PSS and makes it past the line above?

E.g. (with https://github.com/philipWendland/IsoApplet/tree/jc304 and https://github.com/philipWendland/OpenSC/tree/jc304):

#!/bin/bash

pin=0000
key_id=0

set -e

java -jar gp.jar --uninstall IsoApplet/IsoApplet.cap
java -jar gp.jar --install IsoApplet/IsoApplet.cap

echo "$pin
$pin

" | pkcs15-init -C
pkcs15-init --generate-key "rsa/2048" --pin $pin --id $key_id --auth-id "FF" --label "rsa-pss-test"

pkcs11-tool --sign --input-file test.txt -m "SHA256-RSA-PKCS-PSS" --pin $pin
edgecase14 commented 4 years ago

I have #79 NXP J3D081 and testing as requested,


pkcs11-tool --sign --input-file test.txt -m "SHA256-RSA-PKCS-PSS" --pin $pin

PSS parameters: hashAlg=SHA256, mgf=MGF1-SHA256, salt_len=32 B 
error: PKCS11 function C_SignInit failed: rv = CKR_MECHANISM_INVALID (0x70)
Aborting

but with SHA256-RSA-PKCS1 it returns a result with no error. I will double check the result against openssl, and also that I am running OpenSC jc304 branch, since I did a half-install only.

philipWendland commented 4 years ago

Thank you.

OPENSC_DEBUG=10 pkcs11-tool might help, but you might also be using another (old) opensc library. I don't expect it to work yet though, I am more interested whether your card also crashes (before I order another card).

Jeremy Jackson notifications@github.com schrieb am Di., 16. Juni 2020, 22:45:

I have #79 https://github.com/crocs-muni/JCAlgTest/tree/master/Profiles/results/NXP_JCOP_J3D081_v242r2_ICFabDate_2012_334_3b%20f9%2013%2000%2000%2081%2031%20fe%2045%204a%2043%204f%2050%2032%2034%2032%2052%2032%20a3.csv_(provided_by_Martin_Paljak_and_Arnis_UT).csv and testing as requested,

pkcs11-tool --sign --input-file test.txt -m "SHA256-RSA-PKCS-PSS" --pin $pin

PSS parameters: hashAlg=SHA256, mgf=MGF1-SHA256, salt_len=32 B error: PKCS11 function C_SignInit failed: rv = CKR_MECHANISM_INVALID (0x70) Aborting

but with SHA256-RSA-PKCS1 it returns a result with no error. I will double check the result against openssl, and also that I am running OpenSC jc304 branch, since I did a half-install only.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/philipWendland/IsoApplet/issues/18#issuecomment-645002236, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA4R5DAS7SR3ALXAJWZD5EDRW7KWFANCNFSM4IM5ZLIA .

martinpaljak commented 4 years ago

How do you define a crash? Exception? Brick?

philipWendland commented 4 years ago

Good question, I should've been more precise.

The card returns 6F00 on this line of code, without throwing an exception. It remains responsive after that, but this behavior is still against the javacard API specification.

(I've seen other cards getting unresponsive on other occasions, with the need to pull it from the reader to make it work again)

Martin Paljak notifications@github.com schrieb am Mi., 17. Juni 2020, 09:51:

How do you define a crash? Exception? Brick?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/philipWendland/IsoApplet/issues/18#issuecomment-645214171, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA4R5DET6K5HPYIPV7I6HF3RXBYXVANCNFSM4IM5ZLIA .

martinpaljak commented 4 years ago

Are you sure it does not throw some almost-known exception?

philipWendland commented 4 years ago

Yes,I think so. I caught "Exception" i.e. all exceptions, and it didn't make a difference.

Martin Paljak notifications@github.com schrieb am Fr., 19. Juni 2020, 13:19:

Are you sure it does not throw some almost-known exception?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/philipWendland/IsoApplet/issues/18#issuecomment-646581554, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA4R5DDXNUSM5VYSPOAKEWLRXNCS3ANCNFSM4IM5ZLIA .

philipWendland commented 4 years ago

Closing this one, see #23 or https://github.com/philipWendland/IsoApplet/projects/1.