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

Does xrdp support ECC? #1776

Closed
dannytech opened this issue Jan 3, 2021 · 8 comments · Fixed by #1778
Closed

Does xrdp support ECC? #1776

dannytech opened this issue Jan 3, 2021 · 8 comments · Fixed by #1778

Comments

@dannytech
Copy link

I use an ECC-based PKI for whatever I can, and so I attempted to use it for xrdp's TLS encryption. I have a certificate and corresponding EC key (using the secp384r1 curve, generated by OpenSSL). The key is in /etc/ssl/ with the correct permissions (644 for the cert and 640 for the key, with ssl-cert as the group for the latter and xrdp added to the ssl-cert group). This is then symlinked to /etc/xrdp/ in the same way that the default snakeoil certificate is (I've also tried directly pointing to the cert and key). The below configuration is used to enable TLS:

certificate=/etc/xrdp/cert.pem
key_file=/etc/xrdp/key.pem
ssl_protocols=TLSv1.2, TLSv1.3
tls_ciphers=HIGH

However, attempting to connect with both FreeRDP and MSTSC fails, and the latter produces the error Because of a protocol error detected at the client (code 0x2104), this session will be disconnected. Capturing via Wireshark, the server behaves seemingly normally (a couple TLS data continuations) and sometimes sends a FIN, but then the client sends a RST. There are also no errors on the xrdp side:

[20210103-00:03:33] [INFO ] Socket 12: AF_INET6 connection received from ::ffff:192.168.1.32 port 49222
[20210103-00:03:33] [DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.1.51 port 3389)
[20210103-00:03:33] [DEBUG] Closed socket 11 (AF_INET6 :: port 3389)
[20210103-00:03:33] [DEBUG] TLSv1.3 enabled
[20210103-00:03:33] [DEBUG] TLSv1.2 enabled
[20210103-00:03:33] [DEBUG] Security layer: requested 1, selected 1
[20210103-00:03:33] [DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.1.51 port 3389)

Changing to either the snakeoil keys or a self-signed RSA key solves this issue, it's only EC keys that won't work. I've tried both self-signed and CA-signed EC certificates, with a couple different curves. I wasn't able to find anything about whether ECC is supported by xrdp so I assumed by the lack of server errors that it has some level of support, but it apparently has issues with that. ECC works just fine with Windows machines so clearly the protocol supports it correctly (of course TLS would support it though), so I'm not sure where the break is.

Running Linux Mint 20 and xrdp 0.9.12.

@matt335672
Copy link
Member

Hi @dannytech

I'm not familiar with this area of code at all I'm afraid. I've had a quick look however, and I don't think it's good news:-

  • the logging is not all it could be. It's possible that an important message is not going to the log file, but to stdout of the xrdp process.
  • I've found a call to SSL_CTX_use_RSAPrivateKey_file. From what I understand of these things, it seems unlikely this will work with a non-RSA private key!

You should be able to get the full output from the xrdp process with the command sudo journalctl -u xrdp. If you pipe that through grep -i tls, we might get more information on what is happening on the server side.

Are you in a position where you can build xrdp from scratch? If so, we might be able to get a patch together for you.

@dannytech
Copy link
Author

dannytech commented Jan 4, 2021

Thanks for getting back to me, @matt335672. Here are the complete logs via journalctl from a fresh restart of the xrdp service with an EC cert and key (P-384 and SHA384) followed immediately by a connection attempt from MSTSC which fails as described above:

Jan 04 15:42:50 chakotay systemd[1]: Started xrdp daemon.
Jan 04 15:42:51 chakotay xrdp[29693]: (29693)(139907807864640)[INFO ] starting xrdp with pid 29693
Jan 04 15:42:51 chakotay xrdp[29693]: (29693)(139907807864640)[INFO ] address [0.0.0.0] port [3389] mode 1
Jan 04 15:42:51 chakotay xrdp[29693]: (29693)(139907807864640)[INFO ] listening to port 3389 on 0.0.0.0
Jan 04 15:42:51 chakotay xrdp[29693]: (29693)(139907807864640)[INFO ] xrdp_listen_pp done
Jan 04 15:43:04 chakotay xrdp[29693]: (29693)(139907807864640)[INFO ] Socket 12: AF_INET6 connection received from ::ffff:192.168.1.62 port 18503
Jan 04 15:43:04 chakotay xrdp[29693]: (29693)(139907807864640)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.5.51 port 3389)
Jan 04 15:43:04 chakotay xrdp[29697]: (29697)(139907807864640)[DEBUG] Closed socket 11 (AF_INET6 :: port 3389)
Jan 04 15:43:04 chakotay xrdp[29697]: (29697)(139907807864640)[DEBUG] TLSv1.3 enabled
Jan 04 15:43:04 chakotay xrdp[29697]: (29697)(139907807864640)[DEBUG] TLSv1.2 enabled
Jan 04 15:43:04 chakotay xrdp[29697]: (29697)(139907807864640)[DEBUG] Security layer: requested 11, selected 1
Jan 04 15:43:04 chakotay xrdp[29697]: (29697)(139907807864640)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.5.51 port 3389)

