Adding support for configuring a CA to validate client certs, and BATS tests for client-cert auth.

This commit is contained in:
Jason Fulghum
2025-11-07 17:29:25 -08:00
parent abf6d1b525
commit f2969f6b44
19 changed files with 766 additions and 3 deletions

View File

@@ -48,6 +48,7 @@ type commandLineServerConfig struct {
maxWaitConnsTimeout time.Duration
tlsKey string
tlsCert string
caCert string
requireSecureTransport bool
maxLoggedQueryLen int
shouldEncodeLoggedQuery bool
@@ -314,6 +315,12 @@ func (cfg *commandLineServerConfig) TLSCert() string {
return cfg.tlsCert
}
// CACert returns a path to the servers certificate authority file, or "" if there
// is no CA cert configured.
func (cfg *commandLineServerConfig) CACert() string {
return cfg.caCert
}
// RequireSecureTransport is true if the server should reject non-TLS connections.
func (cfg *commandLineServerConfig) RequireSecureTransport() bool {
return cfg.requireSecureTransport

View File

@@ -16,9 +16,11 @@ package servercfg
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net"
"os"
"path/filepath"
"runtime"
"strings"
@@ -178,6 +180,9 @@ type ServerConfig interface {
TLSKey() string
// TLSCert returns a path to the servers PEM-encoded TLS certificate chain. "" if there is none.
TLSCert() string
// CACert returns a path to the servers certificate authority file, or "" if there
// is no CA cert configured.
CACert() string
// RequireSecureTransport is true if the server should reject non-TLS connections.
RequireSecureTransport() bool
// MaxLoggedQueryLen is the max length of queries written to the logs. Queries longer than this number are truncated.
@@ -472,10 +477,25 @@ func LoadTLSConfig(cfg ServerConfig) (*tls.Config, error) {
if err != nil {
return nil, err
}
var caCertPool *x509.CertPool
if cfg.CACert() != "" {
caCertPEM, err := os.ReadFile(cfg.CACert())
if err != nil {
return nil, fmt.Errorf("unable to read CA file at: %s", cfg.CACert())
}
caCertPool = x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(caCertPEM); !ok {
return nil, fmt.Errorf("unable to add CA cert to cert pool")
}
}
return &tls.Config{
Certificates: []tls.Certificate{
c,
},
Certificates: []tls.Certificate{c},
// tlsVerifyClientCertIfGiven will request a client cert from the client,
// and if provided, will validate it against the specified client CAs.
ClientAuth: tls.VerifyClientCertIfGiven,
ClientCAs: caCertPool,
}, nil
}

View File

@@ -91,6 +91,8 @@ type ListenerYAMLConfig struct {
TLSKey *string `yaml:"tls_key,omitempty"`
// TLSCert is a file system path to a TLS certificate chain in PEM format.
TLSCert *string `yaml:"tls_cert,omitempty"`
// CACert is a file system path to a certificate authority in PEM format.
CACert *string `yaml:"ca_cert,omitempty" minver:"TBD"`
// RequireSecureTransport can enable a mode where non-TLS connections are turned away.
RequireSecureTransport *bool `yaml:"require_secure_transport,omitempty"`
// AllowCleartextPasswords enables use of cleartext passwords.
@@ -862,6 +864,15 @@ func (cfg YAMLConfig) TLSCert() string {
return *cfg.ListenerConfig.TLSCert
}
// CACert returns a path to the servers certificate authority file, or "" if there
// is no CA cert configured.
func (cfg YAMLConfig) CACert() string {
if cfg.ListenerConfig.CACert == nil {
return ""
}
return *cfg.ListenerConfig.CACert
}
// RequireSecureTransport is true if the server should reject non-TLS connections.
func (cfg YAMLConfig) RequireSecureTransport() bool {
if cfg.ListenerConfig.RequireSecureTransport == nil {

View File

@@ -0,0 +1,61 @@
The certs and keys in this directory are used for testing cert-based authentication with a running server.
Each cert is set to expire in 100 years. The rest of this file documents the steps used to generate them.
CA private key and cert:
```sh
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 36500 \
-key ca-key.pem -out ca.pem \
-subj "/C=US/ST=Washington/L=Seattle/O=Test CA/CN=MySQL Test CA"
```
Server private key and cert:
```sh
openssl genrsa 2048 > server-key.pem
openssl req -new -key server-key.pem -out server-req.pem \
-subj "/C=US/ST=Washington/L=Seattle/O=Test Server/CN=localhost"
openssl x509 -req -in server-req.pem -days 36500 \
-CA ca.pem -CAkey ca-key.pem -set_serial 01 \
-out server-cert.pem
```
Client private key and cert:
```sh
openssl genrsa 2048 > client-key.pem
openssl req -new -key client-key.pem -out client-req.pem \
-subj "/C=US/ST=Washington/L=Seattle/O=Test Client/CN=testclient"
openssl x509 -req -in client-req.pem -days 36500 \
-CA ca.pem -CAkey ca-key.pem -set_serial 02 \
-out client-cert.pem
```
Alternate CA and client private keys and certs:
```sh
openssl req -x509 -newkey rsa:2048 -days 36500 -keyout alt-ca-key.pem -out alt-ca-cert.pem -subj "/CN=Untrusted Root" -nodes
openssl req -new -newkey rsa:2048 -keyout alt-client-key.pem -out alt-client.csr -subj "/CN=bad" -nodes
openssl x509 -req -in alt-client.csr -CA alt-ca-cert.pem -CAkey alt-ca-key.pem -CAcreateserial -out alt-client-cert.pem -days 36500 \
-extfile <(printf "extendedKeyUsage=clientAuth\nkeyUsage=digitalSignature")
```
Expired private key and cert:
```sh
# many openssl versions do not allow directly creating an expired cert
# through the x509 subcommand, so we use the faketime (libfaketime) tool
# to override the date.
faketime '2008-12-24 08:15:42' openssl req \
-x509 \
-newkey rsa:2048 \
-keyout expired-key.pem \
-out expired-cert.pem \
-sha256 \
-subj "/CN=Expired Test Cert" \
-days 10 \
-nodes
```

View File

@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFTCCAf2gAwIBAgIUBehRa8DqkCXpTNEMjt2VMaKR0iMwDQYJKoZIhvcNAQEL
BQAwGTEXMBUGA1UEAwwOVW50cnVzdGVkIFJvb3QwIBcNMjUxMTExMjA0NzM3WhgP
MjEyNTEwMTgyMDQ3MzdaMBkxFzAVBgNVBAMMDlVudHJ1c3RlZCBSb290MIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0B/slLjxo3N9CWgqrbqhWgFc1TaZ
+MbkY/dBXtI+5XH2KAwVVASyXJ/HJAnrW8bCNFLsbJ3eoDq/5/KTjXyfthUS3mlw
6+st04SxZ3dxVxT8qN7rtipNZH5LbhxqeLGQOTtK2+oRWXs7sOgb/9QmpNqKZngl
gHAJGEtVtkwjUeCfG2l50Lb6ZCdufDjkxKKJBxQ+WnwEu4j+h7L8CVIk02L2+NyO
QDoGcgHpuk123MGsJAXIiOD6mflnsbMj6UfHBXwentUQWem+Oo8jEq5SNkojw4ev
COhu+X6klnU9u9nz4rAprYemZRiDJpL6KKICLwRxN4qS6HYWCOjx/yEmDwIDAQAB
o1MwUTAdBgNVHQ4EFgQU7L+sRuVp+8cCXg/8BM/1eRiiXPIwHwYDVR0jBBgwFoAU
7L+sRuVp+8cCXg/8BM/1eRiiXPIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEANRVztIKk06qAqFU4RTFJwVDkC2/IxGEKNH1xYonYvLuDhBlh9DLE
LqtuNsDp2UzlKAdgxabhp0n+/Ft/J6U60ZB666AyvU3mNS1/mhSnBnMrSzRo7Bow
WykY6IeTs9qcNJFtJDTdYLugcDKx6/BpyVKdPR85w5LsXZNPnXH4VKVV1mNPU61m
oFbksVkyHVGfwgU8U4x4qMqizPRJMrOq3oMbuI7sKVufFxj+r6scnlSl9ytybF6Z
iIUFLuOsUZpuJPtemmAU0ODFtkurnzg1rKJRJqYJOJBfAYL1ubjOkvbkwkPA/Suv
FW8337kOnM+XB9wFxxMmrRrvTTbLgPjNWA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQH+yUuPGjc30J
aCqtuqFaAVzVNpn4xuRj90Fe0j7lcfYoDBVUBLJcn8ckCetbxsI0Uuxsnd6gOr/n
8pONfJ+2FRLeaXDr6y3ThLFnd3FXFPyo3uu2Kk1kfktuHGp4sZA5O0rb6hFZezuw
6Bv/1Cak2opmeCWAcAkYS1W2TCNR4J8baXnQtvpkJ258OOTEookHFD5afAS7iP6H
svwJUiTTYvb43I5AOgZyAem6TXbcwawkBciI4PqZ+WexsyPpR8cFfB6e1RBZ6b46
jyMSrlI2SiPDh68I6G75fqSWdT272fPisCmth6ZlGIMmkvooogIvBHE3ipLodhYI
6PH/ISYPAgMBAAECggEBAKRXcRMG7xfoS+WvsXO5mUtfJBTgpriBJTuitKXRUwUO
9hctY3ISu1zUdgWJJ6YyzotOp44lIvRXL85SCB2DOQIopdumWxqPfII3l3ZiJMdk
tRYL4QjZYn9mEt4B5jkjzQTEQxpgPA7ydnH89o8O0Oz//KVpXgOLdEMQyb/HY2R0
k6jCKjyPkE4C/9GiluBdywENbJgVx2eJ/87hJTQeMgg208Fd+ZuUqo7fbOmlj8qJ
Qxg6xqUqgVuXy4+/UN6FDhyQExY+6GMjVDbYTH/qgtPbczYDYBZ7Uyz7QtYI+1zC
LYhlx3PnOYtykuq5eaOJVC9qcxmjeK+2vVCHtGqJeYECgYEA70YEXHcR2/dzIqYi
zEZTgHp8IQwBl/vdWHJmNsGKvPQtI+3lQ7UpN5rhM0wvvHsI4FZHlGy+3b5nDJPQ
wVEe+rXGfKHI65jfa3EI7/EVYI9iftduMwB08EMQx/kQOkAhwA7ZeNgYg9yC8Fz/
QShTe6DF41+kKPR5i6Yr3Oy/SO8CgYEA3qx5tV0UQC8hFBoQZPUMwivFqrrVF+dO
xQ5cE2ejwggHCYG9zckeIlXyEJYYJBDijKeS2tbSciamQaH9pjBngFlqEPb5BBCi
/yADOFMKj0vzVVR3KupEsIGVqkTn8zgjR96MCxsIeHKAOxfLe1u61WKXEhUXAp4A
xR5RiGvmtOECgYAwG9raoJI1sQ40REUw318AsR/uIRTc8yYxF2dX0RhNH6dH1xhG
wdEUvg5TmxjqA67oNFDWFftWaGcdz0ak5+ObsxrCimD0hds+Jg8O92E99fZu3G/q
z0ez2zgvjPNnUue2TwYI1yIuuRKWs4wbFLmcXNoM+njuRyF9I58kH3HifwKBgCAG
ypKNSqZYoPdVMFp07FrZFNsTeCax/CBXimK4G1OC+BAj+vqoHI9vsRs1m09EpnD4
gSS8lRQZ/vudou/OMnTBZ4H9I5+0DN2I6y2ks/YcRGlXdrRTcYG5gZ81ve67ekeR
+K54OuWoAk19hKS/csXSIkxVgDO+Kfov/CYU7t/BAoGACRZ18ceU/FxNrb5te7QT
0HPX+skdR4ageDCT5IAAuTJVEtE7wTthZDSWYxCK9svJZWZ+w8Ra13UN2qmIFeh7
7W65UEsJzACrU90qXeBPi+CNcy6KyiaCGTzNl1IcRYH1iifG8XkRNaPyUWv11pHf
ehuDpHfvA1+63QeYFlL6Fe0=
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC2zCCAcOgAwIBAgIUMHX2u70NEyASdTFVv2/ys87UwLswDQYJKoZIhvcNAQEL
BQAwGTEXMBUGA1UEAwwOVW50cnVzdGVkIFJvb3QwIBcNMjUxMTExMjA0NzQ3WhgP
MjEyNTEwMTgyMDQ3NDdaMA4xDDAKBgNVBAMMA2JhZDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMTuG5OQCSmc8gwAkWFAoij08Y0vCtievhHxRclX4h/x
EBCvEnLZu0W7khJ73dR7sg2wVN/TVsxsTSwZetitM+ORr19hSDzi25JVyasd+woZ
0kusY9uKMhfjmlC4s860MuOczd9nYOKLUo7T3z37CjjfPIlMafoaO8pUcJBaDudW
XdnHtuYZRikjfzNytV3cJF2nCx5biLnDPzyXKCUXeFKlt7jJiMQQ/AZSQcufHJ9d
cTlOhzdf7UVLCPDaIDUoIvbcSjF/MzcW8vGsK89WRw8kaRTQea+EAx8fD7iu0dbf
TlQXggEWcwaxvEn+Wlb4Am0M2xwar6G1WMBAvdHmKqsCAwEAAaMkMCIwEwYDVR0l
BAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQC9
lFF3gspop/BaJNI7bT4sefi8ktP0PE72csS3vTSXa59rfJhRw6RJm4/1EvpAxrjl
GcX/63A4sm9ZPlE6UtyABMTEAOp7I+V8WT3e+ny8PxsBmpwnLUAj8iSHt2IC1el1
JDb3njt/3Hf2XBe68G6jdOzNwEE3vsbewlbo9VJ++Sfh+HTpuK/SAvJRYbH7q4u2
+zCDIY3BRcR6UqfkdX99G2O2sc56L61LHQr9MptkqiG5ncWEfUnoFcpxvl48qmb2
yMhuXgcOZnGjHXIWIztUbSeaUvLxzy+DwXXyNjadmXG0UJS/1gMEFhfKghrkSujR
wNEHOHnBxNA+dOLE/3Ja
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDE7huTkAkpnPIM
AJFhQKIo9PGNLwrYnr4R8UXJV+If8RAQrxJy2btFu5ISe93Ue7INsFTf01bMbE0s
GXrYrTPjka9fYUg84tuSVcmrHfsKGdJLrGPbijIX45pQuLPOtDLjnM3fZ2Dii1KO
0989+wo43zyJTGn6GjvKVHCQWg7nVl3Zx7bmGUYpI38zcrVd3CRdpwseW4i5wz88
lyglF3hSpbe4yYjEEPwGUkHLnxyfXXE5Toc3X+1FSwjw2iA1KCL23EoxfzM3FvLx
rCvPVkcPJGkU0HmvhAMfHw+4rtHW305UF4IBFnMGsbxJ/lpW+AJtDNscGq+htVjA
QL3R5iqrAgMBAAECggEARD/lTMHZexOKi4BS4iqdSKaDZJPOJX72jo9YyUvs8XcB
Q1b5hNZS4fr8x+0n1zE7ZyUadSvwZA6QvFzkR13XouHlrp+vgnJ4+IFE0Eomq7yB
Nnq7bOW7MK5P1/P7VQL8tAevDeLtH/Z7GUbykq+DPmyXtVnHTMd0u02CaXTcv22C
hrxMhFOvm5Mn6AHskEcfZc57Ww5AiTOz1Unp2k0BWqYHw6HPnySQuuO+XmTtYKmQ
ZPaBljHeunmrfHbFiApPW1/tKAk6229CpE8TBAAyhzwwd987XCbmMV03qOTZFeUy
0MYcxKrrLRaK+adktnM81R2zVQpr9mbjhBqHRJJA6QKBgQDoM+t9qbWmW9c2mfqb
vxkJGkSi3w++pihoBOqdzVDVLkTB1VNVgTP3Eo1e0jrd35YkO2cjoST/V+vRZTQA
lAa8GROww+CCZK15ZdTDhYlw7YTsL2qCgOyGtZ6J7ReSWkri1oFnrv6ZPfEbfe5j
OFoGCzcowvrkUOP+m/eXsrn+nQKBgQDZHMWn8dQk5i/rjg2u8sqjpOFuMTvyY1s3
DjjI6uBZuehmgG1zdjZYFSMtc7DSycELbuuKtk1y2ryCFGMBHAVVFYnWArtdk9hN
bMJN4/xwhIenI6+HfhhSYRm4B3rHCRfVKED6PuQKEcUIze3gn9Fsg56Td+LAAGOY
ZFmcnQ2n5wKBgEY91oHoAaQ2ag8BW1cb4sXnJVYjpg6lEtoMirB7uHUUjwYXsyLN
d9vIx+0kKVyO00tYkOWtTJTVkud/9tAp9zOVXmh9iH/JVtS/YjJXRfFcWHZeDZk2
yNYjQLc2eofyOm8ONo0X2bqfiz0mxiNLm6fyYpg5C05fzehqY+aG0U7dAoGBALbf
11VJCuoxwbdlpfzwoOMKJKAOdHIMYm6TWh1SSbsKLsj38DlLHyc+Vq0YP56tNh+N
RHVIbSALQrFGvsXWdl9ejwVms690ssM0ks3M9XtJBoIwOs+j1JS/GUy7cB1qeVqg
V2rxwl8A7LgnzPBhbaM7kjygxKv5J+ray+hxGWmNAoGAYpOmDdT+HWbDniLrxUf2
vBk63RIqkMNvAd6ABZSBPKu1jikUW7HRmzt4et6OKeuZ1Io7V9ik3apcrr5KEV5Y
DkOwA2VqPy8Qg1ivu8FW0BqbGHXcAVcnJ2qL4z73TZLv9vQZIs81fNgM11zWPv5x
GKTc6aAfMON2B4L0NWJb/MY=
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtMInEEKF12Y7T5CPZDx3ZIFCctNMo2pzNyqgyATv2xzu1r93
aRoK4kZ8OcxxNnaRgFXqZ53aTxax5dsPzkIHEONLMmpK8yKZ60PvZN0atpnElJsq
fxuicbPxGQFMMI+92RWPoidtPsw/uDVhAstJV/0o2nZZGoIQm0Sc/rScx97R9t7u
hd2R/Z/RhZZP6N8WP91kURIh3+4C5lcVzkLrBr/7qarOGso843Y3uuzIPMfuxYmv
JqeUcmhmrmfVE4Dqklju8zCFq6edBh69HmZHRfI8cMGmrSep/cFY/LIyR5MF6Im8
PPVzjNq9whl5BRI1S2mxQwmedYGOMym7dZx+dQIDAQABAoIBAGFkRsXlAdY39/b7
rbbVOYMGfjX+EUnvPhrYNf7vYgjOAwXj7cPMS1b1oVNHCyzMH8NlB0JC8/AvCzUM
neyE+Oepf8evK6jq2MHBPcg7tXvzR87F99S6oADhciMF5vY3TJQdoOE+mwb958sp
v5ZQz7i/53Yl1AaLU8VE5834pIyvYjrQe1iLkN0uTu8tbYRJ5yYJtWLdOvpJeK6E
CxyMbITcLmWtiSDB0NJnvJ0kEmcdVIoBOLGIx1yD1b57J6iVZDRYf5ckPFu0tF4f
xLq/hT02Y0twmhqo3gpqaagwCyU7MsztKRkWRw6UIQFR6Jj7trgyNHArEv405QjW
ncbgukECgYEA6AXoW3I4yChabocNlT5g3VNHM0ivRioV+Kc5Lg8Az+7QC8cDgeFY
RTFzm2P75/uFonuyYHinEpZssoQBt9oGSCrZKRwNIoRYG5lWQCNASx6kwMYH0HQj
nd5v3JZn1phmybKtHTxkID7R8Sp5KHrbCk414Y6rhL7T+Bu0FhDdJ3ECgYEAx3AO
L6i84k2f84CYFFAIj6XBrFO6w5YWE81NnLE0QDfPUWs4Pud+PMU9c1IdYt/YLynO
PW1B27n8t4Uf2s2boUwGNvwBS3nV2FSPdF8okOak0Yr1MADOzJyI4bKVPVWXSVbI
og9TX8/XhILIkt6lKkAPqon+4wTAsB0D9rYyLUUCgYAB82LDug8eJ7Cy8zG7Cn43
/iZAGSFYHqx2nblOWNPx65kWMEMoSWO7mTHWoZ2RkrzJ4+5Y/0qwTlF1osR87jlV
S/7taI33t1MiUES4X1OADi7mbAPOzdsqzZ71JNKUrE1Y7saj00koOD79nxTLsVS8
HnI3hkKM6CnSETGPae7iEQKBgQCbFYXShbIrgBVLcsnPsdSWb1zFNm7avJD6YQFj
QWDSNxPdyjR4pebCNtZsIIR9aHdhZW7c0WMPC/d6deipao0Exmtmwlv3ZwxlJoxO
/9g5pUCxOQ8kftxQu8CtUQNAKJh2DSgC7Uv2C1cZ0eFKZBunWR1Vje1Id1+nE0kL
xe4KyQKBgEdfE1a0oIwiFR+NYgIGo7Ek6dPP/ClThPoWSzJZSqf/puZvRr5jg2X5
a0cwIBdNtkPB4tGH5Na/XRNShMcga0ChE9C+iDcPNVqS8vQ9Lx1ThQThh9CaoTlX
BtRf0sYtI0Uz35k9Jhn9RaVa49CrfzpWIe/F3MN+lLk39fjSQUq2
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDnzCCAoegAwIBAgIUZEggcTJC1u6+5cw3zqQ+ByY+hhQwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcM
B1NlYXR0bGUxEDAOBgNVBAoMB1Rlc3QgQ0ExFjAUBgNVBAMMDU15U1FMIFRlc3Qg
Q0EwIBcNMjUxMTEwMjIxMDQzWhgPMjEyNTEwMTcyMjEwNDNaMF4xCzAJBgNVBAYT
AlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYD
VQQKDAdUZXN0IENBMRYwFAYDVQQDDA1NeVNRTCBUZXN0IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtMInEEKF12Y7T5CPZDx3ZIFCctNMo2pzNyqg
yATv2xzu1r93aRoK4kZ8OcxxNnaRgFXqZ53aTxax5dsPzkIHEONLMmpK8yKZ60Pv
ZN0atpnElJsqfxuicbPxGQFMMI+92RWPoidtPsw/uDVhAstJV/0o2nZZGoIQm0Sc
/rScx97R9t7uhd2R/Z/RhZZP6N8WP91kURIh3+4C5lcVzkLrBr/7qarOGso843Y3
uuzIPMfuxYmvJqeUcmhmrmfVE4Dqklju8zCFq6edBh69HmZHRfI8cMGmrSep/cFY
/LIyR5MF6Im8PPVzjNq9whl5BRI1S2mxQwmedYGOMym7dZx+dQIDAQABo1MwUTAd
BgNVHQ4EFgQU/S/KX17JCaB9DN23uFj8QbrtPbowHwYDVR0jBBgwFoAU/S/KX17J
CaB9DN23uFj8QbrtPbowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
AQEAGY4s/FF54UdT5nixT0CAlnXbEfR0xTCW9YNPUarT9eydvL+MVwPUO09D2QQu
yQ04ilb1Q0Lbo0D+az6Y1gel0FiEUP2ifyRPBDAEneAJpnYu0nber9BPefYXyMYU
ezbomPDLc45mt5TmNIiviZICJoyP06KJo80xgv2/5Imkq9K6XyQOFz1GS5ioEMUK
ys7h3fd7cpkNdGDZYYj0ext/YS9Zr0Mx32HIXRtNOoh8m/oFClIOM9J4wjemhaX8
P7i9st/u7bJPDeMBlnHa8II5wZEjni96xuEGRuwgzJUO02zVT0khZhjoxsb9tiul
cvHqOHKsRyduYyg4nBU64SyH0A==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDMzCCAhsCAQIwDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCVVMxEzARBgNV
BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB1Rlc3Qg
Q0ExFjAUBgNVBAMMDU15U1FMIFRlc3QgQ0EwIBcNMjUxMTEwMjIxMjI1WhgPMjEy
NTEwMTcyMjEyMjVaMF8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9u
MRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtUZXN0IENsaWVudDETMBEGA1UE
AwwKdGVzdGNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALaa
XXrOAlxD9D6D1e+tNm0uC0bHAuqi+4MOF5a84jtOtolPVE4MGpZOaq5AtMmVPVuQ
ksq65xxyUC5YSMxsL0F7EcDJy5t7494pXPNw38ONEGfdGxfT7pdbOCDYIOLwRWi4
llvzlbvwrYGnxwAmGdodaQIeX8pEa4ugmEp4WOIMRInRhzlrRid5ML9F7fzcWsTU
aCrNLo61q1hGINQpLh/FM8fB2RzaYZw7lAg8qNbwi8PnUb116XsFvY+caq23A5tg
22RtLBcyC+SPOZfjAhaCghIJ6GvTs3jc0g92H/P/jOt7KA3fPmouD30D2OjOfW12
0wQgRqku9xLPcj0lktUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAXNnxFo5n8taT
wTqr51mLb1FbxVkJL+Ky5rypbLJsvjvChTz7D7zWHLj3FoPNP5Us60ZsE/E7Id1k
O5qSshRbmrRhXsh9qR8Z1GJa9NE5RQHC19NielQ49TM8GTPbKbOgqNOC2tdqT5O6
jBfqwtveNO7uJwHJ001SzfoKEWBRE04xyFehIgoqZLXvYyQcMFqoZxWvIWZPOBmp
Meu7RmFIoSOpN2fIIasuO3fGCU2liC477ices43RswdHQgR+xkieCdkud+es9XbB
yCxpTCXBJC9SRsQJ8KVU7bl9fF4z0CLjtehJuYb0B1Bso6neOmlrlvWlAIIz2Hrg
ps/GAtt6SA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtppdes4CXEP0PoPV7602bS4LRscC6qL7gw4XlrziO062iU9U
Tgwalk5qrkC0yZU9W5CSyrrnHHJQLlhIzGwvQXsRwMnLm3vj3ilc83Dfw40QZ90b
F9Pul1s4INgg4vBFaLiWW/OVu/CtgafHACYZ2h1pAh5fykRri6CYSnhY4gxEidGH
OWtGJ3kwv0Xt/NxaxNRoKs0ujrWrWEYg1CkuH8Uzx8HZHNphnDuUCDyo1vCLw+dR
vXXpewW9j5xqrbcDm2DbZG0sFzIL5I85l+MCFoKCEgnoa9OzeNzSD3Yf8/+M63so
Dd8+ai4PfQPY6M59bXbTBCBGqS73Es9yPSWS1QIDAQABAoIBAHbvKD/aepMZ97XY
LLoFedO3D8UzzmSBb4w224pk0H2MkTvyHZkQLSkFPlrs7lP2DpbbHaFKB0nx8uOc
wR3UwRrHTBLj3OgS06JaEp7FQBmggbUEwKbOdTLESVSrMRBfKvZAdD7D8x0McBZo
7ybbqi70xPaKTh3yXpH9MfQfWtUvydqKQw9CuIA63RmHgN1GMgHCJdnSOMRYO10S
sNZjY7s6ybZuDa4iC0ib9fyNH7pmw5Wx3SYbT9VpkAU5NyxIzuOT9YM7ATJj/33i
HHoWLny+qwFeHPcFEtPR9Tb6kIRNLKekaAo02ypvtAxL4DW7hUepkFLjUimU9AA9
iwxuTUECgYEA6cDNOkDW9+TsWFv82iF6xKUlmBR80Hd2lsoASbT+ttaMUkgnuhel
pRENrLQWw3OaiF2P+ma7J8UjEPLJUDwBhyF1b9bq3xxhjfw/1THAIS7QBiZFZsKg
oxo+oxJyNKcFByXvPtYBak9TCKq1El0AAECFSPn3kuvp08FZ/ENzvO0CgYEAx/tV
U4wBfmBfWpk1m6eeSIHYb7LzVYwafJOodc2pVO4MYyoVCnLTc7uU+Cds9lCxiCo0
J/LMzxFufH9oEsttqvDdWA3xlW44DbkXA/xHvxMomJZ3sPkC1a/UEaTeWu3Nt5SH
xliqkUmUyJf9l+O9iNnma5tU0uVTQhCqu6PUWIkCgYEAv6BdHipVkHdNAcq3aKMV
n+u6/Aefos6sm0USI1qLjZwpALNCTh5gnwdx7GjeWHCG+M+q3p4lQ58q9hPy0SHA
JuVY/sxzU2BS4TEvqzjTxuA3jTMGpg1b3xn+y3Stx1g8mPWSQjLyihJpgatgMaOo
AoziN0cknH9l+0CA4nrxgKkCgYByyrdw7LXSyBkUFUvrXG0EK9yESZFaMsDlb5DM
hlBD2x0rMvW++KieDzf0thTa0vkFM0ya/clItzXXqv6fgzwhWn+D0wUwhIMShYNL
m13HtYShCgYMhPN2m6Y8tomYYlaqoUzKswy9tyH7fxtnO6gJTSLx88jeAhsnmg+X
A/SZGQKBgQCCmQrT4ZPEJNPWW64Uqpu+YiYl33ZBi07bvbKLWtlueVLOalEUs6ap
aPQOTEAtLn32E49mJ9RDLa9zrPNbhBdIV675C8eoxTy/9rxVOhIPsQ0gc/uYoQHm
jQLmbPInxxTCwYsGYIcCMtD/PlAV76gYvEULZCOJGL3f8d6q8yG5sg==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICpDCCAYwCAQAwXzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x
EDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC1Rlc3QgQ2xpZW50MRMwEQYDVQQD
DAp0ZXN0Y2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtppd
es4CXEP0PoPV7602bS4LRscC6qL7gw4XlrziO062iU9UTgwalk5qrkC0yZU9W5CS
yrrnHHJQLlhIzGwvQXsRwMnLm3vj3ilc83Dfw40QZ90bF9Pul1s4INgg4vBFaLiW
W/OVu/CtgafHACYZ2h1pAh5fykRri6CYSnhY4gxEidGHOWtGJ3kwv0Xt/NxaxNRo
Ks0ujrWrWEYg1CkuH8Uzx8HZHNphnDuUCDyo1vCLw+dRvXXpewW9j5xqrbcDm2Db
ZG0sFzIL5I85l+MCFoKCEgnoa9OzeNzSD3Yf8/+M63soDd8+ai4PfQPY6M59bXbT
BCBGqS73Es9yPSWS1QIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAJVmiEOAcFjM
xqoBZ27HJKuSiWWMqGkjSUbW7Jd8jyT1c4aG4AJPIjv1XQcuuSFMylExAdM0aiXh
bgIL3rDyps0kiMXS7dEH2fBRMUUfwWTCKlrxU3X7i1z6tGPAA/5mDBYDuS2WL4sm
LKtbTF7YYjwiS2Qvx0V8EWKXT8gQoYjgQELmcudnasXvh5xg0NOL5vvVJJaw5rsE
vrY/HggAzaEQcesLbYvCs883uQj/A5+KbRU6oOgzrOqfyBsMZREyCTyBf7wbjcFn
1gwRWj3aNnswRgsGv4B6ps4n/ZMdT2/SnlRGXLmL5J/vSW4QjzQY7Y+bl14Ffd8A
x7pByunkcCo=
-----END CERTIFICATE REQUEST-----

View File

@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDGTCCAgGgAwIBAgIUe7oTaYes9UBKfNKaCcgCsncXorYwDQYJKoZIhvcNAQEL
BQAwHDEaMBgGA1UEAwwRRXhwaXJlZCBUZXN0IENlcnQwHhcNMDgxMjI0MTYxNTQy
WhcNMDkwMTAzMTYxNTQyWjAcMRowGAYDVQQDDBFFeHBpcmVkIFRlc3QgQ2VydDCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALgHuAIpvCldUcGdGjD1btyw
dOl3cd6hkRU2k3B9GiCoVgkIl1lj0/Bylt2idkMt3We1uctkVOlwCOJAb1hijzhk
IcZ/CD70jhzE2jqww1pcejo9KABH0o5AW/qJeVqtBmKSRNkgbHFGkhKa0s/46gNw
hKx5kkVeuIVR4YCZMnzV6kI+xPpsmt+828F5xHLbTrG3eP9qBjJ27biO8eVtNava
7y/Gym5julbHVtYMOgm+9RQ/SWv+YUW0MtzOZyP9x7abO5QwmHu+hj+QaZ0/tvh7
13wDJsjcN4niDhvrSCge1HQOF+wenqZ0K7jgl8ufc4MqemK1OechbVnjohP+ImMC
AwEAAaNTMFEwHQYDVR0OBBYEFIzfe9R0v64IDjDoAibiy/leYCtdMB8GA1UdIwQY
MBaAFIzfe9R0v64IDjDoAibiy/leYCtdMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggEBAETKiZfwZEq1dHW/ZUtqDgNVnFpF4aiPJ7ueHxV4PgBWVCD/
nG0+Sux0tmNv1e4vy7iDSD/AlOdRiYqb+iGAohDU+LILpGRDG3j5Xx+3lKGQh04g
B2UjajEfWtUtMw3iiGECmo3ZJdsAIsN1BzCI/25D/uyaXiaiGCad8yTdYxAReyCF
dhXQtsCNzNDH0xVCy3/ME8Tk1T3J+NW1OdxX/9G4loyMRWst/T05qgqnslV7epWg
w8fQdh5PkyWPdgfAa/kCgXbKaJpNqKzTlQesAXsIw1ZRVfxI/eYqZ6Zi8F/QxHcC
vhrW7+I8f9zwKNEsEhdG58FD717RlxtIWzUFSmw=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4B7gCKbwpXVHB
nRow9W7csHTpd3HeoZEVNpNwfRogqFYJCJdZY9PwcpbdonZDLd1ntbnLZFTpcAji
QG9YYo84ZCHGfwg+9I4cxNo6sMNaXHo6PSgAR9KOQFv6iXlarQZikkTZIGxxRpIS
mtLP+OoDcISseZJFXriFUeGAmTJ81epCPsT6bJrfvNvBecRy206xt3j/agYydu24
jvHlbTWr2u8vxspuY7pWx1bWDDoJvvUUP0lr/mFFtDLczmcj/ce2mzuUMJh7voY/
kGmdP7b4e9d8AybI3DeJ4g4b60goHtR0DhfsHp6mdCu44JfLn3ODKnpitTnnIW1Z
46IT/iJjAgMBAAECggEAUfu+Udhd5t+X6HUgkecE+HPz4X5A0DmR9K1Xialx1lKn
4WZeZog+hsPFyf7ySINKO0WN+7o6ybQLgR/LesiNnUWedltpRQKVvONFhRfyL3M7
UG6mP1m/x3eMglR0J50lVwxqd4AmT2Bs+rTWbagqOFYMBPoz24uTEHGl0DBveYTf
fJfVWRSpm1YzqGVg5bQkbMlpYkjUJCGsVf8sAm0aq5YHPwbVq5igSU5ZuZnX4SmC
byjw2D38RI6Tg+KVcl+TMubdtQu678RdZQG1tRqNsuEoXFYS8CTUPiTrN4X1tkR0
ULw45C5gR9btCcKXzrzJdhYQAG12juYNiSIHuMTGIQKBgQD6IAeqtXy0sm5/h5x5
g1TCw1L6eVWhnRBOYWQh+ZDIxBrre156bO8xcq3+BKbKXyJgkcEQTJbCPzNAfhq/
Pwe80IFzIOSyk2VJ2Et0oYlcO+91Hlrm1G/doMzBrzn16vN0lueD6rBxWa4WCfe3
BL7WCbi8ORIWWbjVJVkHJUAZ5QKBgQC8WkSxrDXYx2t623kcrpiFQleIfLsTNIMz
++ksJmx2Oo1PCGzCvoPl2nc/JQzCBvuG7jVpMqKcKYRZJe9NyF4OYmrd/HSeStcs
icoSR6TLEFA9fZ9q72jpH66ghsbhZ/mVMy5HrrvlNHCadviTvoZVsHGDmn2DnW6E
pDf3C6xmpwKBgQC9d/3WxluM1Yz2ddeGBIH0dtkoezjuj3eGqCedxNpz+nkZ3/4V
ZudZ4bEDNqrRqXb1B/PjUODyi8VbGStRq4FE+fzVJRmYXCbh5UJjOuo+P/iIE1Jw
gIOsst3n6cBSFIQO0TDWsLSvaGuCrlJDBQk6QWr6yZB19ckZTI0/6GvCMQKBgGLA
EPP2DeUx6K/pEX5wK5bySWJNwuc2yPMgSAfVvVffKuccy6juqciA2bRJgH7ZmlYL
3gThf0/QlIsI0IY/XtC72Lu5+IplQpsfQsqCtWuhifAzRLmT+7T931haUTssgDYx
Nzpt6iUpcUAK0Bjl8xhKAbm17chrad4xGwZzIFhRAoGBAO0VTi5NpBi9vun4FDED
AYjSUefMC1ecgJ0F7BqqA4pCgYUz1oBwMjzpce6Azzv/CEjUaPPTDk+oxZ3NqenU
X96OaKA+/00ez39SKdhkmIDnSr8X9PsLvY9WvGlNLa8xTSrQG4zGJ1tAtu3s9La/
IhqmwKD2Emzket0kbRmCiHim
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDMjCCAhoCAQEwDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCVVMxEzARBgNV
BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB1Rlc3Qg
Q0ExFjAUBgNVBAMMDU15U1FMIFRlc3QgQ0EwIBcNMjUxMTEwMjIxMTQ1WhgPMjEy
NTEwMTcyMjExNDVaMF4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9u
MRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtUZXN0IFNlcnZlcjESMBAGA1UE
AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqJdE
901d24SerjOoh0N73fQaCsuRWezHEumrdMs/pgeQs6KkCTP5sQCPZp7CP4NvCSGW
nTZNgzjHIMvknMWrHESQvvbNlgOs8mA0mR5K4UNNY8WL5eAQ12BqQrVuNzY/vZoa
HEYbXew2b+C+j62CC7sJYqNAgE2f+hDIcaRp1qozdyk6cTWleu1u/n/tQcdlhkaG
4Jxf6yZmvdHP7a9lgwh2zpG8fngZQy/xpmRN0dYG8qZYMfcIa/BRGS2hqhUFc5U9
l5ME6TsO7KnAOn5xoDNrk8WUq+vFU+SNStZjD4SBgRuX0YjRn4a4zdwxSIhslz6S
jbMtQxYjdP+HclYMQwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBwrBcik2A1MS7k
msXmiP5+uaLMhhGGvXEchtawMu15YkjmxRglRmmQ90TH2BDknor2jStYhoCMyYCV
QapKwfjrOteq9gJ8PFtDWomA6hoOgmC4wr+jwoLYfsAQbCj5PQuUB9+wHyR+ATdr
SE/5zg6/tD/+y8/NzQxu+vEvpNIKhaJiNmGlLzFhE/f881P3uka0Plazf/S47Clr
Dx6FuGcckLW4bzvq1e28bZFXizDlkG+nYSrqykgbLh1kLCOZUO+AM6GhpztHHb0Y
ptby/+hApYuWqzXhbPFozup9CVo16sQAb82/ehJetQhQGx7DDWYB0vtPAXv9Rats
Bz/qXg+M
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAqJdE901d24SerjOoh0N73fQaCsuRWezHEumrdMs/pgeQs6Kk
CTP5sQCPZp7CP4NvCSGWnTZNgzjHIMvknMWrHESQvvbNlgOs8mA0mR5K4UNNY8WL
5eAQ12BqQrVuNzY/vZoaHEYbXew2b+C+j62CC7sJYqNAgE2f+hDIcaRp1qozdyk6
cTWleu1u/n/tQcdlhkaG4Jxf6yZmvdHP7a9lgwh2zpG8fngZQy/xpmRN0dYG8qZY
MfcIa/BRGS2hqhUFc5U9l5ME6TsO7KnAOn5xoDNrk8WUq+vFU+SNStZjD4SBgRuX
0YjRn4a4zdwxSIhslz6SjbMtQxYjdP+HclYMQwIDAQABAoIBAH99pVG+1/NhXv4t
Yoyno8w9BFSVjN2MCR9sRZSU/xT3M54kqBetjm0kF01rUUnmgtlM5TEOF5/cF/nd
Noy3jqZZ03wV93IyZV8FEcGY/tdKpgOFKD42K4Y0CydXPHnUNG+VUZmACsIEF0aT
lofgli94yagl/GkKSqg4eNw3kTIbWNrzNHzx/ZvuUsng3Qi1Lx6Oa1QJ6diBcCXN
FISloHL3L2vkHp+XRxDhBKASSx2xp6xLhKykRST24O0p0oO9lZFkQqX/LAW+rYG1
fTdxZgHAXA/SpTRfo/CZuEZf/qVwJaO1G5X37/aYnJEQgbQGtlDX/PM2nhPbL7Bm
K9n0FYECgYEA3fAR3tZLZ4Woj98JMKJ3Ko5env+f8Ozdu4PwSKHLrztAkC42B7Rq
Hjiq0IbxGZLzGrdzEXMXqjuNUx7O7ng31AXg7Yec/Sx0yhpkJsASfIRoLtofSQ34
EL7iuz6SMqq1EbWbwEE0h2SMCqhcaLRykpBOF77QiY5oWdVB24NPDwsCgYEAwncz
tXElCEoWDvmChQitX+8ItP8qpPMRdQNuQ85WUUhHVKfHN6Rg12tXReUwcy5/Y0EC
rLtFwjoo3FHWf7fVtOz4w+GA/cDE2Nc3GbipivkhvSh8fb9mK5fJss6HBlbuiZov
ovFhW+IWzinlAxxTyKHURF5NH7SMYTjQk22aGqkCgYABjQ3y6rh4Lrzw1HQx/NCs
YXZT0iGCA4XBK7jgKRFNVjKrT0ddYmtjbq3y6x6AOUCtrR6GvrEppWTlcc+sZvas
6qWZw1rbghYG24xboPgAGsTHnwqc7hYPt+XJvTQ0WnENgKFoBIyjbZZ09JxAtxId
6BhDnjfC3lXoWs8tA4vn5QKBgER2tRS/FduaQbPZ8jKmAGwS+szGPRw/mzjIEWz7
2vXY7YwHWaLkU1fkKaCo9OrIRv8Jp0hq0j90PGh8w3jJnwqIl3hXDxPHZ0Y0VujO
U5pi5Zb0Bwg6d10HnnI+Ndlsh6SYTQcf1jgEHCVPKJp0waaUGuhLDvoHlZiw6PXO
k3+pAoGBAJeb+GbBvIvATULvqR6WMkjJYjRcE6X4KgQFbAwdSDtVxhpCQWCfv9oh
GW88gZAg45huACFSuwELzKP70o/yoVBjaXIGCiUdWD0qEbcHDxy4Btypjw5n3Dsr
c21FgmwGtlWk/yxvb5AwYcdDKxnQi1zC/A1oM1KCU3BmgJotDbqk
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICozCCAYsCAQAwXjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x
EDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC1Rlc3QgU2VydmVyMRIwEAYDVQQD
DAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCol0T3
TV3bhJ6uM6iHQ3vd9BoKy5FZ7McS6at0yz+mB5CzoqQJM/mxAI9mnsI/g28JIZad
Nk2DOMcgy+ScxascRJC+9s2WA6zyYDSZHkrhQ01jxYvl4BDXYGpCtW43Nj+9mhoc
Rhtd7DZv4L6PrYILuwlio0CATZ/6EMhxpGnWqjN3KTpxNaV67W7+f+1Bx2WGRobg
nF/rJma90c/tr2WDCHbOkbx+eBlDL/GmZE3R1gbyplgx9whr8FEZLaGqFQVzlT2X
kwTpOw7sqcA6fnGgM2uTxZSr68VT5I1K1mMPhIGBG5fRiNGfhrjN3DFIiGyXPpKN
sy1DFiN0/4dyVgxDAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAPpwpMdOkjb94
gJLa6P63bDqOipXV5NExsY7ny1WUyAHkSVSw1OmFSAQ/LyVdbodqXaHxILGE6e+j
92dO7MFHXm8sYT03LI4Y+hgqU9zX/0zsAdJaWRXr39SgcIZiRoWd1ZEBEI28lDS1
WSsOXaODKp3cdrJNmew+ue3m/4pgA8QHLSYC2TA3wi9O0RMahK9xlNyF+R/sOKPK
4u3j39a7AF95jlu6uuNZiRvGa1HULlXxRxVe5IPxNnOgTZI0FBV6CwhDCtOWJh75
9QhHOKFO3tQYuBNRO1imcTWFV69cYPRL9Qa/nZ37VUtMDJcaDlg3o3yzGQiNgO/S
LLRX/dbUpg==
-----END CERTIFICATE REQUEST-----

View File

@@ -0,0 +1,347 @@
#!/usr/bin/env bats
load $BATS_TEST_DIRNAME/helper/common.bash
load $BATS_TEST_DIRNAME/helper/query-server-common.bash
setup() {
skiponwindows "tests are flaky on Windows"
if [ "$SQL_ENGINE" = "remote-engine" ]; then
skip "This test tests remote connections directly, SQL_ENGINE is not needed."
fi
export CERTS_DIR=$PWD/certs
setup_no_dolt_init
dolt init
}
teardown() {
stop_sql_server 1 && sleep 0.5
rm -rf $BATS_TMPDIR/sql-server-test$$
teardown_common
}
start_sql_server_with_TLS() {
PORT=$( definePORT )
cat >config.yml <<EOF
log_level: debug
behavior:
disable_client_multi_statements: true
listener:
host: "0.0.0.0"
port: $PORT
ca_cert: $CERTS_DIR/ca.pem
tls_cert: $CERTS_DIR/server-cert.pem
tls_key: $CERTS_DIR/server-key.pem
EOF
dolt sql-server --config ./config.yml --socket "dolt.$PORT.sock" &
SERVER_PID=$!
sleep 1
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails when SSL is required, but not present" {
start_sql_server
dolt sql -q "create user user1@'%' REQUIRE SSL;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT --ssl_mode=DISABLE -e "SELECT 123;"
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth works when SSL is required" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE SSL;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;"
echo "PWD: $(pwd)"
echo "OUTPUT: $output"
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails when X509 is required, but no TLS connection" {
start_sql_server
dolt sql -q "create user user1@'%' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT --ssl_mode=DISABLE -e "SELECT 123;"
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails when X509 is required, but no client cert" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;"
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: client cert auth works without a password (mysql_native_password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED WITH mysql_native_password REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: client cert auth works with a password (mysql_native_password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED WITH mysql_native_password BY 'pass1' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA -ppass1 \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: client cert auth fails with wrong password (mysql_native_password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED WITH mysql_native_password BY 'pass1' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA -pwrongpassword \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: client cert auth works without a password (caching_sha2_password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED WITH caching_sha2_password REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: client cert auth works with a password (caching_sha2_password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED WITH caching_sha2_password BY 'pass1' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA -ppass1 \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: client cert auth fails with wrong password (caching_sha2_password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED WITH caching_sha2_password BY 'pass1' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA -pwrongpassword \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails when the client cert is expired" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/expired-cert.pem \
--ssl-key=$CERTS_DIR/expired-key.pem
[ "$status" -ne 0 ]
# NOTE: This is the same error message returned by MySQL
[[ "$output" =~ "ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails when client cert uses different CA" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE X509;"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA -pwrongpassword \
--ssl-ca=$CERTS_DIR/alt-ca-cert.pem \
--ssl-cert=$CERTS_DIR/alt-client-cert.pem \
--ssl-key=$CERTS_DIR/alt-client-key.pem
[ "$status" -ne 0 ]
# NOTE: this is the exact same error message returned from MySQL
[[ "$output" =~ "ERROR 2026 (HY000): SSL connection error: error:0A000086:SSL routines::certificate verify failed" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails for different SSL cipher" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE CIPHER 'unknown-cipher';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--tls-ciphersuites=TLS_AES_128_GCM_SHA256 \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth works for matching SSL cipher (no password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE CIPHER 'TLS_AES_128_GCM_SHA256';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--tls-ciphersuites=TLS_AES_128_GCM_SHA256 \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth works for matching SSL cipher (with password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED BY 'pass1' REQUIRE CIPHER 'TLS_AES_128_GCM_SHA256';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -ppass1 -e "SELECT 123;" \
--tls-ciphersuites=TLS_AES_128_GCM_SHA256 \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails for different cert issuer" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE ISSUER 'wrong-issuer';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth works for matching cert issuer (no password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE issuer '/C=US/ST=Washington/L=Seattle/O=Test CA/CN=MySQL Test CA';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth works for matching cert issuer (with password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED BY 'passw0rd' REQUIRE issuer '/C=US/ST=Washington/L=Seattle/O=Test CA/CN=MySQL Test CA';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -ppassw0rd -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth fails for different cert subject" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' REQUIRE SUBJECT 'wrong-subject';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -ne 0 ]
[[ "$output" =~ "ERROR 1045 (28000): Access denied for user 'user1'" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth works for matching cert subject (no password)" {
start_sql_server_with_TLS
# TODO: Does MySQL require an exact match, or does it allow spaces or anything around equals, for example? EXACT MATCH!!!
dolt sql -q "create user user1@'%' REQUIRE SUBJECT '/C=US/ST=Washington/L=Seattle/O=Test Client/CN=testclient';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}
# bats test_tags=no_lambda
@test "mutual-tls-auth: auth works for matching cert subject (with password)" {
start_sql_server_with_TLS
dolt sql -q "create user user1@'%' IDENTIFIED BY 'passpass' REQUIRE SUBJECT '/C=US/ST=Washington/L=Seattle/O=Test Client/CN=testclient';"
dolt sql -q "grant all privileges on *.* to user1@'%';"
run mysql -uuser1 --protocol TCP --port $PORT -ppasspass -e "SELECT 123;" \
--ssl-mode=VERIFY_CA \
--ssl-ca=$CERTS_DIR/ca.pem \
--ssl-cert=$CERTS_DIR/client-cert.pem \
--ssl-key=$CERTS_DIR/client-key.pem
[ "$status" -eq 0 ]
[[ "$output" =~ "123" ]] || false
}