sqlx_core_oldapi/postgres/connection/
tls.rs1use bytes::Bytes;
2
3use crate::error::Error;
4use crate::net::TlsConfig;
5use crate::postgres::connection::stream::PgStream;
6use crate::postgres::message::SslRequest;
7use crate::postgres::{PgConnectOptions, PgSslMode};
8
9pub(super) async fn maybe_upgrade(
10 stream: &mut PgStream,
11 options: &PgConnectOptions,
12) -> Result<(), Error> {
13 match options.ssl_mode {
15 PgSslMode::Allow | PgSslMode::Disable => {}
17
18 PgSslMode::Prefer => {
19 upgrade(stream, options).await?;
21 }
22
23 PgSslMode::Require | PgSslMode::VerifyFull | PgSslMode::VerifyCa => {
24 if !upgrade(stream, options).await? {
25 return Err(Error::Tls("server does not support TLS".into()));
27 }
28 }
29 }
30
31 Ok(())
32}
33
34async fn upgrade(stream: &mut PgStream, options: &PgConnectOptions) -> Result<bool, Error> {
35 stream.send(SslRequest).await?;
41
42 match stream.read::<Bytes>(1).await?[0] {
46 b'S' => {
47 }
49
50 b'N' => {
51 return Ok(false);
53 }
54
55 other => {
56 return Err(err_protocol!(
57 "unexpected response from SSLRequest: 0x{:02x}",
58 other
59 ));
60 }
61 }
62
63 let accept_invalid_certs = !matches!(
64 options.ssl_mode,
65 PgSslMode::VerifyCa | PgSslMode::VerifyFull
66 );
67 let accept_invalid_hostnames = !matches!(options.ssl_mode, PgSslMode::VerifyFull);
68
69 let tls_config: TlsConfig<'_> = TlsConfig {
70 accept_invalid_certs,
71 accept_invalid_hostnames,
72 root_cert_path: options.ssl_root_cert.as_ref(),
73 hostname: &options.host,
74 client_cert_path: options.ssl_client_cert.as_ref(),
75 client_key_path: options.ssl_client_key.as_ref(),
76 };
77 stream.upgrade(tls_config).await?;
78
79 Ok(true)
80}