For comparison, I'm also including the logs from a successful connection with an RSA keypair:

Jan 04 15:46:29 chakotay systemd[1]: Started xrdp daemon.
Jan 04 15:46:30 chakotay xrdp[29772]: (29772)(140091503474496)[INFO ] starting xrdp with pid 29772
Jan 04 15:46:30 chakotay xrdp[29772]: (29772)(140091503474496)[INFO ] address [0.0.0.0] port [3389] mode 1
Jan 04 15:46:30 chakotay xrdp[29772]: (29772)(140091503474496)[INFO ] listening to port 3389 on 0.0.0.0
Jan 04 15:46:30 chakotay xrdp[29772]: (29772)(140091503474496)[INFO ] xrdp_listen_pp done
Jan 04 15:46:46 chakotay xrdp[29772]: (29772)(140091503474496)[INFO ] Socket 12: AF_INET6 connection received from ::ffff:192.168.1.62 port 18544
Jan 04 15:46:46 chakotay xrdp[29772]: (29772)(140091503474496)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.5.51 port 3389)
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] Closed socket 11 (AF_INET6 :: port 3389)
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] TLSv1.3 enabled
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] TLSv1.2 enabled
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] Security layer: requested 11, selected 1
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] connected client computer name: SCOTTY
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] adding channel item name rdpdr chan_id 1004 flags 0x80800000
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] adding channel item name rdpsnd chan_id 1005 flags 0xc0000000
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] adding channel item name cliprdr chan_id 1006 flags 0xc0a00000
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] adding channel item name nlr3hv chan_id 1007 flags 0x84200000
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] adding channel item name nlw3hv chan_id 1008 flags 0x84200000
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] adding channel item name drdynvc chan_id 1009 flags 0xc0800000
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] TLS connection established from ::ffff:192.168.1.62 port 18544: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] xrdp_00007450_wm_login_mode_event_00000001
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] Loading keymap file /etc/xrdp/km-00000409.ini
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[WARN ] local keymap file for 0x00000409 found and doesn't match built in keymap, using local keymap file
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] xrdp_wm_log_msg: connecting to sesman ip 127.0.0.1 port 3350
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] xrdp_wm_log_msg: sesman connect ok
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] xrdp_wm_log_msg: sending login info to session manager, please wait...
Jan 04 15:46:46 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] return value from xrdp_mm_connect 0
Jan 04 15:46:47 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] xrdp_wm_log_msg: login successful for display 10
Jan 04 15:46:47 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] xrdp_wm_log_msg: started connecting
Jan 04 15:46:47 chakotay xrdp[29776]: (29776)(140091503474496)[INFO ] lib_mod_log_peer: xrdp_pid=29776 connected to X11rdp_pid=29797 X11rdp_uid=379201103 X11rdp_gid=379200513 client_ip=::ffff:192.168.1.62 client_port=18544
Jan 04 15:46:47 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] xrdp_wm_log_msg: connected ok
Jan 04 15:46:47 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] xrdp_mm_connect_chansrv: chansrv connect successful
Jan 04 15:46:47 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] Closed socket 18 (AF_INET6 ::1 port 44502)
Jan 04 15:46:50 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] Closed socket 12 (AF_INET6 ::ffff:192.168.5.51 port 3389)
Jan 04 15:46:50 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] xrdp_mm_module_cleanup
Jan 04 15:46:50 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] Closed socket 19 (AF_UNIX)
Jan 04 15:46:50 chakotay xrdp[29776]: (29776)(140091503474496)[DEBUG] Closed socket 20 (AF_UNIX)

It appears that the server sees (or at least logs) no issue with what's going on, the only issue is that the client closes the connection early with ECC. I would be happy to set up a build environment for xrdp, would you rather I use a packaged version or the latest version from git?

