如何使用 Vala 建立 TLS 连接?
Posted
技术标签:
【中文标题】如何使用 Vala 建立 TLS 连接?【英文标题】:How can I make a TLS connection using Vala? 【发布时间】:2021-11-18 02:44:36 【问题描述】:我正在尝试弄清楚如何使用 Gio 建立正确的 TLS 连接。 Gio 文档说您可以通过在 SocketClient
上设置 tls
标志来创建 TLS 连接。下面是来自 gnome wiki 的 Gio 网络示例。当我设置tls
标志时,TLS 层会自动配置,但除非我跳过验证,否则验证证书会失败。
我必须自己验证证书还是应该由GLib
进行验证?有人可以提供有关如何在 Vala 中使用 TLS 的完整示例吗?
var host = "developer.gnome.org";
try
// Resolve hostname to IP address
var resolver = Resolver.get_default ();
var addresses = resolver.lookup_by_name (host, null);
var address = addresses.nth_data (0);
print (@"Resolved $host to $address\n");
// Connect
var client = new SocketClient ();
client.set_tls(true);
// skips certificate validation
client.set_tls_validation_flags( 0 );
var conn = client.connect (new InetSocketAddress (address, 443));
print (@"Connected to $host\n");
// Send HTTP GET request
var message = @"GET / HTTP/1.1\r\nHost: $host\r\n\r\n";
conn.output_stream.write (message.data);
print ("Wrote request\n");
// Receive response
var response = new DataInputStream (conn.input_stream);
var status_line = response.read_line (null).strip ();
print ("Received status line: %s\n", status_line);
catch (Error e)
stderr.printf ("%s\n", e.message);
我想问的另一件事是;当我运行上面的代码时,我得到了这个输出:
Resolved developer.gnome.org to 8.43.85.14
Connected to developer.gnome.org
Wrote request
Received status line: HTTP/1.1 200 OK
但是当我尝试连接 'developer.mozilla.org' 时,我收到以下错误:
Resolved developer.mozilla.org to 54.192.235.2
Error performing TLS handshake: A packet with illegal or unsupported version was received.
谁能告诉我出现此错误的原因? (顺便说一下我系统上安装的GLib版本是2.64.6)
【问题讨论】:
【参考方案1】:尝试使用export G_MESSAGES_DEBUG=all
运行程序以获取完整的调试消息。
此外,有关使用 Vala 通过 GIO 编写的 TLS 的完整代码示例,请查看此 Gemini 浏览器的代码:https://github.com/koyuspace/fossil/blob/main/src/util/connection_helper.vala
希望对你有点用处。
【讨论】:
感谢您的指针和链接。我会尽快检查。【参考方案2】:到目前为止,您所做的大部分是正确的,但您可能需要做更多的事情来处理 TLS 握手期间的潜在证书错误(见下文)。
我必须自己验证证书还是应该由 GLib 进行验证?
请注意,SocketClient.set_tls_validation_flags
已弃用。要处理验证错误,您可以在握手之前连接到 TlsClientConnection
上的 accept_certificate
信号:
var client = new SocketClient ();
client.set_tls(true);
client.event.connect ((SocketClientEvent event, SocketConnectable connectable, iostream? connection) =>
if (event == SocketClientEvent.TLS_HANDSHAKING)
((TlsClientConnection) connection).accept_certificate.connect ((peer_cert, errors) =>
// Return true to accept, false to reject
);
);
errors
是GLib.TlsCertificateFlags
,因此您需要确定哪些(如果有)是可接受的。理想情况下,如果有任何错误,您会完全拒绝证书,但如果您想允许例如自签名证书,则可以采用这种方式。
您可以简单地检查标志以查看 errors
中包含哪些标志:
TlsCertificateFlags[] flags = new TlsCertificateFlags[]
TlsCertificateFlags.BAD_IDENTITY,
TlsCertificateFlags.EXPIRED,
TlsCertificateFlags.GENERIC_ERROR,
TlsCertificateFlags.INSECURE,
TlsCertificateFlags.NOT_ACTIVATED,
TlsCertificateFlags.REVOKED,
TlsCertificateFlags.UNKNOWN_CA
;
foreach (var flag in flags)
if ((errors & flag) != 0)
// The flag was included in the errors - respond accordingly
但是当我尝试连接“developer.mozilla.org”时,我得到了 以下错误:
将 developer.mozilla.org 解决为 54.192.235.2 执行 TLS 时出错 握手:收到非法或不支持版本的数据包。
谁能告诉我出现此错误的原因? (由 我系统上安装的 GLib 版本是 2.64.6)
这可能是由于developer.mozilla.org
使用了旧的 TLS 实现(可能是 1.0 或 1.1)。根据此错误报告,自 2.64.x 起,这些在 GLib 网络中被禁用:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=954742
自从您发布此问题后,他们可能已升级到 TLS 1.2 - 我刚刚进行了快速测试并成功使用 TLSv1.2 连接。
【讨论】:
以上是关于如何使用 Vala 建立 TLS 连接?的主要内容,如果未能解决你的问题,请参考以下文章
设置和验证 Python MySQL 连接中使用的 SSL/TLS 版本
如何在 Windows 上对 PHPMailer/OpenSSL TLS SMTP 进行故障排除?