Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions src/servers/src/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::fs::File;
use std::io::{BufReader, Error, ErrorKind};

use rustls::{Certificate, PrivateKey, ServerConfig};
use rustls_pemfile::{certs, pkcs8_private_keys};
use rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys};
use serde::{Deserialize, Serialize};
use strum::EnumString;

Expand Down Expand Up @@ -80,11 +80,21 @@ impl TlsOption {
.map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid cert"))
.map(|mut certs| certs.drain(..).map(Certificate).collect())?;

// TODO(SSebo): support more private key types
let key = pkcs8_private_keys(&mut BufReader::new(File::open(&self.key_path)?))
.map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid key"))
.map(|mut keys| keys.drain(..).map(PrivateKey).next())?
.ok_or_else(|| Error::new(ErrorKind::InvalidInput, "invalid key"))?;
let key = {
let mut pkcs8 = pkcs8_private_keys(&mut BufReader::new(File::open(&self.key_path)?))
Comment thread
killme2008 marked this conversation as resolved.
.map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid key"))?;
if !pkcs8.is_empty() {
PrivateKey(pkcs8.remove(0))
} else {
let mut rsa = rsa_private_keys(&mut BufReader::new(File::open(&self.key_path)?))
.map_err(|_| Error::new(ErrorKind::InvalidInput, "invalid key"))?;
if !rsa.is_empty() {
PrivateKey(rsa.remove(0))
} else {
return Err(Error::new(ErrorKind::InvalidInput, "invalid key"));
}
}
};

// TODO(SSebo): with_client_cert_verifier if TlsMode is Required.
let config = ServerConfig::builder()
Expand Down
84 changes: 62 additions & 22 deletions src/servers/tests/mysql/mysql_server_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,49 +135,69 @@ async fn test_query_all_datatypes() -> Result<()> {

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_prefer_secure_client_plain() -> Result<()> {
let server_tls = TlsOption {
mode: servers::tls::TlsMode::Prefer,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: "tests/ssl/server.key".to_owned(),
};

let client_tls = false;
do_test_query_all_datatypes(server_tls, client_tls).await?;
do_test_query_all_datatypes_with_secure_server(servers::tls::TlsMode::Prefer, false, false)
.await?;
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_prefer_secure_client_secure() -> Result<()> {
let server_tls = TlsOption {
mode: servers::tls::TlsMode::Prefer,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: "tests/ssl/server.key".to_owned(),
};

let client_tls = true;
do_test_query_all_datatypes(server_tls, client_tls).await?;
async fn test_server_prefer_secure_client_plain_with_pkcs8_priv_key() -> Result<()> {
do_test_query_all_datatypes_with_secure_server(servers::tls::TlsMode::Prefer, false, true)
.await?;
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn test_server_require_secure_client_secure() -> Result<()> {
do_test_query_all_datatypes_with_secure_server(servers::tls::TlsMode::Require, true, false)
.await?;
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn test_server_require_secure_client_secure_with_pkcs8_priv_key() -> Result<()> {
do_test_query_all_datatypes_with_secure_server(servers::tls::TlsMode::Require, true, true)
.await?;
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_required_secure_client_plain() -> Result<()> {
let server_tls = TlsOption {
mode: servers::tls::TlsMode::Require,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: "tests/ssl/server.key".to_owned(),
key_path: "tests/ssl/server-rsa.key".to_owned(),
};

let client_tls = true;
do_test_query_all_datatypes(server_tls, client_tls).await?;
let client_tls = false;

#[allow(unused)]
let TestingData {
column_schemas,
mysql_columns_def,
columns,
mysql_text_output_rows,
} = all_datatype_testing_data();
let schema = Arc::new(Schema::new(column_schemas.clone()));
let recordbatch = RecordBatch::new(schema, columns).unwrap();
let table = MemTable::new("all_datatypes", recordbatch);

let mysql_server = create_mysql_server(table, server_tls)?;

let listening = "127.0.0.1:0".parse::<SocketAddr>().unwrap();
let server_addr = mysql_server.start(listening).await.unwrap();

let r = create_connection(server_addr.port(), None, client_tls).await;
assert!(r.is_err());
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_required_secure_client_plain() -> Result<()> {
async fn test_server_required_secure_client_plain_with_pkcs8_priv_key() -> Result<()> {
let server_tls = TlsOption {
mode: servers::tls::TlsMode::Require,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: "tests/ssl/server.key".to_owned(),
key_path: "tests/ssl/server-pkcs8.key".to_owned(),
};

let client_tls = false;
Expand Down Expand Up @@ -345,3 +365,23 @@ async fn create_connection(

mysql_async::Conn::new(opts).await
}

async fn do_test_query_all_datatypes_with_secure_server(
server_tls_mode: servers::tls::TlsMode,
client_tls: bool,
is_pkcs8_priv_key: bool,
) -> Result<()> {
let server_tls = TlsOption {
mode: server_tls_mode,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: {
if is_pkcs8_priv_key {
"tests/ssl/server-pkcs8.key".to_owned()
} else {
"tests/ssl/server-rsa.key".to_owned()
}
},
};

do_test_query_all_datatypes(server_tls, client_tls).await
}
59 changes: 46 additions & 13 deletions src/servers/tests/postgres/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,28 @@ async fn test_query_pg_concurrently() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_secure_prefer_client_plain() -> Result<()> {
common_telemetry::init_default_ut_logging();
do_simple_query_with_secure_server(servers::tls::TlsMode::Prefer, false, false).await?;
Ok(())
}

let server_tls = TlsOption {
mode: servers::tls::TlsMode::Prefer,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: "tests/ssl/server.key".to_owned(),
};
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_secure_prefer_client_plain_with_pkcs8_priv_key() -> Result<()> {
common_telemetry::init_default_ut_logging();
do_simple_query_with_secure_server(servers::tls::TlsMode::Prefer, false, true).await?;
Ok(())
}

let client_tls = false;
do_simple_query(server_tls, client_tls).await?;
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_secure_require_client_secure() -> Result<()> {
common_telemetry::init_default_ut_logging();
do_simple_query_with_secure_server(servers::tls::TlsMode::Require, true, false).await?;
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_secure_require_client_secure_with_pkcs8_priv_key() -> Result<()> {
common_telemetry::init_default_ut_logging();
do_simple_query_with_secure_server(servers::tls::TlsMode::Require, true, true).await?;
Ok(())
}

Expand All @@ -211,7 +224,7 @@ async fn test_server_secure_require_client_plain() -> Result<()> {
let server_tls = TlsOption {
mode: servers::tls::TlsMode::Require,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: "tests/ssl/server.key".to_owned(),
key_path: "tests/ssl/server-rsa.key".to_owned(),
};
let server_port = start_test_server(server_tls).await?;
let r = create_plain_connection(server_port, false).await;
Expand All @@ -220,17 +233,17 @@ async fn test_server_secure_require_client_plain() -> Result<()> {
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_server_secure_require_client_secure() -> Result<()> {
async fn test_server_secure_require_client_plain_with_pkcs8_priv_key() -> Result<()> {
common_telemetry::init_default_ut_logging();

let server_tls = TlsOption {
mode: servers::tls::TlsMode::Require,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: "tests/ssl/server.key".to_owned(),
key_path: "tests/ssl/server-pkcs8.key".to_owned(),
};

let client_tls = true;
do_simple_query(server_tls, client_tls).await?;
let server_port = start_test_server(server_tls).await?;
let r = create_plain_connection(server_port, false).await;
assert!(r.is_err());
Ok(())
}

Expand Down Expand Up @@ -391,3 +404,23 @@ impl ServerCertVerifier for AcceptAllVerifier {
Ok(ServerCertVerified::assertion())
}
}

async fn do_simple_query_with_secure_server(
server_tls_mode: servers::tls::TlsMode,
client_tls: bool,
is_pkcs8_priv_key: bool,
) -> Result<()> {
let server_tls = TlsOption {
mode: server_tls_mode,
cert_path: "tests/ssl/server.crt".to_owned(),
key_path: {
if is_pkcs8_priv_key {
"tests/ssl/server-pkcs8.key".to_owned()
} else {
"tests/ssl/server-rsa.key".to_owned()
}
},
};

do_simple_query(server_tls, client_tls).await
}
10 changes: 10 additions & 0 deletions src/servers/tests/ssl/cert.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.greptime.com
DNS.2 = *.greptime.cloud
DNS.3 = localhost
IP.1 = 127.0.0.1
23 changes: 23 additions & 0 deletions src/servers/tests/ssl/csr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = CN
ST = Hangzhou
L = Hangzhou
O = Greptime
OU = Greptime Developer
CN = greptime.com

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = *.greptime.com
DNS.2 = *.greptime.cloud
DNS.3 = localhost
IP.1 = 127.0.0.1
26 changes: 26 additions & 0 deletions src/servers/tests/ssl/gen-certs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash

# Create the self-signed CA certificate.
openssl req -x509 \
-sha256 -days 356 \
-nodes \
-newkey rsa:2048 \
-subj "/CN=greptime-ca" \
-keyout root-ca.key -out root-ca.crt

# Create the server private key.
openssl genrsa -out server-rsa.key 2048

# Create the server certificate signing request.
openssl req -new -key server-rsa.key -out server.csr -config csr.conf

# Create the server certificate.
openssl x509 -req \
-in server.csr \
-CA root-ca.crt -CAkey root-ca.key \
-CAcreateserial -out server.crt \
-days 365 \
-sha256 -extfile cert.conf

# Create private key of pkcs8 format from rsa key.
openssl pkcs8 -topk8 -inform PEM -in ./server-rsa.key -outform pem -nocrypt -out server-pkcs8.key
17 changes: 17 additions & 0 deletions src/servers/tests/ssl/root-ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICqDCCAZACCQC7+cxd19y8qjANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtn
cmVwdGltZS1jYTAeFw0yMzAxMTYxMzQ5MzVaFw0yNDAxMDcxMzQ5MzVaMBYxFDAS
BgNVBAMMC2dyZXB0aW1lLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAwzdEpod7Br06SU41onxvspu1WdYIxx0Zybfv4YeaTbtmIAmSaZON237La1P2
V72S5lcbH+ImuyJwQkGVy1KZBw4waDbc4pfICX2Sm/UoWCwzegITcBzwYW2Exz4C
skPH09ZU8uHOF4VubJzZwtC3Tx27VUwj+F88/xOD4Ws4btXAPZ+/1Y0CZ8nv5Yjb
t2r+A2B+6YSrifojdKFttTqM8Y8WXRHqhb+YeO9MdxSiqPAWInmwy1sOOXNATVwC
k/BFEfpsjqajCy/NNS9NWUcdvDNAz/zRywJDHzwMk+b5KXzvUkNZuf/ZTXl5jL+d
zzgRmlYKwJylNILH2NsHyERcVwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCi+0Uf
Qd+h2kKo6nm38/RAk6+5sINUzYStoq1C/pNjrYYYz/zVMn4OjBhk5/VtKArSHtEq
YrZL8X6bXqy9e7gNlrwZ4eVxmiCsif5gQt2/jdFrT7hrTRYdax7tEj6yf9XBgjHv
/XZ0TLflbhOhNhy9KA0OyRxmNh9SAcT46psNN+t9S18tLORAHuhE2R95C13P7GHa
HauFFRoG16Wgp1kXXLcrU+mPeJ/+ybWm4OSkyn0ye0wO9XUPfLOLZePTCTeu7xFG
CwXAD1oGR6ZaglZm+guuTR38qG34pPXGcSzLCsBUuTeiMu5amAMOwMIjAbnnH1qe
AtvukomW0uRXHUMw
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions src/servers/tests/ssl/root-ca.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDDN0Smh3sGvTpJ
TjWifG+ym7VZ1gjHHRnJt+/hh5pNu2YgCZJpk43bfstrU/ZXvZLmVxsf4ia7InBC
QZXLUpkHDjBoNtzil8gJfZKb9ShYLDN6AhNwHPBhbYTHPgKyQ8fT1lTy4c4XhW5s
nNnC0LdPHbtVTCP4Xzz/E4Phazhu1cA9n7/VjQJnye/liNu3av4DYH7phKuJ+iN0
oW21OozxjxZdEeqFv5h470x3FKKo8BYiebDLWw45c0BNXAKT8EUR+myOpqMLL801
L01ZRx28M0DP/NHLAkMfPAyT5vkpfO9SQ1m5/9lNeXmMv53POBGaVgrAnKU0gsfY
2wfIRFxXAgMBAAECggEAU1LSzZXEUEMSjtmAESO19XF6vaaaxopISI5nKEdd+FHF
rGUJhmDByu9a2ivTWO4EtqZ1YG2CBJwVeGJQEqHlyVooFUNdkqYgbtSXcFP67W+o
ZSpfq5nejGdXpkd0lSxTLbstNSJmeims0VU9qWa252EUZbsDG29jNKjawKuoQb3h
J/e2RHoAoYcV1G+C/xcryBsKCUppLf0OwDjvsL3XNJq+EI6hViwho0VOIjggwfRn
4DRPnN+lQA0tVVdhyV4+aUv32nPt9/Ss5WpqFRR0+pL1nnd022MkXZXm5796B/8W
YKIxRvRWw1fSufsjc9Q8Hzx42k+tBh5UwF4+XGUEwQKBgQDz9Jb23zPkRHKm196K
U5MQ6Td77TnL2bAuOsjWl8DuBlPoUMi1sH9e30J4q6RWWdjBR0VJKMaYWtvaDRGE
CjchQ82HDtfD9T0ee3nDBjP7kzKgGpJ/giQ5/Jg/ZUyQOB/YGw5w7cc+j+gJc3iK
/tznXXD85pTqq6vn/wJBzKd2oQKBgQDM2qXfGTareMZGEK6m4SfpvbF4mZQOM/YM
bEP6F/FOlNJLpExWVHkoy0vJ0IZMhyAZr2AmyzFWYZ8L9LW5LyrCkFWASXVPKIUe
tF7xS3JKxml1YXUES6GSofb6BPNLB+KEz0G0SLcHQ5kpSOnSso+kJKMpQ1DBiZYn
qGZ4qeKH9wKBgF47lXDI6P98nRjre6/M9prqqx74lIG0lcRVuqyBs+l9kj3DrrPX
+GtKLB/2lSUx0XNfN1k6IfRJ7HB+6cwqMf9sdGB+EERGX5R9t5vosn2z7zM+8GXG
fH3Vn22lkHyI4WwVj295uaPl7IhyDRcLuYK5amKWIuG+7ElSDKokBm/hAoGBAJXb
JRgtU6bgdPrwXTNK5m3BDMCSaJJzRH0V/ixHs4iuqaAYEpfct7016r05w+TbvInN
l2MJpY/xXe3bF8zeSkOGXmW4Vw6PL8KkZAfUD0nQF3l8z6NSyGGCBjAjyu6KWBSb
oQ8HWoz/0F05L4OoiBeljY4z5jGOOr/MGxoN/N9FAoGAIApQmghUZ9+EtqfQcuCe
KZ8t5ckQYHMvZbgn2sZkZfHtThbkYIRi/E5+2yb9CkY3sBL6OpvYzx3qKLJ7iso/
RSCEvQEj+bdM9QDBCzznC7zdhRGFEYQ3MLjAXSag41HnsxdF5IXKrHlYvb0Rp/lZ
l/TLwp65NEuQ4KMFQOVL5Eo=
-----END PRIVATE KEY-----
1 change: 1 addition & 0 deletions src/servers/tests/ssl/root-ca.srl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EE4175C4833353A6
28 changes: 28 additions & 0 deletions src/servers/tests/ssl/server-pkcs8.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDNuWUJloRnDJc4
UvdOqF+YtFdIXn2MPvhzyBdEEqr+vY9nGNnBjBoOhSu6/2yojJpQhFlw8r68p02Q
SKO6ENHrxeZdgs0hQKAFUZBULgF3O3XHWkQ+6P9ajZw8impeYl4cOjFCzYGBXoP1
r1wnpWRDtvmq8U2lISky9HflcTJz0wqnW/qqzhLLV/i7tik0ShoWeCdr9CpKK95C
vyG1NKsOogM3yc5iIkc/zZX82sZ1o8Fsv4oJIpbrePIowZp93T1Vo5iOSSTEzuBY
DVZhaVkSVLWZtemPOqJs2htKVyIEyTpPsA7ulKhN8mEmbiJyP9Ri+pBkZvjRR3vy
0nH/B5c9AgMBAAECggEBAJ6ysdqfnivQbqcoeVbYVEZ8eAh/u+IAgbDvXeNJc1dn
68PgS7se1Mr2uDFc8Plk3XXXYxfaaoElnpP7NTJH32g+FeN1D8DjFY6EyQ3nH4JX
ABh07ciJ/NJiA3BAZqXAxFCKI44g8hJWUv2n9TMwRxRlhlv0Ia2M0zdXl1YL6Jun
guUi4B9vTSbD1xDxBHRuB8VRNidIocBhT2rLmpiMougRoc2hBoVM7wSNDracpD9a
DL3Rm7Ujv0CwbJbTUPxQuaaRNnkIS6TDqsZvj76n2E35aEOIk+116Fl0nRYZ7LHk
PywnbzLhzVMOQsneiDkEWW7tz735nPNdSIPe96mEeYECgYEA9X9292NW6KR6YpKS
+4IG/TqedKjmwdFPOaEyPj3NoXurVZlM4U+Urgc6M7Lw2m8qM7lcw11Xzhbijz29
ntjQeMNAOZH0W9/jGjsgkpelO6jF34QRNw2/Cfxl3+nQL14kZjID/7Gw9kyCZa2S
ChJWluudDHZPpS9PybgtvaoRztUCgYEA1oZaldnpDeLN9ftm17UgMUdl8enta6rQ
nN95YEu3gyjtWf2ry3pxTQ44/ZqcrRLRj1y+iu0D5qSqkuz14vntzwGxoVQz3gjq
zdHEkXv9ZpA3M+uMt+dLUbZ9ebpNIGhLf+oxCQxk+v/cEpo2cO5HaZCGiblXQZSr
S7vuov3IaskCgYEAzYKMxn+ka0/1G7tzy5OH4khGCYay1aEwXx/v/WajUwFB5oBU
eXCzGBP4xvqO4WyZuX78hpcHQACsXBjlOapqqg1ZIFhsZNTBOl4w4EaODak1K+1U
s++P8v4VEiKbImv+sIZCDrRjXWui5Rct37yGPAS1DY+lELTQaB8EO3e5PJkCgYBh
uOY+6PsvJigoa5NXo9y8VgfsgWFz8GYDcBF8ekFocBZfLh06HdbLATWY4PuKI85u
fhMWeg2S3WQOdf80nCFmcSEXmqHd/TXo+CuREmhGdl+POTfq9mPrHzRdZS6JGrl5
1ZbsxkahyDfaCYHPQ9woDHwc9N74st6tKzjz6qOHcQKBgQCP6HeweuBLkCsZfaAv
MUDw1r6MFAosjvAUO+kKtxBSHkxehUwVuhDN/t/nmO2ddetRoQbIDvpTg/3R2obO
vJOiC+FxV8LX+WA8IaTHpv/5Qjl/FDyjGFHWkN+gY+xQ+BTJsR5MPCq9m6ai+ihF
1ynlhxQGWqh6cjuGhdSXYZ6WJg==
-----END PRIVATE KEY-----
Loading