From f55b27716a50e80c4eb0661ea3ec284ec559fc5b Mon Sep 17 00:00:00 2001 From: Matthew Fennell Date: Mon, 17 Jun 2024 22:27:17 +0100 Subject: Allow self-signed .onion file transfer certs (#1149) Most Certificate Authorities don't support issuing X.509 certificates for onion sites. However, it can still be useful to provide a certificate over Tor in some circumstances, for instance to tie your alphanumeric Tor address to your site's main identity. Therefore, many Tor services provide self-signed certificates. This is OK, since the onion service itself guarantees that you are connecting to the entity you think you are. Dino already allows self-signed certs when communicating over Tor (see 81a5505). However, the same exception does not exist yet for HTTP uploads and downloads - causing these to fail over Tor. Therefore, in this commit, we add the same exception for uploads/downloads, by passing the host of the upload/download urls to the already existing invalid certificate connection handler. Note that this handler only allows certificates with type TlsCertificateFlags.UNKNOWN_CA. This means the certificate of your server must also include the onion http upload and download URLs in its certificate - otherwise, the file transfer will fail with TlsCertificateFlags.BAD_IDENTITY. --- plugins/http-files/src/file_provider.vala | 10 ++++++++++ plugins/http-files/src/file_sender.vala | 3 +++ 2 files changed, 13 insertions(+) (limited to 'plugins/http-files') diff --git a/plugins/http-files/src/file_provider.vala b/plugins/http-files/src/file_provider.vala index 34c3a48a..d62e3561 100644 --- a/plugins/http-files/src/file_provider.vala +++ b/plugins/http-files/src/file_provider.vala @@ -120,6 +120,11 @@ public class FileProvider : Dino.FileProvider, Object { var head_message = new Soup.Message("HEAD", http_receive_data.url); head_message.request_headers.append("Accept-Encoding", "identity"); +#if SOUP_3_0 + string transfer_host = Uri.parse(http_receive_data.url, UriFlags.NONE).get_host(); + head_message.accept_certificate.connect((peer_cert, errors) => { return ConnectionManager.on_invalid_certificate(transfer_host, peer_cert, errors); }); +#endif + try { #if SOUP_3_0 yield session.send_async(head_message, GLib.Priority.LOW, null); @@ -153,6 +158,11 @@ public class FileProvider : Dino.FileProvider, Object { var get_message = new Soup.Message("GET", http_receive_data.url); +#if SOUP_3_0 + string transfer_host = Uri.parse(http_receive_data.url, UriFlags.NONE).get_host(); + get_message.accept_certificate.connect((peer_cert, errors) => { return ConnectionManager.on_invalid_certificate(transfer_host, peer_cert, errors); }); +#endif + try { #if SOUP_3_0 InputStream stream = yield session.send_async(get_message, GLib.Priority.LOW, file_transfer.cancellable); diff --git a/plugins/http-files/src/file_sender.vala b/plugins/http-files/src/file_sender.vala index 957611d0..a2f4769b 100644 --- a/plugins/http-files/src/file_sender.vala +++ b/plugins/http-files/src/file_sender.vala @@ -94,7 +94,10 @@ public class HttpFileSender : FileSender, Object { if (stream == null) return; var put_message = new Soup.Message("PUT", file_send_data.url_up); + #if SOUP_3_0 + string transfer_host = Uri.parse(file_send_data.url_up, UriFlags.NONE).get_host(); + put_message.accept_certificate.connect((peer_cert, errors) => { return ConnectionManager.on_invalid_certificate(transfer_host, peer_cert, errors); }); put_message.set_request_body(file_meta.mime_type, file_transfer.input_stream, (ssize_t) file_meta.size); #else put_message.request_headers.set_content_type(file_meta.mime_type, null); -- cgit v1.2.3-70-g09d2