sqlx_core/mysql/connection/
tls.rs

1use crate::error::Error;
2use crate::mysql::connection::MySqlStream;
3use crate::mysql::protocol::connect::SslRequest;
4use crate::mysql::protocol::Capabilities;
5use crate::mysql::{MySqlConnectOptions, MySqlSslMode};
6
7pub(super) async fn maybe_upgrade(
8    stream: &mut MySqlStream,
9    options: &MySqlConnectOptions,
10) -> Result<(), Error> {
11    // https://www.postgresql.org/docs/12/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS
12    match options.ssl_mode {
13        MySqlSslMode::Disabled => {}
14
15        MySqlSslMode::Preferred => {
16            // try upgrade, but its okay if we fail
17            upgrade(stream, options).await?;
18        }
19
20        MySqlSslMode::Required | MySqlSslMode::VerifyIdentity | MySqlSslMode::VerifyCa => {
21            if !upgrade(stream, options).await? {
22                // upgrade failed, die
23                return Err(Error::Tls("server does not support TLS".into()));
24            }
25        }
26    }
27
28    Ok(())
29}
30
31async fn upgrade(stream: &mut MySqlStream, options: &MySqlConnectOptions) -> Result<bool, Error> {
32    if !stream.capabilities.contains(Capabilities::SSL) {
33        // server does not support TLS
34        return Ok(false);
35    }
36
37    stream.write_packet(SslRequest {
38        max_packet_size: super::MAX_PACKET_SIZE,
39        collation: stream.collation as u8,
40    });
41
42    stream.flush().await?;
43
44    let accept_invalid_certs = !matches!(
45        options.ssl_mode,
46        MySqlSslMode::VerifyCa | MySqlSslMode::VerifyIdentity
47    );
48    let accept_invalid_host_names = !matches!(options.ssl_mode, MySqlSslMode::VerifyIdentity);
49
50    stream
51        .upgrade(
52            &options.host,
53            accept_invalid_certs,
54            accept_invalid_host_names,
55            options.ssl_ca.as_ref(),
56        )
57        .await?;
58
59    Ok(true)
60}