@matt335672
Copy link
Member

That's interesting - from what I read yesterday I'd have expected you to see this:-

ssl_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed

the reason for this is that the keyfile you're trying to use isn't an RSA key, It's possible something is going wrong before this point I suppose.

If you're happy to build the devel branch from the main git repo I think that would be a good place to start.

Also, could you generate a gash EC private key and cert and post them here? I'll see if I can reproduce what you're seeing with them. It'll be easier if we're working with the same pairing.

@dannytech
Copy link
Author

Yeah I do find it interesting that there aren't any relevant logs. I've set up a build environment and successfully built from the latest devel code, and can confirm it's still not working. At this point it appears it no longer runs under systemd, so I can't use journalctl to get the stdout. I can of course still use the /var/log/xrdp.log file but let me know if you need stdout logs and where those would be going. I've also upped the log level to TRACE, which gives this log when running the checked-out code with the below certificate:

[20210105-12:11:42] [INFO ] starting xrdp with pid 84800
[20210105-12:11:42] [INFO ] address [0.0.0.0] port [3389] mode 1
[20210105-12:11:42] [INFO ] listening to port 3389 on 0.0.0.0
[20210105-12:11:42] [INFO ] xrdp_listen_pp done
[20210105-12:11:48] [INFO ] Socket 12: AF_INET connection received from 192.168.1.62 port 29209
[20210105-12:11:48] [DEBUG] Closed socket 12 (AF_INET 192.168.5.51:3389)
[20210105-12:11:48] [DEBUG] Closed socket 11 (AF_INET 0.0.0.0:3389)
[20210105-12:11:48] [DEBUG] TLSv1.3 enabled
[20210105-12:11:48] [DEBUG] TLSv1.2 enabled
[20210105-12:11:48] [DEBUG] Security layer: requested 11, selected 1
[20210105-12:11:48] [TRACE] ssl_tls_accept: tls_ciphers=HIGH
[20210105-12:11:48] [DEBUG] Closed socket 12 (AF_INET 192.168.5.51:3389)

I don't think I mentioned it previously but MSTSC sometimes just fails to connect silently, but other times fails with an error. Not sure why.

