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
122 changes: 71 additions & 51 deletions test/envoye2e/basic_flow/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,28 @@
package client_test

import (
"strconv"
"testing"
"time"

"istio.io/proxy/test/envoye2e"
"istio.io/proxy/test/envoye2e/driver"
)

var ProtocolOptions = []struct {
Name string
Quic bool
}{
{
Name: "h2",
Quic: false,
},
{
Name: "quic",
Quic: true,
},
}

func TestBasicTCPFlow(t *testing.T) {
params := driver.NewTestParams(t, map[string]string{
"ConnectionCount": "10",
Expand Down Expand Up @@ -128,59 +143,64 @@ func TestBasicHTTPGateway(t *testing.T) {
}

func TestBasicCONNECT(t *testing.T) {
params := driver.NewTestParams(t, map[string]string{}, envoye2e.ProxyE2ETests)
params.Vars["ServerClusterName"] = "internal_outbound"
params.Vars["ServerInternalAddress"] = "internal_inbound"
params.Vars["ServerNetworkFilters"] = driver.LoadTestData("testdata/filters/restore_tls.yaml.tmpl")
for _, options := range ProtocolOptions {
t.Run(options.Name, func(t *testing.T) {
params := driver.NewTestParams(t, map[string]string{}, envoye2e.ProxyE2ETests)
params.Vars["ServerClusterName"] = "internal_outbound"
params.Vars["ServerInternalAddress"] = "internal_inbound"
params.Vars["ServerNetworkFilters"] = driver.LoadTestData("testdata/filters/restore_tls.yaml.tmpl")
params.Vars["quic"] = strconv.FormatBool(options.Quic)

updateClient := &driver.Update{Node: "client", Version: "{{ .N }}",
Clusters: []string{
driver.LoadTestData("testdata/cluster/internal_outbound.yaml.tmpl"),
driver.LoadTestData("testdata/cluster/original_dst.yaml.tmpl"),
},
Listeners: []string{
driver.LoadTestData("testdata/listener/client.yaml.tmpl"),
driver.LoadTestData("testdata/listener/internal_outbound.yaml.tmpl"),
},
Secrets: []string{
driver.LoadTestData("testdata/secret/client.yaml.tmpl"),
},
}
updateClient := &driver.Update{Node: "client", Version: "{{ .N }}",
Clusters: []string{
driver.LoadTestData("testdata/cluster/internal_outbound.yaml.tmpl"),
driver.LoadTestData("testdata/cluster/original_dst.yaml.tmpl"),
},
Listeners: []string{
driver.LoadTestData("testdata/listener/client.yaml.tmpl"),
driver.LoadTestData("testdata/listener/internal_outbound.yaml.tmpl"),
},
Secrets: []string{
driver.LoadTestData("testdata/secret/client.yaml.tmpl"),
},
}

updateServer := &driver.Update{Node: "server", Version: "{{ .N }}",
Clusters: []string{
driver.LoadTestData("testdata/cluster/internal_inbound.yaml.tmpl"),
},
Listeners: []string{
driver.LoadTestData("testdata/listener/terminate_connect.yaml.tmpl"),
driver.LoadTestData("testdata/listener/server.yaml.tmpl"),
},
Secrets: []string{
driver.LoadTestData("testdata/secret/server.yaml.tmpl"),
},
}
updateServer := &driver.Update{Node: "server", Version: "{{ .N }}",
Clusters: []string{
driver.LoadTestData("testdata/cluster/internal_inbound.yaml.tmpl"),
},
Listeners: []string{
driver.LoadTestData("testdata/listener/terminate_connect.yaml.tmpl"),
driver.LoadTestData("testdata/listener/server.yaml.tmpl"),
},
Secrets: []string{
driver.LoadTestData("testdata/secret/server.yaml.tmpl"),
},
}

if err := (&driver.Scenario{
Steps: []driver.Step{
&driver.XDS{},
updateClient, updateServer,
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
&driver.Sleep{Duration: 1 * time.Second},
driver.Get(params.Ports.ClientPort, "hello, world!"),
// xDS load generator:
// &driver.Repeat{
// Duration: time.Second * 20,
// Step: &driver.Scenario{
// []driver.Step{
// &driver.Sleep{10000 * time.Millisecond},
// updateClient, updateServer,
// // may need short delay so we don't eat all the CPU
// },
// },
// },
},
}).Run(params); err != nil {
t.Fatal(err)
if err := (&driver.Scenario{
Steps: []driver.Step{
&driver.XDS{},
updateClient, updateServer,
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")},
&driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")},
&driver.Sleep{Duration: 1 * time.Second},
driver.Get(params.Ports.ClientPort, "hello, world!"),
// xDS load generator:
// &driver.Repeat{
// Duration: time.Second * 20,
// Step: &driver.Scenario{
// []driver.Step{
// &driver.Sleep{10000 * time.Millisecond},
// updateClient, updateServer,
// // may need short delay so we don't eat all the CPU
// },
// },
// },
},
}).Run(params); err != nil {
t.Fatal(err)
}
})
}
}
25 changes: 16 additions & 9 deletions test/envoye2e/driver/envoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ func (e *Envoy) Run(p *Params) error {
}
log.Printf("envoy bootstrap:\n%s\n", bootstrap)

e.adminPort, err = getAdminPort(bootstrap)
var node string
e.adminPort, node, err = getAdminPortAndNode(bootstrap)
if err != nil {
return err
}
Expand All @@ -105,6 +106,7 @@ func (e *Envoy) Run(p *Params) error {
concurrency = fmt.Sprint(e.Concurrency)
}
args := []string{
"--log-format", "[" + node + ` %T.%e][%t][%l][%n] [%g:%#] %v`,
"-c", e.tmpFile,
"-l", debugLevel,
"--concurrency", concurrency,
Expand Down Expand Up @@ -171,23 +173,28 @@ func (e *Envoy) Cleanup() {
}
}

func getAdminPort(bootstrap string) (uint32, error) {
func getAdminPortAndNode(bootstrap string) (port uint32, node string, err error) {
pb := &bootstrap_v3.Bootstrap{}
if err := ReadYAML(bootstrap, pb); err != nil {
return 0, err
if err = ReadYAML(bootstrap, pb); err != nil {
return
}
if pb.Admin == nil || pb.Admin.Address == nil {
return 0, fmt.Errorf("missing admin section in bootstrap: %v", bootstrap)
err = fmt.Errorf("missing admin section in bootstrap: %v", bootstrap)
return
}
socket, ok := pb.Admin.Address.Address.(*core.Address_SocketAddress)
if !ok {
return 0, fmt.Errorf("missing socket in bootstrap: %v", bootstrap)
err = fmt.Errorf("missing socket in bootstrap: %v", bootstrap)
return
}
port, ok := socket.SocketAddress.PortSpecifier.(*core.SocketAddress_PortValue)
portValue, ok := socket.SocketAddress.PortSpecifier.(*core.SocketAddress_PortValue)
if !ok {
return 0, fmt.Errorf("missing port in bootstrap: %v", bootstrap)
err = fmt.Errorf("missing port in bootstrap: %v", bootstrap)
return
}
return port.PortValue, nil
node = pb.Node.Id
port = portValue.PortValue
return
}

// downloads env based on the given branch name. Return location of downloaded envoy.
Expand Down
3 changes: 2 additions & 1 deletion test/envoye2e/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ func init() {
"TestBasicHTTPGateway",
"TestBasicHTTPwithTLS",
"TestBasicTCPFlow",
"TestBasicCONNECT",
"TestBasicCONNECT/quic",
"TestBasicCONNECT/h2",
"TestHTTPExchange",
"TestHTTPLocalRatelimit",
"TestStackdriverAccessLog/AllClientErrorRequestsGetsLoggedOnNoMxAndError",
Expand Down
55 changes: 28 additions & 27 deletions testdata/certs/client-key.cert
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA07MQ4NQQrnDxl3gwHh5NNUyJzrYmK57GogtoJype0jrEjldw
XZCYnvJEf9DJs1wtZ5p7Zij5wgM0vJsRB1BMM/uH8M8OikmlCyoajmA7wk5VVSRy
56h6ni14T93YOHEGlmnJOF7mkav1940ppuiNeT4V6+f8SDX+M5z1NplnkoOQAPqh
9s9191dpQC4lGinstioMFdnbXXvdtBFcgzDIsKxEL9/EHM/fCSQrcz0+SeJY0RSM
1GrqnnyWGfTQ/77R6pvhtMbW5ULUR4jKuQ5qvYGyLdn9Xh+k/8u+UXlF50Ndj3VC
kxHGnzFEZFy8QtRCd1jiYsh6HZWgOAeAzUkqQQIDAQABAoIBAGhJtU3cil80+n7w
0Vt09/oCu3yelM02SYn4bpWktNOB6eRpRMyC9/yNQptoooR+K0v3eUTJeMhPxgIH
rerZbsDI7538kqAjSW/njO+IjsfYyQbJjuV6RPV5VuSZV/PuEh20/VCMx68JdIFA
BD3aIB+TKz9sqAZ2usR4VQBRsAknat5RhdcE7CGcbEiNGbSn1ASqTif+oiRZBnTZ
hXik9gbjMi57nG2Mq8Ww0XZGAsFY+NxCldTVI//GwHT38uatjUvF8c/pfpKfDpam
iD7U0EJsPUh/nzITCX+py7BDYcYDByhLWbgviH7/CoMT3wnggZQfpljepEG9PqMF
59FYAoUCgYEA9sv853zOR50msCs/66ohh5zbC/1DH1J9yWsk0VsmH096zfgUGCqP
0aTT7b25XnZYkvGiWslp8IEHc6ADEkwGsp88i0EvVO2pK/3xdAaCReVqF6jZs9Dn
0CuJHmJfgZaJsGT8ofQfUOSWhddLXGcLHMinjaPZOakn8XAizbtcoRsCgYEA25gG
pdD1xwU07y8iVY6gxsDQbNRJbAkgtVju/8fIkqe/PxhvwUhxF8zdlL29+P/PYBjw
P4L9zHVXQUKqV4clBECuhA31Yz9zhfivzz6y4NLzM7+6EzjQ4TOLlo2Vp7oPjN3y
29NHbPqG4JEwJ8aqXJqtWMUUdp4LuF+N5dkIM9MCgYAPXUOxZaOx8aam8QpZsY3E
048PgATdvlT2ZSU1o2cMK/aJPBiEKKIrewd2lYkkyFlbTI++9ysRPfcoy51lVjZU
iHVMdhJsRx9xDa4qev1BPLcOIgTrnOXRn+Q5cAZiGu0XfjH8IyaP8qssSer3JbMb
Z6KGvtyXKmDCNyjzheaOYQKBgAsBysuC9t7b9vRKQ4lQVeTAg3IBDhEZQAd3BrvR
cs9PEzoBapCgpfKQdUbgX+ZcRDPH7DrywO//rbj6s3khsAxPha/e1z77TjoX5hAY
T3UPfdtJL/WIsoenQsbwH+FBZUglU+gK5hijUiFthaFoxt9PbYL2lfkAIQxD1eQA
hfW7AoGAGflnz6ea3u1j0hAFykKZ3D/82/qCjaB2H2jmdpl2xHodhUodrmYWkDBu
vB28ez8aTx8QlIk0GIVVYolM7zlyCBs6FXrH34fL9P44najLqfQUbKdUUOqb6lfT
BC1Kcvm8frJLtUUqFTkgtgrRlqihIja1uvF65VoHF1AfjUslhdc=
-----END RSA PRIVATE KEY-----
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCOZbIDvbyKV3pX
JO9ckVHHGkfDcZekdY5QkO8mhyxzgm0db/czaKef8tq8SfoRBiUpDUTeM8EBwBpk
HB4NW7pep1VCYyT0QANwpgkKObW3/c2IB/a+gTF5OS5QpRFRvmHPKdbTEUDqnbfo
+jdTh1RXS13ULml32jLLbJJ8g1hu5Lxp2az50WizwzeNjV8sBcQ6lSfWqJrxkjis
u9UEO9sAv1kYheHtmmEPFZIdbJQqAqwhQvD11Oxz8LZoPGEX0fqGI+G5LMI7dCGC
pIZOd3GXDkevAAorO2kdMokISo0zXbXsM4nS5R6ycpnlfKuCtUwfTYPh7k6MD0kS
9I5ZGScJAgMBAAECggEAF8RUhnhUMDjyk/n3s5kTr6oswSvD9jCizMKsD9+u5San
RKsL9PoqRDGaHaQxR0chy6zJylaUB9FC9mOVBoDBZgwC2H5IzDWk/VfRGXJRaMDF
XceKgPh6Q/PtzYsHjX+7voKKtxbhoWcqq4mb02a6holvQztt4hG6uaZI+txHVda6
94+hgxL06DwNPh9VCiStXC4WeB1BaWRlqj0d5LY8v3ipDDeokOBqxPuR7Haf9kGK
0MwYe5blPdZgBwM0UHg9NAOJNHoEZ5P7zVDMaUk0BTJ2EVzoHmlexzeEcHmg8qRh
EqMjW0jlwcl17jQ1QMXN+zt91AkytklUvbpBKHQtkwKBgQC72ghoeecaBNoyenKR
29unbQ/W8J+OZUYdW701G54xxykAHckeGnYIhZ76fzzfuEVTwII2Is8POlMVeNjl
EbfW/KPaL2t+cxh5yLErcFRsLiB+67RBCwktOUnKRqIm/hVs33xJE753o6aJGm0E
MsYnYeDIFW74Ct+utVJyln4T9wKBgQDCDkPBk0VQBkPZgTp8lUUqvjRQECIUGptx
iC9z/vCXsNekomVPlBHahdPnjVKr6p52aJJcWfiEMUIHvOnTNbQnWJHApfx0h7JS
SNy36BqirynU49nbg3Z2bql7S7zAHkrazocQqnTOzfDT2LDDyHwP6+2jmVAshNv7
O1Xcvb3c/wKBgD4xp8r/YTZKGPvRcpE8G3NJNo9RR2JbwWUC9JfatvuAFuEE+4tN
83pK0yHYco0Xc0yRVgsaZzeBdfSL+DOPNDCnoJAiVxKchKP9gDsDi8/tTbD31Mwc
HUOtzfJ8hD8orGtJatq/ALaXphGKgEF9lgF/9G4KOp1A7GHpgoyRqthtAoGAOkLG
HOv2N1xqKncd9CFsrrSESDVPxfFnEeLtPEoiOaiiVY9cE1RFN/JN+Ir5cxvxj2M9
7fQlJKsVQ/V3zi2ldNqmh8xNyz6iTwoJGj3ZIVatnHj8A2eovU3kHFxUwulVV/QB
oQNMJnq1/yRjjaQ3eyA+LIvvAi6xTPA3ixp8UkkCgYBI7/rSqdHt1aY4Ubp/Qb1P
8F2oqkI0yT0E31+y/H/PP1b0Hf/CedQhyBYfrt2NkLo4ejSX738fH0onCKUgbSiT
dEtO6maVpV/P5qC2D4sYvLI4iaT0FjEz6sbSUWp2qmPlcsQwwq2mF0bUkAd4uCQk
RVD3SeqV4EwOsq/r2ny5VQ==
-----END PRIVATE KEY-----
39 changes: 21 additions & 18 deletions testdata/certs/client.cert
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
-----BEGIN CERTIFICATE-----
MIIDXDCCAkSgAwIBAgIQUwQ9hAAm16Yf+PkWD1VM/jANBgkqhkiG9w0BAQsFADBD
MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVN1bm55dmFsZTET
MBEGA1UECgwKZ29vZ2xlLmNvbTAeFw0xOTA4MTIxODU2MDhaFw0yNDA4MTAxODU2
MDhaMBMxETAPBgNVBAoTCEp1anUgb3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA07MQ4NQQrnDxl3gwHh5NNUyJzrYmK57GogtoJype0jrEjldwXZCY
nvJEf9DJs1wtZ5p7Zij5wgM0vJsRB1BMM/uH8M8OikmlCyoajmA7wk5VVSRy56h6
ni14T93YOHEGlmnJOF7mkav1940ppuiNeT4V6+f8SDX+M5z1NplnkoOQAPqh9s91
91dpQC4lGinstioMFdnbXXvdtBFcgzDIsKxEL9/EHM/fCSQrcz0+SeJY0RSM1Grq
nnyWGfTQ/77R6pvhtMbW5ULUR4jKuQ5qvYGyLdn9Xh+k/8u+UXlF50Ndj3VCkxHG
nzFEZFy8QtRCd1jiYsh6HZWgOAeAzUkqQQIDAQABo3wwejAOBgNVHQ8BAf8EBAMC
BaAwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBT1a7HehaEjoID50KbCqhryIRwh
ETA5BgNVHREBAf8ELzAthitzcGlmZmU6Ly9jbHVzdGVyLmxvY2FsL25zL2RlZmF1
bHQvc2EvY2xpZW50MA0GCSqGSIb3DQEBCwUAA4IBAQBW/xkRoVxuo+g9P6/mWuVI
BSY7tsrdff8qkKzEmRLLSgMUFpDw5529wUSAsOwPjHK9xXeCT5lLxQMcbaGShf70
4r/lceFJXUpQ0NHU6uJx3DdTUXXhDc4Zhq6rX1GaxqYvKWVMAKCPmDEXVHd5Yh4u
ZZIeq1uOTc7t3B6wXhQ68zY2GURjEMksafoCT65J/2CD5fBgBFOEeYxCl4iN5Vcv
MM+xfi1ZiGTAakiCSSOUydaP5MBdbl04ZMKDDEZTRLJwEDmg0T1x6/T7zumtjrnX
5T4c/LV5cEMMb4vjty5MSNY/8t5dT6Bq8T4tAEN83W2OyABfSowyecXAItcMcZ66
MIIDxzCCAq+gAwIBAgIUNcRvk34WYmZ33/X2OmPe5G2mRAswDQYJKoZIhvcNAQEL
BQAwPTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMSEwHwYDVQQKDBhJbnRlcm5l
dCBXaWRnaXRzIFB0eSBMdGQwHhcNMjIxMTAyMTgyMDUyWhcNMjcwNTEwMTgyMDUy
WjA9MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AI5lsgO9vIpXelck71yRUccaR8Nxl6R1jlCQ7yaHLHOCbR1v9zNop5/y2rxJ+hEG
JSkNRN4zwQHAGmQcHg1bul6nVUJjJPRAA3CmCQo5tbf9zYgH9r6BMXk5LlClEVG+
Yc8p1tMRQOqdt+j6N1OHVFdLXdQuaXfaMstsknyDWG7kvGnZrPnRaLPDN42NXywF
xDqVJ9aomvGSOKy71QQ72wC/WRiF4e2aYQ8Vkh1slCoCrCFC8PXU7HPwtmg8YRfR
+oYj4bkswjt0IYKkhk53cZcOR68ACis7aR0yiQhKjTNdtewzidLlHrJymeV8q4K1
TB9Ng+HuTowPSRL0jlkZJwkCAwEAAaOBvjCBuzAJBgNVHRMEAjAAMBEGCWCGSAGG
+EIBAQQEAwIHgDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIw
NgYDVR0RBC8wLYYrc3BpZmZlOi8vY2x1c3Rlci5sb2NhbC9ucy9kZWZhdWx0L3Nh
L2NsaWVudDAdBgNVHQ4EFgQUEr3U4t0vU2OfEkNhkv/OQkZzHvMwHwYDVR0jBBgw
FoAU4QAONZ/lVw4pbdUOVA03YKVvqGAwDQYJKoZIhvcNAQELBQADggEBAC76IVYv
kkD+ojj6O9w40y5U7YJ6UL2s7tN5HHZrV6t608YdgooJ9GLvUVDRlOohCB3MjBQE
M059b7+b6rqGJYNWQWlICdvZ1rSHUQRdWNAe9xqgmYXGT2zLgZJyhplboz381oPu
BUwFhs+j6Xek+1ub+NpiYjRZQ37jp5xeh6jodyKJdkGY6Arxe6nrO6ZuebIySXbG
k5GbeGyvXcCgqycatromMWmtG71zUtesfCu7GNyrReuJQ4f778Tb/N5qopBXOOum
ciJgRQH2bVUMEMutLvj+FROOl54YtO/3Lxi2kzzLAEfBHG6NC6yfq+TBIi++xgsP
3au7z8O9muicSto=
-----END CERTIFICATE-----
7 changes: 7 additions & 0 deletions testdata/certs/client_ext.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
basicConstraints = CA:FALSE
nsCertType = client
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
subjectAltName = @alt_names
[alt_names]
URI.1 = spiffe://cluster.local/ns/default/sa/client
12 changes: 10 additions & 2 deletions testdata/certs/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
openssl genrsa -out root.key 2048
openssl req -x509 -new -nodes -key root.key -sha256 -days 1825 -out root.cert

# generate mTLS cert for client as follows:
go run security/tools/generate_cert/main.go -host="spiffe://cluster.local/ns/default/sa/client" -signer-priv=mixer/test/client/pilotplugin_mtls/testdata/root.key -signer-cert=mixer/test/client/pilotplugin_mtls/testdata/root.cert --mode=signer
# Server certificate:
openssl genrsa -out server-key.cert 2048
openssl req -new -key server-key.cert -out server.csr
openssl x509 -req -in server.csr -CA root.cert -CAkey root.key -out server.cert -days 1650 -sha256 -extfile server_ext.cnf

# Client certificate:
openssl genrsa -out client-key.cert 2048
openssl req -new -key client-key.cert -out client.csr
openssl x509 -req -in client.csr -CA root.cert -CAkey root.key -out client.cert -days 1650 -sha256 -extfile client_ext.cnf


# Stackdriver certs need localhost as the common name
37 changes: 18 additions & 19 deletions testdata/certs/root.cert
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDZzCCAk+gAwIBAgIUMzjfEUF3LQ/WfBiwIC9h+qndbGYwDQYJKoZIhvcNAQEL
BQAwQzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZh
bGUxEzARBgNVBAoMCmdvb2dsZS5jb20wHhcNMTkwODEyMTgzMTAyWhcNMjQwODEw
MTgzMTAyWjBDMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVN1
bm55dmFsZTETMBEGA1UECgwKZ29vZ2xlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAL2O52MbZig1pfU1tut+QX/ISI3m2uMi079ZWy4ZE+Ccm4Ta
XdR66T94T2x7uWbT2AtNIxZO+LPT75Suh1Zb/O1px3dKul7U1Fpl7gLVnKXQ35zL
/fCh7MPa+aipZHH1KGG56ebdmoXrKM+S5k502Dm0Q0uyGxksBAiXHyixaiq00rYV
XYrv9qw1wphYea2SLBRaQOpJrPI1CZu267LTMTq9a6gGTwMuz9tDveT/cM8Nh17C
so+6PrLEbpXAJPqNUyuJBGsDG9AyqBh4ZKmgRDR+ZE03jNncaEx2vkjFenXLI+//
YgZA1NJVAefCFfGRNGRZ+bR/01brUbnuGJCgJv0CAwEAAaNTMFEwHQYDVR0OBBYE
FPVrsd6FoSOggPnQpsKqGvIhHCERMB8GA1UdIwQYMBaAFPVrsd6FoSOggPnQpsKq
GvIhHCERMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALKX8nmy
SN8+MB5cSj/LymQpYlJVdvf0p2cBikWCVcAWL+CvBafYF0Y93ooKbv/jCZhWdGmz
ItbJjwauaXDphHEGbAzyjsQXH1ZQti6+HigMIvTOYuqiOd+Lstdim9QHvgLCywT0
PJ3k44/KyfEXN870heJmEDN4uv+hASmH+9zvhRqE/ABnb2An4auQT5j3/BXU0jjl
sv3XDZ/Ke4PXqPptg4VGbhQi1+OUFoqAgvQFGbur0hnWFPsehC29kISMAJt/iTGJ
HC0g4ZKkij56ohHIB6OLNJ1rGMS9OFwt+0ok0AI7kVI5K3KLdhPEY1k48t6ThFCn
wPWDdGnjesEmztc=
MIIDWzCCAkOgAwIBAgIUEQ3MTVIpIdYHZPx7+Y0cmOTjR/QwDQYJKoZIhvcNAQEL
BQAwPTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMSEwHwYDVQQKDBhJbnRlcm5l
dCBXaWRnaXRzIFB0eSBMdGQwHhcNMjIxMTAyMTgwMTI5WhcNMjcxMTAxMTgwMTI5
WjA9MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJqJYGCKrPqgrHE8fsi+P1uXbqsFzO322Za168wNJh0cIy4Lzd0zGbDXvsVujQ0s
UOUfNyM2qgb6G/7GJ5WYluwSWRYbv2Cc1c3XiGyIBl/eE/utNQ+wfIgf6XbMilWm
CG1WzOEU+ss8d1qewk+Kfdf7u+vKMKU52QMOd75Kwpn513QHZGFBVxAZCVlRtyhe
qL+Nk1pT7mQLux22bwUDqLjT5wwtSscSjPWOgQHetjiz6W1nD+pyMRUl0YMf37pY
t0n44lR98hh1mv0LPYfSKGo/RzjlUEJiGEfomwbb4sBW3dQnInqeMrH6vDsDSHzK
Wt5XoQs17uu/YkIChrIpA2kCAwEAAaNTMFEwHQYDVR0OBBYEFOEADjWf5VcOKW3V
DlQNN2Clb6hgMB8GA1UdIwQYMBaAFOEADjWf5VcOKW3VDlQNN2Clb6hgMA8GA1Ud
EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFgY2O2ueINKw4dbMcJqMo+6
cG6AszL9GafnlA1qSJtD6cHyyF8lkhWzHtIAM1/QrwO3/yciquMw1gTubwxF44Uk
NvTPUnqw4bPWNXlqowrXzoM1uqQcvGCwhcEfHkOtiSVXR7Sa+0fGCLGpmlwdWUw1
WbRTFCOKqmJFC0/J7/smcTrCzac28YRcELnTsVOVa6jXrib9TUvnwzK2nI8tK8OO
SLQTJFjEgig17XztZ8OCT0MTPwvE7A+nLaPwf5/vC5NtCF7HyL67H3ItdbNX6C/U
w7LGFivmoENW31jZirbAEmbRpvCBvlarEP+vteR61JDkZ3Y7KfgYxzykxRK6WFw=
-----END CERTIFICATE-----
Loading