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

Can't get DTLS SSL to work (TLS handshake error: -9984) #59080

Open
Toupoc opened this issue Mar 12, 2022 · 12 comments
Open

Can't get DTLS SSL to work (TLS handshake error: -9984) #59080

Toupoc opened this issue Mar 12, 2022 · 12 comments

Comments

@Toupoc
Copy link

Toupoc commented Mar 12, 2022

Godot version

3.4.3

System information

windows 10, linux CentOS

Issue description

I'm using godot 3.4.3 to edit and export my projects. I'm running the server projects through godot 3.4.2 linux_server version. I have my server code running in the document root of a dedicated server. I bought an SSL from a 3rd party. I tried runnning the server project as the root user, as well as a non-root user. My cert and keys load properly in godot on the server and on the client ( I checked by having it print them when they're loaded) I tried loading the cert and key directly from where they are installed on the server, AND i tryed loading copies of them from the res:// directory in godot instead. My SSL definately works in some respect because when I go to the URL that's connected to my server I do get the little lock icon.

THE PROBLEM: when I try to use this dang SSL for a DTLS connection when the player signs in (and change setdtlsvarifyenabled() to TRUE) I just keep getting a handshake error. When I keep it false, everything works fine. But when I try to use my newly aquired SSL and switch it to true. Handshake errors for days. This is the error I get TLS handshake error: -9984
I've been grappling with this issue for weeks now. I really need this DTLS to work for sign in. Does anyone have any idea what could be wrong? I'm losing my mind over here.

Please help.

Godot version Godot 3.4.3 + Godot 3.4.2_linux_server.64

Steps to reproduce

Just download and run the minumal reproduction project. You'll see that it connects to the server with dtls disabled but when you set it to true using the 3rd party signed SSL (WHICH IS NOT FROM LETSENCRYPT) you get handshake errors.

I WILL KEEP MY SERVER RUNNING INDEFINATELY SO YOU BEAUTIFUL PEOPLE CAN TEST THIS.

Minimal reproduction project

Reproduction.zip

@Calinou
Copy link
Member

Calinou commented Mar 12, 2022

This is the error I get --> E 0:00:04.727 _dohandshake: TLS handshake error: -9984

-9984 is an mbedTLS error code in decimal form (#58807). It means that your TLS certificate is invalid (e.g. it's expired or not considered trusted by a certificate authority).
Does your .crt file include the full validation chain? See #37739. Also make sure that the .crt file is included in your export preset (see #18327).

PS: Please upload a minimal reproduction project to make this easier to troubleshoot. (The code sample alone is not a complete minimal reproduction project, as it cannot run on its own.)

@Calinou Calinou changed the title DTLS SSL Can't get DTLS SSL to work (TLS handshake error: -9984) Mar 12, 2022
@Toupoc Toupoc closed this as completed Mar 14, 2022
@Toupoc Toupoc reopened this Mar 14, 2022
@Toupoc
Copy link
Author

Toupoc commented Mar 14, 2022

This is the error I get --> E 0:00:04.727 _dohandshake: TLS handshake error: -9984

-9984 is an mbedTLS error code in decimal form (#58807). It means that your TLS certificate is invalid (e.g. it's expired or not considered trusted by a certificate authority). Does your .crt file include the full validation chain? See #37739. Also make sure that the .crt file is included in your export preset (see #18327).

PS: Please upload a minimal reproduction project to make this easier to troubleshoot. (The code sample alone is not a complete minimal reproduction project, as it cannot run on its own.)

Thank you. I believe I have fixed the post. The crt does have the full validation chain. I checked it with ssllabs.com, though some of the results from the check did seem puzzling. Also, the .crt file IS included in the export presets. Excellent suggestions. These were my first thoughts as well.

PS. Here is a direct link to the SSL test results incase you want to see for yourself (which isn't a bad idea, I could be doing it wrong) and don't want to type in the domain/ip https://www.ssllabs.com/ssltest/analyze.html?d=stopclock.app&latest

@sigrudds1
Copy link

I have been helping Toupoc with this issue, I tried it a different way using StreamPeerSSL and I get the same result, not sure what I am doing wrong. I made a small test, cut down from a working game Orbem Wars, for Toupoc to put on their server and then I proceeded to test it on another server. I created a Ubuntu20LTS vm, used no-ip and letsencrypt made via certbot. The cert works without verify but not with it . Here is a link to the github proj I made for Toupoc to test, if you want the certificate I can send them to you in DM but did not upload them in the project for obvious security reasons. https://github.com/sigrudds1/Godot-DTLS-3rdParty

@sigrudds1
Copy link

sigrudds1 commented Jul 18, 2022

OK got it to work, thanks to Nisovin on the Godot Discord for suggesting using the fullchain1.pem as the ssl_cert and chain1.pem for ssl_chain in the StreamPeerSSL.accept_stream(tcp_peer, ssl_key, ssl_cert, ssl_chain). I also use symlink to the files created by certbot which will automatically update the certificates using ln -s privkey1.pem ssl_key.key; ln -s fullchain1.pem ssl_cert.crt; ln -s chain1.pem ssl_chain.crt

@Calinou
Copy link
Member

Calinou commented Jul 18, 2022

For reference, the above comment was cross-posted on the Godot Q&A: https://godotengine.org/qa/135488/has-anyone-ever-gotten-a-3rd-party-ssl-to-work

@Faless Is this a bug with accept_stream(), or do we need to change something in the documentation?

@Faless
Copy link
Collaborator

Faless commented Jul 19, 2022

I think it's a bug, in the sense that the ca_chain argument effectively does nothing, and you need to use the "fullchain" certificate.
I think we should just deprecate the "ca_chain" parameter, and just require full chain certificates (there is really no difference in mbdedtls or in the spec, fullchain is simply ca_chain and cert concatenated).

@sigrudds1
Copy link

Well without the verify it works as documented, especially going the self-signed route per the docs where the fullchain is not produced, maybe additional direction in the docs for the CA section, unless you want to change the docs entirely. If/While the docs are being edited I would also suggest noting that the pem files should be renamed or symlinked to .key and .crt, it alludes to it, I figured it out, but is not clear when using a CA provided cert.

@Faless
Copy link
Collaborator

Faless commented Jul 19, 2022

@sigrudds1 well, in the case of self-signed certificates the certificate itself is the full chain, so it should work as long as it is (self-)signed for the correct domain.

The problem there in case is that when you do certificate pinning (e.g. self-signed certificates), you don't really care about the domain name so that check might be redundant.

But there is a conceptual difference between "just my cert" (certificate pinning), and "just one CA" (a Root CA).

Maybe we can detect self signed certificates and disable hostname verification in that case specifically, but I'm a bit reluctant as it might have security implications which I'm not thinking of right now.

There might also be a better solution I'm not seeing right now.

In any case, I would much prefer we make a clear tutorial/example of using SSL/DTLS with self-signed (we can use Crypto now) and letsencrypt cert.

@sigrudds1
Copy link

sigrudds1 commented Jul 19, 2022

@Faless Here is a thought, if the fullchain is a combination of the chain and the cert then is the purpose of the chain parameter to concatenate the cert with the chain parameters? If this were the case then the bug would be that is not happening and if it did so it would have worked.
cert_chain

As I thought, nothing is being done with chain, an oversight?
accept_stream

@sigrudds1
Copy link

sigrudds1 commented Jul 20, 2022

Crude way of doing it but this works

Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain) {
	ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER);

	if (p_cert.is_valid() && p_ca_chain.is_valid()) {
		Error err;
		String cert = FileAccess::get_file_as_string(p_cert->get_path(), &err);
		ERR_FAIL_COND_V(err != OK, err); 
		
		String chain = FileAccess::get_file_as_string(p_ca_chain->get_path(), &err);
		ERR_FAIL_COND_V(err != OK, err); 
		
		String certs = cert + chain;
		CharString cs = certs.utf8();
		
		err = p_cert->load_from_memory((uint8_t *)cs.ptr(), cs.size());
		ERR_FAIL_COND_V(err != OK, err);
	}

@blurrred
Copy link

I was having the -9984 error when trying to communicate with a secure WebSocket (wss://). It was because I updated my SSL certificate on my server but didn't update nginx-selfsigned.crt on my Godot client. After doing that, everything worked as expected.

@sigrudds1
Copy link

I was having the -9984 error when trying to communicate with a secure WebSocket (wss://). It was because I updated my SSL certificate on my server but didn't update nginx-selfsigned.crt on my Godot client. After doing that, everything worked as expected.

This is not the same problem but is the same error code, which in a nutshell means the cert is not legit either thru verify or the cert itself; self signed cannot use verify flag, it will never pass, Your experience is not the same as the OP which is due to that the 3rd party provider did not give the full chain cert, some do but not all, and the function indicates parameters for the cert and chain separately which is what the full chain really is and proven by concatenating the chain with the cert and in the cert parameter of the function.

@github-project-automation github-project-automation bot moved this to For team assessment in Network Issue Triage Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: For team assessment
Development

No branches or pull requests

5 participants