OpenVPN / openvpn

OpenVPN is an open source VPN daemon
http://openvpn.net
Other
10.75k stars 2.99k forks source link

PKCS11 no longer works in newer version #505

Open amin1best opened 7 months ago

amin1best commented 7 months ago

Hi, Is there a plan to support Trusted Platform Module (TPM) in the next release? Thanks.

schwabe commented 7 months ago

On what platform and on what capacity? It might be already support or not depending what you actually are looking for. E.g. https://github.com/tpm2-software/tpm2-openssl should already work with OpenVPN.

amin1best commented 7 months ago

I used tpm2-pkcs11 in old versions, but it does not work in the new version of OpenVPN. Would it be possible for you to explain step by step how I can use tpm2-openssl in OpenVPN or at least guide me.

schwabe commented 7 months ago

pkcs11 is should be supported in the old and new version. And also say what old and new version are. So if it doesn't work anymore that is a regression. But you need to provide more input here. Give us a log from the old version and the new version, so we can have an idea what is different. As for helping with tmp2-openssl, I never used that myself, so I cannot help there. But OpenSSL providers work in general, so that one should also work.

amin1best commented 7 months ago

I think the problem is not OpenVPN and tpm2-pkcs11 doesn't work with OpenSSL 3. The new version means the version of OpenVPN that has migrated to OpenSSL 3. To use tpm2-pkcs11 in OpenVPN, I used the following command:

openvpn --config ./openvpn.config --ca ./connection.crt --pkcs11-providers /usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1 --pkcs11-id "$URL"

The question is, what command should I use in OpenVPN to use tpm2-openssl? Or with what command in general how to introduce TPM to OpenVPN? Even without PKCS11. ​

selvanair commented 7 months ago

The question is, what command should I use in OpenVPN to use tpm2-openssl? Or with what command in general how to introduce TPM to OpenVPN? Even without PKCS11.

As tpm2-openssl can encapsulate the key in a pem file with TSS2 PRIVATE KEY header, I think you can just use the key and corresponding cert as you would do with normal key and cert files in pem format. However, you will need to add --providers tpm2 default to the comand line or in the config file.

Here is a minimal example (untested)

$ cat client.conf
client
dev tun
providers tpm2 default
ca ca.crt
cert mycert.crt
key mykey.pem  # this is a TSS2 PRIVATE KEY protected by TPM
remote myserver.foo.bar
$ sudo openvpn --config client.conf