Here's a quick self-signed certificate I came up with. Note that it's pretty barebones (i.e. doesn't include a SAN or anything), I can make it a little more complex if you need but my actual production certificates with SANs and everything don't work anyway so I'm not exactly sure if there are specific requirements.

Private Key:

-----BEGIN EC PARAMETERS-----
BgUrgQQAIg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDDR41c5WWDGR5dK/il5kv+2YizlR/D1jg19wP29ITl1p7exGsQGMiVX
IpsZVIaznx+gBwYFK4EEACKhZANiAAS6g0G6sD85ZEK/WYkpsb4w5rXQmcy1S/t5
u2K9+wAr/VYtQwuJxRfjA2XbZq13Ic/PmB9hiiWIQ4f+Nmhrz5lYIovn0VHpNOF6
8nrE4JttgJvBWEjPKsI4pKHLxSNEJCE=
-----END EC PRIVATE KEY-----

Certificate (including metadata section):

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            51:c8:1e:bb:b1:81:12:51:f0:4b:0b:7f:90:2b:42:c9:04:49:92:d9
        Signature Algorithm: ecdsa-with-SHA384
        Issuer: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = XRDP Test EC Certificate
        Validity
            Not Before: Jan  5 20:02:35 2021 GMT
            Not After : Jan  5 20:02:35 2022 GMT
        Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = XRDP Test EC Certificate
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:ba:83:41:ba:b0:3f:39:64:42:bf:59:89:29:b1:
                    be:30:e6:b5:d0:99:cc:b5:4b:fb:79:bb:62:bd:fb:
                    00:2b:fd:56:2d:43:0b:89:c5:17:e3:03:65:db:66:
                    ad:77:21:cf:cf:98:1f:61:8a:25:88:43:87:fe:36:
                    68:6b:cf:99:58:22:8b:e7:d1:51:e9:34:e1:7a:f2:
                    7a:c4:e0:9b:6d:80:9b:c1:58:48:cf:2a:c2:38:a4:
                    a1:cb:c5:23:44:24:21
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                80:74:78:DF:E2:CD:F1:B2:78:0D:E2:25:AF:FA:81:F1:4B:7F:30:24
            X509v3 Authority Key Identifier: 
                keyid:80:74:78:DF:E2:CD:F1:B2:78:0D:E2:25:AF:FA:81:F1:4B:7F:30:24

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA384
         30:66:02:31:00:d4:b7:41:62:8b:11:0a:83:79:d1:9f:98:39:
         39:c7:23:b6:f3:25:34:a9:f8:83:bd:dc:63:0a:7a:2b:1a:16:
         04:b5:b8:43:6d:30:6b:c4:9a:1a:1e:b0:0a:92:5f:91:5f:02:
         31:00:ee:f2:f4:dc:ed:03:b6:d0:89:55:96:68:41:65:ae:bb:
         b0:bb:34:3e:41:ec:74:3c:d2:9c:a5:a5:dd:15:76:80:8a:e0:
         7d:97:e9:07:21:9d:ae:2c:29:62:f4:37:3d:66
-----BEGIN CERTIFICATE-----
MIICYzCCAeigAwIBAgIUUcgeu7GBElHwSwt/kCtCyQRJktkwCgYIKoZIzj0EAwMw
aDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEhMB8GA1UEAwwYWFJEUCBUZXN0IEVDIENl
cnRpZmljYXRlMB4XDTIxMDEwNTIwMDIzNVoXDTIyMDEwNTIwMDIzNVowaDELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDEhMB8GA1UEAwwYWFJEUCBUZXN0IEVDIENlcnRpZmlj
YXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEuoNBurA/OWRCv1mJKbG+MOa10JnM
tUv7ebtivfsAK/1WLUMLicUX4wNl22atdyHPz5gfYYoliEOH/jZoa8+ZWCKL59FR
6TThevJ6xOCbbYCbwVhIzyrCOKShy8UjRCQho1MwUTAdBgNVHQ4EFgQUgHR43+LN
8bJ4DeIlr/qB8Ut/MCQwHwYDVR0jBBgwFoAUgHR43+LN8bJ4DeIlr/qB8Ut/MCQw
DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEA1LdBYosRCoN50Z+Y
OTnHI7bzJTSp+IO93GMKeisaFgS1uENtMGvEmhoesAqSX5FfAjEA7vL03O0DttCJ
VZZoQWWuu7C7ND5B7HQ80pylpd0VdoCK4H2X6Qchna4sKWL0Nz1m
-----END CERTIFICATE-----

@matt335672
Copy link
Member

I don't think there are any specific requirements - the Windows client just moans if the name doesn't match for RSA, so I'm assuming that this is also the case for other certs.

I'll pop those two on a test VM and step through the code and let you know how I get on.

I see from your profile on github you've got some programming experience. Have you got any experience with gdb? If so I can give you some tips to step through the xrdp code yourself. Also you might want to check the expiry date of the cert for hellstern.org.

@matt335672
Copy link
Member

Just run through - here's a patch for you to try:-

diff --git a/common/ssl_calls.c b/common/ssl_calls.c
index aee18c28..6b5a2cf4 100644
--- a/common/ssl_calls.c
+++ b/common/ssl_calls.c
@@ -740,7 +740,7 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
 
     SSL_CTX_set_read_ahead(self->ctx, 0);
 
-    if (SSL_CTX_use_RSAPrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM)
+    if (SSL_CTX_use_PrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM)
             <= 0)
     {
         g_writeln("ssl_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed");

It's about as simple as it gets. I'm also getting:-

[INFO ] TLS connection established from aaa.bbb.ccc.ddd port 62123: TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384

Gotta dash - family duties. Let me know how you get on.

@dannytech
Copy link
Author

Fixed!

I see the same log, everything seems to be working correctly. Confirmed with both the cert I shared and with my CA-signed certificate, seems that it works just fine. You'll probably catch it, but g_writeln("ssl_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed"); still has RSA in the diff you provided.

Good catch on the expired cert... it was DNS + broken automatic certificate renewal. Thanks for that, and for the help figuring this issue out.

@matt335672 matt335672 reopened this Jan 6, 2021
@matt335672
Copy link
Member

I've taken the liberty of re-opening this so I've got something to pin a PR on. It'll get closed automatically when the PR gets pulled.

Following needs to be done for a production fix:-

  • Fix broken logging. so we get a better clue next time. @dannytech - thanks for the heads up on the duff string.
  • Check this patch works with RSA keys
  • Check the call is available for older builds.

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

Successfully merging a pull request may close this issue.

2 participants