Skip to content

Commit

Permalink
Changed the PAA download script to use RESTful API (#23510)
Browse files Browse the repository at this point in the history
  • Loading branch information
vijs authored Nov 7, 2022
1 parent c4042a3 commit b0d92ca
Show file tree
Hide file tree
Showing 28 changed files with 128 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ FgQUzfLv60FwRw2mmGqbQBlhNzbBKzwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQY
MBaAFM3y7+tBcEcNpphqm0AZYTc2wSs8MAoGCCqGSM49BAMCA0kAMEYCIQCmkeYO
7qrsL+K7lD+83jwG1kwlUjmk7j8TiMRZugoXggIhAKjU1921/HtVg5vruWnAldE0
OluYL3u0qG/zUnQBBZdU
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ DgQWBBR5tgRpKKdeSNjbz17/o/nb5fWDeDAOBgNVHQ8BAf8EBAMCAYYwHwYDVR0j
BBgwFoAUebYEaSinXkjY289e/6P52+X1g3gwCgYIKoZIzj0EAwIDRwAwRAIgWUD0
xLr2FYyVoMzrYMeBS4k5yBpgOFy2lmCd1fbwqUICIAxr0LCI2jDduTxnR/YNbcAx
cxTw3DvHgFVC2NzdHsuj
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Af8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUwrzWQPP16qF6
7EZqS2lIuWrNDXowHwYDVR0jBBgwFoAUwrzWQPP16qF67EZqS2lIuWrNDXowCgYI
KoZIzj0EAwIDSAAwRQIhAMQEa0y9YDbmxw4sH0tsTUR401k2ikOAoPtlhbAJ7kc+
AiAuZvx5Dx2B4jEH7Q6fmeUvecU9VSCmC+WMOtN4bUPt4w==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ IaPmNeuTo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTA4GQVAOxn
Z+J8r3xuLUmUx3Pet7owCgYIKoZIzj0EAwIDSQAwRgIhANQPosj8Q06GATusRAtX
VQFXJSSm8AgsulWwI35mEf22AiEAxiY2sTXcV3ZUiNl/O4RQ10UWMRMjrgo076cn
zy5r7zE=
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ VR0OBBYEFNN/BuHbYf5ymSl9lcFPG2QHWENzMB8GA1UdIwQYMBaAFNN/BuHbYf5y
mSl9lcFPG2QHWENzMAoGCCqGSM49BAMCA0gAMEUCIQCcjSilivNmAJtkj0A/utii
BNrK8jl4yLq3JwAjKR/pNwIgVygv+9XbvzNTGZoQ8mM2d74vIZ+1y1XH3nM0Xggf
2HE=
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Binary file not shown.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ DwEB/wQEAwIBBjAdBgNVHQ4EFgQUk4YyXgbZseQmMESNNOb7SNUM7SUwHwYDVR0j
BBgwFoAUk4YyXgbZseQmMESNNOb7SNUM7SUwCgYIKoZIzj0EAwIDSAAwRQIgJeX5
H6GY+nhDObPbinkoEDAweQOOYSPfsgUbypL4yrYCIQCksMRPy62kSdxfaTmR1C4K
gYU/+xitxnDp3AmKJKhWeg==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ cq95hXRsPUirHNQ7IkH6c0b3MYhGCimiKeXD9aNmMGQwEgYDVR0TAQH/BAgwBgEB
NGriMB8GA1UdIwQYMBaAFFsjg5exUHGu9YHHsqt2vlbkNGriMAoGCCqGSM49BAMC
A0gAMEUCIQCfk1qC0eCKdp/VvPiv8fvnQWnfOgFJQCAKmb1Qp1CIIAIgN9zymm1c
FwdwvNhapM3Fsgl5n1J5y7+/fOnVi3kudgs=
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBT6ks8JXvpC
4RQwZRYy/v4bLHenyDAfBgNVHSMEGDAWgBT6ks8JXvpC4RQwZRYy/v4bLHenyDAK
BggqhkjOPQQDAgNIADBFAiBQp5AzZLZT/w6kY9xoSobdJccxo57+s8IM0t7RtmB+
LwIhAK/U7UtqmeX4xVIdcB68+f1TuTlP2A/FmZL/Plu7tgo1
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLAAVoG4iGKJYoDhIRihqL4J3pMhMB8GA1Ud
IwQYMBaAFLAAVoG4iGKJYoDhIRihqL4J3pMhMAoGCCqGSM49BAMCA0gAMEUCIQCV
c26cVlyqjhQfcgN3udpne6zZQdyVMNLRWZn3EENBkAIgasUeFU8zaUt8bKNWd0k+
4RQp5Cp5wYzrE8AxJ9BiA/E=
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ qMMAppiYUXy33CEg2y0So2YwZDASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB
FoAUz54KFniLQDDs3as0ucLse+U0VcAwCgYIKoZIzj0EAwIDSQAwRgIhAKAjdnZk
FnHDMfhjmhBM+Iy1yLuHIKQxzKSMKSBDwqs9AiEA/FdiFtWLTFiRMVqYw1Cn5ryF
VucH+4/cuLf3wdKRl08=
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ IwQYMBaAFOKQjTacPKPBE7sJ4k3BzMWmZpHUMB0GA1UdDgQWBBTikI02nDyjwRO7
CeJNwczFpmaR1DAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAPZJ
skxY48EcSnatPseu6GcuFZw/bE/7uvp/PknnofJVAiAFXbU9SkxGi+Lqqa4YQRx9
tpcQ/mhg7DECwutZLCxKyA==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ MAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSTcZ6kFxCT9n6v5jpS
xRlH7j5aqDAfBgNVHSMEGDAWgBSTcZ6kFxCT9n6v5jpSxRlH7j5aqDAKBggqhkjO
PQQDAgNIADBFAiEA4uhwfF4Nw8rna6gYZV03lEQG2wEwIzo83OiTcknqPC0CIGLG
79IPfTibBunADTztyXRIKwNF7S2+Or8Xc8nsQ4WV
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ MB0GA1UdDgQWBBQSX9Aagss/AwlQ6JWVprNY9SpalDAfBgNVHSMEGDAWgBQSX9Aa
gss/AwlQ6JWVprNY9SpalDAKBggqhkjOPQQDAgNHADBEAiBoZq5htW2zMEhKXp9/
JR+KPraZp4oVGh8ZK1IVSbOwagIgQ6Psk09HUrO7Fsgk4/FZqlBuoFQ6+WbfACu/
5Ijq4O0=
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ MAYBAf8CAQEwHwYDVR0jBBgwFoAU+Jmp1a1xceTDgX8UEH948Nn3YukwHQYDVR0O
BBYEFPiZqdWtcXHkw4F/FBB/ePDZ92LpMA4GA1UdDwEB/wQEAwIBhjAKBggqhkjO
PQQDAgNIADBFAiBYIsjeauI2nDknU1ThEDzyGfg4F9tLSkiuTrTJGr5EqQIhAMFX
bxTzgOfx0RPgpEU8syFEYyXCBcv4hV14rWddc08G
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Af8EBAMCAQYwHQYDVR0OBBYEFMyJ4O3dahIP1NEztGk/BdUX5xPvMB8GA1UdIwQY
MBaAFMyJ4O3dahIP1NEztGk/BdUX5xPvMAoGCCqGSM49BAMCA0cAMEQCIHgoNVBU
zlr/rbfgtNKXQ/ilwW9BTTkw8CNr7iY6vIqsAiBh1VXKrhwDfwVQ518Un1KuGTfi
kA7JtstGj2BddjUFSg==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ aev81dsMZDYLPx2GPIcuMB0GA1UdDgQWBBR8ywOatWnr/NXbDGQ2Cz8dhjyHLjAO
BgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAO5zMiVkAWP/9zVhdN3A
23bzLrRasxMC3qDDpQyMlyMKAiB9DvCoRAt+eD5+HKQMm245vJ57NePvosuiM5oz
xzbsqQ==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Af8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUdqY/wPeRT+rf
3dOd8BgWRwF9cV8wHwYDVR0jBBgwFoAUdqY/wPeRT+rf3dOd8BgWRwF9cV8wCgYI
KoZIzj0EAwIDSAAwRQIhALUi1VbKwRIhQyYDtUOUm4G3CU0hD0lscb4+CI5D4XMi
AiACSnX2ca2oOre7SidIUdLfO2MX++rZyfqWDmPMzHSdTw==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFIC/kimaZjzaNI+i
TYBz9PGDJD42MB8GA1UdIwQYMBaAFIC/kimaZjzaNI+iTYBz9PGDJD42MAoGCCqG
SM49BAMCA0cAMEQCIHp7fR5Mj2HqqtqTEHqFCApvTYCDy1fv8WwTUiqv7TTzAiA4
yyB38NIexJzRZjmEUcyrD3f2HRw5qEI9s6kHLLMF7w==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
174 changes: 95 additions & 79 deletions credentials/fetch-paa-certs-from-dcl.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,8 @@

# Script that was used to fetch CHIP Development Product Attestation Authority (PAA)
# certificates from DCL.
# The script expects the path to the dcld tool binary as an input argument.
#
# Usage example when the script is run from the CHIP SDK root directory:
# python ./credentials/development/fetch-development-paa-certs-from-dcl.py /path/to/dcld
#
# Usage example when the script is run from the CHIP SDK root directory for fetching production PAAs:
# python ./credentials/development/fetch-development-paa-certs-from-dcl.py /path/to/dcld production
#
# The result will be stored in:
# credentials/development/paa-root-certs
# In case of production - 2nd usage example above - the result will be stored in:
# credentials/production/paa-root-certs
#
# For usage please run:.
# python ./credentials/fetch-paa-certs-from-dcl.py --help

from contextlib import nullcontext
import os
Expand All @@ -40,8 +29,13 @@
import re
from cryptography.hazmat.primitives import serialization
from cryptography import x509
import click
from click_option_group import optgroup, RequiredMutuallyExclusiveOptionGroup
import requests

PRODUCTION_NODE_URL = 'https://on.dcl.csa-iot.org:26657'
PRODUCTION_NODE_URL = "https://on.dcl.csa-iot.org:26657"
PRODUCTION_NODE_URL_REST = "https://on.dcl.csa-iot.org"
TEST_NODE_URL_REST = "https://on.test-net.dcl.csa-iot.org"


def parse_paa_root_certs(cmdpipe, paa_list):
Expand Down Expand Up @@ -79,90 +73,112 @@ def parse_paa_root_certs(cmdpipe, paa_list):
else:
if b': ' in line:
key, value = line.split(b': ')
result[key.strip(b' -')] = value.strip()
result[key.strip(b' -').decode("utf-8")] = value.strip().decode("utf-8")
parse_paa_root_certs.counter += 1
if parse_paa_root_certs.counter % 2 == 0:
paa_list.append(copy.deepcopy(result))


def write_paa_root_cert(cmdpipe, subject, prefix):
pem_read = False
subject_as_text_read = False

filename = prefix + 'paa-root-certs/dcld_mirror_' + \
def write_paa_root_cert(certificate, subject):
filename = 'dcld_mirror_' + \
re.sub('[^a-zA-Z0-9_-]', '', re.sub('[=, ]', '_', subject))
with open(filename + '.pem', 'wb+') as outfile:
while True:
line = cmdpipe.stdout.readline()
if not line:
with open(filename + '.pem', 'w+') as outfile:
outfile.write(certificate)
# convert pem file to der
with open(filename + '.pem', 'rb') as infile:
pem_certificate = x509.load_pem_x509_certificate(infile.read())
with open(filename + '.der', 'wb+') as outfile:
der_certificate = pem_certificate.public_bytes(
serialization.Encoding.DER)
outfile.write(der_certificate)


def parse_paa_root_cert_from_dcld(cmdpipe):
subject = None
certificate = ""

while True:
line = cmdpipe.stdout.readline()
if not line:
break
else:
if b'pemCert: |' in line:
while True:
line = cmdpipe.stdout.readline()
certificate += line.strip(b' \t').decode("utf-8")
if b'-----END CERTIFICATE-----' in line:
break
if b'subjectAsText:' in line:
subject = line.split(b': ')[1].strip().decode("utf-8")
break
else:
if b'pemCert: |' in line:
while True:
line = cmdpipe.stdout.readline()
outfile.write(line.strip(b' \t'))
if b'-----END CERTIFICATE-----' in line:
pem_read = True
break
if b'subjectAsText:' in line:
new_subject = line.split(b': ')[1].strip().decode("utf-8")
new_filename = prefix + 'paa-root-certs/dcld_mirror_' + \
re.sub('[=,\\\\ ]', '_', new_subject)
subject_as_text_read = True
break

# if successfully obtained all mandatory fields from the root certificate
if pem_read == True and subject_as_text_read == True:
os.rename(filename + '.pem', new_filename + '.pem')
# convert pem file to der
with open(new_filename + '.pem', 'rb') as infile:
pem_certificate = x509.load_pem_x509_certificate(infile.read())
with open(new_filename + '.der', 'wb+') as outfile:
der_certificate = pem_certificate.public_bytes(
serialization.Encoding.DER)
outfile.write(der_certificate)


def main():
if len(sys.argv) >= 2:
dcld = sys.argv[1]
else:
sys.exit(
"Error: Please specify exactly one input argument; the path to the dcld tool binary")

return (certificate, subject)


def use_dcld(dcld, production, cmdlist):
return [dcld] + cmdlist + (['--node', PRODUCTION_NODE_URL] if production else [])


@click.command()
@click.help_option('-h', '--help')
@optgroup.group('Input data sources', cls=RequiredMutuallyExclusiveOptionGroup)
@optgroup.option('--use-main-net-dcld', type=str, default='', metavar='PATH', help="Location of `dcld` binary, to use `dcld` for mirroring MainNet.")
@optgroup.option('--use-test-net-dcld', type=str, default='', metavar='PATH', help="Location of `dcld` binary, to use `dcld` for mirroring TestNet.")
@optgroup.option('--use-main-net-http', is_flag=True, type=str, help="Use RESTful API with HTTPS against public MainNet observer.")
@optgroup.option('--use-test-net-http', is_flag=True, type=str, help="Use RESTful API with HTTPS against public TestNet observer.")
@optgroup.group('Optional arguments')
@optgroup.option('--paa-trust-store-path', default='paa-root-certs', type=str, metavar='PATH', help="PAA trust store path (default: paa-root-certs)")
def main(use_main_net_dcld, use_test_net_dcld, use_main_net_http, use_test_net_http, paa_trust_store_path):
"""DCL PAA mirroring tools"""

production = False
if len(sys.argv) >= 3:
if sys.argv[2] == "production":
production = True
dcld = use_test_net_dcld

previous_dir = os.getcwd()
abspath = os.path.dirname(sys.argv[0])
os.chdir(abspath)
if len(use_main_net_dcld) > 0:
dcld = use_main_net_dcld
production = True

os.makedirs('paa-root-certs', exist_ok=True)
use_rest = use_main_net_http or use_test_net_http
if use_main_net_http:
production = True

cmdlist = ['query', 'pki', 'all-x509-root-certs']
production_node_cmdlist = ['--node', PRODUCTION_NODE_URL]
rest_node_url = PRODUCTION_NODE_URL_REST if production else TEST_NODE_URL_REST

cmdpipe = subprocess.Popen([dcld] + cmdlist + production_node_cmdlist if production else [],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
os.makedirs(paa_trust_store_path, exist_ok=True)
os.chdir(paa_trust_store_path)

paa_list = []
parse_paa_root_certs.counter = 0
parse_paa_root_certs(cmdpipe, paa_list)
if use_rest:
paa_list = requests.get(f"{rest_node_url}/dcl/pki/root-certificates").json()["approvedRootCertificates"]["certs"]
else:
cmdlist = ['query', 'pki', 'all-x509-root-certs']

cmdpipe = subprocess.Popen(use_dcld(dcld, production, cmdlist), stdout=subprocess.PIPE, stderr=subprocess.PIPE)

paa_list = []
parse_paa_root_certs.counter = 0
parse_paa_root_certs(cmdpipe, paa_list)

for paa in paa_list:

cmdlist = ['query', 'pki', 'x509-cert', '-u',
paa[b'subject'].decode("utf-8"), '-k', paa[b'subjectKeyId'].decode("utf-8")]
if use_rest:
response = requests.get(
f"{rest_node_url}/dcl/pki/certificates/{paa['subject']}/{paa['subjectKeyId']}").json()["approvedCertificates"]["certs"][0]
certificate = response["pemCert"]
subject = response["subjectAsText"]
else:
cmdlist = ['query', 'pki', 'x509-cert', '-u', paa['subject'], '-k', paa['subjectKeyId']]

cmdpipe = subprocess.Popen(use_dcld(dcld, production, cmdlist), stdout=subprocess.PIPE, stderr=subprocess.PIPE)

(certificate, subject) = parse_paa_root_cert_from_dcld(cmdpipe)

cmdpipe = subprocess.Popen(
[dcld] + cmdlist + production_node_cmdlist if production else [],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
write_paa_root_cert(cmdpipe, paa[b'subject'].decode("utf-8"), "production/" if production else "development/")
certificate = certificate.rstrip('\n')

os.chdir(previous_dir)
write_paa_root_cert(certificate, subject)


if __name__ == "__main__":
main()
if len(sys.argv) == 1:
main.main(['--help'])
else:
main()
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ DgQWBBQyUEUZM0RZm0Zl1Fn9OhXxwRbMvTAfBgNVHSMEGDAWgBQyUEUZM0RZm0Zl
1Fn9OhXxwRbMvTAKBggqhkjOPQQDAgNJADBGAiEAh88I/wwZ6/x4wrLLZeEZZEQi
KqmgvTeRD3kPQ1LoCFgCIQCKVfavo16G+mSmMEFD2O/vsx15c2U1SS0rTK/ogRAP
4g==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ HRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUl+Rp0MUE
FMJvxwH3fpR3OQmN9qUwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3OQmN9qUw
CgYIKoZIzj0EAwIDSAAwRQIgearlB0fCJ49UoJ6xwKPdlPEopCOL9jVCviODEleI
+mQCIQDvvDCKi7kvj4R4BoFS4BVZGCk4zJ84W4tfTTfu89lRbQ==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ MBIGA1UdEwEB/wQIMAYBAf8CAQEwHwYDVR0jBBgwFoAUN04pWsVRcwuvZdUpg5tO
4J05WIowHQYDVR0OBBYEFDdOKVrFUXMLr2XVKYObTuCdOViKMA4GA1UdDwEB/wQE
AwIBBjAKBggqhkjOPQQDAgNGADBDAh8a5dw6CObybMr8nqaou9lv9PqPbj3DSd+c
yQm19Mg7AiAVcSK0RXTwLjAef55gWgq7SBRM/u3f3nRV/fvCYgWZfA==
-----END CERTIFICATE-----
-----END CERTIFICATE-----
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIBxDCCAWqgAwIBAgIICmgdKV4p8FgwCgYIKoZIzj0EAwIwMzEbMBkGA1UEAwwS
VFAtTGluayBNYXR0ZXIgUEFBMRQwEgYKKwYBBAGConwCAQwEMTE4ODAgFw0yMjEw
MTYxNDIzNDNaGA85OTk5MTIzMTIzNTk1OVowMzEbMBkGA1UEAwwSVFAtTGluayBN
YXR0ZXIgUEFBMRQwEgYKKwYBBAGConwCAQwEMTE4ODBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABBthPNrOBLxk1aUHRQ0qNpp5jxrxD0IYU2VrkqPao+N5W8yXX0co
Ye5mQRUoKx/1auDoaKu56CgtKFbP7sHTsoCjZjBkMBIGA1UdEwEB/wQIMAYBAf8C
AQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTFhTFBnuA+5KHc9VHgNEDcK77C
CjAfBgNVHSMEGDAWgBTFhTFBnuA+5KHc9VHgNEDcK77CCjAKBggqhkjOPQQDAgNI
ADBFAiAPczAEcWoN58U17EoNmiFaBzDo1OknOOnJJ7ooAaSWcQIhAPOWwghDzToJ
FGEBvcYtYdEgv9Za5uwKYfQt9J4/loDc
-----END CERTIFICATE-----

0 comments on commit b0d92ca

Please sign in to comment.