From 609d0f18eed95c0497fa7898ed11303a5090fa56 Mon Sep 17 00:00:00 2001 From: Ufuk Celebi <1756620+uce@users.noreply.github.com> Date: Mon, 17 May 2021 22:46:38 +0200 Subject: [PATCH 1/3] config: add sslmode `verify-ca` and `verify-full` When a connection is established, the added modes are treated in the same way as the existing `require` mode as they both require a TLS connection. It's the responsibility of the user to configure the TLS stream to match the semantics of Postgres client (e.g. enable peer cert verification). --- postgres/src/config.rs | 4 +++- tokio-postgres/src/config.rs | 10 +++++++++- tokio-postgres/src/connect_tls.rs | 11 ++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/postgres/src/config.rs b/postgres/src/config.rs index c8dffa330..470d1914e 100644 --- a/postgres/src/config.rs +++ b/postgres/src/config.rs @@ -34,7 +34,9 @@ use tokio_postgres::{Error, Socket}; /// * `options` - Command line options used to configure the server. /// * `application_name` - Sets the `application_name` parameter on the server. /// * `sslmode` - Controls usage of TLS. If set to `disable`, TLS will not be used. If set to `prefer`, TLS will be used -/// if available, but not used otherwise. If set to `require`, TLS will be forced to be used. Defaults to `prefer`. +/// if available, but not used otherwise. If set to `require`, `verify-ca`, or `verify-full`, TLS will be forced to +/// be used. Defaults to `prefer`. Note that for modes `verify-ca` and `verify-full`, it's up to the user to configure +/// the SSL stream to respect the desired configuration (e.g. verification of certs, hostname verification). /// * `host` - The host to connect to. On Unix platforms, if the host starts with a `/` character it is treated as the /// path to the directory containing Unix domain sockets. Otherwise, it is treated as a hostname. Multiple hosts /// can be specified, separated by commas. Each host will be tried in turn when connecting. Required if connecting diff --git a/tokio-postgres/src/config.rs b/tokio-postgres/src/config.rs index 111487173..c8cb6e3f1 100644 --- a/tokio-postgres/src/config.rs +++ b/tokio-postgres/src/config.rs @@ -42,6 +42,10 @@ pub enum SslMode { Prefer, /// Require the use of TLS. Require, + /// Require the use of TLS. Verify peer cert without hostname verification. + VerifyCa, + /// Require the use of TLS. Verify peer cert and hostname. + VerifyFull, } /// Channel binding configuration. @@ -85,7 +89,9 @@ pub enum Host { /// * `options` - Command line options used to configure the server. /// * `application_name` - Sets the `application_name` parameter on the server. /// * `sslmode` - Controls usage of TLS. If set to `disable`, TLS will not be used. If set to `prefer`, TLS will be used -/// if available, but not used otherwise. If set to `require`, TLS will be forced to be used. Defaults to `prefer`. +/// if available, but not used otherwise. If set to `require`, `verify-ca`, or `verify-full`, TLS will be forced to +/// be used. Defaults to `prefer`. Note that for modes `verify-ca` and `verify-full`, it's up to the user to configure +/// the SSL stream to respect the desired configuration (e.g. verification of certs, hostname verification). /// * `host` - The host to connect to. On Unix platforms, if the host starts with a `/` character it is treated as the /// path to the directory containing Unix domain sockets. Otherwise, it is treated as a hostname. Multiple hosts /// can be specified, separated by commas. Each host will be tried in turn when connecting. Required if connecting @@ -409,6 +415,8 @@ impl Config { "disable" => SslMode::Disable, "prefer" => SslMode::Prefer, "require" => SslMode::Require, + "verify-ca" => SslMode::VerifyCa, + "verify-full" => SslMode::VerifyFull, _ => return Err(Error::config_parse(Box::new(InvalidValue("sslmode")))), }; self.ssl_mode(mode); diff --git a/tokio-postgres/src/connect_tls.rs b/tokio-postgres/src/connect_tls.rs index 5ef21ac5c..0022d51cf 100644 --- a/tokio-postgres/src/connect_tls.rs +++ b/tokio-postgres/src/connect_tls.rs @@ -21,7 +21,7 @@ where SslMode::Prefer if !tls.can_connect(ForcePrivateApi) => { return Ok(MaybeTlsStream::Raw(stream)) } - SslMode::Prefer | SslMode::Require => {} + SslMode::Prefer | SslMode::Require | SslMode::VerifyCa | SslMode::VerifyFull => {} } let mut buf = BytesMut::new(); @@ -32,10 +32,11 @@ where stream.read_exact(&mut buf).await.map_err(Error::io)?; if buf[0] != b'S' { - if SslMode::Require == mode { - return Err(Error::tls("server does not support TLS".into())); - } else { - return Ok(MaybeTlsStream::Raw(stream)); + match mode { + SslMode::Disable | SslMode::Prefer => return Ok(MaybeTlsStream::Raw(stream)), + SslMode::Require | SslMode::VerifyCa | SslMode::VerifyFull => { + return Err(Error::tls("server does not support TLS".into())) + } } } From 0a828636fd2dc87409da889e3d4c57434c0f89d5 Mon Sep 17 00:00:00 2001 From: Ufuk Celebi <1756620+uce@users.noreply.github.com> Date: Mon, 17 May 2021 22:49:45 +0200 Subject: [PATCH 2/3] openssl: add from_tls_config constructor Adds a convenience constructor that creates a `MakeTlsConnector` that matches the semantics of Postgres clients. Check out https://www.postgresql.org/docs/current/libpq-ssl.html for more details on the expected behavior. --- postgres-openssl/src/lib.rs | 74 +++++++++++++++++++++++-- postgres-openssl/src/test.rs | 103 +++++++++++++++++++++++++++++++++++ test/other.crt | 19 +++++++ 3 files changed, 191 insertions(+), 5 deletions(-) create mode 100644 test/other.crt diff --git a/postgres-openssl/src/lib.rs b/postgres-openssl/src/lib.rs index dce3dff5d..e4b61464d 100644 --- a/postgres-openssl/src/lib.rs +++ b/postgres-openssl/src/lib.rs @@ -43,13 +43,12 @@ #[cfg(feature = "runtime")] use openssl::error::ErrorStack; -use openssl::hash::MessageDigest; -use openssl::nid::Nid; #[cfg(feature = "runtime")] use openssl::ssl::SslConnector; -use openssl::ssl::{self, ConnectConfiguration, SslRef}; +use openssl::ssl::{self, ConnectConfiguration, SslFiletype, SslRef}; use openssl::x509::X509VerifyResult; -use std::error::Error; +use openssl::{hash::MessageDigest, ssl::SslMethod}; +use openssl::{nid::Nid, ssl::SslVerifyMode}; use std::fmt::{self, Debug}; use std::future::Future; use std::io; @@ -57,16 +56,28 @@ use std::pin::Pin; #[cfg(feature = "runtime")] use std::sync::Arc; use std::task::{Context, Poll}; +use std::{error::Error, path::PathBuf}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_openssl::SslStream; -use tokio_postgres::tls; #[cfg(feature = "runtime")] use tokio_postgres::tls::MakeTlsConnect; use tokio_postgres::tls::{ChannelBinding, TlsConnect}; +use tokio_postgres::{config::SslMode, tls}; #[cfg(test)] mod test; +/// TLS configuration. +#[cfg(feature = "runtime")] +pub struct TlsConfig { + /// SSL mode (`sslmode`). + pub mode: SslMode, + /// Location of the client cert and key (`sslcert`, `sslkey`). + pub client_cert: Option<(PathBuf, PathBuf)>, + /// Location of the root certificate (`sslrootcert`). + pub root_cert: Option, +} + /// A `MakeTlsConnect` implementation using the `openssl` crate. /// /// Requires the `runtime` Cargo feature (enabled by default). @@ -87,6 +98,59 @@ impl MakeTlsConnector { } } + /// Creates a new connector from the provided [`TlsConfig`]. + /// + /// The returned [`MakeTlsConnector`] will be configured to mimick libpq-ssl behavior. + pub fn from_tls_config(tls_config: TlsConfig) -> Result { + let mut builder = SslConnector::builder(SslMethod::tls_client())?; + // The mode dictates whether we verify peer certs and hostnames. By default, Postgres is + // pretty relaxed and recommends SslMode::VerifyCa or SslMode::VerifyFull for security. + // + // For more details, check out Table 33.1. SSL Mode Descriptions in + // https://postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-PROTECTION. + let (verify_mode, verify_hostname) = match tls_config.mode { + SslMode::Disable | SslMode::Prefer => (SslVerifyMode::NONE, false), + SslMode::Require => match tls_config.root_cert { + // If a root CA file exists, the behavior of sslmode=require will be the same as + // that of verify-ca, meaning the server certificate is validated against the CA. + // + // For more details, check out the note about backwards compatibility in + // https://postgresql.org/docs/current/libpq-ssl.html#LIBQ-SSL-CERTIFICATES. + Some(_) => (SslVerifyMode::PEER, false), + None => (SslVerifyMode::NONE, false), + }, + SslMode::VerifyCa => (SslVerifyMode::PEER, false), + SslMode::VerifyFull => (SslVerifyMode::PEER, true), + _ => panic!("unexpected sslmode {:?}", tls_config.mode), + }; + + // Configure peer verification + builder.set_verify(verify_mode); + + // Configure certificates + if tls_config.client_cert.is_some() { + let (cert, key) = tls_config.client_cert.unwrap(); + builder.set_certificate_file(cert, SslFiletype::PEM)?; + builder.set_private_key_file(key, SslFiletype::PEM)?; + } + if tls_config.root_cert.is_some() { + builder.set_ca_file(tls_config.root_cert.unwrap())?; + } + + let mut tls_connector = MakeTlsConnector::new(builder.build()); + + // Configure hostname verification + match (verify_mode, verify_hostname) { + (SslVerifyMode::PEER, false) => tls_connector.set_callback(|connect, _| { + connect.set_verify_hostname(false); + Ok(()) + }), + _ => {} + } + + Ok(tls_connector) + } + /// Sets a callback used to apply per-connection configuration. /// /// The the callback is provided the domain name along with the `ConnectConfiguration`. diff --git a/postgres-openssl/src/test.rs b/postgres-openssl/src/test.rs index 15ed90ad5..c283a3dec 100644 --- a/postgres-openssl/src/test.rs +++ b/postgres-openssl/src/test.rs @@ -25,6 +25,15 @@ where assert_eq!(rows[0].get::<_, i32>(0), 1); } +async fn from_tls_config_smoke_test(config: TlsConfig) { + let mut connector = MakeTlsConnector::from_tls_config(config).unwrap(); + smoke_test( + "user=ssl_user dbname=postgres", + MakeTlsConnect::::make_tls_connect(&mut connector, "localhost").unwrap(), + ) + .await +} + #[tokio::test] async fn require() { let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); @@ -109,3 +118,97 @@ async fn runtime() { assert_eq!(rows.len(), 1); assert_eq!(rows[0].get::<_, i32>(0), 1); } + +#[tokio::test] +async fn from_tls_config_base() { + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::Disable, + client_cert: None, + root_cert: None, + }) + .await; + + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::Prefer, + client_cert: None, + root_cert: None, + }) + .await; + + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::Require, + client_cert: None, + root_cert: None, + }) + .await; + + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::Require, + client_cert: None, + root_cert: Some(PathBuf::from("../test/server.crt")), + }) + .await; + + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::VerifyCa, + client_cert: None, + root_cert: Some(PathBuf::from("../test/server.crt")), + }) + .await; + + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::VerifyFull, + client_cert: None, + root_cert: Some(PathBuf::from("../test/server.crt")), + }) + .await; +} + +#[tokio::test] +#[should_panic(expected = "certificate verify failed")] +async fn from_tls_config_require_with_wrong_root_cert_err() { + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::Require, + client_cert: None, + root_cert: Some(PathBuf::from("../test/other.crt")), + }) + .await; +} + +#[tokio::test] +#[should_panic(expected = "certificate verify failed")] +async fn from_tls_config_verify_ca_with_wrong_root_cert_err() { + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::VerifyCa, + client_cert: None, + root_cert: Some(PathBuf::from("../test/other.crt")), + }) + .await; +} + +#[tokio::test] +#[should_panic(expected = "certificate verify failed")] +async fn from_tls_config_verify_full_with_wrong_root_cert_err() { + from_tls_config_smoke_test(TlsConfig { + mode: SslMode::VerifyFull, + client_cert: None, + root_cert: Some(PathBuf::from("../test/other.crt")), + }) + .await; +} + +#[tokio::test] +#[should_panic(expected = "Hostname mismatch")] +async fn from_tls_config_verify_full_with_wrong_hostname_err() { + let tls_config = TlsConfig { + mode: SslMode::VerifyFull, + client_cert: None, + root_cert: Some(PathBuf::from("../test/server.crt")), + }; + let mut connector = MakeTlsConnector::from_tls_config(tls_config).unwrap(); + smoke_test( + "user=ssl_user dbname=postgres", + MakeTlsConnect::::make_tls_connect(&mut connector, "otherhost").unwrap(), + ) + .await +} diff --git a/test/other.crt b/test/other.crt new file mode 100644 index 000000000..7c260eb72 --- /dev/null +++ b/test/other.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgIJAMpak9jpV15CMA0GCSqGSIb3DQEBBQUAMA8xDTALBgNV +BAMMBHJvb3QwHhcNMjEwNTEyMDg1NDEyWhcNMzEwNTEwMDg1NDEyWjAPMQ0wCwYD +VQQDDARyb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuPNlaHj +ssg2sQQ0CmbMl9KocZufjAmXdW7GCDvwXGRFSw+HPwKbcOPmmI96/JEO0jf9lExh +pLoMJsi6IuwL1IpXOkwLmZbiNMaJxC7SbQ/J6f3EdVfdKA15YfgCjHZBVomK+nSy +S0AERKypPNO+tv23wtpM7YmUw8O0e08Aqi7PLENyT4McBF6sSSV94OP+o4GOQ2rT +TMM+lrze1t+YQjhwOFjF3sKTrmE9J9F5R5/eN1syPlS2xLyN+bmWaByK64myNfh3 +fRcjpiVfhkbePkuitJBo5MfUHgn90q2Y1OtP/7UhsJX5XUgmRFY1iGiIMkB2jmEr +6Ugy8rFuYMuIkwIDAQABo3MwcTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTL +5f6++2fV0v/Y3WJYo4zkEbv7DzA/BgNVHSMEODA2gBTL5f6++2fV0v/Y3WJYo4zk +Ebv7D6ETpBEwDzENMAsGA1UEAwwEcm9vdIIJAMpak9jpV15CMA0GCSqGSIb3DQEB +BQUAA4IBAQAmOb/aXndz63uk6eSrwkwwM4oAeie333kosG3Bpzo5/EdNEvsZRLs9 +xhZRYCoyW/pBOcPs7FAI90G/1OuhoQk8MkvjS5MukZmcNj2Yrew6/1WedfHwwIYV +q9Wt6WaXRNu/pMn2IHrNrBaC1utmHIF5Yj2njVDIUGWbe3xBUl90dxHtt11830fc +N6rqSZiBRMwK8Il2z31VPCCbURX/9BI1TUfgZbOyvEDA43QEUTIDfxTbkZKUC7KF +7ClcHl7Py4kqlPkpkyWKBrnokMNRDKGlSDDYy1+hDO/xObx2U6Z1x/ksv/+G05fI +hfrnzZaanvotLMZf2Fut1Ee5BjsnZE3Y +-----END CERTIFICATE----- From 39d517833668c3bc419301042e14f67778c5a8ba Mon Sep 17 00:00:00 2001 From: Ufuk Celebi <1756620+uce@users.noreply.github.com> Date: Mon, 17 May 2021 23:15:43 +0200 Subject: [PATCH 3/3] openssl: add clientcert tests Adds clientcert auth tests for the newly introduced `MakeTlsConnector::from_tls_config(TlsConfig)` convenience constructor. --- docker/sql_setup.sh | 127 +++++++++++++++++++++-------------- postgres-openssl/src/test.rs | 79 ++++++++++++++++++++-- test/cert_user_full.crt | 17 +++++ test/cert_user_full.key | 28 ++++++++ test/postgres.crt | 17 +++++ test/postgres.key | 28 ++++++++ test/root.crt | 19 ++++++ test/root.key | 28 ++++++++ test/server.crt | 37 +++++----- test/server.der | Bin 1016 -> 0 bytes test/server.key | 28 ++++++++ 11 files changed, 333 insertions(+), 75 deletions(-) create mode 100644 test/cert_user_full.crt create mode 100644 test/cert_user_full.key create mode 100644 test/postgres.crt create mode 100644 test/postgres.key create mode 100644 test/root.crt create mode 100644 test/root.key delete mode 100644 test/server.der create mode 100644 test/server.key diff --git a/docker/sql_setup.sh b/docker/sql_setup.sh index 422dcbda9..a8c5c7745 100755 --- a/docker/sql_setup.sh +++ b/docker/sql_setup.sh @@ -2,60 +2,76 @@ set -e cat > "$PGDATA/server.key" <<-EOKEY ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAllItXwrj62MkxKVlz2FimJk42WWc3K82Rn2vAl6z38zQxSCj -t9uWwXWTx5YOdGiUcA+JUAruZxqN7vdfphJoYtTrcrpT4rC/FsCMImBxkj1cxdYT -q94SFn9bQBRZk7RUx4Kolt+/h0d3PpNIb4DbyQ8A0MVvNVxLpRRVwc6yQP+NkRMy -gHR+m3P8fxHEtkHCVy7HORbASvN8fRlREMHDL2hkadX0BNM72DDo+DWhPA8GF6WX -tIl1gU6GP6pSbEeMHD3f+uj7f9iSjvkrHrOt2nLUQ9Qnev2nhmU0/dOIweQ17/Fr -lL9jYDUUFNORyjRnlXXUoP5BO/LdEAAqT2A0pwIDAQABAoIBAQCIXu74XUneHuiZ -Wa+eTqwC4mZXmz6OWonzs0vU65NlgksXuv+r6ZO/2GoD1Bcy9jlL3Fxm+DPF56pB -07u7TtHSb3VWdMFrU4tYGcBH45TE5dRHSmo4LlPcgxeGb6/ANwX+pYNKtJvuHyCH -7Vf2iEFcCrdjrumv0BZ0IZmXJGxEV+7mK2Og0bZ/zbmJNaH25muuWj6BKlvLhL0N -S2LlBjKx3HqtppUgUqNFqjLs6IA1u79S5dAomOsxZtnuByaX5WFzpktU2pveZmyF -cl0dwHYZIaxR3ewYeQXGF8ANUmIx3nnxD2JOysPkitaGzeqt6dQZV14tPlDZDKat -Vf0b6BHhAoGBAMWV7rG+7nVXoQ30CIcPGklkST3mVOlrzeBbKP1SeAwoGRbfsdhp -rFMkh5UxTexnOzD4O8HPuJ6NGeWRQfqZT1nnjwHPeJWtiMHT6cnWxlzvxAZ61mio -0jRfb8flhgFKk+G9+Xa6WaYAAwGWdF062EMe2Ym92oKM9ilTPGFVRk1XAoGBAMLD -ETSQd2UqTF/y7wxMPqF3l6d1KBjwpuNuin2IjkXTOfGkDnAU3mSQlr7K1IPX8NPO -gdyMfJoysfRaBuRcNA/o/0l0wyxW4HWtTtPYI0+pRCFtRLsI1MB997QKeaGKb+me -3nBXkOksPSr9oa0Cs27z2cSoBOkpq2N/zzBseHExAoGAOyq3rKBZNehEwTHnb9I0 -8+9FA3U6zh9LKjkCIEGW00Uapj/cOMsEIG2a8DEwfW84SWS8OEBkr43fSGBkGo/Y -NDrkFw2ytVee0TQNGTTod6IQ2EPmera7I5XEml5/71kOyZWi40vQVqZAQDR2qgha -BFdzmwywJ1Hg0OUs+pSXlccCgYEAgyOVki80NYolovWQwFcWVOKR2s+oECL6PGlS -FvS714hCm9I7ZnymwlAZMJ6iOaRNJFEIX9i4jZtU95Mm0NzEsXHRc0SLpm9Y8+Oe -EEaYgCsZFOjePpHTr0kiYLgs7fipIkU2wa40hMyk4y2kjzoiV7MaDrCTnevQ205T -0+c1sgECgYBAXKcwdkh9JVSrLXFamsxiOx3MZ0n6J1d28wpdA3y4Y4AAJm4TGgFt -eG/6qHRy6CHdFtJ7a84EMe1jaVLQJYW/VrOC2bWLftkU7qaOnkXHvr4CAHsXQHcx -JhLfvh4ab3KyoK/iimifvcoS5z9gp7IBFKMyh5IeJ9Y75TgcfJ5HMg== ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDX71FGKHUepupP +7c4VGoeX+Dkn5PZjDkwv+DYsTxpcZ0x/S4fHSz+aEX7cP8M0vxPmxOwJPoAm2Vt2 +RTva+8TrGClzWPT8YHzyN7r8jdP9crBQDAidYuQdHxPpXji9TMyRAGk51Qy0U+K/ +Wjx787LsWF3DFTgvJdw7YaD9EZzG7sqXvCaWAQ8sxUdj0moSm42ftVFx4Ztv5JEo +nAgKkuJ+0KklLJ08/KTp8OMm95PJzHPl+MDxqDv3jqvg5eVUnm+nE9kgZvTBtNNH +YJM3VZ0rjQDThNlLz9PdHWpfKlBTv1uVGg2SWfVpiaqxq4n686QZPHS0fu/ZQejx +h0bZ8qeBAgMBAAECggEBAKKZ3XOdJ4RrYGnLwrF1hsFS84ctDLPOomRE3lZDQrBu +QNZiQ944ta4ImqSzhwUDFbNiefMEE3AtoIfQ3p+pksENMrlfNSuOZMfoW2+uRQHH +CSldxmbtfqTHMDE8+DDj0e8mhhY8bhKkUEyTYJReEE+UwxYRtnsaYVp9y8KFLq9E +4f6NDMzzSpw/ujkcACtx0DxeWZfaP6Ms4ydh2uDEvzUwnmw4kpsgo4NtPLHDNx/y +kshfSpayYBKJ08qpzUAOXpi2UIRzvrYZE5cAcXtK6Jw02VnpNIr6+q/DAE58at7W +RwvswhNdpVVVwn04o68c4GUsGQFG/Qve8hDLdN+KygECgYEA//PE9FAeuSy2KWxS +HKSYZ422Sx/M4tuAQrX//yCFizxEhs9SF3ybZX4SCHGeQxeogIqOrFKKrXpzpCcH +3fB4LjRpdUKdv11sxFoo0Jw6wtY3N+24yM3jrpDsQqcCxUxm+qOgwGyKRJCkLxK3 +RNkAAmoT2mONeaMyWLg5g4wVW5ECgYEA1/miyi6PmT3+y4DCdNYdJll3NRmR4DGk +HDYOd+Qb+DSoBhcxz/bqBDDdXr6FT3nZEkTxKAsaPjarzKjK2J88fvnF2JRnM5Oy +HKRNk3a9KxM//UwUgoLCdg/qZe4EXX9LJr06G6YGgg0uG6Cjsa+rZ33FiucBYrEL +aevQ+cReNPECgYEAsCDlRWHk4nQ8HiEmGAPDxG6mJOgLK4j0p/Np5/xPKVMdrM75 +pKPgo2SvsBPPXkfnchzmtPpP57S94xXguf8CFHmIoGJo/wihEjUgpPz9CpoygVAa +ukPEC5o6mlsm8vHyY0M6GXAXbbtC4Am3B69z7DVm1/9tmWiN+rM7EKTTBaECgYBi +qOUWmyJ6DHoCmLU8DjuOszvjg+TBl6uyP3doiUnFnrhK3/mfWNoaRAA8MahQYAcr +c1b+xeOdG/hrK4hOYJ+QGaWphFGInCW3M89EV++eZ9LJcSHFZNpUeHzJR2uzEl1Q +Owz6aGN8sWyorj9ZAji4tBmzlEdrwBjIsDLshinK4QKBgEbmw1Dp1ZQEZcNiNKBl +EEzce+yHf8FSaC4KQSOnZIK30ZoHGLkQfr+C+8qKeDe4WYn3yf5zhjG7ssyxgWrB +S8GdV0OgrtvO5zhDH72KqddZe+api/34Zh2zY/2PKG2gBZ+ubsRpgptVK2ny5pmj +WN5CmfEv9kwQmSKzzSGUJ59l +-----END PRIVATE KEY----- EOKEY chmod 0600 "$PGDATA/server.key" cat > "$PGDATA/server.crt" <<-EOCERT -----BEGIN CERTIFICATE----- -MIID9DCCAtygAwIBAgIJAIYfg4EQ2pVAMA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNjA2MjgyMjQw -NDFaFw0yNjA2MjYyMjQwNDFaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21l -LVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV -BAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJZS -LV8K4+tjJMSlZc9hYpiZONllnNyvNkZ9rwJes9/M0MUgo7fblsF1k8eWDnRolHAP -iVAK7mcaje73X6YSaGLU63K6U+KwvxbAjCJgcZI9XMXWE6veEhZ/W0AUWZO0VMeC -qJbfv4dHdz6TSG+A28kPANDFbzVcS6UUVcHOskD/jZETMoB0fptz/H8RxLZBwlcu -xzkWwErzfH0ZURDBwy9oZGnV9ATTO9gw6Pg1oTwPBhell7SJdYFOhj+qUmxHjBw9 -3/ro+3/Yko75Kx6zrdpy1EPUJ3r9p4ZlNP3TiMHkNe/xa5S/Y2A1FBTTkco0Z5V1 -1KD+QTvy3RAAKk9gNKcCAwEAAaOBvjCBuzAdBgNVHQ4EFgQUEcuoFxzUZ4VV9VPv -5frDyIuFA5cwgYsGA1UdIwSBgzCBgIAUEcuoFxzUZ4VV9VPv5frDyIuFA5ehXaRb -MFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJ -bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdIIJAIYf -g4EQ2pVAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHwMzmXdtz3R -83HIdRQic40bJQf9ucSwY5ArkttPhC8ewQGyiGexm1Tvx9YA/qT2rscKPHXCPYcP -IUE+nJTc8lQb8wPnFwGdHUsJfCvurxE4Yv4Oi74+q1enhHBGsvhFdFY5jTYD9unM -zBEn+ZHX3PlKhe3wMub4khBTbPLK+n/laQWuZNsa+kj7BynkAg8W/6RK0Z0cJzzw -aiVP0bSvatAAcSwkEfKEv5xExjWqoewjSlQLEZYIjJhXdtx/8AMnrcyxrFvKALUQ -9M15FXvlPOB7ez14xIXQBKvvLwXvteHF6kYbzg/Bl1Q2GE9usclPa4UvTpnLv6gq -NmFaAhoxnXA= +MIICojCCAYoCCQD51cTqxXxVZDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdy +b290LWNhMB4XDTIxMDUxNzIxMDExM1oXDTIyMDUxNzIxMDExM1owFDESMBAGA1UE +AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1+9R +Rih1HqbqT+3OFRqHl/g5J+T2Yw5ML/g2LE8aXGdMf0uHx0s/mhF+3D/DNL8T5sTs +CT6AJtlbdkU72vvE6xgpc1j0/GB88je6/I3T/XKwUAwInWLkHR8T6V44vUzMkQBp +OdUMtFPiv1o8e/Oy7FhdwxU4LyXcO2Gg/RGcxu7Kl7wmlgEPLMVHY9JqEpuNn7VR +ceGbb+SRKJwICpLiftCpJSydPPyk6fDjJveTycxz5fjA8ag7946r4OXlVJ5vpxPZ +IGb0wbTTR2CTN1WdK40A04TZS8/T3R1qXypQU79blRoNkln1aYmqsauJ+vOkGTx0 +tH7v2UHo8YdG2fKngQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAqJLwuK1HIq2p0 +I4N7HUjApiyxYWKqAeiC/65sLyU5TUfTgiSxTJRh625NwEYXzGTGbY674quIYK7I +uUIDrWTu2GBT1DIZJG78xbYfeWoHtKrTZ+MYy70FK448dI4lv0lZbmub0HircR2M +9MVqhWw8ik5FrpiR2DcwTkwNuNlVSu+hr/c/ljhvNP7dBfIxc9Og6xp1tyHW2hce +Vm/3HFjJqBfLw/lbZ6rx5wJA3E13r0LpnwuKQlgPYyaighfgetJdxorj37gCxLn3 +77qfpOnFfk/mgY+bLFu9ncR2svab4CGRXPey9Kb6wP+OCwnh0vCBioocUFRANkLb +bEjAYyqo +-----END CERTIFICATE----- +EOCERT + +cat > "$PGDATA/root.crt" <<-EOCERT +-----BEGIN CERTIFICATE----- +MIIDHTCCAgWgAwIBAgIJAPuMcWp8Si1PMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV +BAMMB3Jvb3QtY2EwHhcNMjEwNTE3MjEwMTEzWhcNMzEwNTE1MjEwMTEzWjASMRAw +DgYDVQQDDAdyb290LWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +vhPvG4K6R1GAe3/MwLWsb3uQX3Zs8Z+1R15+h1Sx1SwgXLuLDwxMxg0dkip/R0ic +XyJFeVntOQqZfZpwd3iD47AZx6c4/Hn+U6OQtfvY6FmYNfmhngAnk9nr5te4Fu+S +n7YwUJ0+pfC8b6idM5XB2YBnO1azqP5Sa230gSqxBlzjOqUC8rlvF1woDej49E3l +pzP7jD6yrZ3Z3SvF1+ZhW+6CvWi4cm8xfMaTCCvwoR3E7ia6OGUmNP/rkyxXSUHV +O1ELw0FY63+J46BzONR/MRuoXBm2SF07WY9+kS35SIOK1PjO0ndNRlXYv7xzCxDW +4EnfoTfDLwZ6vOBvcST9VwIDAQABo3YwdDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTbVbnrDPLMcVV0ExWd/EexzCMhzDBCBgNVHSMEOzA5gBTbVbnrDPLMcVV0 +ExWd/EexzCMhzKEWpBQwEjEQMA4GA1UEAwwHcm9vdC1jYYIJAPuMcWp8Si1PMA0G +CSqGSIb3DQEBCwUAA4IBAQA83u6ILbpsQRwyb074exRo2vLC0pjtOBeRLyhi95zk +TtilDHNP5oYf4pmrTAagv+i5eOwwAvoaXil1+mAtckUkV0FRoxAX9U6ZTUFge9HE +G0VLfhqmzlExRl7O6Jr/O7fC6hOz5YDD0SdAaLGx35J9kbWyOLXAWCte3FImetdB +72lbGD8M9J9Sm12aN+e9a8xovFQQG8Sah4XVTubs3Yw8QOhs+kxIrw3LzRt3Nisa +ASCK93sHNpRUfePn/9x+2VAd6p1r4ypDJAH9Tr1E7duPBe+2YwBjMMDviA7eCiFA +Xi7zm5vUeHGuQOBUIz6HE7RGMhQNkORbQiopzVFOBkys -----END CERTIFICATE----- EOCERT @@ -64,6 +80,7 @@ port = 5433 ssl = on ssl_cert_file = 'server.crt' ssl_key_file = 'server.key' +ssl_ca_file = 'root.crt' EOCONF cat > "$PGDATA/pg_hba.conf" <<-EOCONF @@ -80,6 +97,16 @@ hostssl all ssl_user ::0/0 trust host all ssl_user 0.0.0.0/0 reject host all ssl_user ::0/0 reject +hostssl all cert_user_ca 0.0.0.0/0 trust clientcert=verify-ca +hostssl all cert_user_ca ::0/0 trust clientcert=verify-ca +host all cert_user_ca 0.0.0.0/0 reject +host all cert_user_ca ::0/0 reject + +hostssl all cert_user_full 0.0.0.0/0 trust clientcert=verify-full +hostssl all cert_user_full ::0/0 trust clientcert=verify-full +host all cert_user_full 0.0.0.0/0 reject +host all cert_user_full ::0/0 reject + # IPv4 local connections: host all postgres 0.0.0.0/0 trust # IPv6 local connections: @@ -94,6 +121,8 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL SET password_encryption TO 'scram-sha-256'; CREATE ROLE scram_user PASSWORD 'password' LOGIN; CREATE ROLE ssl_user LOGIN; + CREATE ROLE cert_user_ca LOGIN; + CREATE ROLE cert_user_full LOGIN; CREATE EXTENSION hstore; CREATE EXTENSION citext; EOSQL diff --git a/postgres-openssl/src/test.rs b/postgres-openssl/src/test.rs index c283a3dec..c283d3184 100644 --- a/postgres-openssl/src/test.rs +++ b/postgres-openssl/src/test.rs @@ -145,21 +145,21 @@ async fn from_tls_config_base() { from_tls_config_smoke_test(TlsConfig { mode: SslMode::Require, client_cert: None, - root_cert: Some(PathBuf::from("../test/server.crt")), + root_cert: Some(PathBuf::from("../test/root.crt")), }) .await; from_tls_config_smoke_test(TlsConfig { mode: SslMode::VerifyCa, client_cert: None, - root_cert: Some(PathBuf::from("../test/server.crt")), + root_cert: Some(PathBuf::from("../test/root.crt")), }) .await; from_tls_config_smoke_test(TlsConfig { mode: SslMode::VerifyFull, client_cert: None, - root_cert: Some(PathBuf::from("../test/server.crt")), + root_cert: Some(PathBuf::from("../test/root.crt")), }) .await; } @@ -203,7 +203,7 @@ async fn from_tls_config_verify_full_with_wrong_hostname_err() { let tls_config = TlsConfig { mode: SslMode::VerifyFull, client_cert: None, - root_cert: Some(PathBuf::from("../test/server.crt")), + root_cert: Some(PathBuf::from("../test/root.crt")), }; let mut connector = MakeTlsConnector::from_tls_config(tls_config).unwrap(); smoke_test( @@ -212,3 +212,74 @@ async fn from_tls_config_verify_full_with_wrong_hostname_err() { ) .await } + +#[tokio::test] +async fn from_tls_config_client_cert_verify_ca() { + let tls_config = TlsConfig { + mode: SslMode::VerifyCa, + client_cert: Some(( + PathBuf::from("../test/postgres.crt"), + PathBuf::from("../test/postgres.key"), + )), + root_cert: Some(PathBuf::from("../test/root.crt")), + }; + let mut connector = MakeTlsConnector::from_tls_config(tls_config).unwrap(); + smoke_test( + "user=cert_user_ca dbname=postgres", + MakeTlsConnect::::make_tls_connect(&mut connector, "localhost").unwrap(), + ) + .await; +} + +#[tokio::test] +async fn from_tls_config_client_cert_verify_full() { + let tls_config = TlsConfig { + mode: SslMode::VerifyFull, + client_cert: Some(( + PathBuf::from("../test/cert_user_full.crt"), + PathBuf::from("../test/cert_user_full.key"), + )), + root_cert: Some(PathBuf::from("../test/root.crt")), + }; + let mut connector = MakeTlsConnector::from_tls_config(tls_config).unwrap(); + smoke_test( + "user=cert_user_full dbname=postgres", + MakeTlsConnect::::make_tls_connect(&mut connector, "localhost").unwrap(), + ) + .await; +} + +#[tokio::test] +#[should_panic(expected = "connection requires a valid client certificate")] +async fn from_tls_config_client_cert_verify_full_no_cert_err() { + let tls_config = TlsConfig { + mode: SslMode::VerifyFull, + client_cert: None, + root_cert: Some(PathBuf::from("../test/root.crt")), + }; + let mut connector = MakeTlsConnector::from_tls_config(tls_config).unwrap(); + smoke_test( + "user=cert_user_full dbname=postgres", + MakeTlsConnect::::make_tls_connect(&mut connector, "localhost").unwrap(), + ) + .await; +} + +#[tokio::test] +#[should_panic(expected = "\\\"trust\\\" authentication failed for user \\\"cert_user_full\\\"")] +async fn from_tls_config_client_cert_verify_full_wrong_cert_err() { + let tls_config = TlsConfig { + mode: SslMode::VerifyFull, + client_cert: Some(( + PathBuf::from("../test/postgres.crt"), + PathBuf::from("../test/postgres.key"), + )), + root_cert: Some(PathBuf::from("../test/root.crt")), + }; + let mut connector = MakeTlsConnector::from_tls_config(tls_config).unwrap(); + smoke_test( + "user=cert_user_full dbname=postgres", + MakeTlsConnect::::make_tls_connect(&mut connector, "localhost").unwrap(), + ) + .await; +} diff --git a/test/cert_user_full.crt b/test/cert_user_full.crt new file mode 100644 index 000000000..c20705128 --- /dev/null +++ b/test/cert_user_full.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpzCCAY8CCQD51cTqxXxVZzANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdy +b290LWNhMB4XDTIxMDUxNzIxMDcxNVoXDTIyMDUxNzIxMDcxNVowGTEXMBUGA1UE +AwwOY2VydF91c2VyX2Z1bGwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDk6alFxouky9Jx38ATn2hx3ecMfKI5WpQJ/lKdcZ2QIGHBsAvqYXOkYJ4/nbjD +v3QsTdkCujiZvJJD7nEhDGpgJoqquI8zlPkXWmeqC+0lhvs3SP+cUyewKbRUxRN4 +mxYIsq7854FNlTtJfeleNFxWOzh42C9IzAxXkZsWVzz5yJorXbJlUklV2LA2szN5 +9HgO7HMFA8Jc2Ok7hm9gmhQsXUsDkcy5Y1aW04CQat5LVjSUHPJLjSa0l996FIgc +5H8kw8ZvIwfGPu0JusRJL6OdtCp0RhhbPhW1gM7l7CIaiG8WeRSHscgP970uR1dg +nU0X3kb/UC9SAcEJ4AkrHAXdAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJBiyyF+ +zYMaj2Xz8N6ZTUzUCQabIT+VqYacFeihYdTWHXkgbO/yIDg67ybYMscrcNnQujpP +bj9+cTwStk5pwIycyZS+hbgOINXtGQyE48kKksgaU1ctZvmlPbKWbdis4f7Cqr9V +YXmZW3ZQwtmsq5e8OfXJ/6oqbcyuT6wYgDj0f+av1a9QbrN7JcRVRntyKtZ/KBqz +VzIGJYIikopmDTt7pQ61Z11LUhYDsNHbDyeM7s/CV9hfotITS+ZGrZ/wGXAqP1Go +ctCF7MkWqvyQFtz1jwcrqaJ9UXocojm1iDE0MWPpDCLggUwtaglCwSDaiycKt4sa +PiNCaLcOfO3xzIQ= +-----END CERTIFICATE----- diff --git a/test/cert_user_full.key b/test/cert_user_full.key new file mode 100644 index 000000000..9f0f34ea0 --- /dev/null +++ b/test/cert_user_full.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDk6alFxouky9Jx +38ATn2hx3ecMfKI5WpQJ/lKdcZ2QIGHBsAvqYXOkYJ4/nbjDv3QsTdkCujiZvJJD +7nEhDGpgJoqquI8zlPkXWmeqC+0lhvs3SP+cUyewKbRUxRN4mxYIsq7854FNlTtJ +feleNFxWOzh42C9IzAxXkZsWVzz5yJorXbJlUklV2LA2szN59HgO7HMFA8Jc2Ok7 +hm9gmhQsXUsDkcy5Y1aW04CQat5LVjSUHPJLjSa0l996FIgc5H8kw8ZvIwfGPu0J +usRJL6OdtCp0RhhbPhW1gM7l7CIaiG8WeRSHscgP970uR1dgnU0X3kb/UC9SAcEJ +4AkrHAXdAgMBAAECggEBAIaA9UFWhD70tFbMziO5irk9VcF0ii2BF3M3yHtSgu5o +2IfiVV4GnNh9HP7sQeBi4nQV2elMWm2a66aWuEpe7TJJ8ziU8S+x3Rrnt/mmwFVI +ltvJPMgx5CQSnS8iDWrUVYIO29smfEeF5Cwum60Kvya77Va0UDRKEQZzO9lIsT9i +jv3teKAEP9NDHl9V5IeOcpN5h/PqlEArOSfKOXUFcN8q1uYmjk0pl3kfkjGRBirB +IbhsbjkZhsy4FvNzbliLJCn79In72neIgLPTdMQvXwn9hjQiIZn2a8RQ7Ats2nBk +TlEr8qOFwsM5nrVOHtC5ySacK6y6ySoPDIxCW3pXuIECgYEA+K45tYuFoBMb02Dc +sORcW3F6XNRksdPjmL/pydMWpNPeexIelGv5EbX0NqY2WFgZRFNpp+UrPEUQphis +Tca6tBZleZU8ovpdf8RuvXKVEG49aD1ARX1f13ylfmYyB7g3D8zbYRiNIct4c0x6 +7a4mg/0E8IWQXsnSOy26TkUY9yUCgYEA66Z85NriSAtGLBbhQQ1lu4q5aO8pcpZq +0KmKSj3Fjm1zoUSRDZI1ga0NDtH1ZVmYR0cRb1NslGwvXeTqK6Gl0CCweppXwH1B +V5ibt/gb0Q4/NPl11/+PVV2MhTOkQjysDyE8B7vieUR+ozYW173ynIjFYPJhWP7x +i+ahwZ8fklkCgYEA0zmZRvzVaVwRvH9/tLijQgCnQIYfaXRi03HfMFCd4S8cwEhp +tQPpMQPuBSU07+EUxRZcngFnse+v7oTyhbWRDDohwx3hvUUPeeDtdvkGaEha3Fl6 +aAvQBoaXQz+mqyvriP4mMNjbt6LOEpEZsRzFFkMpmOq57+lZKm7y2lySkgkCgYAD +tt8XGGAitJLJlR690ME+wIQFpGdp1/cdDN8SJoEbqpv8+cCzjw9q2Nhw2Fxe2Zet +3+/lalI20LG6cCZEw8qCSlGdzRr+/Lpv8AbcUnvVwry6UAhMfEm9FblmTBcVuDEa +F/MDSDHcqXi5h9u6UNMnJny993QTXAlgpCT+kUyFGQKBgQDqrZz1XX6YoIRkrJfW +oBy7CjEOvwkHkV1DjC0u/9jTszJhawvjat9qNXajbaF95CD/6rdCzacjoamKLDzs +GzzyWyiLZA75KLElUzJz7dzBzgON5wZoH7Wo1wBt/Up9q8RvI2htXHIUyop/2WXS +NRuVcx1Rh5cjPBtcaLG9kk7a6A== +-----END PRIVATE KEY----- diff --git a/test/postgres.crt b/test/postgres.crt new file mode 100644 index 000000000..f830b8527 --- /dev/null +++ b/test/postgres.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICoTCCAYkCCQD51cTqxXxVZTANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdy +b290LWNhMB4XDTIxMDUxNzIxMDE0M1oXDTIyMDUxNzIxMDE0M1owEzERMA8GA1UE +AwwIcG9zdGdyZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhSXov +zJq1WAS6RBI6L1lH488KSoPN8K+D+dMbP29GO9OMis6siuDGFNANTq9YFWo/7JgW +JCWskhCZIVpgwdWsUvo+swbCQSvJ4grLPHBKssSjbiUAtsZiXNYxRnNRTi1IdSFD +5TomsDe2jkZhme/beWemu5K0ah2smveRHTOunbo+emHBnyv+d6IVslEFy4Ly5wXz +Gp/1qRIN++dLfdEAl10VuQGf0A3a46ONPIYRklcxHsXuS3VhHqkQvAmWBtsE7I1H +LjyzJznXXBI6G7Pl+WjCNoxvqJg85OzZ8pnfg6uKZGp3A244kb6ddmUnNwtidCS1 +4BxDsSd6k8s4cbRvAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEnnxV2B8ztUe/Je +Nk/10FtI2s/Njl0YieLXUGw3FgT6ZQuEHffEyw8kCr9lhi4jETEllqM1WpRacN4E +S2mXMODaG8eNiJajnZMU9O9pYmPS0e4pSYPlyeSbjGReyrr5wlMd10Fh3eFYbdDc +eNP+GfRiQi5xZ5IdInm8L/VYJRETbKRs30Kn1FqNKokmYrGCVswhWByCMDHSnEps +3QLJWOvHF0I7+gQrqK8Jpmr194Mhe/0IIm3+AxAXCoo+KXyZOSsASnLyoqk62lLP +kXSvnFBZj4u3AUCzr4eO4C104I91/Ljll9kw24AUuaqDIOS3OgAjbklW0BwL5cdh +Cy7l8y4= +-----END CERTIFICATE----- diff --git a/test/postgres.key b/test/postgres.key new file mode 100644 index 000000000..8382ad3a5 --- /dev/null +++ b/test/postgres.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDhSXovzJq1WAS6 +RBI6L1lH488KSoPN8K+D+dMbP29GO9OMis6siuDGFNANTq9YFWo/7JgWJCWskhCZ +IVpgwdWsUvo+swbCQSvJ4grLPHBKssSjbiUAtsZiXNYxRnNRTi1IdSFD5TomsDe2 +jkZhme/beWemu5K0ah2smveRHTOunbo+emHBnyv+d6IVslEFy4Ly5wXzGp/1qRIN +++dLfdEAl10VuQGf0A3a46ONPIYRklcxHsXuS3VhHqkQvAmWBtsE7I1HLjyzJznX +XBI6G7Pl+WjCNoxvqJg85OzZ8pnfg6uKZGp3A244kb6ddmUnNwtidCS14BxDsSd6 +k8s4cbRvAgMBAAECggEBAN4PJOb0kBHrfk1zR1wey6v2ul70b9KQSRCXMSSMdEwQ +MEc5ktmz0jas0R4sztzNzvrPZGF+o7vkBYRKweDZbpn6+DrRD/ptbpIBwo3tNuoK +J5THvqVjg0v1IhNT09ryaeQfv/hCe/0ieOfyeSE/MJNuqWJJRSOb7T/zR867r/OO +HyMrYlMOrYOntrunRTiF3hdm3OpJB0ThHOERLEk/4vruvLELL1X3ZKBv/ZdQ4n9M +ASsiKqfxVN8OklaXetnPNgUAsMnOZ5cB3yaV/mkZkm0aQCbeWKLQb+kisJOQpFza +DR17TwtDiGvUEj7mEqCFiJsXxPdi3pv0PnJZSGa07FECgYEA9ywTvbhK3QKVGRU4 +eJtIBu+M6bjak6T2zo5hYEAWog+aC09EaiYlxGhQkiUFsG2Xs7hbkU2b4RXYZixn +P2FR6TCsIHywLRG6DmXZ01kh71ZOvZJgIOMXVK0jnYsQDirNbmd6VBKMyn60O8jt +tXAOci3HQ2H8cD/OxhizWMxNLE0CgYEA6VVNP4CGCqMgFiRA7wOFBQYZOCVlsrZ6 +0pnCT3VPDk6YlQsmaqhMbPDK7Af1rRUw9ATAzgqyBGmySU6snpOOatVn8c1bXRnf +BnWJ3c4y/LCm2fILgpHBMneMAkx2c7dRX5ehUTt76VujxTC2HKGjlrjzKs31GeGd ++FJVxY7EEasCgYBp9M0poR0GjRrZO82PdhF0V7ByaLnaXPcoKMT5e7+4DTQd8QcE +8gFypr0TSSedL/2+HyOxsDFIVhMECbjg5Jk2e5TuAEWNrHGzxlmQTj9L2BW9Ekh/ +EJppxCbmXDyvtg2GbHl2HNWZ4KLmlgXAp56pt5IaAqEyhUfgh6oqQLo8aQKBgQCu +QbZfJmz0pL7hylF0Lvy4s8VB2SwKO52eipZDISjZVnk9VgZqwSXSdkIV5BvmF11n +3+Td+77W7NjpRohEJY7G2nm2a9c/wIJ/IGjF7ajGbmctfUZ7TL8sIXu+e7w6zz1G +VsdzEymHLZkxOx/GYjD570YrQYU6vvRq75J+6BAl4QKBgBXfxncPKlo/xDUP0nlr +UScgosfTOvMxgk79zV5eoEHcU9ay9ncvef+qpm7lr7+UGMUHqnBGY6st451rhNNW +5Kw97urguUh3B3cky0mvwNRfVjRcZ9/NGONWTFjJKf6Ij9/hzZpqGZYB2XGKdIE4 +ZYrqIVCvqekv4GxE6U4hm8kf +-----END PRIVATE KEY----- diff --git a/test/root.crt b/test/root.crt new file mode 100644 index 000000000..03b0f5c52 --- /dev/null +++ b/test/root.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHTCCAgWgAwIBAgIJAPuMcWp8Si1PMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV +BAMMB3Jvb3QtY2EwHhcNMjEwNTE3MjEwMTEzWhcNMzEwNTE1MjEwMTEzWjASMRAw +DgYDVQQDDAdyb290LWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +vhPvG4K6R1GAe3/MwLWsb3uQX3Zs8Z+1R15+h1Sx1SwgXLuLDwxMxg0dkip/R0ic +XyJFeVntOQqZfZpwd3iD47AZx6c4/Hn+U6OQtfvY6FmYNfmhngAnk9nr5te4Fu+S +n7YwUJ0+pfC8b6idM5XB2YBnO1azqP5Sa230gSqxBlzjOqUC8rlvF1woDej49E3l +pzP7jD6yrZ3Z3SvF1+ZhW+6CvWi4cm8xfMaTCCvwoR3E7ia6OGUmNP/rkyxXSUHV +O1ELw0FY63+J46BzONR/MRuoXBm2SF07WY9+kS35SIOK1PjO0ndNRlXYv7xzCxDW +4EnfoTfDLwZ6vOBvcST9VwIDAQABo3YwdDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTbVbnrDPLMcVV0ExWd/EexzCMhzDBCBgNVHSMEOzA5gBTbVbnrDPLMcVV0 +ExWd/EexzCMhzKEWpBQwEjEQMA4GA1UEAwwHcm9vdC1jYYIJAPuMcWp8Si1PMA0G +CSqGSIb3DQEBCwUAA4IBAQA83u6ILbpsQRwyb074exRo2vLC0pjtOBeRLyhi95zk +TtilDHNP5oYf4pmrTAagv+i5eOwwAvoaXil1+mAtckUkV0FRoxAX9U6ZTUFge9HE +G0VLfhqmzlExRl7O6Jr/O7fC6hOz5YDD0SdAaLGx35J9kbWyOLXAWCte3FImetdB +72lbGD8M9J9Sm12aN+e9a8xovFQQG8Sah4XVTubs3Yw8QOhs+kxIrw3LzRt3Nisa +ASCK93sHNpRUfePn/9x+2VAd6p1r4ypDJAH9Tr1E7duPBe+2YwBjMMDviA7eCiFA +Xi7zm5vUeHGuQOBUIz6HE7RGMhQNkORbQiopzVFOBkys +-----END CERTIFICATE----- diff --git a/test/root.key b/test/root.key new file mode 100644 index 000000000..4cb799927 --- /dev/null +++ b/test/root.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC+E+8bgrpHUYB7 +f8zAtaxve5Bfdmzxn7VHXn6HVLHVLCBcu4sPDEzGDR2SKn9HSJxfIkV5We05Cpl9 +mnB3eIPjsBnHpzj8ef5To5C1+9joWZg1+aGeACeT2evm17gW75KftjBQnT6l8Lxv +qJ0zlcHZgGc7VrOo/lJrbfSBKrEGXOM6pQLyuW8XXCgN6Pj0TeWnM/uMPrKtndnd +K8XX5mFb7oK9aLhybzF8xpMIK/ChHcTuJro4ZSY0/+uTLFdJQdU7UQvDQVjrf4nj +oHM41H8xG6hcGbZIXTtZj36RLflIg4rU+M7Sd01GVdi/vHMLENbgSd+hN8MvBnq8 +4G9xJP1XAgMBAAECggEBAL0tBcrxnwggG6nOljAuIEKMTjJUoTUR6M/xQijaqGsr +kcH5ffsqGLb8krPIzAhcQhWE/HQ8hhdBb2ZM8SZWsZ1IxT+qNNNDb1Y68mnNECKg +GRePLcUdDkbemySTCkr5gYqnPwrclV9+a20N+fc/U0FvxE6Qihrlk44MT07G+I0E +6oy7AvgzUycU4OwMTCDShBJ01Vc0kybWoizO7vWSJDnQ034OY8Omy8FjZxMX8tbt +QG029CQtCTA3IP6RldP2lF2sityIrLOhX+ICtdMAGFGNEGtw5EV2BE1MYoC0Vi9b +B5QBaCOubji6WbxsBHodUQfbtK+w4A8KGa8fKVGLH9ECgYEA4P/LTTaVaf+Ifp46 +xUZT4n+0Wo6VWyvObERcS+Y+PLxerlErwe7d7qwcqPi4uxjYlvhzxGNi/khyazix +n5tJyTsVbFE3zNzUx3dx0uLLh+Gx4bDCbAichCeZom92PGxDPriDmJVv0tThyV77 +oQmxajko7NaYSI0jt+TkqoyGkhsCgYEA2ERjsyHGzNtSXNwGLgoG1cmXAYB92n0B +05znUw4Pb+jFbgVafnQkBR/GjkfQcH7LnWYtyTXYPc3L8MDkJvUr3GpbOS0ejkMI +F+5Xpi1l1nP6rCi70kYeIo6na1gMsNgB8avn7wOxemY96VfsX9kAvtt/oOYPJBkv +EITSOCN4FXUCgYEAllFOeZ9l4xMdFbqQeQurLz8yNu3bSrXRivOA1hRUsC8I8ly4 +ZzA2hSXnX9wLTrQiv3ntnd7oXAn6pzeRM5iDizU18s+v/+XpIfniyYlLgNSACtAU +lCiMqJ3sPmFJFMUfh9+ty1rLAofG8MnMQqI/LUBS3yffRVlF6624N1j67tECgYEA +n30X9YPkQzE/NUIBwLQeRE1NcosaxSVJUpC0u7hzw/jqmG+URAtMgQbk/AqT+lJX +wLUY8PknhrSdQOhPmTdXaE57BdhzX0Cp2FQqCWATaSrQ42OK19Bj6uI/L1eYzFYQ +YPSAr/COUxDReaMgq7Kx7Q6cucDPy7RS1CDPkxz9Mv0CgYBv7qLFgMWi2I7tNiG9 +Pm2Sps1SNCYChjW2ZXsXhOB7YPJBhMTgEokLx+egnv/WDCP1HoWEC/VCmEGeyXGQ +EKvfSXN4SFVIsfmKYq550Ii5C31kq7569c/Rm2jXngJv9sYDjkzWilN8CeWPh83I +5KqZj2ARtpwUVkDkZ3bdgVJdaA== +-----END PRIVATE KEY----- diff --git a/test/server.crt b/test/server.crt index aa8bcf163..cce949d15 100644 --- a/test/server.crt +++ b/test/server.crt @@ -1,24 +1,17 @@ -----BEGIN CERTIFICATE----- -MIID9DCCAtygAwIBAgIJAIYfg4EQ2pVAMA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNjA2MjgyMjQw -NDFaFw0yNjA2MjYyMjQwNDFaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21l -LVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV -BAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJZS -LV8K4+tjJMSlZc9hYpiZONllnNyvNkZ9rwJes9/M0MUgo7fblsF1k8eWDnRolHAP -iVAK7mcaje73X6YSaGLU63K6U+KwvxbAjCJgcZI9XMXWE6veEhZ/W0AUWZO0VMeC -qJbfv4dHdz6TSG+A28kPANDFbzVcS6UUVcHOskD/jZETMoB0fptz/H8RxLZBwlcu -xzkWwErzfH0ZURDBwy9oZGnV9ATTO9gw6Pg1oTwPBhell7SJdYFOhj+qUmxHjBw9 -3/ro+3/Yko75Kx6zrdpy1EPUJ3r9p4ZlNP3TiMHkNe/xa5S/Y2A1FBTTkco0Z5V1 -1KD+QTvy3RAAKk9gNKcCAwEAAaOBvjCBuzAdBgNVHQ4EFgQUEcuoFxzUZ4VV9VPv -5frDyIuFA5cwgYsGA1UdIwSBgzCBgIAUEcuoFxzUZ4VV9VPv5frDyIuFA5ehXaRb -MFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJ -bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdIIJAIYf -g4EQ2pVAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHwMzmXdtz3R -83HIdRQic40bJQf9ucSwY5ArkttPhC8ewQGyiGexm1Tvx9YA/qT2rscKPHXCPYcP -IUE+nJTc8lQb8wPnFwGdHUsJfCvurxE4Yv4Oi74+q1enhHBGsvhFdFY5jTYD9unM -zBEn+ZHX3PlKhe3wMub4khBTbPLK+n/laQWuZNsa+kj7BynkAg8W/6RK0Z0cJzzw -aiVP0bSvatAAcSwkEfKEv5xExjWqoewjSlQLEZYIjJhXdtx/8AMnrcyxrFvKALUQ -9M15FXvlPOB7ez14xIXQBKvvLwXvteHF6kYbzg/Bl1Q2GE9usclPa4UvTpnLv6gq -NmFaAhoxnXA= +MIICojCCAYoCCQD51cTqxXxVZDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdy +b290LWNhMB4XDTIxMDUxNzIxMDExM1oXDTIyMDUxNzIxMDExM1owFDESMBAGA1UE +AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1+9R +Rih1HqbqT+3OFRqHl/g5J+T2Yw5ML/g2LE8aXGdMf0uHx0s/mhF+3D/DNL8T5sTs +CT6AJtlbdkU72vvE6xgpc1j0/GB88je6/I3T/XKwUAwInWLkHR8T6V44vUzMkQBp +OdUMtFPiv1o8e/Oy7FhdwxU4LyXcO2Gg/RGcxu7Kl7wmlgEPLMVHY9JqEpuNn7VR +ceGbb+SRKJwICpLiftCpJSydPPyk6fDjJveTycxz5fjA8ag7946r4OXlVJ5vpxPZ +IGb0wbTTR2CTN1WdK40A04TZS8/T3R1qXypQU79blRoNkln1aYmqsauJ+vOkGTx0 +tH7v2UHo8YdG2fKngQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAqJLwuK1HIq2p0 +I4N7HUjApiyxYWKqAeiC/65sLyU5TUfTgiSxTJRh625NwEYXzGTGbY674quIYK7I +uUIDrWTu2GBT1DIZJG78xbYfeWoHtKrTZ+MYy70FK448dI4lv0lZbmub0HircR2M +9MVqhWw8ik5FrpiR2DcwTkwNuNlVSu+hr/c/ljhvNP7dBfIxc9Og6xp1tyHW2hce +Vm/3HFjJqBfLw/lbZ6rx5wJA3E13r0LpnwuKQlgPYyaighfgetJdxorj37gCxLn3 +77qfpOnFfk/mgY+bLFu9ncR2svab4CGRXPey9Kb6wP+OCwnh0vCBioocUFRANkLb +bEjAYyqo -----END CERTIFICATE----- diff --git a/test/server.der b/test/server.der deleted file mode 100644 index 99a519c8d2e4b2a3b36335f22a7d7eb05344e0de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1016 zcmXqLV*X;##B^r?GZP~d6DLEPd~>6~t*H(Mylk9WZ60mkc^Mg5Ss4r>4Y>_C*_cCF z*o2uJLk)!u1VJ1QVXol(+*IA*lEji!Lq!95kRX?^glAq!YEfQli9&d0N_u8Vu|hye zrGigMilLB!07wb5FlSDFa$-(KesPI`oH(zcnSq&+g^`hofr(+1IIj_iYX;@g(&{Eg zC1j5>vNA9?G4eAQG%<29H8C?#m)boi+GiF-cOr3LQy_s9>dZxI| z_s?87s<3$b?P&)~Cm)~2SCTQMfWI?<>s`83@4N5u%Y-tLuDmYV75r$!ez5~RN(qIN zY-5gI6JC8!NUT2EK_qhWmXPC3E2iDw-|k*+H`yb<;r2;>h6_jYO=G;5ii93Kx5?pu z??hpvhLXD3#eeDrk8E>16s~vNQtW`&=bBo{K!JmY^)pg3uYO^Q#T2x22l=z1(r|iRt@~ z*;Do>Czy(eT%LH!Bzl?DGCtv}rrV9@eUFj>yT%*epFxN)CB<8A|4V8qGtv52vV z2%cUcE^{TlHS}xn`=`GSpXhF7o^H_C4U$)8X>2xVY-qr$W?}4-Xd1?56H@Bs0XasP zh1GzWk?}ur6a&*TFp3!&YIx42-ra6{@pIvcQW2%%UTIbKzdMg?NS>fQ>9&81zT82^ zO&#eQXNSB$evRSZl5gvdbJ>(0vTf&AbhMi@<<6%N>Cep1#TnDq1a<)>m`l-!>>T27HBdr%$R=?M0eZTeL(N}KL=lBm! f4>6PQ&)ay?Kf6`mZ|3R!E40iKqnM-&=N13}y%2zP diff --git a/test/server.key b/test/server.key new file mode 100644 index 000000000..ed23cb1bf --- /dev/null +++ b/test/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDX71FGKHUepupP +7c4VGoeX+Dkn5PZjDkwv+DYsTxpcZ0x/S4fHSz+aEX7cP8M0vxPmxOwJPoAm2Vt2 +RTva+8TrGClzWPT8YHzyN7r8jdP9crBQDAidYuQdHxPpXji9TMyRAGk51Qy0U+K/ +Wjx787LsWF3DFTgvJdw7YaD9EZzG7sqXvCaWAQ8sxUdj0moSm42ftVFx4Ztv5JEo +nAgKkuJ+0KklLJ08/KTp8OMm95PJzHPl+MDxqDv3jqvg5eVUnm+nE9kgZvTBtNNH +YJM3VZ0rjQDThNlLz9PdHWpfKlBTv1uVGg2SWfVpiaqxq4n686QZPHS0fu/ZQejx +h0bZ8qeBAgMBAAECggEBAKKZ3XOdJ4RrYGnLwrF1hsFS84ctDLPOomRE3lZDQrBu +QNZiQ944ta4ImqSzhwUDFbNiefMEE3AtoIfQ3p+pksENMrlfNSuOZMfoW2+uRQHH +CSldxmbtfqTHMDE8+DDj0e8mhhY8bhKkUEyTYJReEE+UwxYRtnsaYVp9y8KFLq9E +4f6NDMzzSpw/ujkcACtx0DxeWZfaP6Ms4ydh2uDEvzUwnmw4kpsgo4NtPLHDNx/y +kshfSpayYBKJ08qpzUAOXpi2UIRzvrYZE5cAcXtK6Jw02VnpNIr6+q/DAE58at7W +RwvswhNdpVVVwn04o68c4GUsGQFG/Qve8hDLdN+KygECgYEA//PE9FAeuSy2KWxS +HKSYZ422Sx/M4tuAQrX//yCFizxEhs9SF3ybZX4SCHGeQxeogIqOrFKKrXpzpCcH +3fB4LjRpdUKdv11sxFoo0Jw6wtY3N+24yM3jrpDsQqcCxUxm+qOgwGyKRJCkLxK3 +RNkAAmoT2mONeaMyWLg5g4wVW5ECgYEA1/miyi6PmT3+y4DCdNYdJll3NRmR4DGk +HDYOd+Qb+DSoBhcxz/bqBDDdXr6FT3nZEkTxKAsaPjarzKjK2J88fvnF2JRnM5Oy +HKRNk3a9KxM//UwUgoLCdg/qZe4EXX9LJr06G6YGgg0uG6Cjsa+rZ33FiucBYrEL +aevQ+cReNPECgYEAsCDlRWHk4nQ8HiEmGAPDxG6mJOgLK4j0p/Np5/xPKVMdrM75 +pKPgo2SvsBPPXkfnchzmtPpP57S94xXguf8CFHmIoGJo/wihEjUgpPz9CpoygVAa +ukPEC5o6mlsm8vHyY0M6GXAXbbtC4Am3B69z7DVm1/9tmWiN+rM7EKTTBaECgYBi +qOUWmyJ6DHoCmLU8DjuOszvjg+TBl6uyP3doiUnFnrhK3/mfWNoaRAA8MahQYAcr +c1b+xeOdG/hrK4hOYJ+QGaWphFGInCW3M89EV++eZ9LJcSHFZNpUeHzJR2uzEl1Q +Owz6aGN8sWyorj9ZAji4tBmzlEdrwBjIsDLshinK4QKBgEbmw1Dp1ZQEZcNiNKBl +EEzce+yHf8FSaC4KQSOnZIK30ZoHGLkQfr+C+8qKeDe4WYn3yf5zhjG7ssyxgWrB +S8GdV0OgrtvO5zhDH72KqddZe+api/34Zh2zY/2PKG2gBZ+ubsRpgptVK2ny5pmj +WN5CmfEv9kwQmSKzzSGUJ59l +-----END PRIVATE KEY-----