Add tests. This actually adds the initial tests for the TLS listener,
then layers reloading tests on top.
This commit is contained in:
parent
baf0763b3c
commit
c6066af4c1
|
@ -1,12 +1,22 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/logical"
|
||||||
|
"github.com/hashicorp/vault/vault"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTCPListener(t *testing.T) {
|
func TestTCPListener(t *testing.T) {
|
||||||
ln, _, err := tcpListenerFactory(map[string]string{
|
ln, _, _, err := tcpListenerFactory(map[string]string{
|
||||||
"address": "127.0.0.1:0",
|
"address": "127.0.0.1:0",
|
||||||
"tls_disable": "1",
|
"tls_disable": "1",
|
||||||
})
|
})
|
||||||
|
@ -18,24 +28,83 @@ func TestTCPListener(t *testing.T) {
|
||||||
return net.Dial("tcp", ln.Addr().String())
|
return net.Dial("tcp", ln.Addr().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
testListenerImpl(t, ln, connFn)
|
testListenerImpl(t, ln, connFn, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestTCPListener_tls tests both TLS generally and also the reload capability
|
||||||
|
// of core, system backend, and the listener logic
|
||||||
func TestTCPListener_tls(t *testing.T) {
|
func TestTCPListener_tls(t *testing.T) {
|
||||||
// TODO
|
wd, _ := os.Getwd()
|
||||||
t.Skip()
|
wd += "/test-fixtures/reload/"
|
||||||
|
|
||||||
ln, _, err := tcpListenerFactory(map[string]string{
|
td, err := ioutil.TempDir("", fmt.Sprintf("vault-test-%d", rand.New(rand.NewSource(time.Now().Unix())).Int63))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(td)
|
||||||
|
|
||||||
|
// Setup initial certs
|
||||||
|
inBytes, _ := ioutil.ReadFile(wd + "reload_foo.pem")
|
||||||
|
ioutil.WriteFile(td+"reload_curr.pem", inBytes, 0777)
|
||||||
|
inBytes, _ = ioutil.ReadFile(wd + "reload_foo.key")
|
||||||
|
ioutil.WriteFile(td+"reload_curr.key", inBytes, 0777)
|
||||||
|
inBytes, _ = ioutil.ReadFile(wd + "reload_ca.pem")
|
||||||
|
certPool := x509.NewCertPool()
|
||||||
|
ok := certPool.AppendCertsFromPEM(inBytes)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("not ok when appending CA cert")
|
||||||
|
}
|
||||||
|
|
||||||
|
ln, _, reloadFunc, err := tcpListenerFactory(map[string]string{
|
||||||
"address": "127.0.0.1:0",
|
"address": "127.0.0.1:0",
|
||||||
"tls_disable": "1",
|
"tls_cert_file": td + "reload_curr.pem",
|
||||||
|
"tls_key_file": td + "reload_curr.key",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
connFn := func(lnReal net.Listener) (net.Conn, error) {
|
core, _, root := vault.TestCoreUnsealed(t)
|
||||||
return net.Dial("tcp", ln.Addr().String())
|
bc := &logical.BackendConfig{
|
||||||
|
Logger: nil,
|
||||||
|
System: logical.StaticSystemView{
|
||||||
|
DefaultLeaseTTLVal: time.Hour * 24,
|
||||||
|
MaxLeaseTTLVal: time.Hour * 24 * 30,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
testListenerImpl(t, ln, connFn)
|
vault.NewSystemBackend(core, bc)
|
||||||
|
core.AddReloadFunc("listentest", reloadFunc)
|
||||||
|
|
||||||
|
connFn := func(lnReal net.Listener) (net.Conn, error) {
|
||||||
|
conn, err := tls.Dial("tcp", ln.Addr().String(), &tls.Config{
|
||||||
|
RootCAs: certPool,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = conn.Handshake(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
testListenerImpl(t, ln, connFn, "foo.example.com")
|
||||||
|
|
||||||
|
inBytes, _ = ioutil.ReadFile(wd + "reload_bar.pem")
|
||||||
|
ioutil.WriteFile(td+"reload_curr.pem", inBytes, 0777)
|
||||||
|
inBytes, _ = ioutil.ReadFile(wd + "reload_bar.key")
|
||||||
|
ioutil.WriteFile(td+"reload_curr.key", inBytes, 0777)
|
||||||
|
|
||||||
|
req := logical.TestRequest(t, logical.UpdateOperation, "sys/reload")
|
||||||
|
req.ClientToken = root
|
||||||
|
resp, err := core.HandleRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if resp != nil {
|
||||||
|
t.Fatal("expected nil response")
|
||||||
|
}
|
||||||
|
|
||||||
|
testListenerImpl(t, ln, connFn, "bar.example.com")
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -9,14 +10,17 @@ import (
|
||||||
|
|
||||||
type testListenerConnFn func(net.Listener) (net.Conn, error)
|
type testListenerConnFn func(net.Listener) (net.Conn, error)
|
||||||
|
|
||||||
func testListenerImpl(t *testing.T, ln net.Listener, connFn testListenerConnFn) {
|
func testListenerImpl(t *testing.T, ln net.Listener, connFn testListenerConnFn, certName string) {
|
||||||
serverCh := make(chan net.Conn, 1)
|
serverCh := make(chan net.Conn, 1)
|
||||||
go func() {
|
go func() {
|
||||||
server, err := ln.Accept()
|
server, err := ln.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
if certName != "" {
|
||||||
|
tlsConn := server.(*tls.Conn)
|
||||||
|
tlsConn.Handshake()
|
||||||
|
}
|
||||||
serverCh <- server
|
serverCh <- server
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -24,6 +28,18 @@ func testListenerImpl(t *testing.T, ln net.Listener, connFn testListenerConnFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if certName != "" {
|
||||||
|
tlsConn := client.(*tls.Conn)
|
||||||
|
if len(tlsConn.ConnectionState().PeerCertificates) != 1 {
|
||||||
|
t.Fatalf("err: number of certs too long")
|
||||||
|
}
|
||||||
|
peerName := tlsConn.ConnectionState().PeerCertificates[0].Subject.CommonName
|
||||||
|
if peerName != certName {
|
||||||
|
t.Fatalf("err: bad cert name %s, expected %s", peerName, certName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server := <-serverCh
|
server := <-serverCh
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAwF7sRAyUiLcd6es6VeaTRUBOusFFGkmKJ5lU351waCJqXFju
|
||||||
|
Z6i/SQYNAAnnRgotXSTE1fIPjE2kZNH1hvqE5IpTGgAwy50xpjJrrBBI6e9lyKqj
|
||||||
|
7T8gLVNBvtC0cpQi+pGrszEI0ckDQCSZHqi/PAzcpmLUgh2KMrgagT+YlN35KHtl
|
||||||
|
/bQ/Fsn+kqykVqNw69n/CDKNKdDHn1qPwiX9q/fTMj3EG6g+3ntKrUOh8V/gHKPz
|
||||||
|
q8QGP/wIud2K+tTSorVXr/4zx7xgzlbJkCakzcQQiP6K+paPnDRlE8fK+1gRRyR7
|
||||||
|
XCzyp0irUl8G1NjYAR/tVWxiUhlk/jZutb8PpwIDAQABAoIBAEOzJELuindyujxQ
|
||||||
|
ZD9G3h1I/GwNCFyv9Mbq10u7BIwhUH0fbwdcA7WXQ4v38ERd4IkfH4aLoZ0m1ewF
|
||||||
|
V/sgvxQO+h/0YTfHImny5KGxOXfaoF92bipYROKuojydBmQsbgLwsRRm9UufCl3Q
|
||||||
|
g3KewG5JuH112oPQEYq379v8nZ4FxC3Ano1OFBTm9UhHIAX1Dn22kcHOIIw8jCsQ
|
||||||
|
zp7TZOW+nwtkS41cBwhvV4VIeL6yse2UgbOfRVRwI7B0OtswS5VgW3wysO2mTDKt
|
||||||
|
V/WCmeht1il/6ZogEHgi/mvDCKpj20wQ1EzGnPdFLdiFJFylf0oufQD/7N/uezbC
|
||||||
|
is0qJEECgYEA3AE7SeLpe3SZApj2RmE2lcD9/Saj1Y30PznxB7M7hK0sZ1yXEbtS
|
||||||
|
Qf894iDDD/Cn3ufA4xk/K52CXgAcqvH/h2geG4pWLYsT1mdWhGftprtOMCIvJvzU
|
||||||
|
8uWJzKdOGVMG7R59wNgEpPDZDpBISjexwQsFo3aw1L/H1/Sa8cdY3a0CgYEA39hB
|
||||||
|
1oLmGRyE32Q4GF/srG4FqKL1EsbISGDUEYTnaYg2XiM43gu3tC/ikfclk27Jwc2L
|
||||||
|
m7cA5FxxaEyfoOgfAizfU/uWTAbx9GoXgWsO0hWSN9+YNq61gc5WKoHyrJ/rfrti
|
||||||
|
y5d7k0OCeBxckLqGDuJqICQ0myiz0El6FU8h5SMCgYEAuhigmiNC9JbwRu40g9v/
|
||||||
|
XDVfox9oPmBRVpogdC78DYKeqN/9OZaGQiUxp3GnDni2xyqqUm8srCwT9oeJuF/z
|
||||||
|
kgpUTV96/hNCuH25BU8UC5Es1jJUSFpdlwjqwx5SRcGhfjnojZMseojwUg1h2MW7
|
||||||
|
qls0bc0cTxnaZaYW2qWRWhECgYBrT0cwyQv6GdvxJCBoPwQ9HXmFAKowWC+H0zOX
|
||||||
|
Onmd8/jsZEJM4J0uuo4Jn8vZxBDg4eL9wVuiHlcXwzP7dYv4BP8DSechh2rS21Ft
|
||||||
|
b59pQ4IXWw+jl1nYYsyYEDgAXaIN3VNder95N7ICVsZhc6n01MI/qlu1zmt1fOQT
|
||||||
|
9x2utQKBgHI9SbsfWfbGiu6oLS3+9V1t4dORhj8D8b7z3trvECrD6tPhxoZqtfrH
|
||||||
|
4apKr3OKRSXk3K+1K6pkMHJHunspucnA1ChXLhzfNF08BSRJkQDGYuaRLS6VGgab
|
||||||
|
JZTl54bGvO1GkszEBE/9QFcqNVtWGMWXnUPwNNv8t//yJT5rvQil
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,20 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDQzCCAiugAwIBAgIULLCz3mZKmg2xy3rWCud0f1zcmBwwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMzEwMDIzNjQ0WhcNMzYw
|
||||||
|
MzA1MDEzNzE0WjAaMRgwFgYDVQQDEw9iYXIuZXhhbXBsZS5jb20wggEiMA0GCSqG
|
||||||
|
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAXuxEDJSItx3p6zpV5pNFQE66wUUaSYon
|
||||||
|
mVTfnXBoImpcWO5nqL9JBg0ACedGCi1dJMTV8g+MTaRk0fWG+oTkilMaADDLnTGm
|
||||||
|
MmusEEjp72XIqqPtPyAtU0G+0LRylCL6kauzMQjRyQNAJJkeqL88DNymYtSCHYoy
|
||||||
|
uBqBP5iU3fkoe2X9tD8Wyf6SrKRWo3Dr2f8IMo0p0MefWo/CJf2r99MyPcQbqD7e
|
||||||
|
e0qtQ6HxX+Aco/OrxAY//Ai53Yr61NKitVev/jPHvGDOVsmQJqTNxBCI/or6lo+c
|
||||||
|
NGUTx8r7WBFHJHtcLPKnSKtSXwbU2NgBH+1VbGJSGWT+Nm61vw+nAgMBAAGjgYQw
|
||||||
|
gYEwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSVoF8F
|
||||||
|
7qbzSryIFrldurAG78LvSjAfBgNVHSMEGDAWgBRzDNvqF/Tq21OgWs13B5YydZjl
|
||||||
|
vzAgBgNVHREEGTAXgg9iYXIuZXhhbXBsZS5jb22HBH8AAAEwDQYJKoZIhvcNAQEL
|
||||||
|
BQADggEBAGmz2N282iT2IaEZvOmzIE4znHGkvoxZmrr/2byq5PskBg9ysyCHfUvw
|
||||||
|
SFA8U7jWjezKTnGRUu5blB+yZdjrMtB4AePWyEqtkJwVsZ2SPeP+9V2gNYK4iktP
|
||||||
|
UF3aIgBbAbw8rNuGIIB0T4D+6Zyo9Y3MCygs6/N4bRPZgLhewWn1ilklfnl3eqaC
|
||||||
|
a+JY1NBuTgCMa28NuC+Hy3mCveqhI8tFNiOthlLdgAEbuQaOuNutAG73utZ2aq6Q
|
||||||
|
W4pajFm3lEf5zt7Lo6ZCFtY/Q8jjURJ9e4O7VjXcqIhBM5bSMI6+fgQyOH0SLboj
|
||||||
|
RNanJ2bcyF1iPVyPBGzV3dF0ngYzxEY=
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,20 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDNTCCAh2gAwIBAgIUBeVo+Ce2BrdRT1cogKvJLtdOky8wDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMzEwMDIzNTM4WhcNMzYw
|
||||||
|
MzA1MDIzNjA4WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
|
||||||
|
AQEBBQADggEPADCCAQoCggEBAPTQGWPRIOECGeJB6tR/ftvvtioC9f84fY2QdJ5k
|
||||||
|
JBupXjPAGYKgS4MGzyT5bz9yY400tCtmh6h7p9tZwHl/TElTugtLQ/8ilMbJTiOM
|
||||||
|
SiyaMDPHiMJJYKTjm9bu6bKeU1qPZ0Cryes4rygbqs7w2XPgA2RxNmDh7JdX7/h+
|
||||||
|
VB5onBmv8g4WFSayowGyDcJWWCbu5yv6ZdH1bqQjgRzQ5xp17WXNmvlzdp2vate/
|
||||||
|
9UqPdA8sdJzW/91Gvmros0o/FnG7c2pULhk22wFqO8t2HRjKb3nuxALEJvqoPvad
|
||||||
|
KjpDTaq1L1ZzxcB7wvWyhy/lNLZL7jiNWy0mN1YB0UpSWdECAwEAAaN7MHkwDgYD
|
||||||
|
VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHMM2+oX9Orb
|
||||||
|
U6BazXcHljJ1mOW/MB8GA1UdIwQYMBaAFHMM2+oX9OrbU6BazXcHljJ1mOW/MBYG
|
||||||
|
A1UdEQQPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAp17XsOaT9
|
||||||
|
hculRqrFptn3+zkH3HrIckHm+28R5xYT8ASFXFcLFugGizJAXVL5lvsRVRIwCoOX
|
||||||
|
Nhi8XSNEFP640VbHcEl81I84bbRIIDS+Yheu6JDZGemTaDYLv1J3D5SHwgoM+nyf
|
||||||
|
oTRgotUCIXcwJHmTpWEUkZFKuqBxsoTGzk0jO8wOP6xoJkzxVVG5PvNxs924rxY8
|
||||||
|
Y8iaLdDfMeT7Pi0XIliBa/aSp/iqSW8XKyJl5R5vXg9+DOgZUrVzIxObaF5RBl/a
|
||||||
|
mJOeklJBdNVzQm5+iMpO42lu0TA9eWtpP+YiUEXU17XDvFeQWOocFbQ1Peo0W895
|
||||||
|
XRz2GCwCNyvW
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpgIBAAKCAQEAzNyVieSti9XBb5/celB5u8YKRJv3mQS9A4/X0mqY1ePznt1i
|
||||||
|
ilG7OmG0yM2VAk0ceIAQac3Bsn74jxn2cDlrrVniPXcNgYtMtW0kRqNEo4doo4EX
|
||||||
|
xZguS9vNBu29useHhif1TGX/pA3dgvaVycUCjzTEVk6qI8UEehMK6gEGZb7nOr0A
|
||||||
|
A9nipSqoeHpDLe3a4KVqj1vtlJKUvD2i1MuBuQ130cB1K9rufLCShGu7mEgzEosc
|
||||||
|
gr+K3Bf03IejbeVRyIfLtgj1zuvV1katec75UqRA/bsvt5G9JfJqiZ9mwFN0vp3g
|
||||||
|
Cr7pdQBSBQ2q4yf9s8CuY5c5w9fl3F8f5QFQoQIDAQABAoIBAQCbCb1qNFRa5ZSV
|
||||||
|
I8i6ELlwMDqJHfhOJ9XcIjpVljLAfNlcu3Ld92jYkCU/asaAjVckotbJG9yhd5Io
|
||||||
|
yp9E40/oS4P6vGTOS1vsWgMAKoPBtrKsOwCAm+E9q8UIn1fdSS/5ibgM74x+3bds
|
||||||
|
a62Em8KKGocUQkhk9a+jq1GxMsFisbHRxEHvClLmDMgGnW3FyGmWwT6yZLPSC0ey
|
||||||
|
szmmjt3ouP8cLAOmSjzcQBMmEZpQMCgR6Qckg6nrLQAGzZyTdCd875wbGA57DpWX
|
||||||
|
Lssn95+A5EFvr/6b7DkXeIFCrYBFFa+UQN3PWGEQ6Zjmiw4VgV2vO8yX2kCLlUhU
|
||||||
|
02bL393ZAoGBAPXPD/0yWINbKUPcRlx/WfWQxfz0bu50ytwIXzVK+pRoAMuNqehK
|
||||||
|
BJ6kNzTTBq40u+IZ4f5jbLDulymR+4zSkirLE7CyWFJOLNI/8K4Pf5DJUgNdrZjJ
|
||||||
|
LCtP9XRdxiPatQF0NGfdgHlSJh+/CiRJP4AgB17AnB/4z9/M0ZlJGVrzAoGBANVa
|
||||||
|
69P3Rp/WPBQv0wx6f0tWppJolWekAHKcDIdQ5HdOZE5CPAYSlTrTUW3uJuqMwU2L
|
||||||
|
M0Er2gIPKWIR5X+9r7Fvu9hQW6l2v3xLlcrGPiapp3STJvuMxzhRAmXmu3bZfVn1
|
||||||
|
Vn7Vf1jPULHtTFSlNFEvYG5UJmygK9BeyyVO5KMbAoGBAMCyAibLQPg4jrDUDZSV
|
||||||
|
gUAwrgUO2ae1hxHWvkxY6vdMUNNByuB+pgB3W4/dnm8Sh/dHsxJpftt1Lqs39ar/
|
||||||
|
p/ZEHLt4FCTxg9GOrm7FV4t5RwG8fko36phJpnIC0UFqQltRbYO+8OgqrhhU+u5X
|
||||||
|
PaCDe0OcWsf1lYAsYGN6GpZhAoGBAMJ5Ksa9+YEODRs1cIFKUyd/5ztC2xRqOAI/
|
||||||
|
3WemQ2nAacuvsfizDZVeMzYpww0+maAuBt0btI719PmwaGmkpDXvK+EDdlmkpOwO
|
||||||
|
FY6MXvBs6fdnfjwCWUErDi2GQFAX9Jt/9oSL5JU1+08DhvUM1QA/V/2Y9KFE6kr3
|
||||||
|
bOIn5F4LAoGBAKQzH/AThDGhT3hwr4ktmReF3qKxBgxzjVa8veXtkY5VWwyN09iT
|
||||||
|
jnTTt6N1CchZoK5WCETjdzNYP7cuBTcV4d3bPNRiJmxXaNVvx3Tlrk98OiffT8Qa
|
||||||
|
5DO/Wfb43rNHYXBjU6l0n2zWcQ4PUSSbu0P0bM2JTQPRCqSthXvSHw2P
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,20 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDQzCCAiugAwIBAgIUFVW6i/M+yJUsDrXWgRKO/Dnb+L4wDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMzEwMDIzNjA1WhcNMzYw
|
||||||
|
MzA1MDEzNjM1WjAaMRgwFgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqG
|
||||||
|
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDM3JWJ5K2L1cFvn9x6UHm7xgpEm/eZBL0D
|
||||||
|
j9fSapjV4/Oe3WKKUbs6YbTIzZUCTRx4gBBpzcGyfviPGfZwOWutWeI9dw2Bi0y1
|
||||||
|
bSRGo0Sjh2ijgRfFmC5L280G7b26x4eGJ/VMZf+kDd2C9pXJxQKPNMRWTqojxQR6
|
||||||
|
EwrqAQZlvuc6vQAD2eKlKqh4ekMt7drgpWqPW+2UkpS8PaLUy4G5DXfRwHUr2u58
|
||||||
|
sJKEa7uYSDMSixyCv4rcF/Tch6Nt5VHIh8u2CPXO69XWRq15zvlSpED9uy+3kb0l
|
||||||
|
8mqJn2bAU3S+neAKvul1AFIFDarjJ/2zwK5jlznD1+XcXx/lAVChAgMBAAGjgYQw
|
||||||
|
gYEwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBRNJoOJ
|
||||||
|
dnazDiuqLhV6truQ4cRe9jAfBgNVHSMEGDAWgBRzDNvqF/Tq21OgWs13B5YydZjl
|
||||||
|
vzAgBgNVHREEGTAXgg9mb28uZXhhbXBsZS5jb22HBH8AAAEwDQYJKoZIhvcNAQEL
|
||||||
|
BQADggEBAHzv67mtbxMWcuMsxCFBN1PJNAyUDZVCB+1gWhk59EySbVg81hWJDCBy
|
||||||
|
fl3TKjz3i7wBGAv+C2iTxmwsSJbda22v8JQbuscXIfLFbNALsPzF+J0vxAgJs5Gc
|
||||||
|
sDbfJ7EQOIIOVKQhHLYnQoLnigSSPc1kd0JjYyHEBjgIaSuXgRRTBAeqLiBMx0yh
|
||||||
|
RKL1lQ+WoBU/9SXUZZkwokqWt5G7khi5qZkNxVXZCm8VGPg0iywf6gGyhI1SU5S2
|
||||||
|
oR219S6kA4JY/stw1qne85/EmHmoImHGt08xex3GoU72jKAjsIpqRWopcD/+uene
|
||||||
|
Tc9nn3fTQW/Z9fsoJ5iF5OdJnDEswqE=
|
||||||
|
-----END CERTIFICATE-----
|
Loading…
Reference in New Issue