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

.Net 9 Core > TPM Provider > tlsv1 alert decrypt error:../ssl/record/rec_layer_s3.c:1584:SSL alert number 51 #111251

Open
serkanturhanxl opened this issue Jan 9, 2025 · 4 comments
Labels
area-System.Security untriaged New issue has not been triaged by the area owner

Comments

@serkanturhanxl
Copy link

serkanturhanxl commented Jan 9, 2025

If I run the openssl server and client commands it communicates to each other.

openssl s_server -provider tpm2 -provider default -propquery '?provider=tpm2' -accept 4567 -key handle:0x81000006 -cert ssl_certificate.pem -cert_chain combinedchain.pem -cipher AES128-GCM-SHA256 -max_protocol TLSv1.2

openssl s_client -connect localhost:4567 -cipher AES128-GCM-SHA256 -debug -msg -min_protocol TLSv1.2 -max_protocol TLSv1.2

But If I implement the Server command into a console application and (client the same as console) It gives error:

Interop+Crypto+OpenSslCryptographicException: error:0A000093:SSL routines::decryption failed

Here is the client side error:

4067BCE3AC7F0000:error:0A00041B:SSL routines:ssl3_read_bytes:tlsv1 alert decrypt error:../ssl/record/rec_layer_s3.c:1584:SSL alert number 51

Here is the wiereshark screenshot.
Image

This is the code I used to get key from TPM.

string handle = "handle:0x81000006";
SafeEvpPKeyHandle privateKey = SafeEvpPKeyHandle.OpenKeyFromProvider("tpm2", handle);
RSAOpenSsl rsa = new(privateKey);
X509Certificate2 tmpCert = new X509Certificate2("/etc/ssl/certs/ssl_certificate.pem");
X509Certificate2 certificate = tmpCert.CopyWithPrivateKey(rsa);

Here is the code to set sslOptions:

SslServerAuthenticationOptions sslOptions = new SslServerAuthenticationOptions
{
    EnabledSslProtocols = SslProtocols.Tls12, // Only use these protocols
    CipherSuitesPolicy = new CipherSuitesPolicy(new[]
    {
        TlsCipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256
    }),
    ServerCertificate = cert, //cert from 0x81000006 handle
    ClientCertificateRequired = true,
    EncryptionPolicy = EncryptionPolicy.RequireEncryption,
    
};
_stream.AuthenticateAsServer(sslOptions);

Here is the example application to reproduce the issue:
https://github.com/serkanturhanxl/TPMHandler

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Jan 9, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

@bartonjs
Copy link
Member

bartonjs commented Jan 9, 2025

@krwq Any immediate thoughts spring to mind?

@krwq
Copy link
Member

krwq commented Jan 15, 2025

First validate if encrypt and decrypt work with RSA instance you get from the provider - make sure to use public key directly rather than using provider key for verify/encryption.

Now assuming that works fine I have two things which come to my mind:

For a workaround right now you might need to use OpenKeyFromEngine instead which doesn't require separately passing OSSL_LIB_CTX along with EVP_PKEY

@GuyWithDogs
Copy link

GuyWithDogs commented Jan 15, 2025

I'm wondering if my question about where the OpenSSL default provider is being loaded (ref. #111250) might be relevant here.

Looking at the OpenSSL README-PROVIDERS page (https://github.com/openssl/openssl/blob/master/README-PROVIDERS.md), it says

The Default Provider
The default provider collects together all of the standard built-in OpenSSL algorithm implementations. If an application doesn't specify anything else explicitly (e.g. in the application or via config), then this is the provider that will be used. It is loaded automatically the first time that we try to get an algorithm from a provider if no other provider has been loaded yet. If another provider has already been loaded then it won't be loaded automatically. Therefore, if you want to use it in conjunction with other providers, then you must load it explicitly. This is a "built-in" provider, which means that it is compiled and linked into the libcrypto library and does not exist as a separate standalone module.

I did some experimenting using the openssl s_server command and found that it would fail if the default provider was not available, either as a -provider default parameter or by being activated in openssl.cnf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Security untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

4 participants