PS: --providers default tpm2 or set a propquery to use tpm2 only when necessary would be preferred as TPM is slow. But that requires a fairly recent version of tpm2-openssl because of a bug (#tpm2-software/tpm2-openssl/issues/81)

amin1best commented 3 months ago

Thank @schwabe , @selvanair , I followed https://github.com/OpenVPN/openvpn/issues/505#issuecomment-1960016502 and got following error from server side:

OpenSSL: error:02000088:rsa routines::salt length check failed:expected: 32 retrieved: 222
selvanair commented 3 months ago

I followed https://github.com/OpenVPN/openvpn/issues/505#issuecomment-1960016502 and got following error from server side: OpenSSL: error:02000088:rsa routines::salt length check failed:expected: 32 retrieved: 222

Are you using TLS 1.3 ?

While 222 bytes looks like a valid salt length (assuming 2048 bit key, sha256 hash, 222 bytes would be result from maximizing the salt length), but TLS 1.3 requires the salt length to be same as digest length.

That said, I do not understand how this mismatch could happen unless TPM2 or tpm2-openssl on client-side is misbehaving -- I think OpenSSL on client will indicate appropriate salt length in the signature request -- is TPM ignoring that? Raise this in tpm2-openssl.

amin1best commented 3 months ago

@selvanair ,

I used tls-version-{min,max} but it made no difference.

assuming 2048 bit key, sha256 hash

yes,

I changed 2048 to 1024 and got the following error:

OpenSSL: error:02000088:rsa routines::salt length check failed:expected: 32 retrieved: 94

Any idea how to change 32? It seems very low!

selvanair commented 3 months ago

Googling brings up several reports on Windows about a similar TPM2/TLS1.3 interoperability issue. All due to a conflict between the TPM2 specs and TLS1.3. Old TPM2 standard did require salt length to be maximized, but the standard appears to have been amended[1] to be compliant with FIPS and TLS 1.3. You probably have an old firmware or OS version

I tested on my ubuntu 22.04 laptop and it works for me. Both when used through OpenVPN via tpm2-openssl provider, or directly using tpm2_sign, signatures are generated with salt length = digest length. What OS are you using?

If firmware/OS updates do not help or not available, your options are (i) Use an EC key for client certificate OR (ii) Restrict signature algorithm in openssl.cnf and set tls-version-max to 1.2 in OpenVPN --- not ideal

I used tls-version-{min,max} but it made no difference.

TLS 1.2 also defaults to using RSAPSS though not mandatory unlike TLS 1.3. So you would need to do both the steps mentioned in (ii) above.

[1] Annex B, page 264 of of https://trustedcomputinggroup.org/wp-content/uploads/TPM-2.0-1.83-Part-1-Architecture.pdf

krwq commented 3 months ago

Sorry if this message is a bit offtopic as I found it while doing something else with TPM2 provider. I believe the problem might be related to the issue I reported above (https://github.com/tpm2-software/tpm2-openssl/issues/115) - TPM2 provider seem to be ignoring when you set salt length and will use max length instead. On validation side you can simply use EVP_PKEY_CTX_set_rsa_pss_saltlen with RSA_PSS_SALTLEN_AUTO (or max) for signing that's problematic as I didn't find any way to workaround - it ignores both placeholder and explicit setting of length

amin1best commented 3 months ago

My environment:

Debian 12
OpenVPN 2.6.3
OpenSSL 3.0.11
TPM9660-TT
TPM firmware is up to date.

@selvanair , thanks for the follow up, EC key worked. I used tls-version-{min,max}, tls-cipher, tls-cert-profile in RSA mode and restrict signature algorithm in openssl.cnf but it made no difference. If I'm not mistaken you believe that the problem is my TPM with TLS 1.3 but why was there no problem in tpm2-pkcs11, OpenSSL 1? Unfortunately, this problem has prevented us from updating OpenVPN.

selvanair commented 3 months ago

I used tls-version-{min,max}, tls-cipher, tls-cert-profile in RSA mode and restrict signature algorithm in openssl.cnf but it made no difference.

It should be possible to avoid PSS using tls-version-max 1.2 and restricted sigalgs. No other options needed. Here is a relevant snippet of /etc/ssl/openssl.cnf that has worked for me in the past for this, though not for using TPM.

openssl_conf = default_conf

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.1
SignatureAlgorithms = RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512

That said, downgrading to TLS 1.2 is not a good option.

If I'm not mistaken you believe that the problem is my TPM with TLS 1.3 but why was there no problem in tpm2-pkcs11, OpenSSL 1?

Which version of OpenSSL 1? -- I think OpenSSL 1.1.1 should exhibit the same issue. Probably the version combination you were using earlier did not trigger PSS signatures.

amin1best commented 2 months ago

Everything was fine in this environment:

Debian 11
OpenVPN 2.5.1
OpenSSL 1.1.1w
tpm2-pkcs11 1.9.0

@selvanair , Thank you very much for helping me. Last question, In tpm2-pkcs11 I used --pkcs11-id to introduce the key but in tpm2-openssl you suggested the pem format file. Is there no way not to save the key as a file and and have a handle to the TPM?

selvanair commented 2 months ago

Last question, In tpm2-pkcs11 I used --pkcs11-id to introduce the key but in tpm2-openssl you suggested the pem format file. Is there no way not to save the key as a file and and have a handle to the TPM?

OpenVPN's --key option expects a file (or inlined PEM), not a URI. So I don't think something like handle:0x81000000 would work. You can inline the PEM data into the config file though.

amin1best commented 2 months ago

Does OpenVPN have a plan to support URI like handle:0x81000000?

@selvanair and @schwabe

selvanair commented 1 month ago

Does OpenVPN have a plan to support URI like handle:0x81000000?

I'm not sure about this very non-standard and poorly named URI, but, in general, it looks useful to modernize our key/cert options to take URIs like pkcs11: used by pkcs11-provider. Also not all providers are expected to support a PEM file wrapper.

@amin1best If you want to test, I have a draft implementation here. Specify the key as --key handle:0x81000000 or any URI supported by loaded providers or filename. Same with --cert.