Add Python mTLS greeter example (#40)

pull/25843/head
Ryan Kim 5 years ago committed by GitHub
parent c11aafda85
commit 383c247775
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 49
      examples/python/helloworld/mtls_greeter_client.py
  2. 57
      examples/python/helloworld/mtls_greeter_server.py
  3. 19
      examples/python/helloworld/testdata/README.md
  4. 30
      examples/python/helloworld/testdata/ca.cert
  5. 51
      examples/python/helloworld/testdata/ca.key
  6. 13
      examples/python/helloworld/testdata/certificate.conf
  7. 51
      examples/python/helloworld/testdata/client.key
  8. 30
      examples/python/helloworld/testdata/client.pem
  9. 51
      examples/python/helloworld/testdata/service.key
  10. 30
      examples/python/helloworld/testdata/service.pem

@ -0,0 +1,49 @@
# Copyright 2020 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the GRPC helloworld.Greeter client with mTLS."""
from __future__ import print_function
import argparse
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
def run(server_addr, root_cert, client_key, client_pem):
with open(root_cert, 'rb') as f:
trusted_certs = f.read()
with open(client_key, 'rb') as f:
private_key = f.read()
with open(client_pem, 'rb') as f:
certificate_chain = f.read()
channel_creds = grpc.ssl_channel_credentials(trusted_certs, private_key, certificate_chain)
with grpc.secure_channel(server_addr, channel_creds) as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='world'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
logging.basicConfig()
parser = argparse.ArgumentParser()
parser.add_argument('--server_address', default='localhost:50051', help='address of the server')
parser.add_argument('--server_root_cert_pem_path', default='testdata/ca.cert', help='path to root X509 certificate')
parser.add_argument('--client_key_pem_path', default='testdata/client.key', help='path to client\'s private key')
parser.add_argument('--client_cert_pem_path', default='testdata/client.pem',
help='path to client\'s X509 certificate')
args = vars(parser.parse_args())
run(args['server_address'], args['server_root_cert_pem_path'], args['client_key_pem_path'],
args['client_cert_pem_path'])

@ -0,0 +1,57 @@
# Copyright 2020 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-1.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the GRPC helloworld.Greeter server with mTLS."""
from concurrent import futures
import argparse
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
print('Received: ' + request.name)
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve(port, root_cert, server_key, server_pem):
with open(root_cert, 'rb') as f:
trusted_certs = f.read()
with open(server_key, 'rb') as f:
private_key = f.read()
with open(server_pem, 'rb') as f:
certificate_chain = f.read()
server_creds = grpc.ssl_server_credentials(((private_key, certificate_chain,),), trusted_certs, True)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_secure_port('[::]:'+port, server_creds)
server.start()
print('Greeter server is listening on port ' + port)
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
parser = argparse.ArgumentParser()
parser.add_argument('--port', default='50051', help='port number to use for connection')
parser.add_argument('--client_root_cert_pem_path', default='testdata/ca.cert', help='path to root X509 certificate')
parser.add_argument('--server_key_pem_path', default='testdata/service.key', help='path to server\'s private key')
parser.add_argument('--server_cert_pem_path', default='testdata/service.pem',
help='path to server\'s X509 certificate')
args = vars(parser.parse_args())
serve(args['port'], args['client_root_cert_pem_path'], args['server_key_pem_path'], args['server_cert_pem_path'])

@ -0,0 +1,19 @@
## Key Generation
### CA Key/Cert Generation
```
openssl genrsa -out ca.key 4096
openssl req -new -x509 -key ca.key -sha256 -subj "/C=US/ST=NJ/O=CA, Inc." -days 365 -out ca.cert
```
### Client Key/Cert Generation
```
openssl genrsa -out client.key 4096
openssl req -new -key client.key -sha256 -subj "/C=US/ST=NJ/O=CA/CN=localhost" -out client.csr
openssl x509 -req -in client.csr -CA ca.cert -CAkey ca.key -CAcreateserial -out client.pem -days 365 -sha256 -extfile certificate.conf -extensions req_ext
```
### Server Key/Cert Generation
```
openssl genrsa -out service.key 4096
openssl req -new -key service.key -sha256 -subj "/C=US/ST=NJ/O=CA/CN=localhost" -out service.csr
openssl x509 -req -in service.csr -CA ca.cert -CAkey ca.key -CAcreateserial -out service.pem -days 365 -sha256 -extfile certificate.conf -extensions req_ext
```

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFOjCCAyKgAwIBAgITQsrYv0UhsPwdU1mS6uEv5Gm4CjANBgkqhkiG9w0BAQsF
ADAtMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkoxETAPBgNVBAoMCENBLCBJbmMu
MB4XDTIwMDUxOTE5MTYzOFoXDTIxMDUxOTE5MTYzOFowLTELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAk5KMREwDwYDVQQKDAhDQSwgSW5jLjCCAiIwDQYJKoZIhvcNAQEB
BQADggIPADCCAgoCggIBAPA0yxFul5Q2BIYJyOnyxuSRh8/AWEdztNaZ0mxnfTk/
A2U8hqHzqAI9mkUfzSxT/U2wO2Ej1GDrCp6kFILLia+3meLHA3gQy07CtE3+W9Ra
GKe3ec3rr7PCEWwuJH2pCstQ8PXhiBkYUD01VqC1wd+z2SuK79PsFSo/4Nr5epas
vVUepk8hab0jLdiDcMhKj6g0l/CX7SzJZjsSJZcJv4YgMDNdnP5H2twKZwuL1R1U
BPpiOnwHlEeQ0o7GQsS3V6rcdOaVFKjEi/5uUAVA7pvMN8k7lIF3Fdjon1wvgufG
XrFlWbdnCeuTgpkkf9oxb6uyW7K1tsMww0kOvqSj4uk2oETeZzbCsHZRWOtQE/Th
2nTglqyBPwc7ocwWgpzo4H9sJlamuNiuobpjOre01jn/ca1ayU4xcz8tgC2t48yh
BiZIFJywSn8URubgwPctsoLMy8YLFRK2F6iEpPOI/czgYKW0Feh1kF0ZJuoOcmoW
uGkDTzGoEeM4ouht1t4x0VaOl+/me0Pqeqj/Z1ppkQzag1SCRlC1o9qTFOnJrZT8
bFD5Fl5NBCqsdCr28NCf03xAc0qXsEBQRo1+y54J9L1Z61YfNDLDvyHNwgp7J73u
T03M+4fUhh+aRRMxrkdTF9X66/OPpHozwYvf+Sy0988iMjG0HlC4nZpjE2NX/VvV
AgMBAAGjUzBRMB0GA1UdDgQWBBSHuBDlMpjoNNQb5poqc4LaTdZV8TAfBgNVHSME
GDAWgBSHuBDlMpjoNNQb5poqc4LaTdZV8TAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4ICAQDDie5TJY9NXZEkAkNIRbnQhdhAT8PwrpuE/8xtQlHyVfVl
P7vlUgYt4HasZc/LQNKoSOwi+rK5jzH+mE2xh3kD57ig2oD5sniE8W9AuU4zo21X
tIXI57c5kEvs3QphuODaThPNyfG7S86pqeWvxkN6YGfLXJnV0rLbqa8awMSD1+js
XHK4xaPUbu9SKmMTfpO1SuQ8G6CeaapnU5QN/80nhqmeNhWIUgjYSgx5L6L7kPRg
UqHrG/7LXgLB1fXdv3xXGRAZeU83TaE6TTuNT7n9YL/NrP9GuyGjDMIXcmD5QwWw
quqCiK04ArB34gworWySTluvpMoL8HtlaIAiUi9+bod5jD54ks+lVfpdmWIy4x3Z
IwAg5nCCC4vUF+yBos0mA9Jp4OlmepqSxCxOxk32iD6A/jghXGvbCryT8eCtb6LY
bGDwPY9NKgTdRMG88dnawdfLVoblBN35sX3d5JHJp2oDT9tRw5odaXYFNWJHTON5
7vvP3KlFhTJEif7DQViZ1t+mxLAoIqgDVu/h6pHJmXF7Ae85+JcnQBSVX/AjcO4z
YuBNw0cunn20bMvV0441l2uiedyRNnka0gZXmHiisHKUDxgKx81TXBjhbBCT5nBh
3TSVydD5gOZAgYIm6D/ZrVYMT50TCSsNfQJgdAVDNVzzFnQY0yAFd8PCX88YZQ==
-----END CERTIFICATE-----

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEA8DTLEW6XlDYEhgnI6fLG5JGHz8BYR3O01pnSbGd9OT8DZTyG
ofOoAj2aRR/NLFP9TbA7YSPUYOsKnqQUgsuJr7eZ4scDeBDLTsK0Tf5b1FoYp7d5
zeuvs8IRbC4kfakKy1Dw9eGIGRhQPTVWoLXB37PZK4rv0+wVKj/g2vl6lqy9VR6m
TyFpvSMt2INwyEqPqDSX8JftLMlmOxIllwm/hiAwM12c/kfa3ApnC4vVHVQE+mI6
fAeUR5DSjsZCxLdXqtx05pUUqMSL/m5QBUDum8w3yTuUgXcV2OifXC+C58ZesWVZ
t2cJ65OCmSR/2jFvq7JbsrW2wzDDSQ6+pKPi6TagRN5nNsKwdlFY61AT9OHadOCW
rIE/BzuhzBaCnOjgf2wmVqa42K6humM6t7TWOf9xrVrJTjFzPy2ALa3jzKEGJkgU
nLBKfxRG5uDA9y2ygszLxgsVErYXqISk84j9zOBgpbQV6HWQXRkm6g5yaha4aQNP
MagR4zii6G3W3jHRVo6X7+Z7Q+p6qP9nWmmRDNqDVIJGULWj2pMU6cmtlPxsUPkW
Xk0EKqx0Kvbw0J/TfEBzSpewQFBGjX7Lngn0vVnrVh80MsO/Ic3CCnsnve5PTcz7
h9SGH5pFEzGuR1MX1frr84+kejPBi9/5LLT3zyIyMbQeULidmmMTY1f9W9UCAwEA
AQKCAgAbJtyNa+LWbgS04gZD651v2MNxSFyyNvIKD/kpJ8mP3v+TQfQ1+kTTfAMk
LSQUDqpjTbhokpQ/IFJi/EkVP8yggDB04eoSeFOC459d8ZKPvl9rFeI+1JVXzGgL
wmt9iM4fjVavdH7d11G6mXzhTapMjxfNRDc3zUfXLsFL/0dMINqF9KD38N7y8jcM
ck8dVNBIQympmILGvT1BEBwPpppvntPT+pD0bUrf9I0RUQ0V85lcdB4IRxMLw+MJ
IIALnG3ccm8EYXWkXhM0/2MsNNrD4aGsrX9r4volOqZI1VYGvPWXN82cXZlRd6sb
hHSvRUdKMS8MVF4EUk7Aw1npYl0Tp3RVAqwN+dB0hV0M8hyjYIeFRcYGjePU7iN+
zVTY2Chz/W7s0ymoQkAIANFnAWA8ObLaCjByu+NvgfimAOxXqPrR1axHPxZ4dVnA
ErsJCxXSm+TcLwITA4kz7/H02S0b27wnGbjwbjDhoYalkti3TW9eTpVFy7iNHNSO
Q7iy96goCSBzE6f/w1TfDnCPuslKVLQfueLDrKzxRfc/z6Ksw6JYo7tOqWS/8RkA
HgAK09zZtRVJp3Ps7zbMUuEEBT47uhi708o/77asHcqnSPPLshGDrfg2n9ZJzlNd
Cezq3bDKjq/VTGh+I/exN39aSQVAegE2yAas8+Md00dM4M4dQQKCAQEA/qb52Afu
dBnPd0G4TMB3n/6aGSSzJlzzmjHGZffVjv2xj3q/o+HwZV2xuA2dOEnxEPRFnVna
XZolw4RKqKRBFV3W9Xrf+7NFeW64vNz/Eu7fv7dzm/TGLjvUX+4KNhDR0uh2lLpZ
JzOQ1sEF7N16gii5Hrcl/2z9X35rjA8zoedGJlJIgJfQ+RHv5HTrZZnEC9XF1Xg4
tLrVKpa+qGm83u88KSsFZkELWnN0EchWeMAVMLYLv3dNrdneRROw7TLXPTwLM2he
o02bMv0gvF8cp2/WXrcbhYgwNsvjEYJ5t1XWgWaMLsTbvac2kAzWY/y++JngAPiO
gPaoL85kpFcF2wKCAQEA8Xo+nmMhZmsHaT3S1aflTaV35pIriPgYieyIs7vGWUnH
k5Wr8yJDGxZXJ0HYCmWp5sfrb6oq+CCVohl3+hvco+ZqZgSOa69K48DFNTMuobb/
4bGftWgbriQAnQvlEZ0v07B7xlY7kcXbqGbAaqAyRUOIJ19/Lw9OKc+CIATPCtSC
0QhpVF2GdNfG0FELpsOvuA/SwJ+7r5w8mWhntndjyOxYnFycv2MlM0iNLz5J6f1e
s2/hg7XBUQRWbK28PU0zO35ubYV6w1NCcREKPh/UftBW05fBLex2I/xjo/lSfpp0
tfuXDx5Jb0Qs+jOaCR4fHezjWam7xTI4wKOJwaVMDwKCAQEA8oxsMH3te5wR5Y8t
Ub2Is1W3xPcVxBaI2HdMd1cFjDrLYtQRsLDFXmdNnPcqprCW8gUYQXWR7dGi4oUg
71vzubw1wH8W1BC+vZjeUNVWBtyLNXownX0ZPnQyJmT+SNzgXbiZKbQMsrAE5ufX
EvMpesv69uyPPqi69LffC/p2vWEhieKZuBHiMzoIelt60r0Q5AzrcBYgPNQvsW7/
jj2YbecEMFoPvIN7ot2Q0lc1NbIO/OSIcAfcbxizAqxsuqDQLj0Alih066pBhuFe
ysz05+44CuLxTdCXy7mLP+Q8tokF1R6tquZKPmwEJlRz56yW4Qb/Oy2D3gYRz+cQ
KQ/SPQKCAQAm2MKgGlRyNH+ht5dmVbc20YrDZfpo83iHH60yNOAI1yyrGmXqHDXt
cp+cqiQGMCqv/LNsaFS3TA6mYDCD5N2O5G9zcAI1YqLKluVi1JQI4fayKTAHL/Nc
BWCv4wz702yxQm/3DUJSBiF7KuSDgrfzmpSZuOwt9uldIovNeNiR5nQRCqhfMRiD
TX8nXhJgxpRLKQh/gnLgImNBTqF4oiZEWXk71k5FH78JS/+ifQPJB8CnXzVJSgEK
docsvppMxlGanZFIPzPrnkZPCC28psQ5jmyZZ41lROgQi/a/l0llIpXp/MplXTr1
EmOl8I00MEtTNhuw/fQ+GgE1RFnR9DSTAoIBADurkng7FgGNtPM5gthtiCxf7Qlq
7LAQsrmqwpkQXFtxGT9L9WVNx8g0DcRD/41MgdjrDNN1FZvB/az6UxLwde3ZPUSe
9yNQEOMyNhs1YwW9hFXfQcR986fgRKOVZPEXfMSPHwG3NB64JEC1qsiHYJjUp60U
csqo8JEsB8h3b4PokMR7KqfbZNHHLIsyuo7AXWX4Rm7KE7ccBqCC2S7htZ2REk81
IurM4avn3J2kEGhamQfcPjZ3Mwvqv0zcZ3+VLyEhArvLqGTrFGqKcqoGki3imP3p
rQHDUeNMoSwgPbPJl50O3agySGTh6mKxn8VL0+2XF2ff5hIDJDuIO5PtMOM=
-----END RSA PRIVATE KEY-----

@ -0,0 +1,13 @@
[req]
default_bits = 4096
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
CN = localhost
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFDCCAvygAwIBAgIUUThbo74GjXYW5GpJXwzb4UZzOHYwDQYJKoZIhvcNAQEL
BQAwLTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5KMREwDwYDVQQKDAhDQSwgSW5j
LjAeFw0yMDA1MjAyMjE4MzBaFw0yMTA1MjAyMjE4MzBaMDsxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJOSjELMAkGA1UECgwCQ0ExEjAQBgNVBAMMCWxvY2FsaG9zdDCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALgCRyUJegwUgUmK61R7Eydv
rBlLSd/EU/ReS06K0GNaoJvH1wcFPukjLVLNJaQu5xV/p9n/IwIVHrHD1eNTRPJZ
R0O4XVA+P1jzTTLVXDMxwmeH9N2I1KVtbTZw8RfM2Z8AGY4BRpPPi1mCrNWKI3YQ
MhcrNu+7io2AsY3/p+kPGR8UO74TVj5KIMKEyPFituXfFYvUfj1QFK8NUQmE4Ezz
jPwcI+0xKlC1YxI2E7vg5QmRP2cn2AljY9YLp7K0tv+hCE+BiIpGPHEv3+frkzRF
WeM6J6Z8ZY3xjNFz61wIN+JIsaU1ECrefrC5MYUERapPjGKbaEN/3rg5F5GhV+JP
kK738VlOJZWY23SNK1o3XBvDPNVFmdstc1k8s1QyDLNSpez1enfRrwJX8o4CwZjo
bRao1mZrZHwCHPQYErPfdAlPfS0kkmzpm61VTvumZg5tlIq06T7W1ngB7Z3OFK1M
9EMVT/cxY43A2KT1L0XSFXB+kdmbEHxQ42xRjvkR3mgLsP1T738KOPvrNkqRUyx0
rOTn264plBxvqrHrSATgKR/rAcLEJBO5/jdFCKyl+GDPKCh1GnPi6eRdlV0sMRnz
xmUfDwU0RYLCDS6myThCYPxyfIqFpAKQjyaQHLWlxsF30DQhTmj0WwshisdstdRX
tIx/kvZLcirgrVtTLEqTAgMBAAGjHjAcMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcE
fwAAATANBgkqhkiG9w0BAQsFAAOCAgEA4tmdBpb2igseEFFnIYJZV/I4zABBr6pl
nEEWMN1ijnhABXqcMonoPBPFqdD1PH+lGA6fPvB6JlS5bjgTAJSHFBej71x9cVGW
E9cE/n3rrNpCU7NFBe2SRDHqjoJMlDoQLM8mBZf5Xs6euP+ufSheX7nqIEAYCTtw
nvTyq3AYkQ5i/75B/RpY+3v0OaXB53GJQbbI1axU07C3rXd9OCa8p+XprykKwlWI
YfJho2Z1unAwVDgd7ZXNVXNVkgmCMhkJtmbsiSSIj6ABRtEjNacJJZK3ReHJ4kCu
dAElLnb+ynf05Q0aXhTHOO/IRdaDFU6YiAeFn14k/nGOFZqkRpWcHawVAqpjBSor
COw9M23s8xAhsVteASh66syJ16+JHpyEHWg24XPuUjoqetCurfE4YI1hf21QBDkX
32q60PJ4czQ1gkJ0jA86N1TpmpIM/5ilKc5bgqpUFfObJV762Gs88q1XMn9QYgM0
Df7l4+YROtkSGy/5PoxvvyF1m7QnMqZqvCbxapkMYWfN8aKt3tBRQAUwFt7MxmnN
B3YQixeExellCFsu30Wx9ZdSXGI8AaP8++sT9nLvvWv1wiHOMf+xVwpS6de0ITYO
FCfuY1lRvXKBZLx8cKgDq6NJS/QojNVJOstGiCvrLxu824w8IcgYySDtqkqHZb4B
Jci4P011SGc=
-----END CERTIFICATE-----

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFDCCAvygAwIBAgIUUThbo74GjXYW5GpJXwzb4UZzOHcwDQYJKoZIhvcNAQEL
BQAwLTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5KMREwDwYDVQQKDAhDQSwgSW5j
LjAeFw0yMDA1MjAyMjE4MzlaFw0yMTA1MjAyMjE4MzlaMDsxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJOSjELMAkGA1UECgwCQ0ExEjAQBgNVBAMMCWxvY2FsaG9zdDCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKJzZ2PG+xkW5x6CenNR/qhf
N6s+NT75KlT0TrKwys30lca3G7RVdaP/UQ/ZmqDd+9y9QXJD2ghdcGrSnxebiRSX
7V/LSYa8rHIin8PlF8lOQOBiHOcWvi98jfc0jPE1m9PO9zou6G/i/pWv6EODT8j4
WCmyGcpqFDarOKl8XctlcjM1wwedKY75ED8rtrrpa2FT2HcXX+qTRr28ZdPXG2NZ
DVuJ091P+EPCXbPD1prz0fBcM/kk6CtRECZBSnnHcBfbgABDWkJHyv18YuHtp0sD
tSm3whf5Q2hAeyteGgNt8V8moU3Am+Zzz7yVVv++6+FhYGAtQExC7MdxUrPheHHY
+orBKEUJtW4T/OD5lrth4hxF6rsTi40Eh2n7qMMfw0PNNqpD+W2q1MgTQdVSFZC8
Bw9ZominEZkH5GzQMVDMwJYSyhBjSpRMkDx5tz7WjkqjR/S5yFUNJOK9+Igy92Bj
98XDeglVLzUZdnIa7dFxzqxwfpgS2iBmZTzGa2F35A84wI18SIw1gYnekvAhPYPR
ybu5UWObCn+yrLxGGUas2+lSGWv39omyWwE6EQKvxhauCtRoqDRcv+4DG9pxfSFj
1hZiqEfRn6iuPuZYTk/Dxy4dD5RgI7VXTkD+ZPnRDfxsnLpnx+mwxCCrRqplj9Dw
cZY3Y3fKPiphFOwo017vAgMBAAGjHjAcMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcE
fwAAATANBgkqhkiG9w0BAQsFAAOCAgEAu9QvoULqCkSXc0nuRtAPO8rEnkcLoA2d
gHj1Sj47ZXXe2p14Y6Z3joj7zpqPc4Y1T0V/AXqskvK4UHevkwVGcoDlottccpOF
eCcFIZrJZcmmXPgVnDs4WMk1wmM//R9dRkbv+JPJEjVhQ0mn/KPNye5IcLaRw4TH
cAw2idWag8SIc5WokIj+iNxsrzwmq57sqkqvAlRFHiWqQ4x5zfwic6wP9KZtha6u
Per4wLKPq3C4agILBKdozpHB+nl/lJH09tADmP9nHZC0N4KB8YfCNfIsmrzNuQYY
9USBnSQpnx5P4ko/7A8By1skQ9AQRAXiNhw7NbaWREBb1wN68wpp/T+xuCbSn8gY
LqON2x+X1xoKZHbgRHNv9/Qf9CCjwgzAvA//ZccSHmCyf1jmGouyULqmT1BIfr4V
hbj7h3y03kTPJJzIdUdS4AGCVMFCLBdlbkF1pNiiWj98B4otqpG7RzcHXpIFtRna
KLfT8W0VU59jEPJCOg2lUmb9P9L18iHRZqoQ1pqBWUA6sIFEZC4g00XFPI/Lts/c
Z2Tneb5fmjYV2N9zLn2/OOILYCHuIDeEfpcaDwG5GvyUh1KckBB5BNXVvkRdHbK8
9wzrMKevZOREu5Q+rB34IjblfRT+eEjct0THxTQo8gnxcv2JwJLE7pj70mRZBEf4
XAaXeoMGuFA=
-----END CERTIFICATE-----
Loading…
Cancel
Save