Skip to content

Add TLS/TCP and DTLS/UDP support for both server and client#70

Open
ordinary-hacker wants to merge 3 commits intorobiot:masterfrom
ordinary-hacker:feat/tls-and-dtls-support
Open

Add TLS/TCP and DTLS/UDP support for both server and client#70
ordinary-hacker wants to merge 3 commits intorobiot:masterfrom
ordinary-hacker:feat/tls-and-dtls-support

Conversation

@ordinary-hacker
Copy link
Copy Markdown

Still just a draft, right now the code compiles and it already has some stuff tied up for it to support these two encryption methods. This draft PR is mostly to keep a little bit on progress and also if anyone has any suggestions and stuff like that.

I'll keep adding more commits to this as I test stuff, change stuff, and so on.

Fixes #59

@ordinary-hacker
Copy link
Copy Markdown
Author

Rn I mostly just need to actually test this and do some code refinements

@ordinary-hacker ordinary-hacker marked this pull request as ready for review August 14, 2025 16:13
@ordinary-hacker
Copy link
Copy Markdown
Author

Now this is ready to merge! In case needed for vetting here's a little guide to test:

first TLS works with DER format, meanwhile DTLS with PKCS#12 format, you can generate some quick test files with:

openssl genrsa -out server-key.pem 2048 && \
openssl req -new -x509 -key server-key.pem -out server-cert.pem -days 365 -subj "/CN=localhost" && \
openssl x509 -in server-cert.pem -outform DER -out server-cert-new.der && \
openssl rsa -in server-key.pem -outform DER -out server-key-new.der && \
openssl pkcs12 -export -in server-cert.pem -inkey server-key.pem -out server-new.p12 -name "rustcat-server" -passout pass:

then for example if using rcat listener and client for TLS

# Terminal 1 (TLS Listener)
./target/debug/rcat listen -i --protocol tls --cert server-cert-new.der --key server-key-new.der 8443

# Terminal 2 (rcat TLS Client)
./target/debug/rcat connect -s bash --protocol tls localhost 8443

rcat TLS listener but with openssl client

# Terminal 1 (TLS Listener)
./target/debug/rcat listen -i --protocol tls --cert server-cert-new.der --key server-key-new.der 8443

# Terminal 2 (OpenSSL Client)
openssl s_client -connect localhost:8443 -verify_return_error

rcat for DTLS listener and client

# Terminal 1 (DTLS Listener)
./target/debug/rcat listen -i --protocol dtls --cert server-new.p12 8444

# Terminal 2 (rcat DTLS Client)
./target/debug/rcat connect -s bash --protocol dtls --cert server-new.p12 localhost 8444

if just doing some echo tests for TLS:

# Terminal 1
./target/debug/rcat listen -i --protocol tls --cert server-cert-new.der --key server-key-new.der 8443

# Terminal 2
echo "Hello TLS" | openssl s_client -connect localhost:8443 -quiet

for dtls:

# Terminal 1
./target/debug/rcat listen -i --protocol dtls --cert server-new.p12 8444

# Terminal 2
./target/debug/rcat connect -s cat --protocol dtls --cert server-new.p12 localhost 8444

@robiot
Copy link
Copy Markdown
Owner

robiot commented Aug 14, 2025

looks cool

@ordinary-hacker
Copy link
Copy Markdown
Author

@robiot thanks :D

could you do the merge???

Comment thread src/listener/mod.rs
Comment on lines +162 to +165
let cert_path = opts.cert.as_ref().expect("TLS listener requires --cert");
let key_path = opts.key.as_ref().expect("TLS listener requires --key");
let cert_data = fs::read(cert_path).expect("Failed to read cert file");
let key_data = fs::read(key_path).expect("Failed to read key file");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

Establish a standard location for these files (analogous to of $HOME/.ssh/), preferably in a path like $XDG_CONFIG_DIR/rustcat1. The files .../server-cert.der2 and .../server-key.der, stored in that directory, could be loaded automatically if --protocol tls is used but no --cert and/or no --key argument (respectively) is given. To save the user having to type them every time.

(Another command line flag could disable automatic file loading even in the absence of --cert or --key, for the paranoid or in scripts. Something like --no-user-defaults, --ignore-user-keys, etc.)

Notes

  1. Where the XDG spec defines $XDG_CONFIG_DIR as either the contents of that envvar, or $HOME/.config/ if no such environment variable is set.
  2. (Or default-cert.der / default-key.der, you get the idea.)

Comment thread src/listener/mod.rs
Comment on lines +164 to +165
let cert_data = fs::read(cert_path).expect("Failed to read cert file");
let key_data = fs::read(key_path).expect("Failed to read key file");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second suggestion: Take a page from SSH et al, and check the permissions on any files being read, whether from a default location or one passed in via --cert / --key. Refuse to load encryption files if they're world-readable or (worse!) world-writable.

(SSH recommends, but doesn't enforce, that $HOME/.ssh/ have 0700 permissions, and will refuse to use any private key that's accessible by others, i.e. their private keyfile permissions mask is 0077.)

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 this pull request may close these issues.

Add crypto TCP/UDP data

3 participants