summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2020-05-30 18:27:03 +0200
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>2020-06-13 15:13:38 +0200
commit168c595b14ff034ec40642ec1cb5d2c77ce82e0e (patch)
treed5977ea29ceff22b9795adb535b3fbc729637173
parent5e7be6e666aa5cbb02b929fe09f43e0ba757444a (diff)
Chunk 12 of CMP contribution to OpenSSL: CLI-based high-level tests
Certificate Management Protocol (CMP, RFC 4210) extension to OpenSSL Also includes CRMF (RFC 4211) and HTTP transfer (RFC 6712). Adds the CMP and CRMF API to libcrypto and the "cmp" app to the CLI. Adds extensive documentation and tests. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11998)
-rw-r--r--test/recipes/81-test_cmp_cli.t291
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/12345.txt1
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/big_issuing.crt1577
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/big_root.crt1554
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/big_server.crt1550
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/big_trusted.crt1552
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/empty.txt0
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/issuing.crt45
-rwxr-xr-xtest/recipes/81-test_cmp_cli_data/Mock/new.key27
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/new_pass_12345.key30
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/random.binbin0 -> 102400 bytes
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/root.crt22
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/server.cnf16
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/server.crt19
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/server.key27
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/signer.crt68
-rwxr-xr-xtest/recipes/81-test_cmp_cli_data/Mock/signer.key27
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/signer.p12bin0 -> 5341 bytes
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/signer_issuing.crt45
-rwxr-xr-xtest/recipes/81-test_cmp_cli_data/Mock/signer_only.crt21
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/signer_root.crt22
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/test.cnf140
-rw-r--r--test/recipes/81-test_cmp_cli_data/Mock/trusted.crt19
-rw-r--r--test/recipes/81-test_cmp_cli_data/test_commands.csv54
-rw-r--r--test/recipes/81-test_cmp_cli_data/test_connection.csv43
-rw-r--r--test/recipes/81-test_cmp_cli_data/test_credentials.csv46
-rw-r--r--test/recipes/81-test_cmp_cli_data/test_enrollment.csv112
-rw-r--r--test/recipes/81-test_cmp_cli_data/test_verification.csv51
28 files changed, 7359 insertions, 0 deletions
diff --git a/test/recipes/81-test_cmp_cli.t b/test/recipes/81-test_cmp_cli.t
new file mode 100644
index 0000000000..3be02c6166
--- /dev/null
+++ b/test/recipes/81-test_cmp_cli.t
@@ -0,0 +1,291 @@
+#! /usr/bin/env perl
+# Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright Nokia 2007-2019
+# Copyright Siemens AG 2015-2019
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+use POSIX;
+use File::Spec::Functions qw/catfile/;
+use File::Compare qw/compare_text/;
+use OpenSSL::Test qw/:DEFAULT with data_file data_dir bldtop_dir/;
+use OpenSSL::Test::Utils;
+use Data::Dumper; # for debugging purposes only
+
+setup("test_cmp_cli");
+
+plan skip_all => "This test is not supported in a no-cmp build"
+ if disabled("cmp");
+plan skip_all => "This test is not supported in a no-ec build"
+ if disabled("ec");
+plan skip_all => "Tests involving server not available on Windows or VMS"
+ if $^O =~ /^(VMS|MSWin32)$/;
+
+sub chop_dblquot { # chop any leading & trailing '"' (needed for Windows)
+ my $str = shift;
+ $str =~ s/^\"(.*?)\"$/$1/;
+ return $str;
+}
+
+my $proxy = "<EMPTY>";
+$proxy = chop_dblquot($ENV{http_proxy} // $ENV{HTTP_PROXY} // $proxy);
+$proxy =~ s{^https?://}{}i;
+my $no_proxy = $ENV{no_proxy} // $ENV{NO_PROXY};
+
+my $app = "apps/openssl cmp";
+
+my @cmp_basic_tests = (
+ [ "show help", [ "-config", '""', "-help" ], 0 ],
+ [ "CLI option not starting with '-'", [ "-config", '""', "days", "1" ], 1 ],
+ [ "unknown CLI option", [ "-config", '""', "-dayss" ], 1 ],
+ [ "bad int syntax: non-digit", [ "-config", '""', "-days", "a/" ], 1 ],
+ [ "bad int syntax: float", [ "-config", '""', "-days", "3.14" ], 1 ],
+ [ "bad int syntax: trailing garbage", [ "-config", '""', "-days", "314_+" ], 1 ],
+ [ "bad int: out of range", [ "-config", '""', "-days", "2147483648" ], 1 ],
+);
+
+my $rsp_cert = "signer_only.crt";
+my $outfile = "test.cert.pem";
+my $secret = "pass:test";
+my $localport = 1700;
+
+# this uses the mock server directly in the cmp app, without TCP
+sub use_mock_srv_internally
+{
+ ok(run(cmd([bldtop_dir($app),
+ "-config", '""',
+ "-use_mock_srv", "-srv_ref", "mock server",
+ "-srv_cert", "server.crt", # used for setting sender
+ "-srv_secret", $secret,
+ "-poll_count", "1",
+ "-rsp_cert", $rsp_cert,
+ "-cmd", "cr",
+ "-subject", "/CN=any",
+ "-newkey", "signer.key",
+ "-recipient", "/O=openssl_cmp", # if given must be consistent with sender
+ "-secret", $secret,
+ "-ref", "client under test",
+ "-certout" , $outfile]))
+ && compare_text($outfile, $rsp_cert) == 0,
+ "CMP app with -use_mock_srv and -poll_count 1");
+ unlink $outfile;
+}
+
+# the CMP server configuration consists of:
+my $ca_dn; # The CA's Distinguished Name
+my $server_dn; # The server's Distinguished Name
+my $server_host;# The server's host name or IP address
+my $server_port;# The server's port
+my $server_tls; # The server's TLS port, if any, or 0
+my $server_path;# The server's CMP alias
+my $server_cert;# The server's cert
+my $kur_port; # The server's port for kur (cert update)
+my $pbm_port; # The server port to be used for PBM
+my $pbm_ref; # The reference for PBM
+my $pbm_secret; # The secret for PBM
+my $column; # The column number of the expected result
+my $sleep = 0; # The time to sleep between two requests
+
+# The local $server_name variables below are among others taken as the name of a
+# sub-directory with server-specific certs etc. and CA-specific config section.
+
+sub load_config {
+ my $server_name = shift;
+ my $section = shift;
+ my $test_config = $ENV{OPENSSL_CMP_CONFIG} // "$server_name/test.cnf";
+ open (CH, $test_config) or die "Cannot open $test_config: $!";
+ my $active = 0;
+ while (<CH>) {
+ if (m/\[\s*$section\s*\]/) {
+ $active = 1;
+ } elsif (m/\[\s*.*?\s*\]/) {
+ $active = 0;
+ } elsif ($active) {
+ $ca_dn = $1 eq "" ? '""""' : $1 if m/^\s*ca_dn\s*=\s*(.*)?\s*$/;
+ $server_dn = $1 eq "" ? '""""' : $1 if m/^\s*server_dn\s*=\s*(.*)?\s*$/;
+ $server_host = $1 eq "" ? '""""' : $1 if m/^\s*server_host\s*=\s*(\S*)?\s*(\#.*)?$/;
+ $server_port = $1 eq "" ? '""""' : $1 if m/^\s*server_port\s*=\s*(.*)?\s*$/;
+ $server_tls = $1 eq "" ? '""""' : $1 if m/^\s*server_tls\s*=\s*(.*)?\s*$/;
+ $server_path = $1 eq "" ? '""""' : $1 if m/^\s*server_path\s*=\s*(.*)?\s*$/;
+ $server_cert = $1 eq "" ? '""""' : $1 if m/^\s*server_cert\s*=\s*(.*)?\s*$/;
+ $kur_port = $1 eq "" ? '""""' : $1 if m/^\s*kur_port\s*=\s*(.*)?\s*$/;
+ $pbm_port = $1 eq "" ? '""""' : $1 if m/^\s*pbm_port\s*=\s*(.*)?\s*$/;
+ $pbm_ref = $1 eq "" ? '""""' : $1 if m/^\s*pbm_ref\s*=\s*(.*)?\s*$/;
+ $pbm_secret = $1 eq "" ? '""""' : $1 if m/^\s*pbm_secret\s*=\s*(.*)?\s*$/;
+ $column = $1 eq "" ? '""""' : $1 if m/^\s*column\s*=\s*(.*)?\s*$/;
+ $sleep = $1 eq "" ? '""""' : $1 if m/^\s*sleep\s*=\s*(.*)?\s*$/;
+ }
+ }
+ close CH;
+ die "Cannot find all CMP server config values in $test_config section [$section]\n"
+ if !defined $ca_dn
+ || !defined $server_dn || !defined $server_host
+ || !defined $server_port || !defined $server_tls
+ || !defined $server_path || !defined $server_cert
+ || !defined $kur_port || !defined $pbm_port
+ || !defined $pbm_ref || !defined $pbm_secret
+ || !defined $column || !defined $sleep;
+ $server_dn = $server_dn // $ca_dn;
+}
+
+my @server_configurations = ("Mock");
+@server_configurations = split /\s+/, $ENV{OPENSSL_CMP_SERVER} if $ENV{OPENSSL_CMP_SERVER};
+# set env variable, e.g., OPENSSL_CMP_SERVER="Mock Insta" to include further CMP servers
+
+my @all_aspects = ("connection", "verification", "credentials", "commands", "enrollment");
+@all_aspects = split /\s+/, $ENV{OPENSSL_CMP_ASPECTS} if $ENV{OPENSSL_CMP_ASPECTS};
+# set env variable, e.g., OPENSSL_CMP_ASPECTS="commands enrollment" to select specific aspects
+
+my $faillog;
+if ($ENV{HARNESS_FAILLOG}) {
+ my $file = $ENV{HARNESS_FAILLOG};
+ open($faillog, ">", $file) or die "Cannot open $file for writing: $!";
+}
+
+sub test_cmp_cli {
+ my $server_name = shift;
+ my $aspect = shift;
+ my $n = shift;
+ my $i = shift;
+ my $title = shift;
+ my $params = shift;
+ my $expected_exit = shift;
+ my $path_app = bldtop_dir($app);
+ with({ exit_checker => sub {
+ my $actual_exit = shift;
+ my $OK = $actual_exit == $expected_exit;
+ if ($faillog && !$OK) {
+ sub quote_spc_empty(_) { $_ eq "" ? '""' : $_ =~ m/ / ? '"'.$_.'"' : $_ };
+ my $invocation = ("$path_app ").join(' ', map quote_spc_empty @$params);
+ print $faillog "$server_name $aspect \"$title\" ($i/$n)".
+ " expected=$expected_exit actual=$actual_exit\n";
+ print $faillog "$invocation\n\n";
+ }
+ return $OK; } },
+ sub { ok(run(cmd([$path_app, @$params,])),
+ $title); });
+}
+
+sub test_cmp_cli_aspect {
+ my $server_name = shift;
+ my $aspect = shift;
+ my $tests = shift;
+ subtest "CMP app CLI $server_name $aspect\n" => sub {
+ my $n = scalar @$tests;
+ plan tests => $n;
+ my $i = 1;
+ foreach (@$tests) {
+ SKIP: {
+ test_cmp_cli($server_name, $aspect, $n, $i++, $$_[0], $$_[1], $$_[2]);
+ sleep($sleep);
+ }
+ }
+ };
+ unlink "test.cert.pem", "test.cacerts.pem", "test.extracerts.pem";
+}
+
+indir data_dir() => sub {
+ plan tests => 1 + @server_configurations * @all_aspects
+ + (grep(/^Mock$/, @server_configurations)
+ && grep(/^certstatus$/, @all_aspects) ? 0 : 1);
+
+ test_cmp_cli_aspect("basic", "options", \@cmp_basic_tests);
+
+ indir "Mock" => sub {
+ use_mock_srv_internally();
+ };
+
+ foreach my $server_name (@server_configurations) {
+ $server_name = chop_dblquot($server_name);
+ load_config($server_name, $server_name);
+ my $launch_mock = $server_name eq "Mock" && !$ENV{OPENSSL_CMP_CONFIG};
+ if ($launch_mock) {
+ indir "Mock" => sub {
+ stop_mock_server(); # in case a previous run did not exit properly
+ start_mock_server("") || die "Cannot start CMP mock server";
+ }
+ }
+ foreach my $aspect (@all_aspects) {
+ $aspect = chop_dblquot($aspect);
+ next if $server_name eq "Mock" && $aspect eq "certstatus";
+ load_config($server_name, $aspect); # update with any aspect-specific settings
+ indir $server_name => sub {
+ my $tests = load_tests($server_name, $aspect);
+ test_cmp_cli_aspect($server_name, $aspect, $tests);
+ };
+ };
+ stop_mock_server() if $launch_mock;
+ };
+};
+
+close($faillog) if $faillog;
+
+sub load_tests {
+ my $server_name = shift;
+ my $aspect = shift;
+ my $test_config = $ENV{OPENSSL_CMP_CONFIG} // "$server_name/test.cnf";
+ my $file = data_file("test_$aspect.csv");
+ my @result;
+
+ open(my $data, '<', $file) || die "Cannot open $file for reading: $!";
+ LOOP:
+ while (my $line = <$data>) {
+ chomp $line;
+ $line =~ s{\r\n}{\n}g; # adjust line endings
+ $line =~ s{_CA_DN}{$ca_dn}g;
+ $line =~ s{_SERVER_DN}{$server_dn}g;
+ $line =~ s{_SERVER_HOST}{$server_host}g;
+ $line =~ s{_SERVER_PORT}{$server_port}g;
+ $line =~ s{_SERVER_TLS}{$server_tls}g;
+ $line =~ s{_SERVER_PATH}{$server_path}g;
+ $line =~ s{_SERVER_CERT}{$server_cert}g;
+ $line =~ s{_KUR_PORT}{$kur_port}g;
+ $line =~ s{_PBM_PORT}{$pbm_port}g;
+ $line =~ s{_PBM_REF}{$pbm_ref}g;
+ $line =~ s{_PBM_SECRET}{$pbm_secret}g;
+ my $noproxy = $line =~ m/,\s*-no_proxy\s*,(.*?)(,|$)/ ? $1 : $no_proxy;
+ next LOOP if $no_proxy && ($noproxy =~ $server_host)
+ && $line =~ m/,\s*-proxy\s*,/;
+ next LOOP if $server_tls == 0 && $line =~ m/,\s*-tls_used\s*,/;
+ $line =~ s{-section,,}{-section,,-proxy,$proxy,} unless $line =~ m/,\s*-proxy\s*,/;
+ $line =~ s{-section,,}{-config,../$test_config,-section,$server_name $aspect,};
+ my @fields = grep /\S/, split ",", $line;
+ s/^<EMPTY>$// for (@fields); # used for proxy=""
+ s/^\s+// for (@fields); # remove leading whitespace from elements
+ s/\s+$// for (@fields); # remove trailing whitespace from elements
+ s/^\"(\".*?\")\"$/$1/ for (@fields); # remove escaping from quotation marks from elements
+ my $expected_exit = $fields[$column];
+ my $description = 1;
+ my $title = $fields[$description];
+ next LOOP if (!defined($expected_exit)
+ || ($expected_exit ne 0 && $expected_exit ne 1));
+ @fields = grep {$_ ne 'BLANK'} @fields[$description + 1 .. @fields - 1];
+ push @result, [$title, \@fields, $expected_exit];
+ }
+ close($data);
+ return \@result;
+}
+
+sub mock_server_pid {
+ return `lsof -iTCP:$localport -sTCP:LISTEN | tail -n 1 | awk '{ print \$2 }'`;
+}
+
+sub start_mock_server {
+ return 0 if mock_server_pid(); # already running
+ my $args = $_[0]; # optional further CLI arguments
+ my $dir = bldtop_dir("");
+ return system("LD_LIBRARY_PATH=$dir DYLD_LIBRARY_PATH=$dir " .
+ bldtop_dir($app) . " -config server.cnf " .
+ "$args &") == 0; # start in background, check for success
+}
+
+sub stop_mock_server {
+ my $pid = mock_server_pid();
+ system("kill $pid") if $pid;
+}
diff --git a/test/recipes/81-test_cmp_cli_data/Mock/12345.txt b/test/recipes/81-test_cmp_cli_data/Mock/12345.txt
new file mode 100644
index 0000000000..e56e15bb7d
--- /dev/null
+++ b/test/recipes/81-test_cmp_cli_data/Mock/12345.txt
@@ -0,0 +1 @@
+12345
diff --git a/test/recipes/81-test_cmp_cli_data/Mock/big_issuing.crt b/test/recipes/81-test_cmp_cli_data/Mock/big_issuing.crt
new file mode 100644
index 0000000000..e96f3cf788
--- /dev/null
+++ b/test/recipes/81-test_cmp_cli_data/Mock/big_issuing.crt
@@ -0,0 +1,1577 @@
+Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz
+WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T
+dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD
+EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj
+vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz
+2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW
+VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90
+OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL
+857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ
+Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp
+Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ
+YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8
+8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ
+pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E
+mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq
+YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U
+gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg==
+-----END CERTIFICATE-----
+
+Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA
+-----BEGIN CERTIFICATE-----
+MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa
+Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
+YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT
+B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO
+nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6
+iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo
+D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm
+H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+
+2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6
+hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5
+j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239
+MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ
+4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9
+Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U
+7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/
+e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU
+wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb
+-----END CERTIFICATE-----
+
+
+
+-----BEGIN CERTIFICATE-----
+MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT
+AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu
+ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50
+YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j
+b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT
+wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2
+g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY
+fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud
+JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB
+h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f
+BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l
+dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH
+AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds
+ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC
+GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91
+dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5
+b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t
+ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy
+bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl
+LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv
+b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh
+cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n
+b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC
+CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl
+LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv
+b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL
+Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu
+Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv
+b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL
+Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n
+bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n
+bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n
+bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n
+bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n
+bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n
+bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n
+bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n
+bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n
+bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v
+Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou
+Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC
+DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u
+YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j
+b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds
+ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv
+b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q
+Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp
+gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t
+Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu
+Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n
+bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n
+b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP
+Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u
+aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv
+bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl
+LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v
+Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou
+Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC
+DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u
+c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j
+b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds
+ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv
+b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu
+ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v
+Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq
+Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n
+ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n
+bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou
+Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1
+ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v
+Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv
+ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v
+Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq
+Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s
+dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n
+bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou
+Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12
+ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv
+b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC
+CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv
+b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL
+Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu
+cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v
+Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq
+Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50
+Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n
+bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou
+Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1
+ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ
+Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n
+bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i
+ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln
+b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n
+bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j
+aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn
+b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu
+Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC
+DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds
+ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s
+c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v
+Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv
+LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn
+b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu
+Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t
+LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo
+gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n
+b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n
+bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu
+Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t
+LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo
+gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n
+b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n
+bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu
+Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t
+Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m
+gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n
+b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n
+bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu
+Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t
+LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi
+gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n
+b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n
+bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu
+Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC
+CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v
+Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu
+ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ
+Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n
+bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o
+coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn
+b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v
+Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv
+b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl
+Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC
+CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v
+Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu
+bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q
+cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ
+Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ
+Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n
+bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z
+ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln
+b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds
+ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu
+gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv
+b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG
+9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD
+LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8
+KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA==
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT
+AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu
+ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50
+YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j
+b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT
+wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2
+g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY
+fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud
+JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB
+h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f
+BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l
+dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH
+AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds
+ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC
+GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91
+dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5
+b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t
+ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy
+bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl
+LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv
+b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh
+cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n
+b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC
+CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl
+LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv
+b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL
+Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu
+Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv
+b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL
+Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n
+bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n
+bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n
+bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n
+bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n
+bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n
+bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n
+bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n
+bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n
+bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v
+Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou
+Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC
+DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u
+YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j
+b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds
+ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv
+b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q
+Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp
+gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t
+Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu
+Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n
+bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n
+b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP
+Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u
+aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv
+bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl
+LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v
+Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou
+Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC
+DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u
+c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j
+b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds
+ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv
+b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu
+ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v
+Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq
+Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n
+ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n
+bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou
+Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1
+ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v
+Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv
+ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v
+Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq
+Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s
+dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n
+bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou
+Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12
+ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv
+b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC
+Cy