Skip to content
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

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

Closed
gesteur opened this issue Aug 19, 2019 · 17 comments
Closed

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

gesteur opened this issue Aug 19, 2019 · 17 comments

Comments

@gesteur
Copy link

gesteur commented Aug 19, 2019

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
Copy link
Owner

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
Copy link
Author

gesteur commented Aug 20, 2019

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.
https://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
Copy link

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
Copy link
Author

gesteur commented May 12, 2020

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
Copy link
Owner

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
Copy link

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
Copy link
Author

gesteur commented May 12, 2020

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.

https://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.
openssl/openssl#7968 (comment)
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
Copy link
Author

gesteur commented May 13, 2020

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:

  • downgrade the TLS connection to TLSv.1.1 which uses old SHA1 signing algo and deprecated padding scheme. (TLSv.1.2 will not work either)
  • choose an applet which allows encryption without padding : CKM_RSA_X_509 / ALG_RSA_NOPAD / RSA_NO_PADDING (all synonyms used by different programs)

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
Copy link
Owner

philipWendland commented May 18, 2020

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
Copy link
Owner

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
Copy link

edgecase14 commented Jun 16, 2020

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
Copy link
Owner

philipWendland commented Jun 17, 2020 via email

@martinpaljak
Copy link
Contributor

How do you define a crash? Exception? Brick?

@philipWendland
Copy link
Owner

philipWendland commented Jun 17, 2020 via email

@martinpaljak
Copy link
Contributor

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

@philipWendland
Copy link
Owner

philipWendland commented Jun 19, 2020 via email

@philipWendland
Copy link
Owner

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

No branches or pull requests

4 participants