Closed robhancocksed closed 10 months ago
Actually, if I'm following right, I think C_Decrypt might actually be the behavior required here (encrypt uses the public key, decrypt uses the private).
So the issue here actually seems larger than this - the problem is that OpenVPN is using TLS 1.3 which requires the RSASSA-PSS signature scheme. It appears that OpenSSL is doing the PSS internally and then passing on the request with RSA_NO_PADDING. It doesn't appear the HSM can currently do either the PSS padding itself or a "raw" RSA operation which would allow PSS to be done in software. So nothing in either pkcs11-helper or the Optiga PKCS#11 implementation can ultimately fix that, it appears.
Eventually pkcs11-helper may need to be updated to support the CKM_*_RSA_PKCS_PSS mechanisms, but right now OpenSSL is handling it internally in pkey_rsa_sign before __pkcs11h_openssl_rsa_enc is even called, so it would likely need to be hooked in at a higher level.
I've created a feature request for RSASSA-PSS on the Optiga HSM: https://github.com/Infineon/optiga-trust-m/issues/92
RSA-PSS is supported by OpenvPN 2.6 with pkcs11-helper, but not in any currently released versions. In your case that's not going to help as your hardware is not able to handle PSS signatures. If raw RSA is also not supported, the only option I see is to use TLS 1.2 and restrict signature algorithms. Restricting sigalgs is done in openssl.cnf. Combine it with --tls-version-max 1.2 in OpenVPN. Both are required because OpenSSL 1.1.1 and later defaults to PSS signatures even for TLS1.2 when using RSA keys.
See https://community.openvpn.net/openvpn/ticket/1296?cversion=0&cnum_hist=11#comment:17 (the comment in there about Windows versions that do not read openssl.cnf is now outdated -- versions 2.5.5 onwards also works on Windows, if that's a concern).
By the way I do not think the comment you quoted about RAW RSA signature (CKM_RSA_X_509) should use Decrypt is correct. In fact the pkcs#11 docs you linked to does list Sign/Verify/Decrypt/Encrypt/Wrap/Unwrap as functions supported for CKM_RSA_X_509. That said there may be tokens out there which does Decrypt with raw RSA but not signature. TPM is a different beast and has its own limitations and restrictions.
I am trying to set up OpenVPN to use client certificates and private keys stored on an Infineon Optiga Trust M HSM device. This has a PKCS11 implementation available at https://github.com/Infineon/optiga-trust-m/blob/develop/examples/utilities/pkcs11_trustm.c which I am trying to use. The current version has various bugs which I am trying to fix and work through to get things working.
The problem I am running into now is that during the session negotiation process, OpenVPN and OpenSSL end up calling __pkcs11h_openssl_rsa_enc with padding set to RSA_NO_PADDING. pkcs11-helper then ends up calling pkcs11h_certificate_signAny with mechanism set to CKM_RSA_X_509, which ends up in the Optiga library in C_SignInit. It rejects that with CKR_MECHANISM_INVALID because the only supported mechanisms for RSA are CKM_RSA_PKCS, CKM_SHA256_RSA_PKCS, CKM_SHA384_RSA_PKCS, CKM_SHA512_RSA_PKCS, so things pretty much grind to a halt at that point.
I found a report against an error with CKM_RSA_X_509 in tpm2-pkcs11 here: https://github.com/tpm2-software/tpm2-pkcs11/issues/335 In that report the conclusion seems to have been that CKM_RSA_X_509 should not be used with C_SignInit:
I'm not quite sure what to make of that. I may be able to make the Optiga signing operations support CKM_RSA_X_509, but possibly pkcs11-helper should be using C_Encrypt instead when asked for RSA_NO_PADDING?